Chi-Tech
lbs_04c_io_flux_moments.cc
Go to the documentation of this file.
1#include "lbs_solver.h"
2
4
5#include "chi_runtime.h"
6#include "chi_log.h"
7
8#include <fstream>
9#include <cstring>
10#include <cassert>
11
12//###################################################################
13/**Makes a source-moments vector from scattering and fission based
14 * on the latest phi-solution.*/
15std::vector<double> lbs::LBSSolver::
17{
18 size_t num_local_dofs = discretization_->GetNumLocalDOFs(flux_moments_uk_man_);
19
20 std::vector<double> source_moments(num_local_dofs,0.0);
21 for (auto& groupset : groupsets_)
22 {
24 groupset,
25 source_moments,
29 }
30
31 return source_moments;
32}
33
34
35//###################################################################
36/**Writes a given flux-moments vector to file.*/
38 WriteFluxMoments(const std::string &file_base,
39 const std::vector<double>& flux_moments)
40{
41 std::string file_name =
42 file_base + std::to_string(Chi::mpi.location_id) + ".data";
43
44 //============================================= Open file
45 Chi::log.Log() << "Writing flux-moments to files with base-name " << file_base
46 << " and extension .data";
47 std::ofstream file(file_name,
48 std::ofstream::binary | //binary file
49 std::ofstream::out | //no accidental reading
50 std::ofstream::trunc); //clear file contents when opened
51
52 //============================================= Check file is open
53 if (not file.is_open())
54 {
56 << __FUNCTION__ << "Failed to open " << file_name;
57 return;
58 }
59
60 //============================================= Write header
61 std::string header_info =
62 "Chi-Tech LinearBoltzmann: Flux moments file\n"
63 "Header size: 500 bytes\n"
64 "Structure(type-info):\n"
65 "uint64_t num_local_nodes\n"
66 "uint64_t num_moments\n"
67 "uint64_t num_groups\n"
68 "uint64_t num_records\n"
69 "uint64_t num_cells\n"
70 "Each cell:\n"
71 " uint64_t cell_global_id\n"
72 " uint64_t num_nodes\n"
73 " Each node:\n"
74 " double x_position\n"
75 " double y_position\n"
76 " double z_position\n"
77 "Each record:\n"
78 " uint64_t cell_global_id\n"
79 " unsigned int node_number\n"
80 " unsigned int moment_num\n"
81 " unsigned int group_num\n"
82 " double flux_moment_value\n";
83
84 int header_size = (int)header_info.length();
85
86 char header_bytes[500];
87 memset(header_bytes, '-', 500);
88 strncpy(header_bytes, header_info.c_str(),std::min(header_size,499));
89 header_bytes[499]='\0';
90
91 file << header_bytes;
92
93 //============================================= Get relevant items
95 auto& sdm = discretization_;
96 uint64_t num_local_nodes = discretization_->GetNumLocalDOFs(NODES_ONLY);
97 uint64_t num_moments_t = static_cast<uint64_t>(num_moments_);
98 uint64_t num_groups_t = static_cast<uint64_t>(num_groups_);
99 uint64_t num_local_dofs = discretization_->GetNumLocalDOFs(flux_moments_uk_man_);
100 uint64_t num_local_cells = grid_ptr_->local_cells.size();
101
102 //============================================= Write num_ quantities
103 file.write((char*)&num_local_nodes,sizeof(uint64_t));
104 file.write((char*)&num_moments_t ,sizeof(uint64_t));
105 file.write((char*)&num_groups_t ,sizeof(uint64_t));
106 file.write((char*)&num_local_dofs ,sizeof(uint64_t));
107 file.write((char*)&num_local_cells,sizeof(uint64_t));
108
109 //============================================= Write nodal positions for
110 // each cell
111 for (const auto& cell : grid_ptr_->local_cells)
112 {
113 uint64_t cell_global_id = static_cast<uint64_t>(cell.global_id_);
114 file.write((char *) &cell_global_id, sizeof(uint64_t));
115
116 uint64_t num_nodes = discretization_->GetCellNumNodes(cell);
117 file.write((char *) &num_nodes, sizeof(uint64_t));
118
119 auto node_locations = discretization_->GetCellNodeLocations(cell);
120 for (const auto& node : node_locations)
121 {
122 file.write((char *) &node.x, sizeof(double));
123 file.write((char *) &node.y, sizeof(double));
124 file.write((char *) &node.z, sizeof(double));
125 }//for node
126 }//for cell
127
128 //============================================= Write per dof data
129 for (const auto& cell : grid_ptr_->local_cells)
130 for (unsigned int i=0; i<sdm->GetCellNumNodes(cell); ++i)
131 for (unsigned int m=0; m<num_moments_t; ++m)
132 for (unsigned int g=0; g < num_groups_; ++g)
133 {
134 uint64_t cell_global_id = cell.global_id_;
135 uint64_t dof_map = sdm->MapDOFLocal(cell, i, flux_moments_uk_man_, m, g);
136
137 assert(dof_map < flux_moments.size());
138 double value = flux_moments[dof_map];
139
140 file.write((char*)&cell_global_id,sizeof(uint64_t));
141 file.write((char*)&i ,sizeof(unsigned int));
142 file.write((char*)&m ,sizeof(unsigned int));
143 file.write((char*)&g ,sizeof(unsigned int));
144 file.write((char*)&value ,sizeof(double));
145 }
146
147 //============================================= Clean-up
148 file.close();
149}
150
151
152//###################################################################
153/**Reads a flux-moments vector from a file in the specified vector.*/
155 const std::string &file_base,
156 std::vector<double>& flux_moments,
157 bool single_file/*=false*/)
158{
159 std::string file_name =
160 file_base + std::to_string(Chi::mpi.location_id) + ".data";
161 if (single_file)
162 file_name = file_base + ".data";
163
164 //============================================= Open file
165 Chi::log.Log() << "Reading flux-moments file " << file_name;
166 std::ifstream file(file_name,
167 std::ofstream::binary | //binary file
168 std::ofstream::in); //no accidental writing
169
170 //============================================= Check file is open
171 if (not file.is_open())
172 {
174 << __FUNCTION__ << "Failed to open " << file_name;
175 return;
176 }
177
178 //============================================= Get relevant items
180 auto& sdm = discretization_;
181 uint64_t num_local_nodes = discretization_->GetNumLocalDOFs(NODES_ONLY);
182 uint64_t num_moments_t = static_cast<uint64_t>(num_moments_);
183 uint64_t num_groups_t = static_cast<uint64_t>(num_groups_);
184 uint64_t num_local_dofs = discretization_->GetNumLocalDOFs(flux_moments_uk_man_);
185 uint64_t num_local_cells = grid_ptr_->local_cells.size();
186
187 uint64_t file_num_local_nodes;
188 uint64_t file_num_moments ;
189 uint64_t file_num_groups ;
190 uint64_t file_num_local_dofs ;
191 uint64_t file_num_local_cells;
192
193 flux_moments.assign(num_local_dofs,0.0);
194
195 //============================================= Read header
196 char header_bytes[500]; header_bytes[499] = '\0';
197 file.read(header_bytes,499);
198
199 file.read((char*)&file_num_local_nodes, sizeof(uint64_t));
200 file.read((char*)&file_num_moments , sizeof(uint64_t));
201 file.read((char*)&file_num_groups , sizeof(uint64_t));
202 file.read((char*)&file_num_local_dofs , sizeof(uint64_t));
203 file.read((char*)&file_num_local_cells, sizeof(uint64_t));
204
205 //============================================= Check compatibility
206 if (not single_file)
207 if (file_num_local_nodes != num_local_nodes or
208 file_num_moments != num_moments_t or
209 file_num_groups != num_groups_t or
210 file_num_local_dofs != num_local_dofs or
211 file_num_local_cells != num_local_cells)
212 {
213 std::stringstream outstr;
214 outstr << "num_local_nodes: " << file_num_local_nodes << " vs "
215 << num_local_nodes << "\n";
216 outstr << "num_moments_ : " << file_num_moments << " vs "
217 << num_moments_t << "\n";
218 outstr << "num_groups : " << file_num_groups << " vs "
219 << num_groups_ << "\n";
220 outstr << "num_local_dofs : " << file_num_local_dofs << " vs "
221 << num_local_dofs << "\n";
222 outstr << "num_local_cells: " << file_num_local_cells << " vs "
223 << num_local_cells << "\n";
225 << "Incompatible DOF data found in file " << file_name << "\n"
226 << "File data vs system:\n" << outstr.str();
227 file.close();
228 return;
229 }
230
231 //============================================= Read cell nodal locations
232 std::map<uint64_t, std::map<uint64_t,uint64_t>> file_cell_nodal_mapping;
233 for (uint64_t c=0; c < file_num_local_cells; ++c)
234 {
235 //============================ Read cell-id and num_nodes
236 uint64_t cell_global_id;
237 uint64_t num_nodes;
238
239 file.read((char*)&cell_global_id, sizeof(uint64_t));
240 file.read((char*)&num_nodes , sizeof(uint64_t));
241
242 //============================ Read node locations
243 std::vector<chi_mesh::Vector3> file_node_locations;
244 file_node_locations.reserve(num_nodes);
245 for (uint64_t n=0; n < num_nodes; ++n)
246 {
247 double x,y,z;
248 file.read((char*)&x, sizeof(double));
249 file.read((char*)&y, sizeof(double));
250 file.read((char*)&z, sizeof(double));
251
252 file_node_locations.emplace_back(x,y,z);
253 }//for file node n
254
255 if (not grid_ptr_->IsCellLocal(cell_global_id)) continue;
256
257 const auto& cell = grid_ptr_->cells[cell_global_id];
258
259 //================ Now map file nodes to system nodes
260 auto system_node_locations = discretization_->GetCellNodeLocations(cell);
261 std::map<uint64_t,uint64_t> mapping;
262
263 //Check num_nodes equal
264 if (system_node_locations.size() != num_nodes)
265 throw std::logic_error(std::string(__FUNCTION__) +
266 ": Incompatible number of nodes for a cell was encountered. Mapping "
267 "could not be performed.");
268
269 bool mapping_successful = true; //Assume true, now try to disprove
270
271 const auto &sys_nodes = system_node_locations;
272 const auto &file_nodes = file_node_locations;
273 size_t num_system_nodes = system_node_locations.size();
274
275 for (uint64_t n = 0; n < num_nodes; ++n)
276 {
277 bool mapping_found = false;
278 for (uint64_t m = 0; m < num_system_nodes; ++m)
279 if ((sys_nodes[m] - file_nodes[n]).NormSquare() < 1.0e-12) {
280 mapping[n] = m; mapping_found = true; }
281
282 if (not mapping_found) {
283 mapping_successful = false; break; }
284 }//for n
285
286 if (not mapping_successful)
287 throw std::logic_error(std::string(__FUNCTION__) +
288 ": Incompatible node locations for a cell was encountered. Mapping "
289 "unsuccessful.");
290
291 file_cell_nodal_mapping[cell_global_id] = std::move(mapping);
292 }//for c (cell in file)
293
294 //============================================= Commit to reading the file
295 for (size_t dof=0; dof < file_num_local_dofs; ++dof)
296 {
297 uint64_t cell_global_id;
298 unsigned int node;
299 unsigned int moment;
300 unsigned int group;
301 double flux_value;
302
303 file.read((char*)&cell_global_id,sizeof(uint64_t));
304 file.read((char*)&node ,sizeof(unsigned int));
305 file.read((char*)&moment ,sizeof(unsigned int));
306 file.read((char*)&group ,sizeof(unsigned int));
307 file.read((char*)&flux_value ,sizeof(double));
308
309 if (grid_ptr_->IsCellLocal(cell_global_id))
310 {
311 const auto& cell = grid_ptr_->cells[cell_global_id];
312 const auto& node_mapping = file_cell_nodal_mapping.at(cell_global_id);
313
314 size_t node_mapped = node_mapping.at(node);
315
316 size_t dof_map = sdm->MapDOFLocal(cell,
317 node_mapped,
318 flux_moments_uk_man_,
319 moment,
320 group);
321
322 assert(dof_map < flux_moments.size());
323 flux_moments[dof_map] = flux_value;
324 }//if cell is local
325 }//for dof
326
327 //============================================= Clean-up
328 file.close();
329}
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream LogAll()
Definition: chi_log.h:237
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
LogStream LogAllWarning()
Definition: chi_log.h:238
static UnknownManager GetUnitaryUnknownManager()
std::shared_ptr< chi_math::SpatialDiscretization > discretization_
Definition: lbs_solver.h:74
std::vector< double > MakeSourceMomentsFromPhi()
chi_math::UnknownManager flux_moments_uk_man_
Definition: lbs_solver.h:88
void ReadFluxMoments(const std::string &file_base, std::vector< double > &flux_moments, bool single_file=false)
std::vector< LBSGroupset > groupsets_
Definition: lbs_solver.h:68
void WriteFluxMoments(const std::string &file_base, const std::vector< double > &flux_moments)
std::vector< double > & PhiOldLocal()
SetSourceFunction active_set_source_function_
Definition: lbs_solver.h:99
@ APPLY_AGS_FISSION_SOURCES
Definition: lbs_structs.h:94
@ APPLY_WGS_FISSION_SOURCES
Definition: lbs_structs.h:93
@ APPLY_WGS_SCATTER_SOURCES
Definition: lbs_structs.h:91
@ APPLY_AGS_SCATTER_SOURCES
Definition: lbs_structs.h:92