18#define DefaultBCDirichlet BoundaryCondition{BCType::DIRICHLET,{0,0,0}}
26 const std::string fname =
"lbs::acceleration::DiffusionMIPSolver::"
28 if (
A_ ==
nullptr or
rhs_ ==
nullptr or
ksp_ ==
nullptr)
29 throw std::logic_error(fname +
": Some or all PETSc elements are null. "
30 "Check that Initialize has been called.");
39 const size_t num_faces = cell.faces_.size();
41 const size_t num_nodes = cell_mapping.
NumNodes();
42 const auto cc_nodes = cell_mapping.GetNodeLocations();
45 const auto& cell_K_matrix = unit_cell_matrices.K_matrix;
46 const auto& cell_M_matrix = unit_cell_matrices.M_matrix;
50 for (
size_t g=0; g<num_groups; ++g)
53 const double Dg = xs.Dg[g];
54 const double sigr_g = xs.sigR[g];
56 std::vector<double> qg(num_nodes, 0.0);
57 for (
size_t j=0; j<num_nodes; j++)
61 for (
size_t i=0; i<num_nodes; i++)
64 double entry_rhs_i = 0.0;
65 for (
size_t j=0; j<num_nodes; j++)
69 const double entry_aij =
70 Dg * cell_K_matrix[i][j] +
71 sigr_g * cell_M_matrix[i][j];
73 entry_rhs_i += qg[j]* cell_M_matrix[i][j];
75 MatSetValue(
A_, imap, jmap, entry_aij, ADD_VALUES);
78 VecSetValue(
rhs_, imap, entry_rhs_i, ADD_VALUES);
82 for (
size_t f=0; f<num_faces; ++f)
84 const auto& face = cell.faces_[f];
85 const auto& n_f = face.normal_;
86 const size_t num_face_nodes = cell_mapping.NumFaceNodes(f);
88 const auto& face_M = unit_cell_matrices.face_M_matrices[f];
89 const auto& face_G = unit_cell_matrices.face_G_matrices[f];
90 const auto& face_Si = unit_cell_matrices.face_Si_vectors[f];
96 if (face.has_neighbor_)
98 const auto& adj_cell =
grid_.
cells[face.neighbor_id_];
101 const size_t acf = Grid::MapCellFace(cell, adj_cell, f);
105 const double adj_Dg = adj_xs.Dg[g];
117 for (
size_t fi=0; fi<num_face_nodes; ++fi)
119 const int i = cell_mapping.MapFaceNode(f,fi);
122 for (
size_t fj=0; fj<num_face_nodes; ++fj)
124 const int jm = cell_mapping.MapFaceNode(f,fj);
130 const double aij = kappa * face_M[i][jm];
132 MatSetValue(
A_, imap, jmmap, aij, ADD_VALUES);
133 MatSetValue(
A_, imap, jpmap, -aij, ADD_VALUES);
142 for (
int i=0; i<num_nodes; i++)
146 for (
int fj=0; fj<num_face_nodes; fj++)
148 const int jm = cell_mapping.MapFaceNode(f,fj);
154 const double aij = -0.5*Dg*n_f.Dot(face_G[jm][i]);
156 MatSetValue(
A_, imap, jmmap, aij, ADD_VALUES);
157 MatSetValue(
A_, imap, jpmap, -aij, ADD_VALUES);
162 for (
int fi=0; fi<num_face_nodes; fi++)
164 const int im = cell_mapping.MapFaceNode(f,fi);
170 for (
int j=0; j<num_nodes; j++)
174 const double aij = -0.5*Dg*n_f.Dot(face_G[im][j]);
176 MatSetValue(
A_, immap, jmap, aij, ADD_VALUES);
177 MatSetValue(
A_, ipmap, jmap, -aij, ADD_VALUES);
185 if (
bcs_.count(face.neighbor_id_) > 0)
186 bc =
bcs_.at(face.neighbor_id_);
190 const double bc_value = bc.values[0];
202 for (
size_t fi=0; fi<num_face_nodes; ++fi)
204 const int i = cell_mapping.MapFaceNode(f,fi);
207 for (
size_t fj=0; fj<num_face_nodes; ++fj)
209 const int jm = cell_mapping.MapFaceNode(f,fj);
212 const double aij = kappa*face_M[i][jm];
213 const double aij_bc_value = aij*bc_value;
215 MatSetValue(
A_ , imap, jmmap, aij, ADD_VALUES);
216 VecSetValue(
rhs_, imap, aij_bc_value, ADD_VALUES);
225 for (
size_t i=0; i<num_nodes; i++)
229 for (
size_t j=0; j<num_nodes; j++)
233 const double aij = -Dg*n_f.Dot(face_G[j][i] + face_G[i][j]);
234 const double aij_bc_value = aij*bc_value;
237 MatSetValue(
A_, imap, jmap, aij, ADD_VALUES);
238 VecSetValue(
rhs_, imap, aij_bc_value, ADD_VALUES);
244 const double aval = bc.values[0];
245 const double bval = bc.values[1];
246 const double fval = bc.values[2];
248 if (std::fabs(bval) < 1.0e-12)
continue;
250 for (
size_t fi=0; fi<num_face_nodes; fi++)
252 const int i = cell_mapping.MapFaceNode(f,fi);
255 if (std::fabs(aval) >= 1.0e-12)
257 for (
size_t fj=0; fj<num_face_nodes; fj++)
259 const int j = cell_mapping.MapFaceNode(f,fj);
262 const double aij = (aval/bval) * face_M[i][j];
264 MatSetValue(
A_, ir , jr, aij, ADD_VALUES);
268 if (std::fabs(fval) >= 1.0e-12)
270 const double rhs_val = (fval/bval) * face_Si[i];
272 VecSetValue(
rhs_, ir, rhs_val, ADD_VALUES);
281 MatAssemblyBegin(
A_, MAT_FINAL_ASSEMBLY);
282 MatAssemblyEnd(
A_, MAT_FINAL_ASSEMBLY);
283 VecAssemblyBegin(
rhs_);
284 VecAssemblyEnd(
rhs_);
289 MatGetInfo(
A_, MAT_GLOBAL_SUM, &info);
291 Chi::log.
Log() <<
"Number of mallocs used = " << info.mallocs
292 <<
"\nNumber of non-zeros allocated = "
294 <<
"\nNumber of non-zeros used = "
296 <<
"\nNumber of unneeded non-zeros = "
302 PetscBool symmetry = PETSC_FALSE;
303 MatIsSymmetric(
A_, 1.0e-6, &symmetry);
304 if (symmetry == PETSC_FALSE)
305 throw std::logic_error(fname +
":Symmetry check failed");
static chi::Timer program_timer
LogStream Log(LOG_LVL level=LOG_0)
std::string GetTimeString() const
const std::vector< chi_mesh::Vector3 > & GetNodeLocations() const
const CellMapping & GetCellMapping(const chi_mesh::Cell &cell) const
virtual int64_t MapDOF(const chi_mesh::Cell &cell, unsigned int node, const UnknownManager &unknown_manager, unsigned int unknown_id, unsigned int component) const =0
virtual int64_t MapDOFLocal(const chi_mesh::Cell &cell, unsigned int node, const UnknownManager &unknown_manager, unsigned int unknown_id, unsigned int component) const =0
std::vector< Unknown > unknowns_
LocalCellHandler local_cells
void AssembleAand_b(const std::vector< double > &q_vector) override
int MapFaceNodeDisc(const chi_mesh::Cell &cur_cell, const chi_mesh::Cell &adj_cell, const std::vector< chi_mesh::Vector3 > &cc_node_locs, const std::vector< chi_mesh::Vector3 > &ac_node_locs, size_t ccf, size_t acf, size_t ccfi, double epsilon=1.0e-12)
double HPerpendicular(const chi_mesh::Cell &cell, unsigned int f)
struct lbs::acceleration::DiffusionSolver::Options options
const chi_math::SpatialDiscretization & sdm_
const chi_math::UnknownManager uk_man_
const chi_mesh::MeshContinuum & grid_
const std::map< uint64_t, BoundaryCondition > bcs_
const MatID2XSMap mat_id_2_xs_map_
const std::vector< UnitCellMatrices > & unit_cell_matrices_
#define DefaultBCDirichlet
bool verbose
Verbosity flag.
bool perform_symmetry_check
For debugging only (very expensive)