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

Developer Documentation: applications/mp-advec-diff/cases/advection_diffusion.hpp Source File
Developer Documentation
advection_diffusion.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/grid/grid_generator.h>
14#include <deal.II/grid/grid_tools_geometry.h>
15#include <deal.II/grid/tria.h>
16
17#include <deal.II/lac/vector.h>
18
19#include <deal.II/numerics/vector_tools.h>
20
23
24#include <cmath>
25#include <memory>
26#include <string>
27
28#include "../advection_diffusion_case.hpp"
29
31{
32 static bool inflow_outflow_bc = false;
33
34 /*
35 * this function specifies the initial field of the level set equation
36 */
37 template <int dim, typename number>
38 class InitialLevelSetField : public dealii::Function<dim, number>
39 {
40 public:
41 InitialLevelSetField(const LevelSet::LevelSetType level_set_type = LevelSet::LevelSetType::tanh,
42 const number eps = 0.0)
43 : dealii::Function<dim>()
44 , distance_sphere(dim == 1 ? dealii::Point<dim, number>(0.0) :
45 (dim == 2) ? dealii::Point<dim, number>(0.0, 0.5) :
46 dealii::Point<dim, number>(0, 0, 0.5),
47 0.25)
49 , eps(eps)
50 {}
51
52 number
53 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
54 {
55 const auto signed_distance = -distance_sphere.value(p);
56
57 switch (level_set_type)
58 {
59 case LevelSet::LevelSetType::tanh:
61 case LevelSet::LevelSetType::smoothed_heaviside:
62 return CharacteristicFunctions::smoothed_heaviside(signed_distance, eps);
63 case LevelSet::LevelSetType::heaviside:
64 return CharacteristicFunctions::sgn(signed_distance);
65 case LevelSet::LevelSetType::signed_distance:
66 return signed_distance;
67 default:
68 DEAL_II_NOT_IMPLEMENTED();
69 }
70 // unreachable dummy return
71 return 0.0;
72 }
73
74 private:
75 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere;
76 const LevelSet::LevelSetType level_set_type;
77 const number eps;
78 };
79
80 template <int dim, typename number>
81 class PrescribedVelocityField : public dealii::Function<dim, number>
82 {
83 public:
85 : dealii::Function<dim>(dim)
86 {}
87
88 number
89 value(const dealii::Point<dim, number> &p, const unsigned int component) const override
90 {
91 dealii::Tensor<1, dim, number> value_;
92
93 const number x = p[0];
94 const number y = p[dim - 1];
95
96 value_[0] = 4 * y;
97 value_[dim - 1] = -4 * x;
98
99 return value_[component];
100 }
101 };
102
103 /*
104 * This class collects all relevant input data for the level set simulation
105 */
106
107 template <int dim, typename number>
109 {
110 public:
113 {}
114
115 void
117 {
118 if (dim == 1 || this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
119 {
120 AssertDimension(dealii::Utilities::MPI::n_mpi_processes(this->mpi_communicator), 1);
121 this->triangulation = std::make_shared<dealii::Triangulation<dim>>();
122 }
123 else
124 {
125 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
126 this->mpi_communicator);
127 }
128
129 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
130 {
131 dealii::GridGenerator::subdivided_hyper_cube_with_simplices(
132 *this->triangulation,
133 dealii::Utilities::pow(2, this->parameters.base.global_refinements),
136 }
137 else
138 {
139 dealii::GridGenerator::hyper_cube(*this->triangulation, left_domain, right_domain);
140 this->triangulation->refine_global(this->parameters.base.global_refinements);
141 }
142 }
143
144 void
146 {
147 /*
148 * create a pair of (boundary_id, dirichlet_function)
149 */
150 constexpr dealii::types::boundary_id inflow_bc = 42;
151 constexpr dealii::types::boundary_id do_nothing = 0;
152
153 auto dirichlet = std::make_shared<dealii::Functions::ConstantFunction<dim>>(-1);
154
156 {
157 this->attach_boundary_condition({inflow_bc, dirichlet},
158 "inflow_outflow",
159 "advection_diffusion");
160 this->attach_boundary_condition({do_nothing, dirichlet},
161 "inflow_outflow",
162 "advection_diffusion");
163 }
164 else
165 this->attach_boundary_condition({inflow_bc, dirichlet}, "dirichlet", "advection_diffusion");
166
167 /*
168 * mark inflow edges with boundary label (no boundary on outflow edges must be prescribed
169 * due to the hyperbolic nature of the analyzed problem
170 *
171 out in
172 (-1,1) +---------------+ (1,1)
173 | : |
174 in | : | out
175 |_______________|
176 | : |
177 out | : | in
178 | : |
179 +---------------+
180 * (-1,-1) in out (1,-1)
181 */
182 if constexpr (dim >= 2)
183 {
184 for (const auto &cell : this->triangulation->cell_iterators())
185 for (const auto &face : cell->face_iterators())
186 if ((face->at_boundary()))
187 {
188 const number half_line = (right_domain + left_domain) / 2;
189
190 if (face->center()[0] == left_domain && face->center()[dim - 1] >= half_line)
191 face->set_boundary_id(inflow_bc);
192 else if (face->center()[0] == right_domain &&
193 face->center()[dim - 1] <= half_line)
194 face->set_boundary_id(inflow_bc);
195 else if (face->center()[dim - 1] == right_domain &&
196 face->center()[0] >= half_line)
197 face->set_boundary_id(inflow_bc);
198 else if (face->center()[dim - 1] == left_domain && face->center()[0] <= half_line)
199 face->set_boundary_id(inflow_bc);
200 else
201 face->set_boundary_id(do_nothing);
202 }
203 }
204 else
205 {
206 (void)do_nothing; // suppress unused variable for 1D
207 }
208 }
209
210 void
212 {
214 std::make_shared<InitialLevelSetField<dim, number>>(
216 0.5 * dealii::GridTools::minimal_cell_diameter(*this->triangulation) / std::sqrt(dim)),
217 "advection_diffusion");
219 "prescribed_velocity",
220 "advection_diffusion");
221 }
222
223 bool
224 add_case_specific_parameters(dealii::ParameterHandler &prm) override
225 {
226 prm.add_parameter("inflow outflow bc",
228 "Set if the inflow/outflow boundary condition should be enabled.");
229 prm.add_parameter(
230 "level set type",
232 "Choose which level set type should be initialized. "
233 "level_set: smooth tanh function, eps is controlled by reinit data; "
234 "smooth_heaviside: smooth heaviside function, eps is controlled by reinit data"
235 "heaviside: jump from 0 to 1 at the interface; "
236 "signed_distance: signed distance level set.");
237
238 return this->parameters.base.do_print_parameters;
239 }
240
241 void
242 do_postprocessing(const GenericDataOut<dim, number> &generic_data_out) const final
243 {
244 dealii::ConditionalOStream pcout(
245 std::cout, dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0);
246
247 pcout << "---------------------------------------------" << std::endl;
248 pcout << " Starting user defined postprocessing" << std::endl;
249 pcout << "---------------------------------------------" << std::endl;
250 pcout << "Accessible vectors:" << std::endl;
251 for (const auto &entry : generic_data_out.entries)
252 for (const auto &name : std::get<3>(entry))
253 {
254 pcout << " * " << std::setw(20) << name << " Max-norm: " << std::setprecision(5)
255 << std::setw(10) << generic_data_out.get_vector(name).linfty_norm()
256 << " number of dofs: " << generic_data_out.get_dof_handler(name).n_dofs()
257 << std::endl;
258 break;
259 }
260 pcout << "---------------------------------------------" << std::endl;
261 pcout << " End of user defined postprocessing" << std::endl;
262 pcout << "---------------------------------------------" << std::endl;
263 }
264
265 private:
266 const number left_domain = -1.0;
267 const number right_domain = 1.0;
268 LevelSet::LevelSetType level_set_type = LevelSet::LevelSetType::tanh;
269 };
270} // namespace MeltPoolDG::Simulation::AdvectionDiffusion
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
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition advection_diffusion.hpp:53
const number eps
Definition advection_diffusion.hpp:77
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition advection_diffusion.hpp:75
const LevelSet::LevelSetType level_set_type
Definition advection_diffusion.hpp:76
InitialLevelSetField(const LevelSet::LevelSetType level_set_type=LevelSet::LevelSetType::tanh, const number eps=0.0)
Definition advection_diffusion.hpp:41
number value(const dealii::Point< dim, number > &p, const unsigned int component) const override
Definition advection_diffusion.hpp:89
PrescribedVelocityField()
Definition advection_diffusion.hpp:84
void set_field_conditions() final
Pure virtual function to set the field conditions.
Definition advection_diffusion.hpp:211
const number right_domain
Definition advection_diffusion.hpp:267
const number left_domain
Definition advection_diffusion.hpp:266
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition advection_diffusion.hpp:116
void set_boundary_conditions() final
Pure virtual function to set the boundary conditions.
Definition advection_diffusion.hpp:145
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Add simulation-specific parameters (can be overridden).
Definition advection_diffusion.hpp:224
LevelSet::LevelSetType level_set_type
Definition advection_diffusion.hpp:268
SimulationAdvec(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition advection_diffusion.hpp:111
void do_postprocessing(const GenericDataOut< dim, number > &generic_data_out) const final
Perform specific postprocessing (can be overridden by derived classes).
Definition advection_diffusion.hpp:242
number smoothed_heaviside(const number &distance, const number &eps)
Definition characteristic_functions.hpp:19
number tanh_characteristic_function(const number &distance, const number &eps)
Definition characteristic_functions.hpp:12
int sgn(const number &x)
Definition characteristic_functions.hpp:63
Definition advection_diffusion.cpp:6
static bool inflow_outflow_bc
Definition advection_diffusion.hpp:32
Definition dealii_tensor.hpp:10