Chi-Tech
mgd_01c_assemble_A_bext.cc
Go to the documentation of this file.
2
3#include "chi_runtime.h"
4#include "chi_log.h"
5#include "utils/chi_timer.h"
6
8
10
11//============================================= assemble matrix A
13{
14 const auto& grid = *grid_ptr_;
15 const auto& sdm = *sdm_ptr_;
16
17 //============================================= Assemble the system
18 unsigned int i_two_grid = do_two_grid_ ? 1 : 0;
19
20 for (const auto& cell : grid.local_cells)
21 {
22 const auto& cell_mapping = sdm.GetCellMapping(cell);
23 const auto qp_data = cell_mapping.MakeVolumetricQuadraturePointData();
24 const size_t num_nodes = cell_mapping.NumNodes();
25
26 const auto& xs = matid_to_xs_map.at(cell.material_id_);
27 const auto& D = xs->DiffusionCoefficient();
28 const auto& sigma_r = xs->SigmaRemoval();
29
30 const auto& qext = matid_to_src_map.at(cell.material_id_);
31 double collapsed_D=0.,collapsed_sig_a=0.;
32 if (do_two_grid_)
33 {
34 const auto &xstg = map_mat_id_2_tginfo.at(cell.material_id_);
35 collapsed_D = xstg.collapsed_D;
36 collapsed_sig_a = xstg.collapsed_sig_a;
37 }
38
39 std::vector<VecDbl> rhs_cell;
40 rhs_cell.resize(num_groups_);
41 for (uint g=0; g < num_groups_; ++g)
42 rhs_cell[g].resize(num_nodes, 0.0);
43
44 std::vector<MatDbl> Acell;
45 Acell.resize(num_groups_ + i_two_grid);
46 for (uint g=0; g < num_groups_ + i_two_grid; ++g)
47 Acell[g].resize(num_nodes, VecDbl(num_nodes, 0.0));
48
49 for (size_t i=0; i<num_nodes; ++i)
50 {
51 for (size_t j=0; j<num_nodes; ++j)
52 {
53 double entry_mij = 0.0;
54 double entry_kij = 0.0;
55 for (size_t qp : qp_data.QuadraturePointIndices())
56 {
57 entry_mij += qp_data.ShapeValue(i, qp) *
58 qp_data.ShapeValue(j, qp) *
59 qp_data.JxW(qp);
60
61 entry_kij += qp_data.ShapeGrad(i, qp).Dot(qp_data.ShapeGrad(j, qp)) *
62 qp_data.JxW(qp);
63 }//for qp
64 for (uint g=0; g < num_groups_; ++g)
65 Acell[g][i][j] = entry_mij * sigma_r[g] + entry_kij * D[g];
66
67 if (do_two_grid_)
68 Acell[num_groups_][i][j] = entry_mij * collapsed_sig_a
69 + entry_kij * collapsed_D;
70 }//for j
71 double entry_rhsi = 0.0;
72 for (size_t qp : qp_data.QuadraturePointIndices())
73 entry_rhsi += qp_data.ShapeValue(i, qp) * qp_data.JxW(qp);
74 for (uint g=0; g < num_groups_; ++g)
75 rhs_cell[g][i] = entry_rhsi * (qext->source_value_g_[g]);
76 }//for i
77
78 //======================= Deal with BC (all based on variations of Robin)
79 const size_t num_faces = cell.faces_.size();
80 for (size_t f=0; f<num_faces; ++f)
81 {
82 const auto& face = cell.faces_[f];
83 // not a boundary face
84 if (face.has_neighbor_) continue;
85
86 auto& bndry = boundaries_[face.neighbor_id_];
87
88 // Robin boundary
89 // for two-grid, it is homogenous Robin
90 if (bndry.type_ == BoundaryType::Robin)
91 {
92 const auto qp_face_data =
93 cell_mapping.MakeSurfaceQuadraturePointData(f);
94 const size_t num_face_nodes = face.vertex_ids_.size();
95
96 auto& aval = bndry.mg_values_[0];
97 auto& bval = bndry.mg_values_[1];
98 auto& fval = bndry.mg_values_[2];
99 if (do_two_grid_)
100 {
101 aval.push_back(0.25);
102 bval.push_back(0.5);
103 fval.push_back(0.0);
104 }
105
106
107 // sanity check, Assert if b=0
108 for (uint g=0; g < num_groups_ + i_two_grid; ++g)
109 {
110 if (std::fabs(bval[g]) < 1e-8)
111 throw std::logic_error("if b=0, this is a Dirichlet BC, not a Robin BC");
112 }
113
114 // true Robin when a!=0, otherwise, it is a Neumann:
115 // only do this part if true Robin (i.e., a!=0)
116 for (uint g=0; g < num_groups_ + i_two_grid; ++g)
117 {
118 if (std::fabs(aval[g]) > 1.0e-8)
119 {
120 // loop over nodes of that face
121 for (size_t fi=0; fi<num_face_nodes; ++fi)
122 {
123 const uint i = cell_mapping.MapFaceNode(f,fi);
124
125 double entry_rhsi = 0.0;
126 for (size_t qp : qp_face_data.QuadraturePointIndices() )
127 entry_rhsi += qp_face_data.ShapeValue(i, qp) * qp_face_data.JxW(qp);
128 if (g < num_groups_) // check due to two-grid
129 rhs_cell[g][i] += fval[g] / bval[g] * entry_rhsi;
130
131 for (size_t fj=0; fj<num_face_nodes; ++fj)
132 {
133 const uint j = cell_mapping.MapFaceNode(f,fj);
134 double entry_aij = 0.0;
135 for (size_t qp : qp_face_data.QuadraturePointIndices())
136 entry_aij += qp_face_data.ShapeValue(i, qp)
137 * qp_face_data.ShapeValue(j, qp)
138 * qp_face_data.JxW(qp);
139 Acell[g][i][j] += aval[g] / bval[g] * entry_aij;
140 }//for fj
141 }//for fi
142 }//end true Robin
143 }//for g
144 }//if Robin
145 }//for face f
146
147 //======================= Develop node mapping
148 std::vector<int64_t> imap(num_nodes, 0); //node-mapping
149 for (size_t i=0; i<num_nodes; ++i)
150 imap[i] = sdm.MapDOF(cell, i);
151
152 //======================= Assembly into system
153 for (uint g=0; g < num_groups_; ++g)
154 for (size_t i=0; i<num_nodes; ++i)
155 VecSetValue(bext_[g], imap[i], rhs_cell[g][i], ADD_VALUES);
156
157 for (uint g=0; g < num_groups_ + i_two_grid; ++g)
158 for (size_t i=0; i<num_nodes; ++i)
159 for (size_t j=0; j<num_nodes; ++j)
160 MatSetValue(A_[g], imap[i], imap[j], Acell[g][i][j], ADD_VALUES);
161
162 }//for cell
163
164 Chi::log.Log() << "Global assembly";
165
166 for (uint g=0; g < num_groups_; ++g)
167 {
168 VecAssemblyBegin(bext_[g]);
169 VecAssemblyEnd(bext_[g]);
170 }
171 for (uint g=0; g < num_groups_ + i_two_grid; ++g)
172 {
173 MatAssemblyBegin(A_[g], MAT_FINAL_ASSEMBLY);
174 MatAssemblyEnd(A_[g], MAT_FINAL_ASSEMBLY);
175 }
176
177// PetscViewer viewer;
178// PetscViewerASCIIOpen(PETSC_COMM_WORLD,"A2_before_bc.m",&viewer);
179// PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
180// MatView(A[0],viewer);
181// PetscViewerPopFormat(viewer);
182// PetscViewerDestroy(&viewer);
183// PetscViewerASCIIOpen(PETSC_COMM_WORLD,"bext2_before_bc.m",&viewer);
184// PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
185// VecView(bext[0],viewer);
186// PetscViewerPopFormat(viewer);
187// PetscViewerDestroy(&viewer);
188
189 Chi::log.Log() << "Done global assembly";
190
191}
std::vector< double > VecDbl
Definition: chi_math.h:12
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
std::map< int, TwoGridCollapsedInfo > map_mat_id_2_tginfo
std::map< int, std::shared_ptr< chi_physics::MultiGroupXS > > matid_to_xs_map
chi_mesh::MeshContinuumPtr grid_ptr_
std::vector< Boundary > boundaries_
std::vector< Mat > A_
std::map< int, std::shared_ptr< chi_physics::IsotropicMultiGrpSource > > matid_to_src_map
chi_math::SDMPtr sdm_ptr_
std::vector< Vec > bext_
#define uint