applications/mp-melt-pool/cases/single_track_melt/single_track_melt.templates.hpp Source File

Developer Documentation: applications/mp-melt-pool/cases/single_track_melt/single_track_melt.templates.hpp Source File
Developer Documentation
single_track_melt.templates.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/function.h>
4#include <deal.II/base/parameter_handler.h>
5#include <deal.II/base/point.h>
6
7#include <deal.II/distributed/tria.h>
8
9#include <deal.II/grid/grid_generator.h>
10#include <deal.II/grid/grid_in.h>
11
12#include <memory>
13#include <string>
14
15#include "../../../mp-heat-transfer/heat_transfer_case.hpp"
16#include "../../melt_pool_case.hpp"
17#include "single_track_melt.hpp"
18
20{
21 template <int dim>
22 GasInletVelocity<dim>::GasInletVelocity(const double inlet_velocity)
23 : Function<dim>(dim)
24 , inlet_velocity(inlet_velocity)
25 {}
26
27
28
29 template <int dim>
30 double
31 GasInletVelocity<dim>::value(const Point<dim> & /*p*/, const unsigned int component) const
32 {
33 AssertThrow(dim == 3, ExcMessage("GasInletVelocity is defined for dim = 3."));
34
35 return component == 2 ? inlet_velocity : 0.0;
36 }
37
38
39
40 template <int dim>
42 : Function<dim>()
43 , y_interface(y_interface)
44 {}
45
46
47
48 template <int dim>
49 double
50 InitialSignedDistance<dim>::value(const Point<dim> &p, const unsigned int /*component*/) const
51 {
52 return -p[1] + y_interface;
53 }
54
55
56
57 template <int dim, typename Number, typename CaseClass>
59 std::string parameter_file,
60 const MPI_Comm mpi_communicator)
61 : CaseClass(parameter_file, mpi_communicator)
62 {}
63
64
65
66 template <int dim, typename Number, typename CaseClass>
67 bool
69 ParameterHandler &prm)
70 {
71 prm.enter_subsection("mesh");
72 {
73 prm.add_parameter("gmsh file name", mesh_file_name, "Path to the gmsh .msh file.");
74 prm.add_parameter("additional refinement 1",
75 n_additional_refinement_1,
76 "Additional refinement of box 1.");
77 prm.add_parameter("additional refinement 2",
78 n_additional_refinement_2,
79 "Additional refinement of box 1.");
80 prm.add_parameter("local refinement 1 bottom left",
81 local_refinement_1_bottom_left,
82 "Bottom left point of locally refined region.");
83 prm.add_parameter("local refinement 1 top right",
84 local_refinement_1_top_right,
85 "Bottom left point of locally refined region.");
86 prm.add_parameter("local refinement 2 bottom left",
87 local_refinement_2_bottom_left,
88 "Bottom left point of locally refined region.");
89 prm.add_parameter("local refinement 2 top right",
90 local_refinement_2_top_right,
91 "Bottom left point of locally refined region.");
92 }
93 prm.leave_subsection();
94
95 prm.enter_subsection("initial conditions");
96 {
97 prm.add_parameter("temperature", T_initial, "Initial temperature.");
98
99 prm.add_parameter("interface y", y_interface, "Initial y-position of the interface.");
100 }
101 prm.leave_subsection();
102
103 prm.enter_subsection("bc");
104 {
105 prm.add_parameter("inlet velocity", inlet_velocity, "Gas inlet velocity in z-direction.");
106
107 prm.add_parameter("inlet temperature",
108 inlet_temperature,
109 "Temperature at gas inlet and outlet.");
110
111 prm.add_parameter("outlet pressure", outlet_pressure, "Outlet pressure.");
112 }
113 prm.leave_subsection();
114
115 return this->parameters.base.do_print_parameters;
116 }
117
118
119
120 template <int dim, typename Number, typename CaseClass>
121 void
123 {
124 AssertThrow(dim == 3, ExcMessage("SimulationSingleTrackMelt expects a 3D gmsh mesh."));
125
126 this->triangulation =
127 std::make_shared<parallel::distributed::Triangulation<dim>>(this->mpi_communicator);
128
129 // ---------------------------------------------------------------------------
130 // Use gmsh mesh if provided
131 // ---------------------------------------------------------------------------
132 if (!mesh_file_name.empty())
133 {
134 std::ifstream input_file(mesh_file_name);
135
136 if (input_file)
137 {
138 GridIn<dim> grid_in;
139 grid_in.attach_triangulation(*this->triangulation);
140
141 grid_in.read_msh(input_file);
142
143 return;
144 }
145 }
146
147 // ---------------------------------------------------------------------------
148 // Otherwise create a simple hyper-rectangle domain
149 // Dimensions taken from the reference geometry (in mm)
150 // then converted to meters.
151 // ---------------------------------------------------------------------------
152
153 constexpr double mm_to_m = 1e-3;
154
155 const Point<dim> p1(-0.5 * mm_to_m, // x_min
156 -1.4 * mm_to_m, // y_min
157 -1.5 * mm_to_m); // z_min
158
159 const Point<dim> p2(0.5 * mm_to_m, // x_max
160 0.6 * mm_to_m, // y_max
161 1.5 * mm_to_m); // z_max
162
163 GridGenerator::hyper_rectangle(*this->triangulation, p1, p2);
164 }
165
166
167
168 template <int dim, typename Number, typename CaseClass>
169 void
171 {
172 /*
173 * Boundary ids from gmsh physical groups / Lethe prm:
174 *
175 * 2,3,4,5,6 : solid walls, no-slip
176 * 7,8,9 : gas slip boundaries
177 * 10 : gas outlet
178 * 11 : gas inlet
179 */
180
181 const std::vector<types::boundary_id> wall_bcs = {2, 3, 4, 5, 6};
182 const std::vector<types::boundary_id> gas_slip_bcs = {7, 8, 9};
183
184 const types::boundary_id gas_outlet_bc = 10;
185 const types::boundary_id gas_inlet_bc = 11;
186
187 if constexpr (std::is_same_v<CaseClass, MeltPoolCase<dim, Number>>)
188 {
189 if (inlet_velocity > 0)
190 this->attach_boundary_condition(
191 {gas_inlet_bc, std::make_shared<Functions::ConstantFunction<dim>>(inlet_temperature)},
192 "dirichlet",
193 "heat_transfer");
194
195 for (const auto id : wall_bcs)
196 this->attach_boundary_condition(id, "no_slip", "navier_stokes_u");
197
198 for (const auto id : gas_slip_bcs)
199 this->attach_boundary_condition(id, "symmetry", "navier_stokes_u");
200
201 this->attach_boundary_condition(
202 {gas_outlet_bc, std::make_shared<Functions::ConstantFunction<dim>>(outlet_pressure)},
203 "open",
204 "navier_stokes_u");
205
206 this->attach_boundary_condition({gas_inlet_bc,
207 std::make_shared<GasInletVelocity<dim>>(inlet_velocity)},
208 "dirichlet",
209 "navier_stokes_u");
210 }
211
212 this->triangulation->refine_global(this->parameters.base.global_refinements);
213
214 // local refinement
215 // 1. region
216 const auto refinement_region_1 =
217 dealii::BoundingBox<dim>({local_refinement_1_bottom_left, local_refinement_1_top_right});
218
219 for (unsigned int j = 0; j < n_additional_refinement_1; ++j)
220 {
221 for (auto &cell : this->triangulation->active_cell_iterators())
222 {
223 if (cell->is_locally_owned())
224 {
225 for (unsigned int i = 0; i < cell->n_vertices(); ++i)
226 if (refinement_region_1.point_inside(cell->vertex(i)))
227 {
228 cell->set_refine_flag();
229 break;
230 }
231 }
232 }
233 this->triangulation->execute_coarsening_and_refinement();
234 }
235
236 // 2. region
237 const auto refinement_region_2 =
238 dealii::BoundingBox<dim>({local_refinement_2_bottom_left, local_refinement_2_top_right});
239
240 for (unsigned int j = 0; j < n_additional_refinement_2; ++j)
241 {
242 for (auto &cell : this->triangulation->active_cell_iterators())
243 {
244 if (cell->is_locally_owned())
245 {
246 for (unsigned int i = 0; i < cell->n_vertices(); ++i)
247 if (refinement_region_2.point_inside(cell->vertex(i)))
248 {
249 cell->set_refine_flag();
250 break;
251 }
252 }
253 }
254 this->triangulation->execute_coarsening_and_refinement();
255 }
256 }
257
258
259
260 template <int dim, typename Number, typename CaseClass>
261 void
263 {
264 if constexpr (std::is_same_v<CaseClass, MeltPoolCase<dim, Number>>)
265 {
266 this->attach_initial_condition(std::make_shared<Functions::ZeroFunction<dim>>(dim),
267 "navier_stokes_u");
268
269 this->attach_initial_condition(std::make_shared<InitialSignedDistance<dim>>(y_interface),
270 "signed_distance");
271 }
272 if constexpr (std::is_same_v<CaseClass, Heat::HeatTransferCase<dim, Number>>)
273 this->attach_initial_condition(std::make_shared<InitialSignedDistance<dim>>(y_interface),
274 "prescribed_signed_distance");
275
276 this->attach_initial_condition(std::make_shared<Functions::ConstantFunction<dim>>(T_initial),
277 "heat_transfer");
278 }
279} // namespace MeltPoolDG::Simulation::SingleTrackMelt
GasInletVelocity(const double inlet_velocity)
Construct the gas inlet velocity function.
Definition single_track_melt.templates.hpp:22
double value(const Point< dim > &p, const unsigned int component=0) const override
Return the velocity value at a point for a selected component.
Definition single_track_melt.templates.hpp:31
Initial signed-distance function for a flat interface.
Definition single_track_melt.hpp:67
InitialSignedDistance(const double y_interface)
Construct the initial signed-distance function.
Definition single_track_melt.templates.hpp:41
double value(const Point< dim > &p, const unsigned int component=0) const override
Evaluate the initial signed-distance value.
Definition single_track_melt.templates.hpp:50
bool add_case_specific_parameters(ParameterHandler &prm) override
Declare case-specific parameters.
Definition single_track_melt.templates.hpp:68
void create_spatial_discretization() override
Create or import the spatial discretization.
Definition single_track_melt.templates.hpp:122
void set_boundary_conditions() override
Attach boundary conditions and apply global/local mesh refinement.
Definition single_track_melt.templates.hpp:170
SimulationSingleTrackMelt(std::string parameter_file, const MPI_Comm mpi_communicator)
Construct the single-track melt simulation case.
Definition single_track_melt.templates.hpp:58
void set_field_conditions() override
Attach initial conditions for velocity, signed distance, and temperature.
Definition single_track_melt.templates.hpp:262
Definition single_track_melt.cpp:9