Chi-Tech
lbsadj_solver_05a_export_imp.cc
Go to the documentation of this file.
1#include "lbsadj_solver.h"
2
3#include "chi_runtime.h"
4#include "chi_log.h"
5#include "chi_mpi.h"
6
7
10
11#include "lbs_adjoint.h"
12
13#include <fstream>
14
15//###################################################################
16/**Exports an importance map in binary format.*/
18 ExportImportanceMap(const std::string &file_name)
19{
20 const std::string fname = __FUNCTION__;
21
22 //============================================= Determine cell averaged
23 // importance map
24 std::set<int> set_group_numbers;
25 for (const auto& groupset : groupsets_)
26 for (const auto& group : groupset.groups_)
27 set_group_numbers.insert(group.id_);
28
29 const auto& m_to_ell_em_map =
30 groupsets_.front().quadrature_->GetMomentToHarmonicsIndexMap();
31
32 typedef chi_math::VectorN<4> Arr4; //phi, J_x, J_y, J_z
33 typedef std::vector<Arr4> MGVec4;
34 typedef std::vector<MGVec4> VecOfMGVec4;
35 const size_t num_groups = set_group_numbers.size();
36 const size_t num_cells = grid_ptr_->local_cells.size();
37
38 VecOfMGVec4 cell_avg_p1_moments(num_cells, MGVec4(num_groups));
39 {
40
41 for (const auto& cell : grid_ptr_->local_cells)
42 {
43 const auto& cell_view = cell_transport_views_[cell.local_id_];
44 const int num_nodes = cell_view.NumNodes();
45 const auto& fe_values = unit_cell_matrices_[cell.local_id_];
46
47 VecOfMGVec4 nodal_p1_moments(num_nodes);
48 for (int i = 0; i < num_nodes; ++i)
49 {
50 //==================================== Get multigroup p1_moments
51 MGVec4 p1_moments(set_group_numbers.size(), VecDbl{0.0,0.0,0.0,0.0});
52 for (int m=0; m < std::max(static_cast<int>(num_moments_), 4); ++m)
53 {
54 const auto& ell = m_to_ell_em_map[m].ell;
55 const auto& em = m_to_ell_em_map[m].m;
56
57 size_t dof_map_g0 = cell_view.MapDOF(i, m, 0); //unknown map
58
59 for (int g : set_group_numbers)
60 {
61 if (ell==0 and em== 0) p1_moments[g](0) = std::fabs(phi_old_local_[dof_map_g0 + g]);
62 if (ell==1 and em== 1) p1_moments[g](1) = phi_old_local_[dof_map_g0 + g];
63 if (ell==1 and em==-1) p1_moments[g](2) = phi_old_local_[dof_map_g0 + g];
64 if (ell==1 and em== 0) p1_moments[g](3) = phi_old_local_[dof_map_g0 + g];
65 }//for g
66 }//for m
67
68 nodal_p1_moments[i] = std::move(p1_moments);
69 }//for node i
70
71 //=========================================== Determine nodal average
72 // p1_moments
73 for (int g : set_group_numbers)
74 {
75 chi_math::VectorN<4> cell_p1_avg(VecDbl{0.0,0.0,0.0,0.0});
76
77 double volume_total = 0.0;
78 for (int i=0; i < num_nodes; ++i)
79 {
80 double IntV_shapeI = fe_values.Vi_vectors[i];
81 cell_p1_avg += nodal_p1_moments[i][g] * IntV_shapeI;
82 volume_total += IntV_shapeI;
83 }//for node i
84 cell_p1_avg /= volume_total;
85
86 cell_avg_p1_moments[cell.local_id_][g] = cell_p1_avg;
87 }//for g
88 }//for cell
89 }
90
91 //============================================= Determine cell-based
92 // exponential-representations
93 typedef std::pair<double, double> ABCoeffsPair;
94 typedef std::vector<ABCoeffsPair> VecOfABCoeffsPair;
95 typedef std::vector<VecOfABCoeffsPair> ExpReps;
96 ExpReps cell_exp_reps(num_cells,VecOfABCoeffsPair(num_groups, {0.0,0.0}));
97 {
98 for (const auto& cell : grid_ptr_->local_cells)
99 {
100 for (int g : set_group_numbers)
101 {
102 const auto& p1_moments = cell_avg_p1_moments[cell.local_id_][g];
103
104 auto a_b = MakeExpRepFromP1({p1_moments[0],
105 p1_moments[1],
106 p1_moments[2],
107 p1_moments[3]});
108
109 cell_exp_reps[cell.local_id_][g] = std::make_pair(a_b[0], a_b[1]);
110 }//for g
111 }//for cell
112 }
113
114 Chi::log.Log() << "Exporting importance map to binary file " << file_name;
115
116 const auto locJ_io_flags = std::ofstream::binary | std::ofstream::out;
117 const auto loc0_io_flags = locJ_io_flags | std::ofstream::trunc;
118 const bool is_home = (Chi::mpi.location_id == 0);
119
120 //======================================== Build header
121 std::string header_info =
122 "Chi-Tech LinearBoltzmann: Importance map file\n"
123 "Header size: 500 bytes\n"
124 "Structure(type-info):\n"
125 "uint64_t num_global_cells\n"
126 "uint64_t num_groups\n"
127 "uint64_t num_records\n"
128 "Each record:\n"
129 " uint64_t cell_global_id\n"
130 " unsigned int group_num\n"
131 " double phi\n"
132 " double J_x\n"
133 " double J_y\n"
134 " double J_z\n"
135 " double a_coefficient\n"
136 " double b_coefficient\n";
137
138 int header_size = (int)header_info.length();
139
140 char header_bytes[400];
141 memset(header_bytes, '-', 400);
142 strncpy(header_bytes, header_info.c_str(),std::min(header_size,399));
143 header_bytes[399]='\0';
144
145 //================================================== Process each location
146 uint64_t num_global_cells = grid_ptr_->GetGlobalNumberOfCells();
147 for (int locationJ=0; locationJ< Chi::mpi.process_count; ++locationJ)
148 {
149 Chi::log.LogAll() << " Barrier at " << locationJ;
151 if (Chi::mpi.location_id != locationJ) continue;
152
153 Chi::log.LogAll() << " Location " << locationJ << " appending data.";
154
155 std::ofstream file(file_name, is_home? loc0_io_flags : locJ_io_flags);
156
157 if (not file.is_open())
158 {
159 std::stringstream outstr;
160
161 outstr << fname << ": Location " << Chi::mpi.location_id
162 << ", failed to open file " << file_name;
163 throw std::logic_error(outstr.str());
164 }
165
166 if (is_home)
167 {
168 file << header_bytes;
169 uint64_t num_groups_t = groups_.size();
170 uint64_t num_records = num_global_cells * num_groups;
171
172 file.write((char*)&num_global_cells ,sizeof(uint64_t));
173 file.write((char*)&num_groups_t ,sizeof(uint64_t));
174 file.write((char*)&num_records ,sizeof(uint64_t));
175 }
176
177 for (const auto& cell : grid_ptr_->local_cells)
178 {
179 MGVec4 p1_moments = cell_avg_p1_moments[cell.local_id_];
180 VecOfABCoeffsPair exp_rep = cell_exp_reps[cell.local_id_];
181
182 auto cell_global_id = static_cast<uint64_t>(cell.global_id_);
183 for (int group : set_group_numbers)
184 {
185 auto g = static_cast<unsigned int>(group);
186 file.write((char *) &cell_global_id, sizeof(uint64_t));
187 file.write((char *) &g, sizeof(unsigned int));
188
189 for (int m=0; m<4; ++m)
190 file.write((char *) &p1_moments[group](m), sizeof(double));
191
192 file.write((char *) &exp_rep[group].first , sizeof(double));
193 file.write((char *) &exp_rep[group].second, sizeof(double));
194 }//for g
195 }//for cell
196
197 file.close();
198 }//for location
199
200 Chi::log.LogAll() << "Done exporting importance map to binary file " << file_name;
202}
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
void Barrier() const
Definition: mpi_info.cc:38
const int & process_count
Total number of processes.
Definition: mpi_info.h:27
const int & location_id
Current process rank.
Definition: mpi_info.h:26
void ExportImportanceMap(const std::string &file_name)
chi_mesh::MeshContinuumPtr grid_ptr_
Definition: lbs_solver.h:75
std::vector< lbs::CellLBSView > cell_transport_views_
Definition: lbs_solver.h:83
std::vector< UnitCellMatrices > unit_cell_matrices_
Definition: lbs_solver.h:81
std::vector< LBSGroup > groups_
Definition: lbs_solver.h:67
std::vector< double > phi_old_local_
Definition: lbs_solver.h:95
std::vector< LBSGroupset > groupsets_
Definition: lbs_solver.h:68
size_t num_moments_
Definition: lbs_solver.h:62
std::array< double, 2 > MakeExpRepFromP1(const std::array< double, 4 > &P1_moments, bool verbose=false)
Definition: lbs_adjoint.cc:16
std::vector< double > VecDbl
Definition: lbs_structs.h:18