include/meltpooldg/heat/laser_intensity_profiles.hpp Source File

Developer Documentation: include/meltpooldg/heat/laser_intensity_profiles.hpp Source File
Developer Documentation
laser_intensity_profiles.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/exceptions.h>
4#include <deal.II/base/function.h>
5#include <deal.II/base/numbers.h>
6#include <deal.II/base/point.h>
7#include <deal.II/base/tensor.h>
8#include <deal.II/base/utilities.h>
9
11
12#include <cmath>
13
14namespace MeltPoolDG::Heat
15{
21 template <int dim, typename number>
22 inline number
23 compute_projection_factor(const dealii::Tensor<1, dim, number> &laser_direction,
24 const dealii::Tensor<1, dim, number> &normal_vector)
25 {
26 Assert(std::abs(laser_direction.norm() - 1.0) < 1e-8,
27 dealii::ExcMessage("The laser direction must be a unit vector"));
28 Assert(std::abs(normal_vector.norm() - 1.0) < 1e-8,
29 dealii::ExcMessage("The laser direction must be a unit vector"));
30
31 const number fac = normal_vector * laser_direction;
32 if (fac < 0.0)
33 return 0.0;
34 return fac;
35 }
36
41 template <int dim, typename number>
42 inline number
43 compute_distance_to_line(const dealii::Point<dim, number> &p,
44 const dealii::Point<dim, number> &line_base,
45 const dealii::Tensor<1, dim, number> &line_direction)
46 {
47 Assert(std::abs(line_direction.norm() - 1.0) < 1e-8,
48 dealii::ExcMessage("The line direction must be a unit vector"));
49
50 if (dim == 1)
51 return 0.0;
52 else if (dim == 2)
53 return std::abs(dealii::cross_product_2d(p - line_base) * line_direction);
54 else if (dim == 3)
55 return dealii::cross_product_3d(p - line_base, line_direction).norm();
56 else
57 Assert(false, dealii::ExcNotImplemented());
58 return 0.0;
59 }
60
61 template <int dim, typename number>
62 class UniformIntensityProfile : public dealii::Function<dim, number>
63 {
64 public:
65 UniformIntensityProfile(const std::function<number(void)> &power_updater_in)
66 : dealii::Function<dim, number>(1)
67 , power_updater(power_updater_in)
68 {}
69
70 inline number
71 value(const dealii::Point<dim> &, const unsigned int /*component*/) const final
72 {
73 return power;
74 }
75
76 void
77 set_time(const number time) final
78 {
79 (void)time;
81 }
82
83 private:
84 number power;
85
86 const std::function<number(void)> power_updater;
87 };
88
97 template <int dim, typename number>
98 class GaussProjectionIntensityProfile : public dealii::Function<dim, number>
99 {
100 public:
101 struct State
102 {
103 const number power;
104 const dealii::Point<dim, number> position;
105 };
106
108 const number radius_in,
109 const dealii::Point<dim, number> &laser_position_in,
110 const dealii::Tensor<1, dim, number> &laser_direction_in)
111 : dealii::Function<dim, number>(1)
112 , radius(radius_in)
113 , laser_position(laser_position_in)
114 , laser_direction(laser_direction_in)
115 , updater()
116 {
117 AssertThrow(radius > 0.0,
118 dealii::ExcMessage("The laser beam radius must be greater than zero! Abort.."));
120 }
121
122 GaussProjectionIntensityProfile(const number radius_in,
123 const dealii::Tensor<1, dim, number> &laser_direction_in,
124 const std::function<const State(void)> &updater_in)
125 : dealii::Function<dim, number>(1)
126 , radius(radius_in)
127 , laser_direction(laser_direction_in)
128 , updater(updater_in)
129 {
130 AssertThrow(radius > 0.0,
131 dealii::ExcMessage("The laser beam radius must be greater than zero! Abort.."));
132 }
133
134 inline number
135 value(const dealii::Point<dim> &p, const unsigned int /*component*/) const final
136 {
138 return peak_power_density * std::exp(-2. * s * s);
139 }
140
141 void
142 set_time(const number time) final
143 {
144 (void)time;
145 if (not updater)
146 return;
147 const auto state = updater();
148 update_peak_power_density(state.power);
149 laser_position = state.position;
150 }
151
152 private:
153 void
154 update_peak_power_density(const number power)
155 {
156 peak_power_density = power / (radius * radius * dealii::numbers::PI_2);
157 }
158
159 const number radius;
160 dealii::Point<dim, number> laser_position;
161 const dealii::Tensor<1, dim, number> laser_direction;
163
164 const std::function<const State(void)> updater;
165 };
166
174 template <int dim, typename number>
175 class GaussVolumetricIntensityProfile : public dealii::Function<dim, number>
176 {
177 public:
178 struct State
179 {
180 const number power;
181 const dealii::Point<dim, number> position;
182 };
183
184 GaussVolumetricIntensityProfile(const number radius_in,
185 const std::function<const State(void)> &updater_in)
186 : dealii::Function<dim, number>(1)
187 , radius(radius_in)
188 , updater(updater_in)
189 {
190 AssertThrow(radius > 0.0,
191 dealii::ExcMessage("The laser beam radius must be greater than zero! Abort.."));
192 }
193
194 inline number
195 value(const dealii::Point<dim> &p, const unsigned int /*component*/) const final
196 {
197 const number s = p.distance(laser_position) / radius;
198 return peak_power_density * std::exp(-2. * s * s);
199 }
200
201 void
202 set_time(const number time) final
203 {
204 (void)time;
205 if (not updater)
206 return;
207 const auto state = updater();
209 state.power / dealii::Utilities::fixed_power<3>(radius * std::sqrt(dealii::numbers::PI_2));
210 laser_position = state.position;
211 }
212
213
214 private:
215 const number radius;
216 dealii::Point<dim, number> laser_position;
218
219 const std::function<const State(void)> updater;
220 };
221
242 template <int dim, typename number>
243 class GusarovIntensityProfile : public dealii::Function<dim, number>
244 {
245 public:
246 struct State
247 {
248 const number power;
249 const dealii::Point<dim, number> position;
250 };
251
253 const number radius_in,
254 const std::function<const State(void)> &updater_in)
255 : dealii::Function<dim, number>(1)
256 , data(data_in)
257 , radius(radius_in)
258 , lambda(data.extinction_coefficient * data.layer_thickness)
259 , a(std::sqrt(1. - data.reflectivity))
260 , D((1. - a) * (1. - a - data.reflectivity * (1. + a)) * std::exp(-2. * a * lambda) -
261 (1. + a) * (1. + a - data.reflectivity * (1. - a)) * std::exp(2. * a * lambda))
262 , updater(updater_in)
263 {
264 AssertThrow(radius > 0.0,
265 dealii::ExcMessage("The laser beam radius must be greater than zero! Abort.."));
266 }
267
268 inline number
269 value(const dealii::Point<dim> &p, const unsigned int /*component*/) const final
270 {
271 const number distance = p.distance(laser_position);
272 const number z = -(p[dim - 1] - laser_position[dim - 1]);
273 const number xi = z * data.extinction_coefficient;
274
275 return z >= data.layer_thickness or z < laser_position[dim - 1] ?
276 0. :
277 -data.extinction_coefficient * power_density(distance) * dq_dxi(xi);
278 }
279
280 void
281 set_time(const number time) final
282 {
283 (void)time;
284 if (not updater)
285 return;
286 const auto state = updater();
287 power = state.power;
288 laser_position = state.position;
289 }
290
291 private:
292 inline number
293 power_density(const number distance) const
294 {
295 return distance <= radius ? 3. * power / (dealii::numbers::PI * radius * radius) *
296 dealii::Utilities::fixed_power<2>(1. - distance / radius) *
297 dealii::Utilities::fixed_power<2>(1 + distance / radius) :
298 0.0;
299 }
300
301 inline number
302 dq_dxi(const number xi) const
303 {
304 const number &rho = data.reflectivity;
305
306 // clang-format off
307 return xi < lambda ?
308 ((3 - 3 * rho) *(std::exp(-xi) + rho * std::exp(xi - 2 * lambda)))
309 / // ------------------------------------------------------
310 (4 * rho - 3)
311 +
312 2 * a * a * rho
313 / // ------------------
314 (D * (4 * rho - 3))
315 *
316 (
317 std::exp(-lambda) * (1 - rho * rho) *
318 (std::exp(-2 * a * xi) * (a - 1) + std::exp(2 * a * xi) * (a + 1))
319 -
320 (rho * std::exp(-2 * lambda) + 3) *
321 (std::exp(2 * a * (xi - lambda)) * (1 - a - rho * (a + 1)) -
322 std::exp(2 * a * (lambda - xi)) * (a + rho * (a - 1) + 1))
323 ) :
324 0.0;
325 // clang-format on
326 }
327
329 number power;
330 const number radius;
331 dealii::Point<dim, number> laser_position;
332 const number lambda;
333 const number a;
334 const number D;
335
336 const std::function<const State(void)> updater;
337 };
338
339} // namespace MeltPoolDG::Heat
Definition laser_intensity_profiles.hpp:99
void update_peak_power_density(const number power)
Definition laser_intensity_profiles.hpp:154
const number radius
Definition laser_intensity_profiles.hpp:159
dealii::Point< dim, number > laser_position
Definition laser_intensity_profiles.hpp:160
const std::function< const State(void)> updater
Definition laser_intensity_profiles.hpp:164
GaussProjectionIntensityProfile(const number radius_in, const dealii::Tensor< 1, dim, number > &laser_direction_in, const std::function< const State(void)> &updater_in)
Definition laser_intensity_profiles.hpp:122
GaussProjectionIntensityProfile(const number power, const number radius_in, const dealii::Point< dim, number > &laser_position_in, const dealii::Tensor< 1, dim, number > &laser_direction_in)
Definition laser_intensity_profiles.hpp:107
const dealii::Tensor< 1, dim, number > laser_direction
Definition laser_intensity_profiles.hpp:161
number peak_power_density
Definition laser_intensity_profiles.hpp:162
number value(const dealii::Point< dim > &p, const unsigned int) const final
Definition laser_intensity_profiles.hpp:135
void set_time(const number time) final
Definition laser_intensity_profiles.hpp:142
Definition laser_intensity_profiles.hpp:176
void set_time(const number time) final
Definition laser_intensity_profiles.hpp:202
number value(const dealii::Point< dim > &p, const unsigned int) const final
Definition laser_intensity_profiles.hpp:195
dealii::Point< dim, number > laser_position
Definition laser_intensity_profiles.hpp:216
number peak_power_density
Definition laser_intensity_profiles.hpp:217
const number radius
Definition laser_intensity_profiles.hpp:215
const std::function< const State(void)> updater
Definition laser_intensity_profiles.hpp:219
GaussVolumetricIntensityProfile(const number radius_in, const std::function< const State(void)> &updater_in)
Definition laser_intensity_profiles.hpp:184
Definition laser_intensity_profiles.hpp:244
const number a
Definition laser_intensity_profiles.hpp:333
GusarovIntensityProfile(const LaserData< number >::GusarovData &data_in, const number radius_in, const std::function< const State(void)> &updater_in)
Definition laser_intensity_profiles.hpp:252
const std::function< const State(void)> updater
Definition laser_intensity_profiles.hpp:336
number power
Definition laser_intensity_profiles.hpp:329
const number radius
Definition laser_intensity_profiles.hpp:330
const number D
Definition laser_intensity_profiles.hpp:334
number dq_dxi(const number xi) const
Definition laser_intensity_profiles.hpp:302
const number lambda
Definition laser_intensity_profiles.hpp:332
void set_time(const number time) final
Definition laser_intensity_profiles.hpp:281
number value(const dealii::Point< dim > &p, const unsigned int) const final
Definition laser_intensity_profiles.hpp:269
dealii::Point< dim, number > laser_position
Definition laser_intensity_profiles.hpp:331
const LaserData< number >::GusarovData & data
Definition laser_intensity_profiles.hpp:328
number power_density(const number distance) const
Definition laser_intensity_profiles.hpp:293
Definition laser_intensity_profiles.hpp:63
number power
Definition laser_intensity_profiles.hpp:84
UniformIntensityProfile(const std::function< number(void)> &power_updater_in)
Definition laser_intensity_profiles.hpp:65
number value(const dealii::Point< dim > &, const unsigned int) const final
Definition laser_intensity_profiles.hpp:71
void set_time(const number time) final
Definition laser_intensity_profiles.hpp:77
const std::function< number(void)> power_updater
Definition laser_intensity_profiles.hpp:86
Definition apparent_capacity.hpp:9
number compute_projection_factor(const dealii::Tensor< 1, dim, number > &laser_direction, const dealii::Tensor< 1, dim, number > &normal_vector)
Definition laser_intensity_profiles.hpp:23
number compute_distance_to_line(const dealii::Point< dim, number > &p, const dealii::Point< dim, number > &line_base, const dealii::Tensor< 1, dim, number > &line_direction)
Definition laser_intensity_profiles.hpp:43
Definition dealii_tensor.hpp:10
Definition laser_intensity_profiles.hpp:102
const dealii::Point< dim, number > position
Definition laser_intensity_profiles.hpp:104
const number power
Definition laser_intensity_profiles.hpp:103
Definition laser_intensity_profiles.hpp:179
const dealii::Point< dim, number > position
Definition laser_intensity_profiles.hpp:181
const number power
Definition laser_intensity_profiles.hpp:180
Definition laser_intensity_profiles.hpp:247
const number power
Definition laser_intensity_profiles.hpp:248
const dealii::Point< dim, number > position
Definition laser_intensity_profiles.hpp:249
Definition laser_data.hpp:86