Chi-Tech
main_initialize.cc
Go to the documentation of this file.
1#include "diffusion_solver.h"
2
4
6
7#include "chi_runtime.h"
8
9#include "chi_log.h"
10#include "chi_mpi.h"
11
12#include "utils/chi_timer.h"
13
14// ###################################################################
15/**Initializes the diffusion solver using the PETSc library.*/
17{
18 Chi::log.Log() << "\n"
20 << ": Initializing Diffusion solver ";
21 this->verbose_info_ = verbose;
22
24 InitializeCommonItems(); // Mostly boundaries
25
26 chi::Timer t_init;
27 t_init.Reset();
28
29 auto sdm_string = basic_options_("discretization_method").StringValue();
30 {
31 using namespace chi_math::finite_element;
32 if (sdm_string == "PWLC")
33 {
36 *grid_ptr_);
38 }
39 else if (sdm_string == "PWLD_MIP")
40 {
43 *grid_ptr_);
45 }
46 else
47 throw std::invalid_argument(TextName() +
48 ": Invalid spatial discretization method, " +
49 sdm_string + ", specified.");
50 }
51
52 unit_integrals_.clear();
53 for (const auto& cell : grid_ptr_->local_cells)
54 {
55 const auto& cell_mapping = discretization_->GetCellMapping(cell);
56 unit_integrals_.insert(std::make_pair(
57 cell.global_id_, UnitIntegralContainer::Make(cell_mapping)));
58 }
59
60 const auto ghost_global_ids = grid_ptr_->cells.GetGhostGlobalIDs();
61 for (const uint64_t global_id : ghost_global_ids)
62 {
63 const auto& cell_mapping =
64 discretization_->GetCellMapping(grid_ptr_->cells[global_id]);
65 unit_integrals_.insert(
66 std::make_pair(global_id, UnitIntegralContainer::Make(cell_mapping)));
67 }
68
69 MPI_Barrier(Chi::mpi.comm);
70 auto& sdm = discretization_;
71
72 //============================================= Get DOF counts
73 local_dof_count_ = sdm->GetNumLocalDOFs(unknown_manager_);
74 global_dof_count_ = sdm->GetNumGlobalDOFs(unknown_manager_);
75 Chi::log.Log() << TextName()
76 << ": Global number of DOFs=" << global_dof_count_;
77
78 //================================================== Initialize discretization
79 // method
80 if (field_functions_.empty())
81 {
82 auto& sdm_ptr = discretization_;
83 std::string solver_name;
84 if (not TextName().empty()) solver_name = TextName() + "-";
85
86 std::string text_name = solver_name + "phi";
87
88 using namespace chi_math;
89 auto initial_field_function =
90 std::make_shared<chi_physics::FieldFunctionGridBased>(
91 text_name, // Text name
92 sdm_ptr, // Spatial Discretization
93 Unknown(UnknownType::SCALAR)); // Unknown/Variable
94
95 field_functions_.push_back(initial_field_function);
96 Chi::field_function_stack.push_back(initial_field_function);
97 } // if not ff set
98
99 //================================================== Determine nodal DOF
100 Chi::log.Log() << "Building sparsity pattern.";
101 std::vector<int64_t> nodal_nnz_in_diag;
102 std::vector<int64_t> nodal_nnz_off_diag;
103 sdm->BuildSparsityPattern(
104 nodal_nnz_in_diag, nodal_nnz_off_diag, unknown_manager_);
105
107 << ": Diffusion Solver initialization time "
108 << t_init.GetTime() / 1000.0 << std::endl;
109
110 //================================================== Initialize x and b
111 ierr_ = VecCreate(PETSC_COMM_WORLD, &x_);
112 CHKERRQ(ierr_);
113 ierr_ = PetscObjectSetName((PetscObject)x_, "Solution");
114 CHKERRQ(ierr_);
115 ierr_ = VecSetSizes(x_,
116 static_cast<PetscInt>(local_dof_count_),
117 static_cast<PetscInt>(global_dof_count_));
118 CHKERRQ(ierr_);
119 ierr_ = VecSetType(x_, VECMPI);
120 CHKERRQ(ierr_);
121 ierr_ = VecDuplicate(x_, &b_);
122 CHKERRQ(ierr_);
123
124 VecSet(x_, 0.0);
125 VecSet(b_, 0.0);
126
127 // ################################################## Create matrix
128 ierr_ = MatCreate(PETSC_COMM_WORLD, &A_);
129 CHKERRQ(ierr_);
130 ierr_ = MatSetSizes(A_,
131 static_cast<PetscInt>(local_dof_count_),
132 static_cast<PetscInt>(local_dof_count_),
133 static_cast<PetscInt>(global_dof_count_),
134 static_cast<PetscInt>(global_dof_count_));
135 CHKERRQ(ierr_);
136 ierr_ = MatSetType(A_, MATMPIAIJ);
137 CHKERRQ(ierr_);
138
139 //================================================== Allocate matrix memory
140 Chi::log.Log() << "Setting matrix preallocation.";
141 MatMPIAIJSetPreallocation(
142 A_, 0, nodal_nnz_in_diag.data(), 0, nodal_nnz_off_diag.data());
143 MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
144 MatSetOption(A_, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE);
145 MatSetUp(A_);
146
147 //================================================== Set up solver
148 ierr_ = KSPCreate(PETSC_COMM_WORLD, &ksp_);
149 ierr_ = KSPSetOperators(ksp_, A_, A_);
150 ierr_ = KSPSetType(ksp_, KSPCG);
151
152 //================================================== Set up preconditioner
153 ierr_ = KSPGetPC(ksp_, &pc_);
154 PCSetType(pc_, PCHYPRE);
155
156 PCHYPRESetType(pc_, "boomeramg");
157
158 //================================================== Setting Hypre parameters
159 // The default HYPRE parameters used for polyhedra
160 // seemed to have caused a lot of trouble for Slab
161 // geometries. This section makes some custom options
162 // per cell type
163 auto first_cell = &grid_ptr_->local_cells[0];
164
165 if (first_cell->Type() == chi_mesh::CellType::SLAB)
166 {
167 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_agg_nl 1");
168 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_P_max 4");
169 PetscOptionsInsertString(nullptr,
170 "-pc_hypre_boomeramg_grid_sweeps_coarse 1");
171
172 PetscOptionsInsertString(nullptr,
173 "-pc_hypre_boomeramg_grid_sweeps_coarse 1");
174 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_max_levels 25");
175 PetscOptionsInsertString(
176 nullptr, "-pc_hypre_boomeramg_relax_type_all symmetric-SOR/Jacobi");
177 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_coarsen_type HMIS");
178 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_interp_type ext+i");
179
180 PetscOptionsInsertString(nullptr, "-options_left");
181 }
182 if (first_cell->Type() == chi_mesh::CellType::POLYGON)
183 {
184 PetscOptionsInsertString(nullptr,
185 "-pc_hypre_boomeramg_strong_threshold 0.6");
186
187 // PetscOptionsInsertString(nullptr,"-pc_hypre_boomeramg_agg_nl 1");
188 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_P_max 4");
189
190 PetscOptionsInsertString(nullptr,
191 "-pc_hypre_boomeramg_grid_sweeps_coarse 1");
192 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_max_levels 25");
193 PetscOptionsInsertString(
194 nullptr, "-pc_hypre_boomeramg_relax_type_all symmetric-SOR/Jacobi");
195 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_coarsen_type HMIS");
196 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_interp_type ext+i");
197
198 PetscOptionsInsertString(nullptr, "-options_left");
199 }
200 if (first_cell->Type() == chi_mesh::CellType::POLYHEDRON)
201 {
202 PetscOptionsInsertString(nullptr,
203 "-pc_hypre_boomeramg_strong_threshold 0.8");
204
205 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_agg_nl 1");
206 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_P_max 4");
207
208 PetscOptionsInsertString(nullptr,
209 "-pc_hypre_boomeramg_grid_sweeps_coarse 1");
210 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_max_levels 25");
211 PetscOptionsInsertString(
212 nullptr, "-pc_hypre_boomeramg_relax_type_all symmetric-SOR/Jacobi");
213 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_coarsen_type HMIS");
214 PetscOptionsInsertString(nullptr, "-pc_hypre_boomeramg_interp_type ext+i");
215 }
216 PetscOptionsInsertString(nullptr, options_string_.c_str());
217 PCSetFromOptions(pc_);
218
219 //=================================== Set up monitor
220 if (verbose)
221 ierr_ =
222 KSPMonitorSet(ksp_, &chi_diffusion::KSPMonitorAChiTech, nullptr, nullptr);
223
224 KSPSetConvergenceTest(
226
227 ierr_ = KSPSetTolerances(ksp_,
228 1.e-50,
229 basic_options_("residual_tolerance").FloatValue(),
230 1.0e50,
231 basic_options_("max_iters").IntegerValue());
232 ierr_ = KSPSetInitialGuessNonzero(ksp_, PETSC_TRUE);
233
234 return false;
235}
static std::vector< chi_physics::FieldFunctionPtr > field_function_stack
Definition: chi_runtime.h:92
static chi::Timer program_timer
Definition: chi_runtime.h:79
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
void Reset()
Definition: chi_timer.cc:16
double GetTime() const
Definition: chi_timer.cc:23
std::string GetTimeString() const
Definition: chi_timer.cc:38
std::map< uint64_t, UnitIntegralContainer > unit_integrals_
void Initialize() override
chi_mesh::MeshContinuumPtr grid_ptr_
void InitializeCommonItems()
Definition: initcommon.cc:11
std::shared_ptr< chi_math::SpatialDiscretization > discretization_
chi_math::UnknownManager unknown_manager_
static UnitIntegralContainer Make(const chi_math::CellMapping &cell_mapping)
unsigned int AddUnknown(UnknownType unk_type, unsigned int dimension=0)
static std::shared_ptr< PieceWiseLinearContinuous > New(const chi_mesh::MeshContinuum &grid, QuadratureOrder q_order=QuadratureOrder::SECOND, CoordinateSystemType cs_type=CoordinateSystemType::CARTESIAN)
static std::shared_ptr< PieceWiseLinearDiscontinuous > New(const chi_mesh::MeshContinuum &grid, QuadratureOrder q_order=QuadratureOrder::SECOND, CoordinateSystemType cs_type=CoordinateSystemType::CARTESIAN)
std::vector< std::shared_ptr< FieldFunctionGridBased > > field_functions_
Definition: chi_solver.h:58
std::string TextName() const
Definition: chi_solver.cc:116
BasicOptions basic_options_
Definition: chi_solver.h:57
PetscErrorCode DiffusionConvergenceTestNPT(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *convergedReason, void *monitordestroy)
PetscErrorCode KSPMonitorAChiTech(KSP ksp, PetscInt n, PetscReal rnorm, void *monitordestroy)