Logbook  (07-04-2025)
Static problems
solver.hpp
1 /******************************************************************************
2  * Copyright (C) Siarhei Uzunbajakau, 2023.
3  *
4  * This program is free software. You can use, modify, and redistribute it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation, either version 3 or (at your option) any later version.
7  * This program is distributed without any warranty.
8  *
9  * Refer to COPYING.LESSER for more details.
10  ******************************************************************************/
11 
12 #ifndef SolverSLDII_H__
13 #define SolverSLDII_H__
14 
15 #define BOOST_ALLOW_DEPRECATED_HEADERS
16 
17 #include <deal.II/base/function.h>
18 #include <deal.II/grid/grid_in.h>
19 #include <deal.II/grid/grid_out.h>
20 #include <deal.II/grid/grid_tools.h>
21 #include <deal.II/grid/manifold_lib.h>
22 
23 #include <deal.II/numerics/fe_field_function.h>
24 
25 #include "exact_solution.hpp"
26 #include "settings.hpp"
27 #include "static_scalar_solver.hpp"
28 
29 #define TMR(__name) TimerOutput::Scope timer_section(timer, __name)
30 
31 using namespace StaticScalarSolver;
32 
38 template<int dim>
40  : public SettingsSLDII
41  , public Solver<dim>
42 {
43 public:
44  SolverSLDII() = delete;
60  SolverSLDII(unsigned int p,
61  unsigned int mapping_degree,
62  unsigned int r,
63  std::string fname)
64  : Solver<dim>(p,
65  mapping_degree,
66  0,
67  fname,
68  &exact_solution,
69  false,
70  false,
71  print_time_tables,
72  project_exact_solution,
73  true)
74  , r(r)
75  , fname(fname)
76  {
78  }
79 
80  ~SolverSLDII() = default;
81 
82 private:
83  const unsigned int r;
84  const std::string fname;
85 
86  const ExactSolutionSLDII_THETA<dim> exact_solution;
87  const Functions::ZeroFunction<dim> dirichlet;
88 
89  SphericalManifold<dim> sphere;
90 
91  virtual void make_mesh() override final;
92  virtual void fill_dirichlet_stack() override final;
93  virtual void solve() override final;
94 
95  void mark_materials();
96 };
97 
98 template<int dim>
99 void
100 SolverSLDII<dim>::fill_dirichlet_stack()
101 {
102  switch (type_of_bc) {
103  case Dirichlet:
104  Solver<dim>::dirichlet_stack = { { bid, &dirichlet } };
105  break;
106  case Exact:
107  Solver<dim>::dirichlet_stack = { { bid, &exact_solution } };
108  break;
109  }
110 }
111 
112 template<int dim>
113 void
115 {
116  GridIn<dim> gridin;
117  gridin.attach_triangulation(Solver<dim>::triangulation);
118 
119  std::string fname_mesh =
120  (dim == 2) ? "../../gmsh/data/square_r" + std::to_string(r) + ".msh"
121  : "../../gmsh/data/cube_r" + std::to_string(r) + ".msh";
122 
123  std::ifstream ifs(fname_mesh);
124  gridin.read_msh(ifs);
125 
126  mark_materials();
127 }
128 
129 template<int dim>
130 void
132 {
133  Solver<dim>::triangulation.reset_all_manifolds();
134 
135  for (auto cell : Solver<dim>::triangulation.active_cell_iterators()) {
136  if (cell->center().norm() < a) {
137  // The cell is inside the shield.
138  cell->set_material_id(mid_1);
139  } else if (cell->center().norm() < b) {
140  // The cell is in the wall of the shield.
141  cell->set_material_id(mid_2);
142  } else {
143  // The cell is outside the shield.
144  cell->set_material_id(mid_3);
145  }
146 
147  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f) {
148  double dif_norm_a = 0.0;
149  double dif_norm_b = 0.0;
150  double dif_norm = 0.0;
151  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face; v++) {
152  dif_norm_a += std::abs(cell->face(f)->vertex(v).norm() - a);
153  dif_norm_b += std::abs(cell->face(f)->vertex(v).norm() - b);
154  dif_norm += std::abs(cell->face(f)->vertex(0).norm() -
155  cell->face(f)->vertex(v).norm());
156  }
157 
158  if ((dif_norm_a < eps) && (std::abs(cell->center().norm()) < a)) {
159  // The face belongs to the interface Gamma_1
160  cell->face(f)->set_user_index(1);
161  cell->set_user_index(1);
162  }
163 
164  if ((dif_norm_b < eps) && (std::abs(cell->center().norm()) < b)) {
165  // The face belongs to the interface Gamma_2
166  cell->face(f)->set_user_index(2);
167  cell->set_user_index(2);
168  }
169 
170  if ((dif_norm < eps) && (cell->center().norm() > rd1) &&
171  (cell->center().norm() < b))
172  cell->face(f)->set_all_manifold_ids(1);
173  }
174  }
175 
176  Solver<dim>::triangulation.set_manifold(1, sphere);
177 }
178 
179 template<int dim>
180 void
182 {
183  SolverControl control(Solver<dim>::system_rhs.size(),
184  1e-8 * Solver<dim>::system_rhs.l2_norm(),
185  false,
186  false);
187 
188  if (log_cg_convergence)
189  control.enable_history_data();
190 
191  GrowingVectorMemory<Vector<double>> memory;
192  SolverCG<Vector<double>> cg(control, memory);
193 
194  PreconditionJacobi<SparseMatrix<double>> preconditioner;
195  preconditioner.initialize(Solver<dim>::system_matrix, 1.0);
196 
200  preconditioner);
201 
203 
204  if (log_cg_convergence) {
205  const std::vector<double> history_data = control.get_history_data();
206 
207  std::ofstream ofs(fname + "_cg_convergence.csv");
208 
209  unsigned int i = 1;
210  for (auto item : history_data) {
211  ofs << i << ", " << item << "\n";
212  i++;
213  }
214  ofs.close();
215  }
216 }
217 
218 #endif
Describes exact solution, , of the Magnetostatic shield - 2 (sld-ii/) numerical experiment in two and...
Global settings for the Magnetostatic shield - 2 (sld-ii/) numerical experiment.
Definition: settings.hpp:32
Implements the Magnetostatic shield - 2 (sld-ii/) numerical experiment.
Definition: solver.hpp:42
SolverSLDII(unsigned int p, unsigned int mapping_degree, unsigned int r, std::string fname)
Definition: solver.hpp:60
Solves static scalar boundary value problem.
void run()
Runs the simulation.