applications/mp-reinit/cases/reinit_circle/reinit_circle_DG.hpp Source File

Developer Documentation: applications/mp-reinit/cases/reinit_circle/reinit_circle_DG.hpp Source File
Developer Documentation
reinit_circle_DG.hpp
Go to the documentation of this file.
1#pragma once
2// deal-specific libraries
3#include <deal.II/base/function.h>
4#include <deal.II/base/function_signed_distance.h>
5#include <deal.II/base/point.h>
6#include <deal.II/base/tensor_function.h>
7
8#include <deal.II/distributed/tria.h>
9
10#include <deal.II/grid/grid_generator.h>
11
12#include <deal.II/lac/vector.h>
13
14#include <deal.II/numerics/error_estimator.h>
15#include <deal.II/numerics/vector_tools.h>
16
19
20#include <cmath>
21#include <iostream>
22
23#include "../../reinitialization_case.hpp"
24
26{
27 /*
28 * this function specifies the initial field of the level set equation
29 */
30
31 template <int dim, typename number>
32 class InitializePhi : public dealii::Function<dim, number>
33 {
34 public:
36 : dealii::Function<dim, number>()
37 , distance_sphere(dim == 1 ? dealii::Point<dim, number>(0.0) :
38 dealii::Point<dim, number>(0.0, 0.5),
39 0.25)
40 {}
41
42 number
43 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
44 {
45 number value;
46 if (dim != 3)
47 {
48 value = 2.0 * (std::sqrt(p[0] * p[0] + p[1] * p[1]) - 0.15);
49 }
50 else
51 {
52 value = 2.0 * (std::sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) - 0.15);
53 }
54
55 return value;
56 }
57
58 private:
59 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere;
60 };
61
62 template <int dim, typename number>
63 class ExactSolution : public dealii::Function<dim, number>
64 {
65 public:
66 ExactSolution(const number eps)
67 : dealii::Function<dim, number>()
68 , distance_sphere(dealii::Point<dim, number>(0.0, 0.5), 0.25)
69 , eps_interface(eps)
70 {}
71
72 number
73 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
74 {
75 number value;
76 if (dim != 3)
77 {
78 value = (std::sqrt(p[0] * p[0] + p[1] * p[1]) - 0.15);
79 }
80 else
81 {
82 value = (std::sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) - 0.15);
83 }
84
85 return value;
86 }
87
88 private:
89 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere;
90 const number eps_interface;
91 };
92 /*
93 * This class collects all relevant input data for the level set simulation
94 */
95
96 template <int dim, typename number>
98 {
99 public:
101 : LevelSet::ReinitializationCase<dim, number>(parameter_file, mpi_communicator)
102 {
103 if (dim == 1)
104 AssertThrow(false, dealii::ExcMessage("Dimension 1 is not supported for this simulation"));
105 }
106
107 void
109 {
110 if (dim == 1 || this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
111 {
112 AssertDimension(dealii::Utilities::MPI::n_mpi_processes(this->mpi_communicator), 1);
113 this->triangulation = std::make_shared<dealii::Triangulation<dim>>();
114 }
115 else
116 {
117 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
118 this->mpi_communicator);
119 }
120
121 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
122 {
123 dealii::GridGenerator::subdivided_hyper_cube_with_simplices(
124 *this->triangulation,
125 dealii::Utilities::pow(2, this->parameters.base.global_refinements),
128 }
129 else
130 {
131 dealii::GridGenerator::hyper_cube(*this->triangulation, left_domain, right_domain);
132 this->triangulation->refine_global(this->parameters.base.global_refinements);
133 }
134 }
135
136 void
138 {
142 }
143
144 void
146 {
147 this->attach_initial_condition(std::make_shared<InitializePhi<dim, number>>(), "level_set");
148 }
149
150 void
151 do_postprocessing(const GenericDataOut<dim, number> &generic_data_out) const final
152 {
153 dealii::ConditionalOStream pcout(
154 std::cout, dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0);
155
156 pcout << "---------------------------------------------" << std::endl;
157 pcout << " Starting user defined postprocessing" << std::endl;
158 pcout << "---------------------------------------------" << std::endl;
159
160 /*Error Calculation*/
161 ExactSolution<dim, number> exact_solution(0.1);
162 exact_solution.set_time(generic_data_out.get_time());
163
164 const auto n_q_points = this->parameters.reinit.fe.degree + 20;
165 dealii::FE_DGQ<dim> fe(this->parameters.reinit.fe.degree);
166
167 dealii::QGauss<dim> quadrature(n_q_points);
168 dealii::FEValues<dim> fe_values(fe,
169 quadrature,
170 dealii::update_values | dealii::update_JxW_values |
171 dealii::update_quadrature_points |
172 dealii::update_gradients);
173
174 dealii::FEValues<dim> fe_values_curvature(fe,
175 quadrature,
176 dealii::update_values | dealii::update_JxW_values |
177 dealii::update_quadrature_points);
178
179 std::vector<number> phi_at_q(dealii::QGauss<dim>(n_q_points).size());
180 std::vector<number> curvature_at_q(dealii::QGauss<dim>(n_q_points).size());
181 std::vector<dealii::Tensor<1, dim, number>> gradient_at_q(
182 dealii::QGauss<dim>(n_q_points).size());
183
184
185
186 generic_data_out.get_vector("reinit_DG_psi").update_ghost_values();
187 generic_data_out.get_vector("curvature").update_ghost_values();
188
189 number error = 0.0;
190 number norm_exact = 0.0;
191 number mass = 0.0;
192 number error_curvature = 0.0;
193 number norm_curvature_exact = 0.0;
194 number error_gradient = 0.0;
195 number norm_gradient_exact = 0.0;
196 // Initialize mass
197 if (init_mass)
198 {
199 for (const auto &cell :
200 generic_data_out.get_dof_handler("reinit_DG_psi").active_cell_iterators())
201 if (cell->is_locally_owned())
202 {
203 fe_values.reinit(cell);
204
205 fe_values.get_function_values(generic_data_out.get_vector("reinit_DG_psi"),
206 phi_at_q); // compute values of old solution
207
208 for (const unsigned int q_index : fe_values.quadrature_point_indices())
209 {
210 if (phi_at_q[q_index] < 0.0)
211 {
212 initial_mass += fe_values.JxW(q_index);
213 }
214 }
215 }
216 initial_mass = dealii::Utilities::MPI::sum(initial_mass, this->mpi_communicator);
217
218 init_mass = false;
219 }
220 for (const auto &cell :
221 generic_data_out.get_dof_handler("reinit_DG_psi").active_cell_iterators())
222 if (cell->is_locally_owned())
223 {
224 fe_values.reinit(cell);
225 fe_values_curvature.reinit(cell);
226
227 fe_values.get_function_values(generic_data_out.get_vector("reinit_DG_psi"),
228 phi_at_q); // compute values of old solution
229
230 fe_values_curvature.get_function_values(generic_data_out.get_vector("curvature"),
231 curvature_at_q); // compute curvature values
232
233 fe_values.get_function_gradients(generic_data_out.get_vector("reinit_DG_psi"),
234 gradient_at_q); // compute values of old solution
235
236 for (const unsigned int q_index : fe_values.quadrature_point_indices())
237 {
238 const auto radius = std::sqrt(
239 fe_values.quadrature_point(q_index)[0] * fe_values.quadrature_point(q_index)[0] +
240 fe_values.quadrature_point(q_index)[1] * fe_values.quadrature_point(q_index)[1]);
241
242 const auto exact_curvature = -1. / radius;
243
244 auto sol_difference = std::abs(
245 exact_solution.value(fe_values.quadrature_point(q_index), 0) - phi_at_q[q_index]);
246
247 auto curv_difference = std::abs(exact_curvature - curvature_at_q[q_index]);
248
249 number norm_gradient = 0.0;
250
251 for (unsigned int d = 0; d < dim; d++)
252 {
253 norm_gradient += gradient_at_q[q_index][d] * gradient_at_q[q_index][d];
254 }
255 norm_gradient = std::sqrt(norm_gradient);
256
257 if (std::abs(exact_solution.value(fe_values.quadrature_point(q_index), 0)) < 0.02)
258 {
259 {
260 error += sol_difference * sol_difference * fe_values.JxW(q_index);
261 error_curvature += curv_difference * curv_difference * fe_values.JxW(q_index);
262
263 norm_exact += exact_solution.value(fe_values.quadrature_point(q_index), 0) *
264 exact_solution.value(fe_values.quadrature_point(q_index), 0) *
265 fe_values.JxW(q_index);
266 norm_curvature_exact +=
267 exact_curvature * exact_curvature * fe_values.JxW(q_index);
268
269 error_gradient +=
270 (norm_gradient - 1.0) * (norm_gradient - 1.0) * fe_values.JxW(q_index);
271
272 norm_gradient_exact += fe_values.JxW(q_index);
273 }
274 }
275 if (phi_at_q[q_index] < 0.0)
276 {
277 mass += fe_values.JxW(q_index);
278 }
279 }
280 }
281
282 error = dealii::Utilities::MPI::sum(error, this->mpi_communicator);
283 norm_exact = dealii::Utilities::MPI::sum(norm_exact, this->mpi_communicator);
284 mass = dealii::Utilities::MPI::sum(mass, this->mpi_communicator);
285 error_curvature = dealii::Utilities::MPI::sum(error_curvature, this->mpi_communicator);
286 norm_curvature_exact =
287 dealii::Utilities::MPI::sum(norm_curvature_exact, this->mpi_communicator);
288
289 error_gradient = dealii::Utilities::MPI::sum(error_gradient, this->mpi_communicator);
290 norm_gradient_exact =
291 dealii::Utilities::MPI::sum(norm_gradient_exact, this->mpi_communicator);
292
293 pcout << "Relative error to exact solution " << std::setprecision(6)
294 << std::sqrt(error) / std::sqrt(norm_exact) << std::endl;
295
296 pcout << "Mass of bubble " << std::setprecision(6) << mass << std::endl;
297 pcout << "Mass loss " << std::setprecision(6)
298 << ((mass - initial_mass) / initial_mass) * 100.0 << " % " << std::endl;
299
300 pcout << "Relative error to exact curvature " << std::setprecision(6)
301 << std::sqrt(error_curvature) / std::sqrt(norm_curvature_exact) << std::endl;
302
303 pcout << "Relative error in gradient " << std::setprecision(6)
304 << std::sqrt(error_gradient) / std::sqrt(norm_gradient_exact) << std::endl;
305
306 pcout << "---------------------------------------------" << std::endl;
307 pcout << " End of user defined postprocessing" << std::endl;
308 pcout << "---------------------------------------------" << std::endl;
309 }
310
311 private:
312 number left_domain = -0.5;
313 number right_domain = 0.5;
314 mutable bool init_mass = true;
315 mutable number initial_mass = 0.0;
316 };
317
318} // namespace MeltPoolDG::Simulation::ReinitCircleDG
A generic utility for managing simulation output data in the MeltPoolDG context.
Definition generic_data_out.hpp:32
Definition reinitialization_case.hpp:79
ReinitializationCase(const std::string &parameter_file_in, MPI_Comm mpi_communicator_in)
Definition reinitialization_case.hpp:83
ReinitializationCaseParameters< number > parameters
Definition reinitialization_case.hpp:81
std::shared_ptr< dealii::Triangulation< dim, spacedim > > triangulation
Definition simulation_case_base.hpp:49
const std::string parameter_file
Definition simulation_case_base.hpp:52
void attach_initial_condition(std::shared_ptr< dealii::Function< dim > > initial_function, const std::string &operation_name)
Definition simulation_case_base.hpp:327
const MPI_Comm mpi_communicator
Definition simulation_case_base.hpp:56
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition reinit_circle_DG.hpp:89
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition reinit_circle_DG.hpp:73
const number eps_interface
Definition reinit_circle_DG.hpp:90
ExactSolution(const number eps)
Definition reinit_circle_DG.hpp:66
InitializePhi()
Definition reinit_circle_DG.hpp:35
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition reinit_circle_DG.hpp:59
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition reinit_circle_DG.hpp:43
void set_boundary_conditions() override
Pure virtual function to set the boundary conditions.
Definition reinit_circle_DG.hpp:137
number right_domain
Definition reinit_circle_DG.hpp:313
bool init_mass
Definition reinit_circle_DG.hpp:314
void do_postprocessing(const GenericDataOut< dim, number > &generic_data_out) const final
Perform specific postprocessing (can be overridden by derived classes).
Definition reinit_circle_DG.hpp:151
SimulationReinitDG(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition reinit_circle_DG.hpp:100
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition reinit_circle_DG.hpp:108
number initial_mass
Definition reinit_circle_DG.hpp:315
void set_field_conditions() override
Pure virtual function to set the field conditions.
Definition reinit_circle_DG.hpp:145
number left_domain
Definition reinit_circle_DG.hpp:312
Definition reinit_circle_DG.cpp:6
Definition dealii_tensor.hpp:10