3#include <deal.II/base/function.h>
4#include <deal.II/base/function_signed_distance.h>
5#include <deal.II/base/mpi.h>
6#include <deal.II/base/mpi.templates.h>
7#include <deal.II/base/point.h>
8#include <deal.II/base/tensor_function.h>
10#include <deal.II/grid/grid_generator.h>
11#include <deal.II/grid/grid_tools.h>
12#include <deal.II/grid/tria.h>
14#include <deal.II/lac/vector.h>
16#include <deal.II/numerics/vector_tools.h>
21#include <boost/math/tools/roots.hpp>
27#include "../../melt_pool_case.hpp"
73 static constexpr double x_min = 0.0;
74 static constexpr double y_min = 0.0;
75 static constexpr double y_max = 1.e-3;
78 namespace AnalyticalSolution
81 template <
typename number>
85 const auto beta_func = [&](
double beta) ->
double {
86 return beta * std::exp(beta * beta) * erf(beta) -
87 parameters.
material.gas.specific_heat_capacity *
88 (T_wall - parameters.
material.boiling_temperature) /
89 (parameters.
material.latent_heat_of_evaporation * std::sqrt(dealii::numbers::PI));
92 std::pair<double, double> result =
93 boost::math::tools::bisect(beta_func, 1e-6, 100., [&](
double min,
double max) ->
bool {
94 return std::abs(max - min) <= 1e-10;
97 return (result.first + result.second) / 2;
100 template <
typename number>
105 const double beta = -1.0)
112 parameters.
material.gas.thermal_conductivity /
113 (parameters.
material.gas.density * parameters.
material.gas.specific_heat_capacity) *
117 template <
typename number>
123 const double beta = -1.0)
128 const double diffusivity =
129 parameters.
material.gas.thermal_conductivity /
130 (parameters.
material.gas.density * parameters.
material.gas.specific_heat_capacity);
133 return parameters.
material.boiling_temperature;
135 return std::max(T_wall + (parameters.
material.boiling_temperature - T_wall) *
136 erf(x / (2. * std::sqrt(diffusivity * time))) / erf(beta),
137 parameters.
material.boiling_temperature);
154 value(
const dealii::Point<dim> &p,
const unsigned int )
const final
165 template <
int dim,
typename number>
177 "The location of the initial interface must be between y_min and y_max."));
181 "_level_set_contour_over_time.txt";
187 prm.add_parameter(
"y interface",
y_interface,
"initial interface location");
188 prm.add_parameter(
"T wall",
T_wall,
"heated temperature of the wall");
190 return this->
parameters.base.do_print_parameters;
196 if (this->
parameters.base.fe.type == FiniteElementType::FE_SimplexP || dim == 1)
198#ifdef DEAL_II_WITH_METIS
199 this->
triangulation = std::make_shared<dealii::parallel::shared::Triangulation<dim>>(
201 dealii::Triangulation<dim>::none,
203 dealii::parallel::shared::Triangulation<dim>::Settings::partition_metis);
208 "Missing Metis support of the deal.II installation. "
209 "Configure deal.II with -D DEAL_II_WITH_METIS='ON' to execute this example."));
214 this->
triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
218 const unsigned int n_elements_per_edge =
219 dim > 1 ? std::pow(dim, this->
parameters.base.global_refinements) :
222 std::vector<unsigned int> refinements(dim, 1);
223 refinements[dim - 1] = n_elements_per_edge;
226 const dealii::Point<dim> bottom_left = dim == 1 ? dealii::Point<dim>(
y_min) :
229 const dealii::Point<dim> top_right = dim == 1 ? dealii::Point<dim>(
y_max) :
233 if (this->
parameters.base.fe.type == FiniteElementType::FE_SimplexP)
236 std::vector<unsigned int> subdivisions(
237 dim, 5 * dealii::Utilities::pow(2, this->
parameters.base.global_refinements));
238 subdivisions[dim - 1] *= 2;
240 dealii::GridGenerator::subdivided_hyper_rectangle_with_simplices(
241 *this->
triangulation, subdivisions, bottom_left, top_right,
true );
245 dealii::GridGenerator::subdivided_hyper_rectangle(
246 *this->
triangulation, refinements, bottom_left, top_right,
true );
253 const unsigned int n_elements = std::min<double>(200, n_elements_per_edge);
254 for (
unsigned int i = 0; i <= n_elements; ++i)
256 auto p = dealii::Point<dim>();
267 const dealii::types::boundary_id bottom_bc = 2 * (dim - 1);
268 const dealii::types::boundary_id top_bc = bottom_bc + 1;
272 {bottom_bc, std::make_shared<dealii::Functions::ConstantFunction<dim>>(-1.0)},
276 {bottom_bc, std::make_shared<dealii::Functions::ConstantFunction<dim>>(
T_wall)},
280 std::make_shared<dealii::Functions::ConstantFunction<dim>>(
281 this->
parameters.material.boiling_temperature)},
290 std::vector<dealii::types::boundary_id> side_walls;
293 for (
unsigned int i = 0; i < 2 * (dim - 1); ++i)
294 side_walls.push_back(i);
309 std::make_shared<dealii::Functions::SignedDistance::Plane<dim>>(
310 dealii::Point<dim>::unit_vector(dim - 1) *
y_interface,
311 dealii::Point<dim>::unit_vector(dim - 1)),
315 this->
parameters.material.boiling_temperature,
332 <<
"time interface_location interface_temperature analytical_interface_location(beta=" +
333 std::to_string(
beta) +
")"
339 if (((this->
parameters.output.paraview.enable) &&
340 !(
n_time_step % this->parameters.output.write_frequency)) ||
341 generic_data_out.get_time() == this->parameters.time_stepping.end_time)
343 generic_data_out.get_vector(
"level_set").update_ghost_values();
344 generic_data_out.get_vector(
"temperature").update_ghost_values();
353 generic_data_out.get_mapping());
357 const auto temperature_evaluation_values =
359 generic_data_out.get_dof_handler(
"temperature"),
360 generic_data_out.get_vector(
"temperature"));
365 const auto file_name = this->
parameters.output.directory +
"/" +
367 "_temperature_profile_" +
368 std::to_string(generic_data_out.get_time()) +
".txt";
371 <<
"coordinate temperature analytical_temperature(beta=" + std::to_string(
beta) +
375 for (
unsigned int i = 0; i < temperature_evaluation_values.size(); ++i)
378 << temperature_evaluation_values[i] <<
" "
382 generic_data_out.get_time(),
393 dealii::FEPointEvaluation<1, dim> temperature_eval(
394 generic_data_out.get_mapping(),
395 generic_data_out.get_dof_handler(
"temperature").get_fe(),
396 dealii::update_values);
398 std::vector<std::pair<dealii::Point<dim>,
double>> vertices_and_temperatures;
400 std::vector<double> buffer;
401 std::vector<dealii::types::global_dof_index> local_dof_indices;
403 LevelSet::Tools::evaluate_at_interface<dim, double>(
404 generic_data_out.get_dof_handler(
"level_set"),
405 generic_data_out.get_mapping(),
406 generic_data_out.get_vector(
"level_set"),
407 [&](
const auto &cell,
408 const auto &points_real,
410 [[maybe_unused]]
const auto &weights) {
411 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
412 buffer.resize(cell->get_fe().n_dofs_per_cell());
413 cell->get_dof_indices(local_dof_indices);
415 const unsigned int n_points = points.size();
417 const dealii::ArrayView<const dealii::Point<dim>> unit_points(points.data(),
419 temperature_eval.reinit(cell, unit_points);
421 cell->get_dof_values(generic_data_out.get_vector(
"temperature"),
426 temperature_eval.evaluate(buffer, dealii::EvaluationFlags::values);
427 for (unsigned int q = 0; q < n_points; ++q)
429 vertices_and_temperatures.emplace_back(points_real[q],
430 temperature_eval.get_value(q));
437 const auto vertices_and_temperatures_all =
438 dealii::Utilities::MPI::reduce<std::vector<std::pair<dealii::Point<dim>,
double>>>(
439 vertices_and_temperatures, this->
mpi_communicator, [](
const auto &a,
const auto &b) {
441 result.insert(result.end(), b.begin(), b.end());
449 if (dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0)
453 << generic_data_out.get_time() <<
" "
454 << vertices_and_temperatures_all[0].first[dim - 1] -
y_interface <<
" "
455 << vertices_and_temperatures_all[0].second <<
" " << interface_analytical
460 dealii::ConditionalOStream pcout(
461 std::cout, dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0);
462 pcout <<
"interface_numerical " << vertices_and_temperatures_all[0].first[dim - 1]
463 <<
" interface_analytical " << interface_analytical <<
" absolute error: "
464 << std::abs(interface_analytical - vertices_and_temperatures_all[0].first[dim - 1])
466 generic_data_out.get_vector(
"level_set").zero_out_ghost_values();
467 generic_data_out.get_vector(
"temperature").zero_out_ghost_values();
475 double y_interface = 5.e-5;
476 double T_wall = 383.15;
483 mutable int n_time_step = 0.0;
484 mutable double beta = -1.0;
486 mutable bool remote_point_is_initialized =
false;
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_periodic_boundary_condition(const dealii::types::boundary_id id_in, const dealii::types::boundary_id id_out, const int direction)
Definition simulation_case_base.hpp:384
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
Definition stefans_problem1_with_flow_and_heat.hpp:143
double value(const dealii::Point< dim > &p, const unsigned int) const final
Definition stefans_problem1_with_flow_and_heat.hpp:154
const double T_sat
Definition stefans_problem1_with_flow_and_heat.hpp:159
const double T_wall
Definition stefans_problem1_with_flow_and_heat.hpp:159
const double y_interface
Definition stefans_problem1_with_flow_and_heat.hpp:159
InitialValuesTemperature(const double T_sat, const double T_wall, const double y_interface)
Definition stefans_problem1_with_flow_and_heat.hpp:145
Definition stefans_problem1_with_flow_and_heat.hpp:167
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition stefans_problem1_with_flow_and_heat.hpp:194
SimulationStefansProblem1WithFlowAndHeat(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition stefans_problem1_with_flow_and_heat.hpp:169
void do_postprocessing(const GenericDataOut< dim, double > &generic_data_out) const final
Definition stefans_problem1_with_flow_and_heat.hpp:322
std::string file_name_level_set_contour
Definition stefans_problem1_with_flow_and_heat.hpp:481
std::vector< dealii::Point< dim > > vertices_along_vertical_axis
Definition stefans_problem1_with_flow_and_heat.hpp:479
double y_interface
Definition stefans_problem1_with_flow_and_heat.hpp:475
dealii::Utilities::MPI::RemotePointEvaluation< dim, dim > remote_point_evaluation
Definition stefans_problem1_with_flow_and_heat.hpp:485
void set_boundary_conditions() final
Pure virtual function to set the boundary conditions.
Definition stefans_problem1_with_flow_and_heat.hpp:264
std::ofstream file_level_set_contour
Definition stefans_problem1_with_flow_and_heat.hpp:480
double beta
Definition stefans_problem1_with_flow_and_heat.hpp:484
std::ofstream file_temperature_profile
Definition stefans_problem1_with_flow_and_heat.hpp:482
const double x_max
Definition stefans_problem1_with_flow_and_heat.hpp:474
bool remote_point_is_initialized
Definition stefans_problem1_with_flow_and_heat.hpp:486
double T_wall
Definition stefans_problem1_with_flow_and_heat.hpp:476
void set_field_conditions() final
Pure virtual function to set the field conditions.
Definition stefans_problem1_with_flow_and_heat.hpp:304
int n_time_step
Definition stefans_problem1_with_flow_and_heat.hpp:483
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Add simulation-specific parameters (can be overridden).
Definition stefans_problem1_with_flow_and_heat.hpp:185
double compute_beta(const MeltPoolCaseParameters< number > ¶meters, const double T_wall)
Definition stefans_problem1_with_flow_and_heat.hpp:83
double analytical_temperature(const MeltPoolCaseParameters< number > ¶meters, const double T_wall, const double time, const double x, const double beta=-1.0)
Definition stefans_problem1_with_flow_and_heat.hpp:119
double analytical_interface_location(const MeltPoolCaseParameters< number > ¶meters, const double T_wall, const double time, const double beta=-1.0)
Definition stefans_problem1_with_flow_and_heat.hpp:102
Definition stefans_problem1_with_flow_and_heat.cpp:6
static constexpr double y_min
Definition stefans_problem1_with_flow_and_heat.hpp:74
static constexpr double x_min
Definition stefans_problem1_with_flow_and_heat.hpp:73
static constexpr double y_max
Definition stefans_problem1_with_flow_and_heat.hpp:75
Definition advection_diffusion.cpp:6
Definition dealii_tensor.hpp:10
Definition melt_pool_case.hpp:52
MaterialData< number > material
Definition melt_pool_case.hpp:235