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

Developer Documentation: applications/mp-advec-diff/cases/advection_diffusion_vortex.hpp Source File
Developer Documentation
advection_diffusion_vortex.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)
87 {}
88
89 number
90 value(const dealii::Point<dim, number> &p, const unsigned int component) const override
91 {
92 dealii::Tensor<1, dim, number> value_;
93
94 const number x = p[0];
95 const number y = p[dim - 1];
96
97 value_[0] = velocity_scale * y;
98 value_[dim - 1] = -velocity_scale * x;
99
100 return value_[component];
101 }
102
103 private:
104 const number velocity_scale;
105 };
106
107 /*
108 * This class collects all relevant input data for the level set simulation
109 */
110
111 template <int dim, typename number>
113 {
114 public:
117 {}
118
119 void
121 {
122 if (dim == 1 || this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
123 {
124 AssertDimension(dealii::Utilities::MPI::n_mpi_processes(this->mpi_communicator), 1);
125 this->triangulation = std::make_shared<dealii::Triangulation<dim>>();
126 }
127 else
128 {
129 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
130 this->mpi_communicator);
131 }
132
133 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
134 {
135 dealii::GridGenerator::subdivided_hyper_cube_with_simplices(
136 *this->triangulation,
137 dealii::Utilities::pow(2, this->parameters.base.global_refinements),
140 }
141 else
142 {
143 dealii::GridGenerator::hyper_cube(*this->triangulation, left_domain, right_domain);
144 this->triangulation->refine_global(this->parameters.base.global_refinements);
145 }
146 }
147
148 void
150 {
151 /*
152 * create a pair of (boundary_id, dirichlet_function)
153 */
154 constexpr dealii::types::boundary_id inflow_bc = 42;
155 constexpr dealii::types::boundary_id do_nothing = 0;
156
157 auto dirichlet = std::make_shared<dealii::Functions::ConstantFunction<dim>>(-1);
158
160 {
161 this->attach_boundary_condition({inflow_bc, dirichlet},
162 "inflow_outflow",
163 "advection_diffusion");
164 this->attach_boundary_condition({do_nothing, dirichlet},
165 "inflow_outflow",
166 "advection_diffusion");
167 }
168 else
169 this->attach_boundary_condition({inflow_bc, dirichlet}, "dirichlet", "advection_diffusion");
170
171 /*
172 * mark inflow edges with boundary label (no boundary on outflow edges must be prescribed
173 * due to the hyperbolic nature of the analyzed problem
174 *
175 out in
176 (-1,1) +---------------+ (1,1)
177 | : |
178 in | : | out
179 |_______________|
180 | : |
181 out | : | in
182 | : |
183 +---------------+
184 * (-1,-1) in out (1,-1)
185 */
186 if constexpr (dim >= 2)
187 {
188 for (const auto &cell : this->triangulation->cell_iterators())
189 for (const auto &face : cell->face_iterators())
190 if ((face->at_boundary()))
191 {
192 const number half_line = (right_domain + left_domain) / 2;
193
194 if (face->center()[0] == left_domain && face->center()[dim - 1] >= half_line)
195 face->set_boundary_id(inflow_bc);
196 else if (face->center()[0] == right_domain &&
197 face->center()[dim - 1] <= half_line)
198 face->set_boundary_id(inflow_bc);
199 else if (face->center()[dim - 1] == right_domain &&
200 face->center()[0] >= half_line)
201 face->set_boundary_id(inflow_bc);
202 else if (face->center()[dim - 1] == left_domain && face->center()[0] <= half_line)
203 face->set_boundary_id(inflow_bc);
204 else
205 face->set_boundary_id(do_nothing);
206 }
207 }
208 else
209 {
210 (void)do_nothing; // suppress unused variable for 1D
211 }
212 }
213
214 void
216 {
218 std::make_shared<InitialLevelSetField<dim, number>>(
220 0.5 * dealii::GridTools::minimal_cell_diameter(*this->triangulation) / std::sqrt(dim)),
221 "advection_diffusion");
224 "prescribed_velocity",
225 "advection_diffusion");
226 }
227
228 bool
229 add_case_specific_parameters(dealii::ParameterHandler &prm) override
230 {
231 prm.add_parameter("inflow outflow bc",
233 "Set if the inflow/outflow boundary condition should be enabled.");
234 prm.add_parameter(
235 "level set type",
237 "Choose which level set type should be initialized. "
238 "level_set: smooth tanh function, eps is controlled by reinit data; "
239 "smooth_heaviside: smooth heaviside function, eps is controlled by reinit data"
240 "heaviside: jump from 0 to 1 at the interface; "
241 "signed_distance: signed distance level set.");
242
243 prm.add_parameter("velocity scale",
245 "Set scaling factor for prescribed velocity field. "
246 "For vortex flow, this parameter represents the angular velocity.");
247
248 return this->parameters.base.do_print_parameters;
249 }
250
251 void
252 do_postprocessing(const GenericDataOut<dim, number> &generic_data_out) const final
253 {
254 dealii::ConditionalOStream pcout(
255 std::cout, dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0);
256
257 pcout << "---------------------------------------------" << std::endl;
258 pcout << " Starting user defined postprocessing" << std::endl;
259 pcout << "---------------------------------------------" << std::endl;
260 pcout << "Accessible vectors:" << std::endl;
261 for (const auto &entry : generic_data_out.entries)
262 for (const auto &name : std::get<3>(entry))
263 {
264 pcout << " * " << std::setw(20) << name << " Max-norm: " << std::setprecision(5)
265 << std::setw(10) << generic_data_out.get_vector(name).linfty_norm()
266 << " number of dofs: " << generic_data_out.get_dof_handler(name).n_dofs()
267 << std::endl;
268 break;
269 }
270 pcout << "---------------------------------------------" << std::endl;
271 pcout << " End of user defined postprocessing" << std::endl;
272 pcout << "---------------------------------------------" << std::endl;
273 }
274
275 private:
276 const number left_domain = -1.0;
277 const number right_domain = 1.0;
278 LevelSet::LevelSetType level_set_type = LevelSet::LevelSetType::tanh;
279 number velocity_scale = 4.0;
280 };
281} // namespace MeltPoolDG::Simulation::AdvectionDiffusionVortex
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
const number eps
Definition advection_diffusion_vortex.hpp:77
InitialLevelSetField(const LevelSet::LevelSetType level_set_type=LevelSet::LevelSetType::tanh, const number eps=0.0)
Definition advection_diffusion_vortex.hpp:41
const LevelSet::LevelSetType level_set_type
Definition advection_diffusion_vortex.hpp:76
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition advection_diffusion_vortex.hpp:53
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition advection_diffusion_vortex.hpp:75
PrescribedVelocityField(const number velocity_scale)
Definition advection_diffusion_vortex.hpp:84
const number velocity_scale
Definition advection_diffusion_vortex.hpp:104
number value(const dealii::Point< dim, number > &p, const unsigned int component) const override
Definition advection_diffusion_vortex.hpp:90
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition advection_diffusion_vortex.hpp:120
SimulationAdvecVortex(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition advection_diffusion_vortex.hpp:115
void do_postprocessing(const GenericDataOut< dim, number > &generic_data_out) const final
Perform specific postprocessing (can be overridden by derived classes).
Definition advection_diffusion_vortex.hpp:252
const number left_domain
Definition advection_diffusion_vortex.hpp:276
number velocity_scale
Definition advection_diffusion_vortex.hpp:279
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Add simulation-specific parameters (can be overridden).
Definition advection_diffusion_vortex.hpp:229
void set_field_conditions() final
Pure virtual function to set the field conditions.
Definition advection_diffusion_vortex.hpp:215
void set_boundary_conditions() final
Pure virtual function to set the boundary conditions.
Definition advection_diffusion_vortex.hpp:149
const number right_domain
Definition advection_diffusion_vortex.hpp:277
LevelSet::LevelSetType level_set_type
Definition advection_diffusion_vortex.hpp:278
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_vortex.cpp:6
static bool inflow_outflow_bc
Definition advection_diffusion_vortex.hpp:32
Definition dealii_tensor.hpp:10