applications/mp-heat-transfer/cases/melt_front_propagation/melt_front_propagation.templates.hpp Source File

Developer Documentation: applications/mp-heat-transfer/cases/melt_front_propagation/melt_front_propagation.templates.hpp Source File
Developer Documentation
melt_front_propagation.templates.hpp
Go to the documentation of this file.
1#pragma once
2
4//
5#include <deal.II/base/exceptions.h>
6#include <deal.II/base/function.h>
7#include <deal.II/base/point.h>
8#include <deal.II/base/types.h>
9
10#include <deal.II/distributed/shared_tria.h>
11#include <deal.II/distributed/tria.h>
12
13#include <deal.II/grid/grid_generator.h>
14#include <deal.II/grid/tria.h>
15
18
19#include <cmath>
20#include <memory>
21#include <type_traits>
22#include <vector>
23
24#include "../../../mp-melt-pool/melt_pool_case.hpp"
25#include "../../heat_transfer_case.hpp"
26
27
29{
30 template <int dim, typename number>
31 class InitialLevelSet : public dealii::Function<dim, number>
32 {
33 public:
35 const LevelSet::LevelSetType level_set_type,
36 const number eps)
37 : dealii::Function<dim, number>()
40 , eps(eps)
41 {}
42
43 number
44 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
45 {
46 const auto signed_distance = z_level - p[dim - 1];
47
48 switch (level_set_type)
49 {
50 case LevelSet::LevelSetType::tanh:
52 case LevelSet::LevelSetType::smoothed_heaviside:
53 return CharacteristicFunctions::smoothed_heaviside(signed_distance, eps);
54 case LevelSet::LevelSetType::signed_distance:
55 return signed_distance;
56 default:
57 DEAL_II_NOT_IMPLEMENTED();
58 }
59 // unreachable dummy return
60 return 0.0;
61 }
62
63 private:
64 const number z_level;
65 const LevelSet::LevelSetType level_set_type;
66 const number eps;
67 };
68
69
70 template <int dim, typename number, typename CaseClass>
72 std::string parameter_file,
73 const MPI_Comm mpi_communicator)
74 : CaseClass(parameter_file, mpi_communicator)
75 {}
76
77
78 template <int dim, typename number, typename CaseClass>
79 bool
81 dealii::ParameterHandler &prm)
82 {
83 prm.add_parameter("domain x min", x_min, "minimum x coordinate of simulation domain");
84 prm.add_parameter("domain x max", x_max, "maximum x coordinate of simulation domain");
85
86 prm.add_parameter("domain z min", z_min, "minimum z coordinate of simulation domain");
87 prm.add_parameter("domain z max", z_max, "maximum z coordinate of simulation domain");
88 if constexpr (dim == 3)
89 {
90 prm.add_parameter("domain y min", y_min, "minimum y coordinate of simulation domain");
91 prm.add_parameter("domain y max", y_max, "maximum y coordinate of simulation domain");
92 }
93 prm.add_parameter("initial temperature", T_0);
94 prm.add_parameter("do two phase", do_two_phase);
95
96 return this->parameters.base.do_print_parameters;
97 }
98
99
100 template <int dim, typename number, typename CaseClass>
101 void
103 {
104 AssertThrow(dim == 1 || x_min < x_max,
105 dealii::ExcMessage(
106 "The upper bound of the domain must be greater than the lower bound! Abort..."));
107 AssertThrow(z_min < z_max,
108 dealii::ExcMessage(
109 "The upper bound of the domain must be greater than the lower bound! Abort..."));
110 if constexpr (dim == 3)
111 AssertThrow(
112 y_min < y_max,
113 dealii::ExcMessage(
114 "The upper bound of the domain must be greater than the lower bound! Abort..."));
115
116 if constexpr (dim == 1)
117 {
118#ifdef DEAL_II_WITH_METIS
119 this->triangulation = std::make_shared<dealii::parallel::shared::Triangulation<1>>(
120 this->mpi_communicator,
121 dealii::Triangulation<dim>::none,
122 false,
123 dealii::parallel::shared::Triangulation<dim>::Settings::partition_metis);
124#else
125 AssertThrow(
126 false,
127 dealii::ExcMessage(
128 "Missing Metis support of the deal.II installation. "
129 "Configure deal.II with -D DEAL_II_WITH_METIS='ON' to execute this example."));
130#endif
131 // create mesh
132 const dealii::Point<1> left(z_min);
133 const dealii::Point<1> right(z_max);
134 dealii::GridGenerator::hyper_rectangle(*this->triangulation, left, right);
135 this->triangulation->refine_global(this->parameters.base.global_refinements);
136 }
137 else if constexpr (dim == 2)
138 {
139 this->triangulation =
140 std::make_shared<dealii::parallel::distributed::Triangulation<2>>(this->mpi_communicator);
141
142 if constexpr (std::is_same_v<CaseClass, Heat::HeatTransferCase<dim, number>>)
143 {
144 if (not do_two_phase)
145 {
146 std::vector<unsigned> refinements(2, 1);
147 refinements[0] = 3;
148 // create mesh
149 const dealii::Point<2> left(0, -z_max);
150 const dealii::Point<2> right(x_max, 0);
151 dealii::GridGenerator::subdivided_hyper_rectangle(*this->triangulation,
152 refinements,
153 left,
154 right);
155 this->triangulation->refine_global(this->parameters.base.global_refinements);
156 }
157 else
158 {
159 std::vector<unsigned> refinements(2, 1);
160 refinements[0] = 3;
161 refinements[1] = 2;
162 // create mesh
163 const dealii::Point<2> left(0, -z_max);
164 const dealii::Point<2> right(x_max, z_max);
165 dealii::GridGenerator::subdivided_hyper_rectangle(*this->triangulation,
166 refinements,
167 left,
168 right);
169 this->triangulation->refine_global(this->parameters.base.global_refinements);
170 }
171 }
172 else
173 {
174 std::vector<unsigned> refinements(2, 1);
175 refinements[0] = 3;
176 refinements[1] = 2;
177 // create mesh
178 const dealii::Point<2> left(0, -z_max);
179 const dealii::Point<2> right(x_max, z_max);
180 dealii::GridGenerator::subdivided_hyper_rectangle(*this->triangulation,
181 refinements,
182 left,
183 right);
184 this->triangulation->refine_global(this->parameters.base.global_refinements);
185 }
186 }
187 else if constexpr (dim == 3)
188 {
189 this->triangulation =
190 std::make_shared<dealii::parallel::distributed::Triangulation<3>>(this->mpi_communicator);
191
192 if constexpr (std::is_same_v<CaseClass, Heat::HeatTransferCase<dim, number>>)
193 {
194 if (not do_two_phase)
195 {
196 std::vector<unsigned int> refinements(3, 1);
197 refinements[0] = 3;
198 refinements[1] = 3;
199 // create mesh
200 const dealii::Point<3> left(0, -y_max, -z_max);
201 const dealii::Point<3> right(x_max, y_max, z_max);
202 dealii::GridGenerator::subdivided_hyper_rectangle(*this->triangulation,
203 refinements,
204 left,
205 right);
206 this->triangulation->refine_global(this->parameters.base.global_refinements);
207 }
208 else
209 {
210 std::vector<unsigned int> refinements(3, 1);
211 refinements[0] = 3;
212 refinements[1] = 3;
213 refinements[2] = 2;
214 // create mesh
215 const dealii::Point<3> left(0, 0, z_max);
216 const dealii::Point<3> right(x_max, y_max, -z_max);
217 dealii::GridGenerator::subdivided_hyper_rectangle(*this->triangulation,
218 refinements,
219 left,
220 right);
221 this->triangulation->refine_global(this->parameters.base.global_refinements);
222 }
223 }
224 else
225 {
226 std::vector<unsigned int> refinements(3, 1);
227 refinements[0] = 3;
228 refinements[1] = 3;
229 refinements[2] = 2;
230 // create mesh
231 const dealii::Point<3> left(0, 0, z_max);
232 const dealii::Point<3> right(x_max, y_max, -z_max);
233 dealii::GridGenerator::subdivided_hyper_rectangle(*this->triangulation,
234 refinements,
235 left,
236 right);
237 this->triangulation->refine_global(this->parameters.base.global_refinements);
238 }
239 }
240 else
241 AssertThrow(false, dealii::ExcMessage("Impossible dimension! Abort ..."));
242 }
243
244
245 template <int dim, typename number, typename CaseClass>
246 void
248 {
249 if constexpr (std::is_same_v<CaseClass, Heat::HeatTransferCase<dim, number>>)
250 {
251 const dealii::types::boundary_id right_bc = 10;
252 for (const auto &cell : this->triangulation->cell_iterators())
253 {
254 for (auto &face : cell->face_iterators())
255 if (face->at_boundary())
256 {
257 if (face->center()[0] == x_max)
258 face->set_boundary_id(right_bc);
259 }
260 }
261 this->attach_boundary_condition(
262 {right_bc, std::make_shared<dealii::Functions::ConstantFunction<dim>>(T_0)},
263 "dirichlet",
264 "heat_transfer");
265 }
266 else if constexpr (std::is_same_v<CaseClass, MeltPoolCase<dim, number>>)
267 {
268 const dealii::types::boundary_id lower_bc = 1;
269 const dealii::types::boundary_id upper_bc = 2;
270 const dealii::types::boundary_id left_bc = 3;
271 const dealii::types::boundary_id right_bc = 4;
272 [[maybe_unused]] const dealii::types::boundary_id front_bc = 5;
273 [[maybe_unused]] const dealii::types::boundary_id back_bc = 6;
274 for (const auto &cell : this->triangulation->cell_iterators())
275 for (auto &face : cell->face_iterators())
276 if (face->at_boundary())
277 {
278 if constexpr (dim == 1)
279 {
280 if (face->center()[0] == z_max)
281 face->set_boundary_id(lower_bc);
282 else if (face->center()[0] == z_min)
283 face->set_boundary_id(upper_bc);
284 }
285 else
286 {
287 if (face->center()[0] == x_max)
288 face->set_boundary_id(right_bc);
289 else if (face->center()[0] == x_min)
290 face->set_boundary_id(left_bc);
291
292 if constexpr (dim == 2)
293 {
294 if (face->center()[1] == -z_max)
295 face->set_boundary_id(lower_bc);
296 if (face->center()[1] == z_max)
297 face->set_boundary_id(upper_bc);
298 }
299 if constexpr (dim == 3)
300 {
301 if (face->center()[1] == -y_max)
302 face->set_boundary_id(lower_bc);
303 if (face->center()[1] == y_max)
304 face->set_boundary_id(upper_bc);
305 if (face->center()[2] == -z_max)
306 face->set_boundary_id(front_bc);
307 if (face->center()[2] == z_max)
308 face->set_boundary_id(back_bc);
309 }
310 }
311 }
312 this->attach_boundary_condition(left_bc, "no_slip", "navier_stokes_u");
313 this->attach_boundary_condition(right_bc, "no_slip", "navier_stokes_u");
314 this->attach_boundary_condition(lower_bc, "no_slip", "navier_stokes_u");
315 this->attach_boundary_condition(upper_bc, "symmetry", "navier_stokes_u");
316 if constexpr (dim == 3)
317 {
318 this->attach_boundary_condition(front_bc, "no_slip", "navier_stokes_u");
319 this->attach_boundary_condition(back_bc, "no_slip", "navier_stokes_u");
320 }
321 this->attach_boundary_condition(lower_bc, "fix_pressure_constant", "navier_stokes_p");
322 this->attach_boundary_condition(
323 {lower_bc, std::make_shared<dealii::Functions::ConstantFunction<dim>>(T_0)},
324 "dirichlet",
325 "heat_transfer");
326 }
327 }
328
329
330 template <int dim, typename number, typename CaseClass>
331 void
333 {
334 this->attach_initial_condition(std::make_shared<dealii::Functions::ConstantFunction<dim>>(T_0),
335 "heat_transfer");
336
337 if constexpr (std::is_same_v<CaseClass, Heat::HeatTransferCase<dim, number>>)
338 if (do_two_phase)
339 {
340 if (this->parameters.heat.operator_type != Heat::TwoPhaseOperatorType::cut)
341 {
342 this->attach_initial_condition(std::make_shared<InitialLevelSet<dim, number>>(
343 0.0,
344 LevelSet::LevelSetType::smoothed_heaviside,
345 z_max / 5),
346 "prescribed_heaviside");
347 }
348 else
349 {
350 const number offset = 6e-6;
351 this->attach_initial_condition(std::make_shared<InitialLevelSet<dim, number>>(
352 offset,
353 LevelSet::LevelSetType::signed_distance,
354 0.0),
355 "prescribed_signed_distance");
356 if (this->parameters.amr.do_amr and
357 this->parameters.application_specific_parameters.amr_strategy ==
358 Heat::AMRStrategy::generic)
359 this->attach_initial_condition(std::make_shared<InitialLevelSet<dim, number>>(
360 offset,
361 LevelSet::LevelSetType::smoothed_heaviside,
362 z_max / 4),
363 "prescribed_heaviside");
364 }
365 }
366
367 if constexpr (std::is_same_v<CaseClass, MeltPoolCase<dim, number>>)
368 {
369 const number eps = this->parameters.ls.reinit.compute_interface_thickness_parameter_epsilon(
370 dealii::GridTools::minimal_cell_diameter(*this->triangulation) /
371 this->parameters.ls.get_n_subdivisions() / std::sqrt(dim));
372 this->attach_initial_condition(
373 std::make_shared<InitialLevelSet<dim, number>>(0.0, LevelSet::LevelSetType::tanh, eps),
374 "level_set");
375 this->attach_initial_condition(
376 std::shared_ptr<dealii::Function<dim, number>>(
377 std::make_shared<dealii::Functions::ZeroFunction<dim, number>>(dim)),
378 "navier_stokes_u");
379 }
380 }
381} // namespace MeltPoolDG::Simulation::MeltFrontPropagation
Definition melt_front_propagation.templates.hpp:32
const LevelSet::LevelSetType level_set_type
Definition melt_front_propagation.templates.hpp:65
InitialLevelSet(const number z_level, const LevelSet::LevelSetType level_set_type, const number eps)
Definition melt_front_propagation.templates.hpp:34
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition melt_front_propagation.templates.hpp:44
const number z_level
Definition melt_front_propagation.templates.hpp:64
const number eps
Definition melt_front_propagation.templates.hpp:66
void set_boundary_conditions() final
Definition melt_front_propagation.templates.hpp:247
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Definition melt_front_propagation.templates.hpp:80
SimulationMeltFrontPropagation(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition melt_front_propagation.templates.hpp:71
void create_spatial_discretization() override
Definition melt_front_propagation.templates.hpp:102
void set_field_conditions() final
Definition melt_front_propagation.templates.hpp:332
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
Definition melt_front_propagation.cpp:9
Definition dealii_tensor.hpp:10