applications/mp-level-set/cases/vortex_bubble_DG.hpp Source File

Developer Documentation: applications/mp-level-set/cases/vortex_bubble_DG.hpp Source File
Developer Documentation
vortex_bubble_DG.hpp
Go to the documentation of this file.
1#pragma once
2#include <deal.II/base/function.h>
3#include <deal.II/base/function_signed_distance.h>
4#include <deal.II/base/point.h>
5#include <deal.II/base/table_handler.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
12#include <deal.II/lac/vector.h>
13
14#include <deal.II/numerics/error_estimator.h>
15#include <deal.II/numerics/vector_tools.h>
16
22
23#include <cmath>
24#include <filesystem>
25#include <fstream>
26#include <iostream>
27
28#include "../level_set_case.hpp"
29
31{
32 // period of the vortex flow
33 static double Tf = 4.0;
34
35 /*
36 * this function specifies the initial field of the level set equation
37 */
38 template <int dim, typename number>
39 class InitializePhi : public dealii::Function<dim, number>
40 {
41 public:
43 : dealii::Function<dim, number>()
44 , distance_sphere(dim == 1 ? dealii::Point<dim, number>(0.5) :
45 dealii::Point<dim, number>(0.5, 0.75),
46 0.15)
47 {}
48
49 number
50 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
51 {
52 return -distance_sphere.value(p);
53 }
54
55 private:
56 const dealii::Functions::SignedDistance::Sphere<dim> distance_sphere;
57 };
58
59 template <int dim, typename number>
60 class PhiExact : public dealii::Function<dim, number>
61 {
62 public:
63 PhiExact(const number eps)
64 : eps(eps)
65 {}
66
67 number
68 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
69 {
70 return distance_sphere.value(p, 0) / (2 * eps);
71 }
72
73 private:
74 const number eps;
76 };
77
78 template <int dim, typename number>
79 class SignedDistanceExact : public dealii::Function<dim, number>
80 {
81 public:
83 : eps(eps)
84 {}
85
86 number
87 value(const dealii::Point<dim, number> &p, const unsigned int /*component*/) const override
88 {
89 const auto val = distance_sphere.value(p, 0);
90 return val > 0 ? std::min(val, 8 * eps) : std::max(val, -8 * eps);
91 }
92
93 private:
94 const number eps;
96 };
97
98 template <int dim, typename number>
99 class AdvectionField : public dealii::Function<dim, number>
100 {
101 public:
103 : dealii::Function<dim, number>(dim)
104 {}
105
106 number
107 value(const dealii::Point<dim, number> &p, const unsigned int c) const override
108 {
109 dealii::Vector<number> values(dim);
110 vector_value(p, values);
111 return values[c];
112 }
113
114 void
115 vector_value(const dealii::Point<dim, number> &p, dealii::Vector<number> &values) const override
116 {
117 if constexpr (dim == 2)
118 {
119 const number time = this->get_time();
120
121 const number x = p[0];
122 const number y = p[1];
123
124 const number reverseCoefficient = std::cos(dealii::numbers::PI * time / Tf);
125
126 values[0] = reverseCoefficient * (std::sin(2. * dealii::numbers::PI * y) *
127 std::pow(std::sin(dealii::numbers::PI * x), 2.));
128 values[1] = reverseCoefficient * (-std::sin(2. * dealii::numbers::PI * x) *
129 std::pow(std::sin(dealii::numbers::PI * y), 2.));
130 }
131 else
132 AssertThrow(false, dealii::ExcMessage("Advection field for dim!=2 not implemented"));
133 }
134 };
135
136 /* for constant Dirichlet conditions we could also use the ConstantFunction
137 * utility from dealii
138 */
139 template <int dim, typename number>
140 class DirichletCondition : public dealii::Function<dim, number>
141 {
142 public:
144 : dealii::Function<dim, number>()
145 {}
146
147 number
148 value(const dealii::Point<dim, number> &p, const unsigned int component = 0) const override
149 {
150 (void)p;
151 (void)component;
152 return -1.0;
153 }
154 };
155
156 /*
157 * This class collects all relevant input data for the level set simulation
158 */
159
160 template <int dim, typename number>
162 {
163 public:
165 : LevelSet::LevelSetCase<dim, number>(parameter_file, mpi_communicator)
166 {}
167
168 void
170 {
171 if (dim == 1 || this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
172 {
173 AssertDimension(dealii::Utilities::MPI::n_mpi_processes(this->mpi_communicator), 1);
174 this->triangulation = std::make_shared<dealii::Triangulation<dim>>();
175 }
176 else
177 {
178 this->triangulation = std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(
179 this->mpi_communicator);
180 }
181
182 if (this->parameters.base.fe.type == FiniteElementType::FE_SimplexP)
183 {
184 dealii::GridGenerator::subdivided_hyper_cube_with_simplices(
185 *this->triangulation,
186 dealii::Utilities::pow(2, this->parameters.base.global_refinements),
189 }
190 else
191 {
192 dealii::GridGenerator::hyper_cube(*this->triangulation, left_domain, right_domain);
193 this->triangulation->refine_global(this->parameters.base.global_refinements);
194 }
195 }
196
197 void
199 {
200 /*
201 * In the DG case it its required to set the boundary even if it is a do nothing boundary
202 */
203 constexpr dealii::types::boundary_id do_nothing = 0;
204
205 // this->attach_boundary_condition(do_nothing, "open" "level_set");
206
207 if constexpr (dim >= 2)
208 {
209 for (const auto &cell : this->triangulation->cell_iterators())
210 for (const auto &face : cell->face_iterators())
211 if ((face->at_boundary()))
212 {
213 face->set_boundary_id(do_nothing);
214 }
215 }
216 }
217
218 void
220 {
222 "signed_distance");
223 this->attach_field_function(std::make_shared<AdvectionField<dim, number>>(),
224 "prescribed_velocity",
225 "level_set");
226 }
227
228 void
229 do_postprocessing(const GenericDataOut<dim, number> &generic_data_out) const final
230 {
231 if constexpr (dim == 2)
232 {
233 dealii::ConditionalOStream pcout(
234 std::cout, dealii::Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0);
235 // compute area
236 const auto n_q_points = this->parameters.base.fe.degree + 3;
237 dealii::FE_DGQ<dim> fe(this->parameters.base.fe.degree);
238
239 dealii::QGauss<dim> quadrature(n_q_points);
240 dealii::FEValues<dim> fe_values(fe,
241 quadrature,
242 dealii::update_values | dealii::update_JxW_values |
243 dealii::update_quadrature_points);
244
245 std::vector<number> phi_at_q(dealii::QGauss<dim>(n_q_points).size());
246
247 std::vector<number> volume_fraction;
248 number area_droplet = 0;
249 number area_bulk = 0;
250 const number threshhold = 0.0;
251
252 generic_data_out.get_vector("level_set").update_ghost_values();
253
254 for (const auto &cell :
255 generic_data_out.get_dof_handler("level_set").active_cell_iterators())
256 if (cell->is_locally_owned())
257 {
258 fe_values.reinit(cell);
259 fe_values.get_function_values(generic_data_out.get_vector("level_set"),
260 phi_at_q); // compute values of old solution
261
262 for (const unsigned int q_index : fe_values.quadrature_point_indices())
263 {
264 if (phi_at_q[q_index] >= threshhold)
265 area_droplet += fe_values.JxW(q_index);
266 else
267 area_bulk += fe_values.JxW(q_index);
268 }
269 }
270 generic_data_out.get_vector("level_set").zero_out_ghost_values();
271
272 area_droplet = dealii::Utilities::MPI::sum(area_droplet, this->mpi_communicator);
273 area_bulk = dealii::Utilities::MPI::sum(area_bulk, this->mpi_communicator);
274
275 std::ostringstream str;
276
277 str << "area (phi>0) " << std::setw(10) << std::left << area_droplet << " ";
278 str << "area (phi<0) " << std::setw(10) << std::left << area_bulk;
279
280 Journal::print_line(pcout, str.str(), "postprocessing", 1);
281 }
282 }
283
284 bool
285 add_case_specific_parameters(dealii::ParameterHandler &prm) override
286 {
287 prm.add_parameter("T", Tf, "Period of vortex flow.");
288
289 return this->parameters.base.do_print_parameters;
290 }
291
292 private:
293 number left_domain = 0.0;
294 number right_domain = 1.0;
295 mutable dealii::TableHandler table;
296 };
297} // namespace MeltPoolDG::Simulation::VortexBubbleDG
A generic utility for managing simulation output data in the MeltPoolDG context.
Definition generic_data_out.hpp:32
Definition level_set_case.hpp:76
LevelSetCase(const std::string &parameter_file_in, MPI_Comm mpi_communicator_in)
Definition level_set_case.hpp:80
LevelSetCaseParameters< number > parameters
Definition level_set_case.hpp:78
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
void attach_field_function(std::shared_ptr< dealii::Function< dim > > function, const std::string &type, const std::string &operation_name)
Definition simulation_case_base.hpp:315
const MPI_Comm mpi_communicator
Definition simulation_case_base.hpp:56
void vector_value(const dealii::Point< dim, number > &p, dealii::Vector< number > &values) const override
Definition vortex_bubble_DG.hpp:115
number value(const dealii::Point< dim, number > &p, const unsigned int c) const override
Definition vortex_bubble_DG.hpp:107
AdvectionField()
Definition vortex_bubble_DG.hpp:102
DirichletCondition()
Definition vortex_bubble_DG.hpp:143
number value(const dealii::Point< dim, number > &p, const unsigned int component=0) const override
Definition vortex_bubble_DG.hpp:148
const dealii::Functions::SignedDistance::Sphere< dim > distance_sphere
Definition vortex_bubble_DG.hpp:56
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition vortex_bubble_DG.hpp:50
InitializePhi()
Definition vortex_bubble_DG.hpp:42
Definition vortex_bubble_DG.hpp:61
const number eps
Definition vortex_bubble_DG.hpp:74
PhiExact(const number eps)
Definition vortex_bubble_DG.hpp:63
const InitializePhi< dim, number > distance_sphere
Definition vortex_bubble_DG.hpp:75
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition vortex_bubble_DG.hpp:68
const InitializePhi< dim, number > distance_sphere
Definition vortex_bubble_DG.hpp:95
SignedDistanceExact(const number eps)
Definition vortex_bubble_DG.hpp:82
const number eps
Definition vortex_bubble_DG.hpp:94
number value(const dealii::Point< dim, number > &p, const unsigned int) const override
Definition vortex_bubble_DG.hpp:87
number left_domain
Definition vortex_bubble_DG.hpp:293
bool add_case_specific_parameters(dealii::ParameterHandler &prm) override
Add simulation-specific parameters (can be overridden).
Definition vortex_bubble_DG.hpp:285
void do_postprocessing(const GenericDataOut< dim, number > &generic_data_out) const final
Perform specific postprocessing (can be overridden by derived classes).
Definition vortex_bubble_DG.hpp:229
void set_field_conditions() override
Pure virtual function to set the field conditions.
Definition vortex_bubble_DG.hpp:219
void create_spatial_discretization() override
Pure virtual function to create the spatial discretization.
Definition vortex_bubble_DG.hpp:169
number right_domain
Definition vortex_bubble_DG.hpp:294
SimulationVortexBubbleDG(std::string parameter_file, const MPI_Comm mpi_communicator)
Definition vortex_bubble_DG.hpp:164
void set_boundary_conditions() override
Pure virtual function to set the boundary conditions.
Definition vortex_bubble_DG.hpp:198
dealii::TableHandler table
Definition vortex_bubble_DG.hpp:295
void print_line(const ConditionalOStream &pcout, const std::string &text="", const std::string &operation_name="", const unsigned int extra_size=0)
Definition journal.cpp:11
Definition vortex_bubble_DG.cpp:6
static double Tf
Definition vortex_bubble_DG.hpp:33
Definition dealii_tensor.hpp:10