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 SolverSCH_H__
13 #define SolverSCH_H__
14 
15 #define BOOST_ALLOW_DEPRECATED_HEADERS
16 
17 #include <deal.II/base/function.h>
18 #include <deal.II/grid/grid_generator.h>
19 #include <deal.II/grid/grid_in.h>
20 #include <deal.II/grid/manifold_lib.h>
21 
22 #include <deal.II/numerics/fe_field_function.h>
23 
24 #include "exact_solution.hpp"
25 #include "settings.hpp"
26 #include "static_scalar_solver.hpp"
27 
28 #define TMR(__name) TimerOutput::Scope timer_section(timer, __name)
29 
30 using namespace StaticScalarSolver;
31 
36 template<int dim>
37 class SolverSCH
38  : public SettingsSCH
39  , public Solver<dim>
40 {
41 public:
42  SolverSCH() = delete;
43 
59  SolverSCH(unsigned int p,
60  unsigned int mapping_degree,
61  unsigned int r,
62  std::string fname)
63  : Solver<dim>(p,
64  mapping_degree,
65  0,
66  fname,
67  &exact_solution,
68  false,
69  false,
70  print_time_tables,
71  project_exact_solution,
72  true)
73  , r(r)
74  , fname(fname)
75  , fe_slice(1)
76  {
77  TimerOutput::OutputFrequency tf =
78  (print_time_tables) ? TimerOutput::summary : TimerOutput::never;
79 
80  TimerOutput timer(std::cout, tf, TimerOutput::cpu_and_wall_times_grouped);
81 
82  {
83  TMR("Solver run");
85  }
86  {
87  TMR("Data slice");
88  data_slice(fname);
89  }
90  }
91 
92  ~SolverSCH() = default;
93 
94 private:
95  const unsigned int r;
96  const std::string fname;
97 
98  const ExactSolutionSCH_PHI<dim> exact_solution;
99  const dealii::Functions::ZeroFunction<dim> dirichlet_function;
100 
101  // The amount of global mesh refinements that need to be done to the
102  // one-dimensional mesh used for the plot of potential vs. x coordinate.
103  const unsigned int nr_slice_global_refs = 10;
104 
105  // These four data members are needed for making the plot of potential
106  // vs. \f$x\f$ coordinate.
107  Triangulation<1, dim> triangulation_slice;
108  FE_Q<1, dim> fe_slice;
109  DoFHandler<1, dim> dof_handler_slice;
110  Vector<double> solution_slice;
111 
112  SphericalManifold<dim> sphere;
113 
114  virtual void make_mesh() override final;
115  virtual void fill_dirichlet_stack() override final;
116  virtual void solve() override final;
117 
118  void mark_materials();
119 
120  // This function makes the plot of potential vs. \f$x\f$ coordinate.
121  void data_slice(std::string fname);
122 };
123 
124 template<int dim>
125 void
126 SolverSCH<dim>::fill_dirichlet_stack()
127 {
128  Solver<dim>::dirichlet_stack = { { bid, &dirichlet_function } };
129 }
130 
131 template<int dim>
132 void
134 {
135  Solver<dim>::triangulation.reset_all_manifolds();
136 
137  for (auto cell : Solver<dim>::triangulation.active_cell_iterators()) {
138  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; f++) {
139  double dif_norm_a = 0.0;
140  double dif_norm = 0.0;
141  for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face; v++) {
142  dif_norm_a += std::abs(cell->face(f)->vertex(v).norm() - a);
143  dif_norm += std::abs(cell->face(f)->vertex(0).norm() -
144  cell->face(f)->vertex(v).norm());
145  }
146 
147  if ((dif_norm_a < eps) && (cell->center().norm() < a)) {
148  cell->face(f)->set_user_index(1);
149  cell->set_user_index(1);
150  }
151 
152  if ((dif_norm < eps) && (cell->center().norm() > rd1))
153  cell->face(f)->set_all_manifold_ids(1);
154  }
155  }
156 
157  Solver<dim>::triangulation.set_manifold(1, sphere);
158 }
159 
160 template<int dim>
161 void
162 SolverSCH<dim>::data_slice(std::string fname)
163 {
164  GridGenerator::hyper_cube(triangulation_slice, 0.0 + eps, b - eps);
165  triangulation_slice.refine_global(nr_slice_global_refs);
166 
167  dof_handler_slice.reinit(triangulation_slice);
168  dof_handler_slice.distribute_dofs(fe_slice);
169  solution_slice.reinit(dof_handler_slice.n_dofs());
170 
171  Functions::FEFieldFunction<dim> potential(Solver<dim>::dof_handler,
173 
174  VectorTools::interpolate(dof_handler_slice, potential, solution_slice);
175 
176  // DataOut<1,DoFHandler<1,dim>> data_out;
177  DataOut<1, dim> data_out;
178 
179  data_out.attach_dof_handler(dof_handler_slice);
180  data_out.add_data_vector(solution_slice, "solution_slice");
181  data_out.build_patches();
182 
183  std::ofstream out(fname + "_slice" + ".gpi");
184 
185  data_out.write_gnuplot(out);
186  out.close();
187 }
188 
189 template<int dim>
190 void
192 {
193  SolverControl control(Solver<dim>::system_rhs.size(),
194  1e-8 * Solver<dim>::system_rhs.l2_norm(),
195  false,
196  false);
197 
198  if (log_cg_convergence)
199  control.enable_history_data();
200 
201  GrowingVectorMemory<Vector<double>> memory;
202  SolverCG<Vector<double>> cg(control, memory);
203 
204  PreconditionJacobi<SparseMatrix<double>> preconditioner;
205  preconditioner.initialize(Solver<dim>::system_matrix, 1.0);
206 
210  preconditioner);
211 
213 
214  if (log_cg_convergence) {
215  const std::vector<double> history_data = control.get_history_data();
216 
217  std::ofstream ofs(fname + "_cg_convergence.csv");
218 
219  unsigned int i = 1;
220  for (auto item : history_data) {
221  ofs << i << ", " << item << "\n";
222  i++;
223  }
224  ofs.close();
225  }
226 }
227 
228 #endif
Describes exact solution, , of the Surface charge (sch/) numerical experiment.
Global settings for the Surface charge (sch/) numerical experiment.
Definition: settings.hpp:25
Implements the Surface charge (sch/) numerical experiment.
Definition: solver.hpp:40
SolverSCH(unsigned int p, unsigned int mapping_degree, unsigned int r, std::string fname)
Definition: solver.hpp:59
Solves static scalar boundary value problem.
void run()
Runs the simulation.