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 SolverFLC_H__
13 #define SolverFLC_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 SolverFLC
38  : public SettingsFLC
39  , public Solver<dim>
40 {
41 public:
42  SolverFLC() = delete;
43 
59  SolverFLC(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  , dirichlet_function_in(1.0)
76  , fe_slice(1)
77  {
78  TimerOutput::OutputFrequency tf =
79  (print_time_tables) ? TimerOutput::summary : TimerOutput::never;
80 
81  TimerOutput timer(std::cout, tf, TimerOutput::cpu_and_wall_times_grouped);
82 
83  {
84  TMR("Solver run");
86  }
87  {
88  TMR("Data slice");
89  data_slice(fname);
90  }
91  }
92 
93  ~SolverFLC() = default;
94 
95 private:
96  const unsigned int r;
97  const std::string fname;
98 
99  const ExactSolutionFLC_PHI<dim> exact_solution;
100  const dealii::Functions::ZeroFunction<dim> dirichlet_function_out;
101  const dealii::Functions::ConstantFunction<dim> dirichlet_function_in;
102 
103  // The amount of global mesh refinements that need to be done to the
104  // one-dimensional mesh used for the plot of potential vs. x coordinate.
105  const unsigned int nr_slice_global_refs = 10;
106 
107  // These four data members are needed for making the plot of potential
108  // vs. x coordinate.
109  Triangulation<1, dim> triangulation_slice;
110  FE_Q<1, dim> fe_slice;
111  DoFHandler<1, dim> dof_handler_slice;
112  Vector<double> solution_slice;
113 
114  SphericalManifold<dim> sphere;
115 
116  virtual void make_mesh() override final;
117  virtual void fill_dirichlet_stack() override final;
118  virtual void solve() override final;
119 
120  void mark_materials();
121 
122  // This function makes the plot of potential vs. x coordinate.
123  void data_slice(std::string fname);
124 };
125 
126 template<int dim>
127 void
128 SolverFLC<dim>::fill_dirichlet_stack()
129 {
130  Solver<dim>::dirichlet_stack = { { bid_in, &dirichlet_function_in },
131  { bid_out, &dirichlet_function_out } };
132 }
133 
134 template<int dim>
135 void
137 {
138  Point<dim> origin;
139 
140  double dist;
141  for (auto cell : Solver<dim>::triangulation.active_cell_iterators()) {
142  dist = cell->center().norm();
143  if (dist < d_1) {
144  cell->set_material_id(mid_1);
145  } else if (dist < d_2) {
146  cell->set_material_id(mid_3);
147  } else if (dist < b) {
148  cell->set_material_id(mid_2);
149  }
150 
151  for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f) {
152  if (cell->face(f)->at_boundary()) {
153  if (cell->center().norm() > d_1) {
154  cell->face(f)->set_all_boundary_ids(bid_out);
155  } else {
156  cell->face(f)->set_all_boundary_ids(bid_in);
157  }
158  }
159  }
160  }
161 
162  Solver<dim>::triangulation.set_all_manifold_ids(1);
163  Solver<dim>::triangulation.set_manifold(1, sphere);
164 }
165 
166 template<int dim>
167 void
168 SolverFLC<dim>::data_slice(std::string fname)
169 {
170  GridGenerator::hyper_cube(triangulation_slice, a + eps, b - eps);
171  triangulation_slice.refine_global(nr_slice_global_refs);
172 
173  dof_handler_slice.reinit(triangulation_slice);
174  dof_handler_slice.distribute_dofs(fe_slice);
175  solution_slice.reinit(dof_handler_slice.n_dofs());
176 
177  Functions::FEFieldFunction<dim> potential(Solver<dim>::dof_handler,
179 
180  VectorTools::interpolate(dof_handler_slice, potential, solution_slice);
181 
182  // DataOut<1,DoFHandler<1,dim>> data_out;
183  DataOut<1, dim> data_out;
184 
185  data_out.attach_dof_handler(dof_handler_slice);
186  data_out.add_data_vector(solution_slice, "solution_slice");
187  data_out.build_patches();
188 
189  std::ofstream out(fname + "_slice" + ".gpi");
190 
191  data_out.write_gnuplot(out);
192  out.close();
193 }
194 
195 template<int dim>
196 void
198 {
199  SolverControl control(Solver<dim>::system_rhs.size(),
200  1e-8 * Solver<dim>::system_rhs.l2_norm(),
201  false,
202  false);
203 
204  if (log_cg_convergence)
205  control.enable_history_data();
206 
207  GrowingVectorMemory<Vector<double>> memory;
208  SolverCG<Vector<double>> cg(control, memory);
209 
210  PreconditionJacobi<SparseMatrix<double>> preconditioner;
211  preconditioner.initialize(Solver<dim>::system_matrix, 1.0);
212 
216  preconditioner);
217 
219 
220  if (log_cg_convergence) {
221  const std::vector<double> history_data = control.get_history_data();
222 
223  std::ofstream ofs(fname + "_cg_convergence.csv");
224 
225  unsigned int i = 1;
226  for (auto item : history_data) {
227  ofs << i << ", " << item << "\n";
228  i++;
229  }
230  ofs.close();
231  }
232 }
233 
234 #endif
Describes exact solution, , of the Floating conductor (flc/) numerical experiment.
Global settings for the Floating conductor (flc/) numerical experiment.
Definition: settings.hpp:25
Implements the solver of the Floating conductor (flc/) numerical experiment.
Definition: solver.hpp:40
SolverFLC(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.