applications/mp-radiative-transport/cases/radiative_transport.templates.hpp Source File

Developer Documentation: applications/mp-radiative-transport/cases/radiative_transport.templates.hpp Source File
Developer Documentation
radiative_transport.templates.hpp
Go to the documentation of this file.
2//
3
4#include <deal.II/base/exceptions.h>
5#include <deal.II/base/function.h>
6#include <deal.II/base/function_signed_distance.h>
7#include <deal.II/base/utilities.h>
8
9#include <deal.II/distributed/shared_tria.h>
10#include <deal.II/distributed/tria.h>
11
12#include <deal.II/grid/grid_generator.h>
13#include <deal.II/grid/grid_tools_geometry.h>
14#include <deal.II/grid/tria.h>
15
20
21#include <algorithm>
22#include <cmath>
23
24#include "../../mp-heat-transfer/heat_transfer_case.hpp"
25#include "../radiative_transport_case.hpp"
26
27
29{
30 template <int dim, typename number>
31 class LevelSetHeaviside : public dealii::Function<dim, number>
32 {
33 public:
34 LevelSetHeaviside(const InterfaceCase interface_case_in,
35 const std::pair<number, number> &interface_case_info_in,
36 const number epsilon_cell_in)
37 : dealii::Function<dim, number>(1)
38 , eps(epsilon_cell_in)
39 , interface_case(interface_case_in)
40 , interface_case_info(interface_case_info_in)
41 {}
42
43 number
44 value(const dealii::Point<dim, number> &p, const unsigned int) const override
45 {
46 if (interface_case == InterfaceCase::straight)
47 {
48 const auto y = p[dim - 1];
49 const auto current_time = this->get_time();
51 level +
53 (current_time < interface_case_info.second ? current_time :
54 interface_case_info.second) /
55 interface_case_info.second -
56 y,
57 eps); // 0 side of H() stands for gas, 1 side of H() stands for liquid
58 }
59 else if (interface_case == InterfaceCase::single_powder_particle)
60 {
61 // say we inherit from a straight interface case
62 const auto y = p[dim - 1];
63
64 number straight_value = CharacteristicFunctions::smoothed_heaviside(
65 level - y,
66 eps); // 0 side of H() stands for gas, 1 side of H() stands for liquid
67
68 dealii::Point<dim, number> sphere_center;
69 sphere_center[dim - 1] = interface_case_info.first;
70
71 // now add a powder particle with gradient:
72 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere(
73 sphere_center, interface_case_info.second);
74 number powder_particle_value =
75 CharacteristicFunctions::smoothed_heaviside(-distance_sphere.value(p), eps);
76 return std::max(straight_value, powder_particle_value);
77 }
78 else
79 {
80 AssertThrow(false, dealii::ExcNotImplemented());
81 return 0.0;
82 }
83 return 0.0;
84 }
85
86 private:
87 const number eps = 0.1;
88 const number level = 0.0;
89 InterfaceCase interface_case = InterfaceCase::straight;
90 std::pair<number, number> interface_case_info = std::pair<number, number>(0., 0.);
91 };
92
93
94 template <int dim, typename number, typename Problem>
96 const MPI_Comm mpi_communicator)
97 : Problem(parameter_file, mpi_communicator)
98 , cell_repetitions(dim, 1)
99 {}
100
101
102 template <int dim, typename number, typename Problem>
103 bool
105 dealii::ParameterHandler &prm)
106 {
107 prm.add_parameter("domain x min", domain_x_min, "minimum x coordinate of simulation domain");
108 prm.add_parameter("domain y min", domain_y_min, "minimum y coordinate of simulation domain");
109 prm.add_parameter("domain x max", domain_x_max, "maximum x coordinate of simulation domain");
110 prm.add_parameter("domain y max", domain_y_max, "maximum y coordinate of simulation domain");
111 prm.add_parameter("cell repetitions",
112 cell_repetitions,
113 "cell repetitions per dim applied before global refinement or amr");
114
115 prm.add_parameter("power",
116 power_in,
117 "Sets the intensity scale of the laser source. Is a scalar value");
118 prm.add_parameter("source center", center_in, "location of the heat source center");
119 prm.add_parameter("source radius", radius_in, "heat source radius");
120
121 prm.add_parameter(
122 "interface case",
123 interface_case,
124 "kind of interface for this simulation. "
125 "straight: straigt interface that moves upwards; "
126 "single_powder_particle: a single hanging powder particle above a static straight interface; "
127 "powder bed: ");
128
129 prm.add_parameter("straight interface upward speed", speed, "straight interface upward speed");
130 prm.add_parameter("straight interface movement end time",
131 end_time,
132 "end time of the straight interface movement");
133
134 prm.add_parameter("powder particle radius",
135 powder_particle_radius,
136 "hanging powder particle radius");
137 prm.add_parameter("powder particle offset",
138 powder_particle_offset,
139 "hanging powder particle offset from [dim-1] = 0 plane");
140
141 return this->parameters.base.do_print_parameters;
142 }
143
144
145 template <int dim, typename number, typename Problem>
146 void
148 {
149 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP || dim == 1)
150 {
151#ifdef DEAL_II_WITH_METIS
152 this->triangulation = std::make_shared<dealii::parallel::shared::Triangulation<dim>>(
153 this->mpi_communicator,
154 dealii::Triangulation<dim>::MeshSmoothing::none,
155 true,
156 dealii::parallel::shared::Triangulation<dim>::Settings::partition_metis);
157#else
158 AssertThrow(
159 false,
160 dealii::ExcMessage(
161 "Missing Metis support of the deal.II installation. "
162 "Configure deal.II with -D DEAL_II_WITH_METIS='ON' to execute this example."));
163#endif
164 }
165 else
166 {
167 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
168 this->mpi_communicator);
169 }
170
171 const dealii::Point<dim, number> bottom_left =
172 dim == 1 ? dealii::Point<dim, number>(domain_y_min) :
173 dim == 2 ? dealii::Point<dim, number>(domain_x_min, domain_y_min) :
174 dealii::Point<dim, number>(domain_x_min, domain_x_min, domain_y_min);
175 const dealii::Point<dim, number> top_right =
176 dim == 1 ? dealii::Point<dim, number>(domain_y_max) :
177 dim == 2 ? dealii::Point<dim, number>(domain_x_max, domain_y_max) :
178 dealii::Point<dim, number>(domain_x_max, domain_x_max, domain_y_max);
179 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
180 {
181 std::vector<unsigned int> subdivisions(
182 dim, 5 * dealii::Utilities::pow(2, this->parameters.base.global_refinements));
183 subdivisions[dim - 1] *= 2;
184 for (int d = 0; d < dim; d++)
185 subdivisions[d] *= cell_repetitions[d];
186
187 dealii::GridGenerator::subdivided_hyper_rectangle_with_simplices(
188 *this->triangulation, subdivisions, bottom_left, top_right, true /*colorize*/);
189 }
190 else
191 {
192 dealii::GridGenerator::subdivided_hyper_rectangle(
193 *this->triangulation, cell_repetitions, bottom_left, top_right, true /*colorize*/);
194 }
195 }
196
197
198 template <int dim, typename number, typename Problem>
199 void
201 {
202 // face numbering according to the deal.II colorize flag
203 [[maybe_unused]] const auto [lower_bc, upper_bc, left_bc, right_bc, front_bc, back_bc] =
204 get_colorized_rectangle_boundary_ids<dim>();
205
206 if (auto temp_ptr =
208 this->attach_boundary_condition(
209 {upper_bc,
210 std::make_shared<Heat::GaussProjectionIntensityProfile<dim, number>>(
211 power_in, radius_in, center_in, -dealii::Point<dim, number>::unit_vector(dim - 1))},
212 "dirichlet",
213 "intensity");
214 else
215 this->parameters.laser.rte_boundary_id = upper_bc;
216
217 if (this->parameters.base.fe.type != FiniteElementType::FE_SimplexP)
218 this->triangulation->refine_global(this->parameters.base.global_refinements);
219 }
220
221
222 template <int dim, typename number, typename Problem>
223 void
225 {
226 // pass simulation-specific parameters to the simulation class.
227 // Done after json parsing, is relevant for heaviside
228 if (interface_case == InterfaceCase::straight)
229 interface_case_info = std::pair<number, number>(speed, end_time);
230 else if (interface_case == InterfaceCase::single_powder_particle)
231 interface_case_info =
232 std::pair<number, number>(powder_particle_offset, powder_particle_radius);
233
234 // determine the interface epsilon parameter from minimum mesh size
235 number thickness_scale_factor = 2.5;
236 const number epsilon_cell = dealii::GridTools::minimal_cell_diameter(*this->triangulation) /
237 std::sqrt(dim) * thickness_scale_factor;
238
239 // attach the prescribed heaviside function field
240 this->attach_initial_condition(std::make_shared<LevelSetHeaviside<dim, number>>(
241 interface_case, interface_case_info, epsilon_cell),
242 "prescribed_heaviside");
243
244 if (auto temp_ptr =
246 this->attach_initial_condition(std::make_shared<dealii::Functions::ZeroFunction<dim>>(),
247 "intensity");
248
249 // this is only used to TODO generate the comparison solution with the gaussian laser
250 if (auto temp_ptr = dynamic_cast<Heat::HeatTransferCase<dim, number> *>(this))
251 // attach dummy initial conditions for the heat transfer operation
252 this->attach_initial_condition(std::make_shared<dealii::Functions::ZeroFunction<dim>>(),
253 "heat_transfer");
254 }
255} // namespace MeltPoolDG::Simulation::RadiativeTransport
Definition heat_transfer_case.hpp:101
Definition radiative_transport_case.hpp:62
Definition radiative_transport.templates.hpp:32
LevelSetHeaviside(const InterfaceCase interface_case_in, const std::pair< number, number > &interface_case_info_in, const number epsilon_cell_in)
Definition radiative_transport.templates.hpp:34
const number eps
Definition radiative_transport.templates.hpp:87
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition radiative_transport.templates.hpp:44
std::pair< number, number > interface_case_info
Definition radiative_transport.templates.hpp:90
InterfaceCase interface_case
Definition radiative_transport.templates.hpp:89
const number level
Definition radiative_transport.templates.hpp:88
SimulationRadTrans(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition radiative_transport.templates.hpp:95
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Definition radiative_transport.templates.hpp:104
void set_boundary_conditions() final
Definition radiative_transport.templates.hpp:200
void create_spatial_discretization() override
Definition radiative_transport.templates.hpp:147
void set_field_conditions() final
Definition radiative_transport.templates.hpp:224
number smoothed_heaviside(const number &distance, const number &eps)
Definition characteristic_functions.hpp:19
Definition radiative_transport.cpp:7
Definition dealii_tensor.hpp:10