applications/mp-melt-pool/cases/stefans_problem/stefans_problem_with_flow.hpp Source File

Developer Documentation: applications/mp-melt-pool/cases/stefans_problem/stefans_problem_with_flow.hpp Source File
Developer Documentation
stefans_problem_with_flow.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/conditional_ostream.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/mpi_remote_point_evaluation.h>
8#include <deal.II/base/point.h>
9#include <deal.II/base/types.h>
10#include <deal.II/base/utilities.h>
11
12#include <deal.II/distributed/shared_tria.h>
13#include <deal.II/distributed/tria.h>
14
15#include <deal.II/grid/grid_generator.h>
16#include <deal.II/grid/tria.h>
17
18#include <deal.II/numerics/vector_tools.h>
19#include <deal.II/numerics/vector_tools_evaluate.h>
20
24
25#include <cmath>
26#include <iostream>
27#include <memory>
28#include <string>
29#include <vector>
30
31#include "../../melt_pool_case.hpp"
32
44{
45 using namespace MeltPoolDG::Simulation;
46
47 /*
48 * This class collects all relevant input data for the level set simulation
49 */
50
51 template <int dim, typename number>
53 {
54 public:
58
59 void
61 {
62 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP || dim == 1)
63 {
64#ifdef DEAL_II_WITH_METIS
65 this->triangulation = std::make_shared<dealii::parallel::shared::Triangulation<dim>>(
66 this->mpi_communicator,
67 dealii::Triangulation<dim>::none,
68 false,
69 dealii::parallel::shared::Triangulation<dim>::Settings::partition_metis);
70#else
71 AssertThrow(
72 false,
73 dealii::ExcMessage(
74 "Missing Metis support of the deal.II installation. "
75 "Configure deal.II with -D DEAL_II_WITH_METIS='ON' to execute this example."));
76#endif
77 }
78 else
79 {
80 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
81 this->mpi_communicator);
82 }
83
84 // create mesh
85 const dealii::Point<dim> bottom_left = dim == 1 ? dealii::Point<dim>(y_min) :
86 dim == 2 ? dealii::Point<dim>(x_min, y_min) :
87 dealii::Point<dim>(x_min, x_min, y_min);
88 const dealii::Point<dim> top_right = dim == 1 ? dealii::Point<dim>(y_max) :
89 dim == 2 ? dealii::Point<dim>(x_max, y_max) :
90 dealii::Point<dim>(x_max, x_max, y_max);
91
92 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
93 {
94 std::vector<unsigned int> subdivisions(
95 dim, 5 * dealii::Utilities::pow(2, this->parameters.base.global_refinements));
96 subdivisions[dim - 1] *= 2;
97
98 dealii::GridGenerator::subdivided_hyper_rectangle_with_simplices(
99 *this->triangulation, subdivisions, bottom_left, top_right, true /*colorize*/);
100 }
101 else
102 {
103 dealii::GridGenerator::hyper_rectangle(*this->triangulation,
104 bottom_left,
105 top_right,
106 true /*colorize*/);
107 this->triangulation->refine_global(this->parameters.base.global_refinements);
108 }
109
110 // get vertices along the vertical axis on rank 0
111 if (dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0)
112 {
113 for (unsigned int i = 0; i <= 100.; ++i)
114 {
115 auto p = dealii::Point<dim>();
116 p[dim - 1] = y_min + (y_max - y_min) / 100. * i;
117 vertices_along_vertical_axis.emplace_back(p);
118 }
119 }
120 }
121
122 void
124 {
125 // faces in dim-1 direction
126 const dealii::types::boundary_id lower_bc = 2 * (dim - 1);
127 const dealii::types::boundary_id upper_bc = 2 * (dim - 1) + 1;
128
129 this->attach_boundary_condition(lower_bc, "no_slip", "navier_stokes_u");
130 this->attach_boundary_condition(upper_bc, "open", "navier_stokes_u");
131
132 // collect boundary ids of side walls
133 std::vector<dealii::types::boundary_id> side_walls;
134
135 for (unsigned int i = 0; i < 2 * (dim - 1); ++i)
136 side_walls.push_back(i);
137
138 for (const auto &s : side_walls)
139 this->attach_boundary_condition(s, "symmetry", "navier_stokes_u");
140 }
141
142 void
144 {
146 std::make_shared<dealii::Functions::SignedDistance::Plane<dim>>(
147 dealii::Point<dim>::unit_vector(dim - 1) * y_interface,
148 -dealii::Point<dim>::unit_vector(dim - 1)),
149 "signed_distance");
150 this->attach_initial_condition(std::make_shared<dealii::Functions::ZeroFunction<dim>>(dim),
151 "navier_stokes_u");
152 }
153
154 void
155 do_postprocessing(const GenericDataOut<dim, double> &generic_data_out) const final
156 {
157 dealii::ConditionalOStream pcout(std::cout,
158 dealii::Utilities::MPI::this_mpi_process(
159 this->mpi_communicator) == 0 and
160 this->parameters.base.verbosity_level >= 1);
161 if (not(n_time_step % this->parameters.output.write_frequency) or
162 generic_data_out.get_time() == this->parameters.time_stepping.end_time)
163 {
164 std::cout.precision(3);
165 generic_data_out.get_vector("velocity").update_ghost_values();
166 generic_data_out.get_vector("heaviside").update_ghost_values();
167 generic_data_out.get_vector("pressure").update_ghost_values();
168
169 /*
170 * evaluate pressure profile
171 */
173 {
175 *this->triangulation,
176 generic_data_out.get_mapping());
177 if (this->parameters.amr.do_amr == false)
178 remote_point_is_initialized = true;
179 }
180
181 const auto pressure_evaluation_values =
182 dealii::VectorTools::point_values<1>(remote_point_evaluation,
183 generic_data_out.get_dof_handler("pressure"),
184 generic_data_out.get_vector("pressure"));
185
186 const auto ls_evaluation_values =
187 dealii::VectorTools::point_values<1>(remote_point_evaluation,
188 generic_data_out.get_dof_handler("heaviside"),
189 generic_data_out.get_vector("heaviside"));
190
191 const auto vel_evaluation_values =
192 dealii::VectorTools::point_values<dim>(remote_point_evaluation,
193 generic_data_out.get_dof_handler("velocity"),
194 generic_data_out.get_vector("velocity"));
195
197 this->parameters.evapor.analytical.function);
198
199 const auto analytical_velocity = [&](const double &ls) -> double {
200 return m_dot.local_compute_evaporative_mass_flux(generic_data_out.get_time()) *
201 (1. - ls) *
202 (1. / this->parameters.material.gas.density -
203 1. / this->parameters.material.liquid.density);
204 };
205
206 const auto analytical_pressure = [&](const double &ls) -> double {
207 return std::pow(m_dot.local_compute_evaporative_mass_flux(generic_data_out.get_time()),
208 2) *
209 ls *
210 (1. / this->parameters.material.gas.density -
211 1. / this->parameters.material.liquid.density);
212 };
213
214 // write values to file
215 if (dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0)
216 {
217 if (this->parameters.output.do_user_defined_postprocessing)
218 {
219 const auto file_name = this->parameters.output.directory + "/" +
220 this->parameters.output.paraview.filename +
221 "_pressure_profile_" +
222 std::to_string(generic_data_out.get_time()) + ".txt";
223 file_pressure_profile.open(file_name);
225 << "% coordinate | velocity | analytical velocity | pressure value | analytical pressure value "
226 << std::endl;
227
228 for (unsigned int i = 0; i < pressure_evaluation_values.size(); ++i)
229 {
231
232 if constexpr (dim > 1)
233 file_pressure_profile << vel_evaluation_values[i][dim - 1] << " ";
234 else
235 file_pressure_profile << vel_evaluation_values[i] << " ";
236 file_pressure_profile << analytical_velocity(ls_evaluation_values[i]) << " "
237 << pressure_evaluation_values[i] << " "
238 << analytical_pressure(ls_evaluation_values[i])
239 << std::endl;
240 }
241 file_pressure_profile.close();
242 }
243
244 // console output
245 if constexpr (dim > 1)
246 {
247 pcout << "POSTPROCESSOR: min velocity: " << vel_evaluation_values[0][dim - 1]
248 << " (analytical: " << analytical_velocity(ls_evaluation_values[0]) << ")"
249 << std::endl;
250 pcout << "POSTPROCESSOR: max velocity: "
251 << vel_evaluation_values[vel_evaluation_values.size() - 1][dim - 1]
252 << " (analytical: "
253 << analytical_velocity(
254 ls_evaluation_values[vel_evaluation_values.size() - 1])
255 << ")" << std::endl;
256 }
257 else
258 {
259 pcout << "POSTPROCESSOR: min velocity: " << vel_evaluation_values[0]
260 << " (analytical: " << analytical_velocity(ls_evaluation_values[0]) << ")"
261 << std::endl;
262 pcout << "POSTPROCESSOR: max velocity: "
263 << vel_evaluation_values[vel_evaluation_values.size() - 1]
264 << " (analytical: "
265 << analytical_velocity(
266 ls_evaluation_values[vel_evaluation_values.size() - 1])
267 << ")" << std::endl;
268 }
269 pcout << "POSTPROCESSOR: max pressure: " << pressure_evaluation_values[0]
270 << " (analytical: " << analytical_pressure(ls_evaluation_values[0]) << ")"
271 << std::endl;
272 pcout << "POSTPROCESSOR: min pressure: "
273 << pressure_evaluation_values[pressure_evaluation_values.size() - 1]
274 << " (analytical: "
275 << analytical_pressure(
276 ls_evaluation_values[pressure_evaluation_values.size() - 1])
277 << ")" << std::endl;
278 }
279
280 generic_data_out.get_vector("level_set").zero_out_ghost_values();
281 generic_data_out.get_vector("velocity").zero_out_ghost_values();
282 generic_data_out.get_vector("pressure").zero_out_ghost_values();
283 }
284 n_time_step += 1;
285 }
286
287
288 private:
289 const double x_min = 0.0;
290 const double x_max = 1.0;
291 const double y_min = 0.0;
292 const double y_max = 1.0;
293 const double y_interface = 0.5;
294
295 // Postprocessor
296 mutable std::ofstream file_velocity_profile;
297 mutable std::ofstream file_pressure_profile;
298 mutable int n_time_step = 0.0;
299 mutable std::vector<dealii::Point<dim>> vertices_along_vertical_axis;
300 mutable bool remote_point_is_initialized = false;
301 mutable dealii::Utilities::MPI::RemotePointEvaluation<dim, dim> remote_point_evaluation;
302 };
303} // namespace MeltPoolDG::Simulation::StefansProblemWithFlow
Definition evaporation_model_constant.hpp:15
A generic utility for managing simulation output data in the MeltPoolDG context.
Definition generic_data_out.hpp:32
Definition melt_pool_case.hpp:290
MeltPoolCaseParameters< number > parameters
Definition melt_pool_case.hpp:292
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
const MPI_Comm mpi_communicator
Definition simulation_case_base.hpp:56
std::ofstream file_velocity_profile
Definition stefans_problem_with_flow.hpp:296
const double x_max
Definition stefans_problem_with_flow.hpp:290
const double y_interface
Definition stefans_problem_with_flow.hpp:293
std::ofstream file_pressure_profile
Definition stefans_problem_with_flow.hpp:297
const double y_max
Definition stefans_problem_with_flow.hpp:292
void set_field_conditions() final
Pure virtual function to set the field conditions.
Definition stefans_problem_with_flow.hpp:143
std::vector< dealii::Point< dim > > vertices_along_vertical_axis
Definition stefans_problem_with_flow.hpp:299
bool remote_point_is_initialized
Definition stefans_problem_with_flow.hpp:300
void set_boundary_conditions() final
Pure virtual function to set the boundary conditions.
Definition stefans_problem_with_flow.hpp:123
dealii::Utilities::MPI::RemotePointEvaluation< dim, dim > remote_point_evaluation
Definition stefans_problem_with_flow.hpp:301
const double x_min
Definition stefans_problem_with_flow.hpp:289
const double y_min
Definition stefans_problem_with_flow.hpp:291
SimulationStefansProblemWithFlow(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition stefans_problem_with_flow.hpp:55
void do_postprocessing(const GenericDataOut< dim, double > &generic_data_out) const final
Definition stefans_problem_with_flow.hpp:155
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition stefans_problem_with_flow.hpp:60
Definition stefans_problem_with_flow.cpp:6
Definition advection_diffusion.cpp:6