deal.II version 9.8.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
function_lib_cutoff.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2001 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
20#include <deal.II/base/point.h>
21#include <deal.II/base/tensor.h>
23
24#include <deal.II/lac/vector.h>
25
26#include <Kokkos_Macros.hpp>
27
28#include <algorithm>
29#include <array>
30#include <cmath>
31#include <string>
32#include <vector>
33
35
36
37namespace Functions
38{
39 template <int dim>
41 const double r,
42 const Point<dim> p,
43 const unsigned int n_components,
44 const unsigned int select,
45 const bool integrate_to_one,
46 const double unitary_integral_value)
48 , center(p)
49 , radius(r)
50 , selected(select)
54 Utilities::fixed_power<dim>(radius)) :
55 1.0)
56 {
57 Assert(r > 0, ExcMessage("You must specify a radius > 0."));
58 }
59
60
61
62 template <int dim>
63 void
68
69
70
71 template <int dim>
72 const Point<dim> &
74 {
75 return center;
76 }
77
78
79
80 template <int dim>
81 void
83 {
84 radius = r;
85 Assert(r > 0, ExcMessage("You must specify a radius > 0."));
87 rescaling =
89 else
90 rescaling = 1.0;
91 }
92
93
94
95 template <int dim>
96 double
98 {
99 return radius;
100 }
101
102
103
104 template <int dim>
105 bool
110
111
112
113 template <int dim>
115 double radius,
116 const Point<dim> &center,
117 const unsigned int n_components,
118 const unsigned int select,
119 const bool integrate_to_one)
121 center,
123 select,
125 , initialized(false)
126 {}
127
128
129
130 template <int dim>
131 void
133 {
135 for (unsigned int i = 0; i < dim; ++i)
136 base[i]->set_center(Point<1>(p[i]));
138 }
139
140
141
142 template <int dim>
143 void
145 {
147 for (unsigned int i = 0; i < dim; ++i)
148 base[i]->set_radius(r);
150 }
151
152
153
154 template <int dim>
155 double
157 const unsigned int component) const
158 {
160 double ret = 1.0;
161 for (unsigned int i = 0; i < dim; ++i)
162 ret *= base[i]->value(Point<1>(p[i]), component);
163 return ret;
164 }
165
166
167
168 template <int dim>
171 const unsigned int component) const
172 {
174 Tensor<1, dim> ret;
175 for (unsigned int d = 0; d < dim; ++d)
176 {
177 ret[d] = base[d]->gradient(Point<1>(p[d]), component)[0];
178 for (unsigned int i = 0; i < dim; ++i)
179 if (i != d)
180 ret[d] *= base[i]->value(Point<1>(p[i]), component);
181 }
182 return ret;
183 }
184
185
186
187 //--------------------------------------------------------------------
188 namespace
189 {
190 // Integral of CutOffFunctionLinfty in dimension 1, 2, and 3 when the radius
191 // is one
192 const double integral_Linfty[] = {2.0,
193 3.14159265358979323846264338328,
194 4.18879020478639098461685784437};
195
196 // Integral of CutOffFunctionW1 in dimension 1, 2, and 3 when the radius
197 // is one
198 const double integral_W1[] = {1.0,
199 1.04719755119659774615421446109,
200 1.04719755119659774615421446109};
201
202 // Integral of CutOffFunctionCinfty in dimension 1, 2, and 3 when the radius
203 // is one
204 const double integral_Cinfty[] = {1.20690032243787617533623799633,
205 1.26811216112759608094632335664,
206 1.1990039070192139033798473858};
207
208 // Integral of CutOffFunctionC1 in dimension 1, 2, and 3 when the radius
209 // is one
210 const double integral_C1[] = {1.0,
211 0.93417655442731527615578663815,
212 0.821155557658032806157358815206};
213 } // namespace
214
215
216 template <int dim>
218 const double r,
219 const Point<dim> p,
220 const unsigned int n_components,
221 const unsigned int select,
222 const bool integrate_to_one)
223 : CutOffFunctionBase<dim>(r,
224 p,
226 select,
228 integral_Linfty[dim - 1])
229 {}
230
231
232 template <int dim>
233 double
235 const unsigned int component) const
236 {
238 component == this->selected)
239 return ((this->center.distance(p) < this->radius) ? this->rescaling : 0.);
240 return 0.;
241 }
242
243
244 template <int dim>
245 void
247 std::vector<double> &values,
248 const unsigned int component) const
249 {
250 Assert(values.size() == points.size(),
251 ExcDimensionMismatch(values.size(), points.size()));
252 AssertIndexRange(component, this->n_components);
253
254
256 component == this->selected)
257 for (unsigned int k = 0; k < values.size(); ++k)
258 values[k] = (this->center.distance(points[k]) < this->radius) ?
259 this->rescaling :
260 0.;
261 else
262 std::fill(values.begin(), values.end(), 0.);
263 }
264
265
266 template <int dim>
267 void
269 const std::vector<Point<dim>> &points,
270 std::vector<Vector<double>> &values) const
271 {
272 Assert(values.size() == points.size(),
273 ExcDimensionMismatch(values.size(), points.size()));
274
275 for (unsigned int k = 0; k < values.size(); ++k)
276 {
277 const double val = (this->center.distance(points[k]) < this->radius) ?
278 this->rescaling :
279 0.;
281 values[k] = val;
282 else
283 {
284 values[k] = 0;
285 values[k](this->selected) = val;
286 }
287 }
288 }
289
290 template <int dim>
292 const Point<dim> p,
293 const unsigned int n_components,
294 const unsigned int select,
295 const bool integrate_to_one)
296 : CutOffFunctionBase<dim>(r,
297 p,
299 select,
301 integral_W1[dim - 1])
302 {}
303
304
305 template <int dim>
306 double
308 const unsigned int component) const
309 {
311 component == this->selected)
312 {
313 const double d = this->center.distance(p);
314 return ((d < this->radius) ?
315 (this->radius - d) / this->radius * this->rescaling :
316 0.);
317 }
318 return 0.;
319 }
320
321
322 template <int dim>
323 void
325 std::vector<double> &values,
326 const unsigned int component) const
327 {
328 Assert(values.size() == points.size(),
329 ExcDimensionMismatch(values.size(), points.size()));
330
332 component == this->selected)
333 for (unsigned int i = 0; i < values.size(); ++i)
334 {
335 const double d = this->center.distance(points[i]);
336 values[i] = ((d < this->radius) ?
337 (this->radius - d) / this->radius * this->rescaling :
338 0.);
339 }
340 else
341 std::fill(values.begin(), values.end(), 0.);
342 }
343
344
345
346 template <int dim>
347 void
349 const std::vector<Point<dim>> &points,
350 std::vector<Vector<double>> &values) const
351 {
352 Assert(values.size() == points.size(),
353 ExcDimensionMismatch(values.size(), points.size()));
354
355 for (unsigned int k = 0; k < values.size(); ++k)
356 {
357 const double d = this->center.distance(points[k]);
358 const double val =
359 (d < this->radius) ?
360 (this->radius - d) / this->radius * this->rescaling :
361 0.;
363 values[k] = val;
364 else
365 {
366 values[k] = 0;
367 values[k](this->selected) = val;
368 }
369 }
370 }
371
372
373 template <int dim>
375 const double r,
376 const Point<dim> p,
377 const unsigned int n_components,
378 const unsigned int select,
379 bool integrate_to_one)
380 : CutOffFunctionBase<dim>(r,
381 p,
383 select,
385 integral_Cinfty[dim - 1])
386 {}
387
388
389 template <int dim>
390 double
392 const unsigned int component) const
393 {
395 component == this->selected)
396 {
397 const double d = this->center.distance(p);
398 const double r = this->radius;
399 if (d >= r)
400 return 0.;
401 const double e = -r * r / (r * r - d * d);
402 return ((e < -50) ? 0. : numbers::E * std::exp(e) * this->rescaling);
403 }
404 return 0.;
405 }
406
407
408 template <int dim>
409 void
411 std::vector<double> &values,
412 const unsigned int component) const
413 {
414 Assert(values.size() == points.size(),
415 ExcDimensionMismatch(values.size(), points.size()));
416
417 const double r = this->radius;
418
420 component == this->selected)
421 for (unsigned int i = 0; i < values.size(); ++i)
422 {
423 const double d = this->center.distance(points[i]);
424 if (d >= r)
425 {
426 values[i] = 0.;
427 }
428 else
429 {
430 const double e = -r * r / (r * r - d * d);
431 values[i] =
432 (e < -50) ? 0. : numbers::E * std::exp(e) * this->rescaling;
433 }
434 }
435 else
436 std::fill(values.begin(), values.end(), 0.);
437 }
438
439
440 template <int dim>
441 void
443 const std::vector<Point<dim>> &points,
444 std::vector<Vector<double>> &values) const
445 {
446 Assert(values.size() == points.size(),
447 ExcDimensionMismatch(values.size(), points.size()));
448
449 for (unsigned int k = 0; k < values.size(); ++k)
450 {
451 const double d = this->center.distance(points[k]);
452 const double r = this->radius;
453 double val = 0.;
454 if (d < this->radius)
455 {
456 const double e = -r * r / (r * r - d * d);
457 if (e > -50)
458 val = numbers::E * std::exp(e) * this->rescaling;
459 }
460
462 values[k] = val;
463 else
464 {
465 values[k] = 0;
466 values[k](this->selected) = val;
467 }
468 }
469 }
470
471
472
473 template <int dim>
476 const unsigned int) const
477 {
478 const double d = this->center.distance(p);
479 const double r = this->radius;
480 if (d >= r)
481 return Tensor<1, dim>();
482 const double e = -d * d / (r - d) / (r + d);
483 return ((e < -50) ?
484 Point<dim>() :
485 (p - this->center) / d *
486 (-2.0 * r * r / Utilities::fixed_power<2>(-r * r + d * d) * d *
487 std::exp(e)) *
488 this->rescaling);
489 }
490
491
492
493 template <int dim>
495 const Point<dim> p,
496 const unsigned int n_components,
497 const unsigned int select,
498 bool integrate_to_one)
499 : CutOffFunctionBase<dim>(r,
500 p,
502 select,
504 integral_C1[dim - 1])
505 {}
506
507
508 template <int dim>
509 double
511 const unsigned int component) const
512 {
514 component == this->selected)
515 {
516 const double d = this->center.distance(p);
517 const double r = this->radius;
518 if (d >= r)
519 return 0.;
520 return .5 * (std::cos(numbers::PI * d / r) + 1) * this->rescaling;
521 }
522 return 0.;
523 }
524
525
526 template <int dim>
527 void
529 std::vector<double> &values,
530 const unsigned int component) const
531 {
532 Assert(values.size() == points.size(),
533 ExcDimensionMismatch(values.size(), points.size()));
534
535 const double r = this->radius;
536
538 component == this->selected)
539 for (unsigned int i = 0; i < values.size(); ++i)
540 {
541 const double d = this->center.distance(points[i]);
542 if (d >= r)
543 {
544 values[i] = 0.;
545 }
546 else
547 {
548 values[i] =
549 .5 * (std::cos(numbers::PI * d / r) + 1) * this->rescaling;
550 }
551 }
552 else
553 std::fill(values.begin(), values.end(), 0.);
554 }
555
556
557 template <int dim>
558 void
560 const std::vector<Point<dim>> &points,
561 std::vector<Vector<double>> &values) const
562 {
563 Assert(values.size() == points.size(),
564 ExcDimensionMismatch(values.size(), points.size()));
565
566 for (unsigned int k = 0; k < values.size(); ++k)
567 {
568 const double d = this->center.distance(points[k]);
569 const double r = this->radius;
570 double val = 0.;
571 if (d < this->radius)
572 {
573 val = .5 * (std::cos(numbers::PI * d / r) + 1) * this->rescaling;
574 }
575
577 values[k] = val;
578 else
579 {
580 values[k] = 0;
581 values[k](this->selected) = val;
582 }
583 }
584 }
585
586
587
588 template <int dim>
590 CutOffFunctionC1<dim>::gradient(const Point<dim> &p, const unsigned int) const
591 {
592 const double d = this->center.distance(p);
593 const double r = this->radius;
594 if (d >= r)
595 return Tensor<1, dim>();
596 return (-0.5 * numbers::PI * std::sin(numbers::PI * d / r) / r) *
597 (p - this->center) / d * this->rescaling;
598 }
599
600
601 // explicit instantiations
602 template class CutOffFunctionBase<1>;
603 template class CutOffFunctionBase<2>;
604 template class CutOffFunctionBase<3>;
605
606 template class CutOffFunctionLinfty<1>;
607 template class CutOffFunctionLinfty<2>;
608 template class CutOffFunctionLinfty<3>;
609
610 template class CutOffFunctionW1<1>;
611 template class CutOffFunctionW1<2>;
612 template class CutOffFunctionW1<3>;
613
614 template class CutOffFunctionCinfty<1>;
615 template class CutOffFunctionCinfty<2>;
616 template class CutOffFunctionCinfty<3>;
617
618 template class CutOffFunctionC1<1>;
619 template class CutOffFunctionC1<2>;
620 template class CutOffFunctionC1<3>;
621
622 template class CutOffFunctionTensorProduct<1>;
623 template class CutOffFunctionTensorProduct<2>;
624 template class CutOffFunctionTensorProduct<3>;
625} // namespace Functions
626
const unsigned int n_components
Definition function.h:162
Function(const unsigned int n_components=1, const time_type initial_time=0.0)
virtual void set_radius(const double r)
virtual void set_center(const Point< dim > &p)
const Point< dim > & get_center() const
static const unsigned int no_component
CutOffFunctionBase(const double radius=1., const Point< dim > center=Point< dim >(), const unsigned int n_components=1, const unsigned int select=CutOffFunctionBase< dim >::no_component, const bool integrate_to_one=false, const double unitary_integral_value=1.0)
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
virtual void vector_value_list(const std::vector< Point< dim > > &points, std::vector< Vector< double > > &values) const override
CutOffFunctionC1(const double radius=1., const Point< dim >=Point< dim >(), const unsigned int n_components=1, const unsigned int select=CutOffFunctionBase< dim >::no_component, bool integrate_to_one=false)
virtual Tensor< 1, dim > gradient(const Point< dim > &p, const unsigned int component=0) const override
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< double > &values, const unsigned int component=0) const override
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< double > &values, const unsigned int component=0) const override
CutOffFunctionCinfty(const double radius=1., const Point< dim >=Point< dim >(), const unsigned int n_components=1, const unsigned int select=CutOffFunctionBase< dim >::no_component, bool integrate_to_one=false)
virtual Tensor< 1, dim > gradient(const Point< dim > &p, const unsigned int component=0) const override
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
virtual void vector_value_list(const std::vector< Point< dim > > &points, std::vector< Vector< double > > &values) const override
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
virtual void vector_value_list(const std::vector< Point< dim > > &points, std::vector< Vector< double > > &values) const override
CutOffFunctionLinfty(const double radius=1., const Point< dim >=Point< dim >(), const unsigned int n_components=1, const unsigned int select=CutOffFunctionBase< dim >::no_component, const bool integrate_to_one=false)
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< double > &values, const unsigned int component=0) const override
std::array< std::unique_ptr< CutOffFunctionBase< 1 > >, dim > base
CutOffFunctionTensorProduct(double radius=1.0, const Point< dim > &center=Point< dim >(), const unsigned int n_components=1, const unsigned int select=CutOffFunctionBase< dim >::no_component, const bool integrate_to_one=false)
virtual Tensor< 1, dim > gradient(const Point< dim > &p, const unsigned int component=0) const override
virtual void set_radius(const double radius) override
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
virtual void set_center(const Point< dim > &center) override
virtual void vector_value_list(const std::vector< Point< dim > > &points, std::vector< Vector< double > > &values) const override
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
CutOffFunctionW1(const double radius=1., const Point< dim >=Point< dim >(), const unsigned int n_components=1, const unsigned int select=CutOffFunctionBase< dim >::no_component, const bool integrate_to_one=false)
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< double > &values, const unsigned int component=0) const override
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
const bool IsBlockVector< VectorType >::value
constexpr T fixed_power(const T t)
Definition utilities.h:942
constexpr double E
Definition numbers.h:215
constexpr double PI
Definition numbers.h:240
::VectorizedArray< Number, width > exp(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)