applications/mp-advec-diff/cases/advection_diffusion_sine_inflow.hpp Source File

Developer Documentation: applications/mp-advec-diff/cases/advection_diffusion_sine_inflow.hpp Source File
Developer Documentation
advection_diffusion_sine_inflow.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/exceptions.h>
4#include <deal.II/base/function.h>
5#include <deal.II/base/function_signed_distance.h>
6#include <deal.II/base/mpi.h>
7#include <deal.II/base/point.h>
8#include <deal.II/base/tensor.h>
9#include <deal.II/base/types.h>
10
11#include <deal.II/distributed/tria.h>
12
13#include <deal.II/fe/fe_q.h>
14
15#include <deal.II/grid/grid_generator.h>
16#include <deal.II/grid/tria.h>
17
18#include <deal.II/lac/vector.h>
19
20#include <deal.II/numerics/vector_tools.h>
21
23
24#include <cmath>
25#include <iostream>
26#include <memory>
27#include <string>
28
29#include "../advection_diffusion_case.hpp"
30
31
33{
34 static bool inflow_outflow_bc = false;
35
36 template <int dim, typename number>
37 class ExactSolution : public dealii::Function<dim, number>
38 {
39 public:
41 : dealii::Function<dim, number>()
43
44 {}
45
46 number
47 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
48 {
49 const number t = this->get_time();
50 return std::sin(4.0 * dealii::numbers::PI * (p[0] - velocity_scale * t));
51 }
52
53 private:
54 const number velocity_scale;
55 };
56
57 /*
58 * this function specifies the initial field of the level set equation
59 */
60 template <int dim, typename number>
61 class InitializePhi : public dealii::Function<dim, number>
62 {
63 public:
65 : dealii::Function<dim, number>()
66 , distance_sphere(dim == 1 ? dealii::Point<dim, number>(0.0) :
67 (dim == 2) ? dealii::Point<dim, number>(0.0, 0.5) :
68 dealii::Point<dim, number>(0, 0, 0.5),
69 0.25)
70 {}
71
72 number
73 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
74 {
75 return std::sin(4.0 * dealii::numbers::PI * p[0]);
76 }
77
78 private:
79 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere;
80 };
81
82 template <int dim, typename number>
83 class AdvectionField : public dealii::Function<dim, number>
84 {
85 public:
87 : dealii::Function<dim, number>(dim)
89 {}
90
91 number
92 value([[maybe_unused]] const dealii::Point<dim, number> &p,
93 const unsigned int component) const override
94 {
95 if (component == 0)
96 return velocity_scale;
97 else
98 return 0.0;
99 }
100
101 private:
102 const number velocity_scale;
103 };
104
105 template <int dim, typename number>
106 class DirichletConditions : public dealii::Function<dim, number>
107 {
108 public:
110 : dealii::Function<dim, number>(dim)
112 {}
113
114 number
115 value([[maybe_unused]] const dealii::Point<dim, number> &p,
116 [[maybe_unused]] const unsigned int component) const override
117 {
118 const number t = this->get_time();
119 return std::sin(4.0 * dealii::numbers::PI * (p[0] - velocity_scale * t));
120 }
121
122 private:
123 const number velocity_scale;
124 };
125
126 /*
127 * This class collects all relevant input data for the level set simulation
128 */
129 template <int dim, typename number>
131 {
132 public:
135 {}
136
137 void
139 {
140 if (dim == 1 || this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
141 {
142 AssertDimension(dealii::Utilities::MPI::n_mpi_processes(this->mpi_communicator), 1);
143 this->triangulation = std::make_shared<dealii::Triangulation<dim>>();
144 }
145 else
146 {
147 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
148 this->mpi_communicator);
149 }
150
151 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
152 {
153 dealii::GridGenerator::subdivided_hyper_cube_with_simplices(
154 *this->triangulation,
155 dealii::Utilities::pow(2, this->parameters.base.global_refinements),
158 }
159 else
160 {
161 dealii::GridGenerator::hyper_cube(*this->triangulation, left_domain, right_domain);
162 this->triangulation->refine_global(this->parameters.base.global_refinements);
163 }
164 }
165
166 void
168 {
169 /*
170 * create a pair of (boundary_id, dirichlet_function)
171 */
172 constexpr dealii::types::boundary_id inflow_bc = 42;
173 constexpr dealii::types::boundary_id do_nothing = 0;
174
175 auto dirichlet = std::make_shared<DirichletConditions<dim, number>>(velocity_scale);
176
178 {
179 this->attach_boundary_condition({inflow_bc, dirichlet},
180 "inflow_outflow",
181 "advection_diffusion");
182 this->attach_boundary_condition({do_nothing, dirichlet},
183 "inflow_outflow",
184 "advection_diffusion");
185 }
186 else
187 this->attach_boundary_condition({inflow_bc, dirichlet}, "dirichlet", "advection_diffusion");
188
189
190 if constexpr (dim >= 2)
191 {
192 for (const auto &cell : this->triangulation->cell_iterators())
193 for (const auto &face : cell->face_iterators())
194 if ((face->at_boundary()))
195 {
196 if (face->center()[0] < -0.49)
197 {
198 face->set_boundary_id(inflow_bc);
199 }
200 else
201 {
202 face->set_boundary_id(do_nothing);
203 }
204 }
205 }
206 else
207 {
208 (void)do_nothing; // suppress unused variable for 1D
209 }
210 }
211
212 void
214 {
216 "advection_diffusion");
218 "prescribed_velocity",
219 "advection_diffusion");
220 }
221
222 bool
223 add_case_specific_parameters(dealii::ParameterHandler &prm) override
224 {
225 prm.add_parameter("inflow outflow bc",
227 "Set if the inflow/outflow boundary condition should be enabled.");
228
229 prm.add_parameter("velocity scale",
231 "Set magnitude of the prescribed transport velocity in x-direction. ");
232
233 return this->parameters.base.do_print_parameters;
234 }
235
236 void
237 do_postprocessing(const GenericDataOut<dim, number> &generic_data_out) const final
238 {
239 dealii::ConditionalOStream pcout(
240 std::cout, dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0);
241
242 /*Error Calculation*/
244 exact_solution.set_time(generic_data_out.get_time());
245
246 const auto n_q_points = 50; // Number is high to get accurate error even on a coarse mesh
247 dealii::FE_Q<dim> fe(this->parameters.advec_diff.fe.degree);
248
249 dealii::QGauss<dim> quadrature(n_q_points);
250 dealii::FEValues<dim> fe_values(fe,
251 quadrature,
252 dealii::update_values | dealii::update_JxW_values |
253 dealii::update_quadrature_points);
254
255 std::vector<number> phi_at_q(dealii::QGauss<dim>(n_q_points).size());
256
257
258
259 generic_data_out.get_vector("advected_field").update_ghost_values();
260
261 number error = 0.0;
262 number norm_exact = 0.0;
263
264 for (const auto &cell :
265 generic_data_out.get_dof_handler("advected_field").active_cell_iterators())
266 if (cell->is_locally_owned())
267 {
268 fe_values.reinit(cell);
269 fe_values.get_function_values(generic_data_out.get_vector("advected_field"),
270 phi_at_q); // compute values of old solution
271
272 for (const unsigned int q_index : fe_values.quadrature_point_indices())
273 {
274 auto sol_difference = std::abs(
275 exact_solution.value(fe_values.quadrature_point(q_index), 0) - phi_at_q[q_index]);
276 error += sol_difference * sol_difference * fe_values.JxW(q_index);
277 norm_exact += exact_solution.value(fe_values.quadrature_point(q_index), 0) *
278 exact_solution.value(fe_values.quadrature_point(q_index), 0) *
279 fe_values.JxW(q_index);
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
285 pcout << "Relative error to exact solution " << std::sqrt(error) / std::sqrt(norm_exact)
286 << std::endl;
287 pcout << "---------------------------------------------" << std::endl;
288 pcout << " End of user defined postprocessing" << std::endl;
289 pcout << "---------------------------------------------" << std::endl;
290 }
291
292 private:
293 const number left_domain = -0.5;
294 const number right_domain = 0.5;
295 number velocity_scale = 1.1;
296 };
297
298} // namespace MeltPoolDG::Simulation::AdvectionDiffusionSineInflow
A generic utility for managing simulation output data in the MeltPoolDG context.
Definition generic_data_out.hpp:32
Definition advection_diffusion_case.hpp:53
AdvectionDiffusionCase(const std::string &parameter_file_in, MPI_Comm mpi_communicator_in)
Definition advection_diffusion_case.hpp:57
AdvectionDiffusionCaseParameters< number > parameters
Definition advection_diffusion_case.hpp:55
void attach_boundary_condition(std::pair< const dealii::types::boundary_id, const std::shared_ptr< dealii::Function< dim > > > id_and_function, const std::string &type, const std::string &operation_name)
Attach a boundary condition for a specific operation.
Definition simulation_case_base.hpp:345
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
void attach_field_function(std::shared_ptr< dealii::Function< dim > > function, const std::string &type, const std::string &operation_name)
Definition simulation_case_base.hpp:315
const MPI_Comm mpi_communicator
Definition simulation_case_base.hpp:56
Definition advection_diffusion_sine_inflow.hpp:84
number value(const dealii::Point< dim, number > &p, const unsigned int component) const override
Definition advection_diffusion_sine_inflow.hpp:92
AdvectionField(const number velocity_scale)
Definition advection_diffusion_sine_inflow.hpp:86
const number velocity_scale
Definition advection_diffusion_sine_inflow.hpp:102
Definition advection_diffusion_sine_inflow.hpp:107
DirichletConditions(const number velocity_scale)
Definition advection_diffusion_sine_inflow.hpp:109
const number velocity_scale
Definition advection_diffusion_sine_inflow.hpp:123
number value(const dealii::Point< dim, number > &p, const unsigned int component) const override
Definition advection_diffusion_sine_inflow.hpp:115
Definition advection_diffusion_sine_inflow.hpp:38
const number velocity_scale
Definition advection_diffusion_sine_inflow.hpp:54
ExactSolution(const number velocity_scale)
Definition advection_diffusion_sine_inflow.hpp:40
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition advection_diffusion_sine_inflow.hpp:47
Definition advection_diffusion_sine_inflow.hpp:62
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition advection_diffusion_sine_inflow.hpp:79
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition advection_diffusion_sine_inflow.hpp:73
InitializePhi()
Definition advection_diffusion_sine_inflow.hpp:64
const number right_domain
Definition advection_diffusion_sine_inflow.hpp:294
number velocity_scale
Definition advection_diffusion_sine_inflow.hpp:295
void set_boundary_conditions() final
Pure virtual function to set the boundary conditions.
Definition advection_diffusion_sine_inflow.hpp:167
SimulationAdvecSineInflow(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition advection_diffusion_sine_inflow.hpp:133
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition advection_diffusion_sine_inflow.hpp:138
void set_field_conditions() final
Pure virtual function to set the field conditions.
Definition advection_diffusion_sine_inflow.hpp:213
const number left_domain
Definition advection_diffusion_sine_inflow.hpp:293
void do_postprocessing(const GenericDataOut< dim, number > &generic_data_out) const final
Perform specific postprocessing (can be overridden by derived classes).
Definition advection_diffusion_sine_inflow.hpp:237
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Add simulation-specific parameters (can be overridden).
Definition advection_diffusion_sine_inflow.hpp:223
Definition advection_diffusion_sine_inflow.cpp:6
static bool inflow_outflow_bc
Definition advection_diffusion_sine_inflow.hpp:34
Definition dealii_tensor.hpp:10