|
1 | 1 | #include "openmc/summary.h" |
2 | 2 |
|
3 | 3 | #include <fmt/core.h> |
| 4 | +#include <map> |
4 | 5 |
|
5 | 6 | #include "openmc/capi.h" |
6 | 7 | #include "openmc/cell.h" |
@@ -93,25 +94,139 @@ void write_nuclides(hid_t file) |
93 | 94 | close_group(macro_group); |
94 | 95 | } |
95 | 96 |
|
| 97 | +void write_triso_particles(hid_t geom_group) |
| 98 | +{ |
| 99 | + // Collect all TRISO surfaces and group by background cell ID |
| 100 | + std::map<int32_t, vector<int32_t>> bg_to_surfs; |
| 101 | + for (int i = 0; i < model::surfaces.size(); ++i) { |
| 102 | + const auto& surf = model::surfaces[i]; |
| 103 | + if (surf->is_triso_surface_) { |
| 104 | + bg_to_surfs[surf->triso_base_index_].push_back(i); |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + int n_groups = bg_to_surfs.size(); |
| 109 | + if (n_groups == 0) |
| 110 | + return; |
| 111 | + |
| 112 | + // Count total TRISO particles |
| 113 | + int n_triso = 0; |
| 114 | + for (const auto& [bg_id, surfs] : bg_to_surfs) { |
| 115 | + n_triso += surfs.size(); |
| 116 | + } |
| 117 | + |
| 118 | + // Build flat arrays |
| 119 | + vector<double> positions(n_triso * 4); |
| 120 | + vector<int32_t> surface_ids(n_triso); |
| 121 | + vector<int32_t> cell_ids(n_triso); |
| 122 | + vector<int32_t> fill_universes(n_triso); |
| 123 | + vector<int32_t> group_offsets(n_groups + 1); |
| 124 | + |
| 125 | + int idx = 0; |
| 126 | + int g = 0; |
| 127 | + group_offsets[0] = 0; |
| 128 | + |
| 129 | + for (const auto& [bg_cell_id, surfs] : bg_to_surfs) { |
| 130 | + for (const auto& i_surf : surfs) { |
| 131 | + const auto& surf = model::surfaces[i_surf]; |
| 132 | + vector<double> center = surf->get_center(); |
| 133 | + double radius = surf->get_radius(); |
| 134 | + positions[idx * 4 + 0] = center[0]; |
| 135 | + positions[idx * 4 + 1] = center[1]; |
| 136 | + positions[idx * 4 + 2] = center[2]; |
| 137 | + positions[idx * 4 + 3] = radius; |
| 138 | + surface_ids[idx] = surf->id_; |
| 139 | + // Get TRISO particle cell via triso_particle_index_ |
| 140 | + int32_t i_cell = model::cell_map.at(surf->triso_particle_index_); |
| 141 | + const auto& cell = model::cells[i_cell]; |
| 142 | + cell_ids[idx] = cell->id_; |
| 143 | + fill_universes[idx] = model::universes[cell->fill_]->id_; |
| 144 | + ++idx; |
| 145 | + } |
| 146 | + group_offsets[g + 1] = idx; |
| 147 | + ++g; |
| 148 | + } |
| 149 | + |
| 150 | + // Write compact TRISO data to HDF5 |
| 151 | + hid_t triso_group = create_group(geom_group, "triso_particles"); |
| 152 | + write_attribute(triso_group, "n_groups", n_groups); |
| 153 | + write_attribute(triso_group, "n_triso", n_triso); |
| 154 | + |
| 155 | + // Write positions as 2D dataset [n_triso, 4] |
| 156 | + hsize_t pos_dims[] = {static_cast<hsize_t>(n_triso), 4}; |
| 157 | + write_dataset_lowlevel(triso_group, 2, pos_dims, "positions", |
| 158 | + H5TypeMap<double>::type_id, H5S_ALL, false, positions.data()); |
| 159 | + |
| 160 | + write_dataset(triso_group, "surface_ids", surface_ids); |
| 161 | + write_dataset(triso_group, "cell_ids", cell_ids); |
| 162 | + write_dataset(triso_group, "fill_universes", fill_universes); |
| 163 | + write_dataset(triso_group, "group_offsets", group_offsets); |
| 164 | + |
| 165 | + // Write per-group metadata (background cell info) |
| 166 | + hid_t groups_group = create_group(triso_group, "groups"); |
| 167 | + g = 0; |
| 168 | + for (const auto& [bg_cell_id, surfs] : bg_to_surfs) { |
| 169 | + auto grp = create_group(groups_group, std::to_string(g)); |
| 170 | + |
| 171 | + int32_t i_bg_cell = model::cell_map.at(bg_cell_id); |
| 172 | + const auto& bg_cell = model::cells[i_bg_cell]; |
| 173 | + |
| 174 | + write_dataset(grp, "background_cell_id", bg_cell->id_); |
| 175 | + write_dataset(grp, "background_material_id", |
| 176 | + model::materials[bg_cell->material_[0]]->id_); |
| 177 | + write_dataset(grp, "background_universe_id", |
| 178 | + model::universes[bg_cell->universe_]->id_); |
| 179 | + write_dataset(grp, "vl_lower_left", bg_cell->vl_lower_left_); |
| 180 | + write_dataset(grp, "vl_pitch", bg_cell->vl_pitch_); |
| 181 | + write_dataset(grp, "vl_shape", bg_cell->vl_shape_); |
| 182 | + |
| 183 | + close_group(grp); |
| 184 | + ++g; |
| 185 | + } |
| 186 | + close_group(groups_group); |
| 187 | + close_group(triso_group); |
| 188 | +} |
| 189 | + |
96 | 190 | void write_geometry(hid_t file) |
97 | 191 | { |
98 | 192 | auto geom_group = create_group(file, "geometry"); |
99 | 193 |
|
100 | | - write_attribute(geom_group, "n_cells", model::cells.size()); |
101 | | - write_attribute(geom_group, "n_surfaces", model::surfaces.size()); |
| 194 | + // Count non-TRISO cells and surfaces for accurate counts |
| 195 | + int n_cells = 0; |
| 196 | + int n_surfaces = 0; |
| 197 | + for (const auto& c : model::cells) { |
| 198 | + if (!c->triso_particle_ && !c->virtual_lattice_) |
| 199 | + ++n_cells; |
| 200 | + } |
| 201 | + for (const auto& surf : model::surfaces) { |
| 202 | + if (!surf->is_triso_surface_) |
| 203 | + ++n_surfaces; |
| 204 | + } |
| 205 | + |
| 206 | + write_attribute(geom_group, "n_cells", n_cells); |
| 207 | + write_attribute(geom_group, "n_surfaces", n_surfaces); |
102 | 208 | write_attribute(geom_group, "n_universes", model::universes.size()); |
103 | 209 | write_attribute(geom_group, "n_lattices", model::lattices.size()); |
104 | 210 |
|
105 | 211 | auto cells_group = create_group(geom_group, "cells"); |
106 | | - for (const auto& c : model::cells) |
| 212 | + for (const auto& c : model::cells) { |
| 213 | + if (c->triso_particle_ || c->virtual_lattice_) |
| 214 | + continue; |
107 | 215 | c->to_hdf5(cells_group); |
| 216 | + } |
108 | 217 | close_group(cells_group); |
109 | 218 |
|
110 | 219 | auto surfaces_group = create_group(geom_group, "surfaces"); |
111 | | - for (const auto& surf : model::surfaces) |
| 220 | + for (const auto& surf : model::surfaces) { |
| 221 | + if (surf->is_triso_surface_) |
| 222 | + continue; |
112 | 223 | surf->to_hdf5(surfaces_group); |
| 224 | + } |
113 | 225 | close_group(surfaces_group); |
114 | 226 |
|
| 227 | + // Write compact TRISO particle data |
| 228 | + write_triso_particles(geom_group); |
| 229 | + |
115 | 230 | auto universes_group = create_group(geom_group, "universes"); |
116 | 231 | for (const auto& u : model::universes) |
117 | 232 | u->to_hdf5(universes_group); |
|
0 commit comments