applications/mp-melt-pool/cases/flow_past_cylinder/flow_past_cylinder.hpp Source File

Developer Documentation: applications/mp-melt-pool/cases/flow_past_cylinder/flow_past_cylinder.hpp Source File
Developer Documentation
flow_past_cylinder.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/function.h>
4#include <deal.II/base/function_signed_distance.h>
5#include <deal.II/base/point.h>
6#include <deal.II/base/tensor_function.h>
7
8#include <deal.II/distributed/tria.h>
9
10#include <deal.II/grid/grid_generator.h>
11#include <deal.II/grid/manifold_lib.h>
12
16
17#include <iostream>
18
19#include "../../melt_pool_case.hpp"
20
22{
23 template <int dim>
24 class InitializePhi : public dealii::Function<dim>
25 {
26 public:
28 : dealii::Function<dim>()
29 , distance_sphere(dim == 1 ? dealii::Point<dim>(0.0) : dealii::Point<dim>(1.3, 0.2), 0.1)
30 {}
31
32 double
33 value(const dealii::Point<dim> &p, const unsigned int /*component*/) const override
34 {
36 }
37
38 private:
39 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere;
40 };
41
42 template <int dim>
43 class InflowVelocity : public dealii::Function<dim>
44 {
45 public:
46 InflowVelocity(const double time, const bool fluctuating)
47 : dealii::Function<dim>(dim, time)
49 {}
50
51 void
52 vector_value(const dealii::Point<dim> &p, dealii::Vector<double> &values) const override
53 {
54 AssertDimension(values.size(), dim);
55
56 // inflow velocity according to Schaefer & Turek
57 const double Um = (dim == 2 ? 1.5 : 2.25);
58 const double H = 0.41;
59 double coefficient = dealii::Utilities::fixed_power<dim - 1>(4.) * Um /
60 dealii::Utilities::fixed_power<2 * dim - 2>(H);
61 values(0) = coefficient * p[1] * (H - p[1]);
62 if (dim == 3)
63 values(0) *= p[2] * (H - p[2]);
64 if (fluctuating)
65 values(0) *= std::sin(this->get_time() * dealii::numbers::PI / 8.);
66 for (unsigned int d = 1; d < dim; ++d)
67 values(d) = 0;
68 }
69
70 private:
71 const bool fluctuating;
72 };
73
74 /* for constant Dirichlet conditions we could also use the ConstantFunction
75 * utility from dealii
76 */
77 template <int dim>
78 class DirichletCondition : public dealii::Function<dim>
79 {
80 public:
82 : dealii::Function<dim>()
83 {}
84
85 double
86 value(const dealii::Point<dim> &p, const unsigned int component = 0) const override
87 {
88 (void)p;
89 (void)component;
90 return -1.0;
91 }
92 };
93
94 /*
95 * This class collects all relevant input data for the level set simulation
96 */
97
98 template <int dim, typename number>
99 class SimulationFlowPastCylinder : public MeltPoolCase<dim, number>
100 {
101 public:
105
106 void
108 {
109 this->triangulation =
110 std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(this->mpi_communicator);
111
112 if constexpr (dim == 2)
113 {
114 dealii::Point<2> p1(0, 0);
115 dealii::Point<2> p2(2.5, 0.4);
116 std::vector<unsigned int> refinements({50, 8});
117 dealii::Triangulation<2> tmp;
118 dealii::GridGenerator::subdivided_hyper_rectangle(tmp, refinements, p1, p2);
119 std::set<dealii::Triangulation<2>::active_cell_iterator> cells_in_void;
120 for (dealii::Triangulation<2>::active_cell_iterator cell = tmp.begin(); cell != tmp.end();
121 ++cell)
122 if (cell->center()[0] > 0.45 && cell->center()[0] < 0.55 && cell->center()[1] > 0.15 &&
123 cell->center()[1] < 0.25)
124 cells_in_void.insert(cell);
125 dealii::GridGenerator::create_triangulation_with_removed_cells(tmp,
126 cells_in_void,
127 *this->triangulation);
128
129 // shift cells at the upper end of the domain from 0.40 to 0.41. It
130 // corresponds to faces with id 3
131 for (dealii::Triangulation<2>::cell_iterator cell = this->triangulation->begin();
132 cell != this->triangulation->end();
133 ++cell)
134 if (cell->at_boundary(3) && cell->face(3)->center()[1] > 0.39999999999)
135 for (unsigned int v = 0; v < dealii::GeometryInfo<2>::vertices_per_face; ++v)
136 cell->face(3)->vertex(v)[1] = 0.41;
137
138 // Set the left boundary (inflow) to 1, the right to 2, the rest to 0.
139 for (dealii::Triangulation<2>::active_cell_iterator cell = this->triangulation->begin();
140 cell != this->triangulation->end();
141 ++cell)
142 for (unsigned int f = 0; f < dealii::GeometryInfo<2>::faces_per_cell; ++f)
143 if (cell->face(f)->at_boundary())
144 {
145 if (std::abs(cell->face(f)->center()[0]) < 1e-12)
146 cell->face(f)->set_all_boundary_ids(1);
147 else if (std::abs(cell->face(f)->center()[0] - 2.5) < 1e-12)
148 cell->face(f)->set_all_boundary_ids(2);
149 else
150 cell->face(f)->set_all_boundary_ids(0);
151 }
152 }
153 else
154 {
155 AssertThrow(false, dealii::ExcNotImplemented());
156 }
157 }
158
159 void
161 {
162 auto dirichlet = std::make_shared<DirichletCondition<dim>>();
163
164 this->attach_boundary_condition({0, dirichlet}, "dirichlet", "level_set");
165 this->attach_boundary_condition({1, dirichlet}, "dirichlet", "level_set");
166
167 this->attach_boundary_condition(0, "no_slip", "navier_stokes_u");
168
170 {1, std::shared_ptr<dealii::Function<dim>>(new InflowVelocity<dim>(0., true))},
171 "dirichlet",
172 "navier_stokes_u");
173
175 {2, std::shared_ptr<dealii::Function<dim>>(new dealii::Functions::ZeroFunction<dim>(1))},
176 "neumann",
177 "navier_stokes_p");
178 }
179
180 void
182 {
183 this->attach_initial_condition(std::make_shared<InitializePhi<dim>>(), "level_set");
184 this->attach_initial_condition(std::shared_ptr<dealii::Function<dim>>(
185 new InflowVelocity<dim>(0., false)),
186 "navier_stokes_u");
187 }
188 };
189} // namespace MeltPoolDG::Simulation::FlowPastCylinder
Definition melt_pool_case.hpp:290
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
double value(const dealii::Point< dim > &p, const unsigned int component=0) const override
Definition flow_past_cylinder.hpp:86
DirichletCondition()
Definition flow_past_cylinder.hpp:81
const bool fluctuating
Definition flow_past_cylinder.hpp:71
InflowVelocity(const double time, const bool fluctuating)
Definition flow_past_cylinder.hpp:46
void vector_value(const dealii::Point< dim > &p, dealii::Vector< double > &values) const override
Definition flow_past_cylinder.hpp:52
InitializePhi()
Definition flow_past_cylinder.hpp:27
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition flow_past_cylinder.hpp:39
double value(const dealii::Point< dim > &p, const unsigned int) const override
Definition flow_past_cylinder.hpp:33
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition flow_past_cylinder.hpp:107
SimulationFlowPastCylinder(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition flow_past_cylinder.hpp:102
void set_field_conditions() override
Pure virtual function to set the field conditions.
Definition flow_past_cylinder.hpp:181
void set_boundary_conditions() override
Pure virtual function to set the boundary conditions.
Definition flow_past_cylinder.hpp:160
int sgn(const number &x)
Definition characteristic_functions.hpp:63
Definition flow_past_cylinder.cpp:6
Definition dealii_tensor.hpp:10