deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\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
flow_function.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) 2007 - 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
19#include <deal.II/base/mpi.h>
20#include <deal.II/base/mutex.h>
22#include <deal.II/base/point.h>
23#include <deal.II/base/tensor.h>
25
26#include <deal.II/lac/vector.h>
27
28#include <Kokkos_Macros.hpp>
29
30#include <algorithm>
31#include <cmath>
32#include <cstddef>
33#include <mutex>
34#include <string>
35#include <vector>
36
37
39
40
41namespace Functions
42{
43 template <int dim>
45 : Function<dim>(dim + 1)
46 , mean_pressure(0)
47 , aux_values(dim + 1)
48 , aux_gradients(dim + 1)
49 {}
50
51
52
53 template <int dim>
54 void
56 {
57 mean_pressure = p;
58 }
59
60
61 template <int dim>
62 void
64 const std::vector<Point<dim>> &points,
65 std::vector<Vector<double>> &values) const
66 {
67 const unsigned int n_points = points.size();
68 Assert(values.size() == n_points,
69 ExcDimensionMismatch(values.size(), n_points));
70
71 // guard access to the aux_*
72 // variables in multithread mode
73 std::scoped_lock lock(mutex);
74
75 for (unsigned int d = 0; d < dim + 1; ++d)
76 aux_values[d].resize(n_points);
77 vector_values(points, aux_values);
78
79 for (unsigned int k = 0; k < n_points; ++k)
80 {
81 Assert(values[k].size() == dim + 1,
82 ExcDimensionMismatch(values[k].size(), dim + 1));
83 for (unsigned int d = 0; d < dim + 1; ++d)
84 values[k](d) = aux_values[d][k];
85 }
86 }
87
88
89 template <int dim>
90 void
92 Vector<double> &value) const
93 {
94 Assert(value.size() == dim + 1,
95 ExcDimensionMismatch(value.size(), dim + 1));
96
97 const unsigned int n_points = 1;
98 std::vector<Point<dim>> points(1);
99 points[0] = point;
101 // guard access to the aux_*
102 // variables in multithread mode
103 std::scoped_lock lock(mutex);
104
105 for (unsigned int d = 0; d < dim + 1; ++d)
106 aux_values[d].resize(n_points);
107 vector_values(points, aux_values);
108
109 for (unsigned int d = 0; d < dim + 1; ++d)
110 value(d) = aux_values[d][0];
111 }
112
113
114 template <int dim>
115 double
117 const unsigned int comp) const
118 {
119 AssertIndexRange(comp, dim + 1);
120 const unsigned int n_points = 1;
121 std::vector<Point<dim>> points(1);
122 points[0] = point;
124 // guard access to the aux_*
125 // variables in multithread mode
126 std::scoped_lock lock(mutex);
127
128 for (unsigned int d = 0; d < dim + 1; ++d)
129 aux_values[d].resize(n_points);
130 vector_values(points, aux_values);
131
132 return aux_values[comp][0];
133 }
134
135
136 template <int dim>
137 void
139 const std::vector<Point<dim>> &points,
140 std::vector<std::vector<Tensor<1, dim>>> &values) const
141 {
142 const unsigned int n_points = points.size();
143 Assert(values.size() == n_points,
144 ExcDimensionMismatch(values.size(), n_points));
145
146 // guard access to the aux_*
147 // variables in multithread mode
148 std::scoped_lock lock(mutex);
149
150 for (unsigned int d = 0; d < dim + 1; ++d)
151 aux_gradients[d].resize(n_points);
152 vector_gradients(points, aux_gradients);
153
154 for (unsigned int k = 0; k < n_points; ++k)
155 {
156 Assert(values[k].size() == dim + 1,
157 ExcDimensionMismatch(values[k].size(), dim + 1));
158 for (unsigned int d = 0; d < dim + 1; ++d)
159 values[k][d] = aux_gradients[d][k];
160 }
161 }
162
163
164 template <int dim>
165 void
167 const std::vector<Point<dim>> &points,
168 std::vector<Vector<double>> &values) const
169 {
170 const unsigned int n_points = points.size();
171 Assert(values.size() == n_points,
172 ExcDimensionMismatch(values.size(), n_points));
173
174 // guard access to the aux_*
175 // variables in multithread mode
176 std::scoped_lock lock(mutex);
177
178 for (unsigned int d = 0; d < dim + 1; ++d)
179 aux_values[d].resize(n_points);
180 vector_laplacians(points, aux_values);
181
182 for (unsigned int k = 0; k < n_points; ++k)
183 {
184 Assert(values[k].size() == dim + 1,
185 ExcDimensionMismatch(values[k].size(), dim + 1));
186 for (unsigned int d = 0; d < dim + 1; ++d)
187 values[k](d) = aux_values[d][k];
188 }
189 }
190
191
192 template <int dim>
193 std::size_t
195 {
197 return 0;
198 }
199
200
201 //----------------------------------------------------------------------//
202
203 template <int dim>
204 PoisseuilleFlow<dim>::PoisseuilleFlow(const double r, const double Re)
205 : inv_sqr_radius(1 / r / r)
206 , Reynolds(Re)
207 {
208 Assert(Reynolds != 0., ExcMessage("Reynolds number cannot be zero"));
209 }
210
211
212
213 template <int dim>
214 void
216 const std::vector<Point<dim>> &points,
217 std::vector<std::vector<double>> &values) const
218 {
219 const unsigned int n = points.size();
220
221 Assert(values.size() == dim + 1,
222 ExcDimensionMismatch(values.size(), dim + 1));
223 for (unsigned int d = 0; d < dim + 1; ++d)
224 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
225
226 for (unsigned int k = 0; k < n; ++k)
227 {
228 const Point<dim> &p = points[k];
229 // First, compute the square of the distance to the x-axis divided by
230 // the radius.
231 double r2 = 0;
232 for (unsigned int d = 1; d < dim; ++d)
233 r2 += p[d] * p[d];
234 r2 *= inv_sqr_radius;
235
236 // x-velocity
237 values[0][k] = 1. - r2;
238 // other velocities
239 for (unsigned int d = 1; d < dim; ++d)
240 values[d][k] = 0.;
241 // pressure
242 values[dim][k] = -2 * (dim - 1) * inv_sqr_radius * p[0] / Reynolds +
243 this->mean_pressure;
244 }
245 }
246
247
248
249 template <int dim>
250 void
252 const std::vector<Point<dim>> &points,
253 std::vector<std::vector<Tensor<1, dim>>> &values) const
254 {
255 const unsigned int n = points.size();
256
257 Assert(values.size() == dim + 1,
258 ExcDimensionMismatch(values.size(), dim + 1));
259 for (unsigned int d = 0; d < dim + 1; ++d)
260 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
261
262 for (unsigned int k = 0; k < n; ++k)
263 {
264 const Point<dim> &p = points[k];
265 // x-velocity
266 values[0][k][0] = 0.;
267 for (unsigned int d = 1; d < dim; ++d)
268 values[0][k][d] = -2. * p[d] * inv_sqr_radius;
269 // other velocities
270 for (unsigned int d = 1; d < dim; ++d)
271 values[d][k] = 0.;
272 // pressure
273 values[dim][k][0] = -2 * (dim - 1) * inv_sqr_radius / Reynolds;
274 for (unsigned int d = 1; d < dim; ++d)
275 values[dim][k][d] = 0.;
276 }
277 }
278
279
280
281 template <int dim>
282 void
284 const std::vector<Point<dim>> &points,
285 std::vector<std::vector<double>> &values) const
286 {
287 const unsigned int n = points.size();
288 (void)n;
289 Assert(values.size() == dim + 1,
290 ExcDimensionMismatch(values.size(), dim + 1));
291 for (unsigned int d = 0; d < dim + 1; ++d)
292 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
293
294 for (auto &point_values : values)
295 std::fill(point_values.begin(), point_values.end(), 0.);
296 }
297
298 //----------------------------------------------------------------------//
299
300 template <int dim>
301 StokesCosine<dim>::StokesCosine(const double nu, const double r)
302 : viscosity(nu)
303 , reaction(r)
304 {}
305
306
307
308 template <int dim>
309 void
310 StokesCosine<dim>::set_parameters(const double nu, const double r)
311 {
312 viscosity = nu;
313 reaction = r;
314 }
315
316
317 template <int dim>
318 void
320 const std::vector<Point<dim>> &points,
321 std::vector<std::vector<double>> &values) const
322 {
323 unsigned int n = points.size();
324
325 Assert(values.size() == dim + 1,
326 ExcDimensionMismatch(values.size(), dim + 1));
327 for (unsigned int d = 0; d < dim + 1; ++d)
328 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
329
330 for (unsigned int k = 0; k < n; ++k)
331 {
332 const Point<dim> &p = points[k];
333 const double x = numbers::PI / 2. * p[0];
334 const double y = numbers::PI / 2. * p[1];
335 const double cx = std::cos(x);
336 const double cy = std::cos(y);
337 const double sx = std::sin(x);
338 const double sy = std::sin(y);
339
340 if (dim == 2)
341 {
342 values[0][k] = cx * cx * cy * sy;
343 values[1][k] = -cx * sx * cy * cy;
344 values[2][k] = cx * sx * cy * sy + this->mean_pressure;
345 }
346 else if (dim == 3)
347 {
348 const double z = numbers::PI / 2. * p[2];
349 const double cz = std::cos(z);
350 const double sz = std::sin(z);
351
352 values[0][k] = cx * cx * cy * sy * cz * sz;
353 values[1][k] = cx * sx * cy * cy * cz * sz;
354 values[2][k] = -2. * cx * sx * cy * sy * cz * cz;
355 values[3][k] = cx * sx * cy * sy * cz * sz + this->mean_pressure;
356 }
357 else
358 {
360 }
361 }
362 }
363
364
365
366 template <int dim>
367 void
369 const std::vector<Point<dim>> &points,
370 std::vector<std::vector<Tensor<1, dim>>> &values) const
371 {
372 unsigned int n = points.size();
373
374 Assert(values.size() == dim + 1,
375 ExcDimensionMismatch(values.size(), dim + 1));
376 for (unsigned int d = 0; d < dim + 1; ++d)
377 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
378
379 for (unsigned int k = 0; k < n; ++k)
380 {
381 const Point<dim> &p = points[k];
382 const double x = numbers::PI / 2. * p[0];
383 const double y = numbers::PI / 2. * p[1];
384 const double c2x = std::cos(2 * x);
385 const double c2y = std::cos(2 * y);
386 const double s2x = std::sin(2 * x);
387 const double s2y = std::sin(2 * y);
388 const double cx2 = .5 + .5 * c2x; // cos^2 x
389 const double cy2 = .5 + .5 * c2y; // cos^2 y
390
391 if (dim == 2)
392 {
393 values[0][k][0] = -.25 * numbers::PI * s2x * s2y;
394 values[0][k][1] = .5 * numbers::PI * cx2 * c2y;
395 values[1][k][0] = -.5 * numbers::PI * c2x * cy2;
396 values[1][k][1] = .25 * numbers::PI * s2x * s2y;
397 values[2][k][0] = .25 * numbers::PI * c2x * s2y;
398 values[2][k][1] = .25 * numbers::PI * s2x * c2y;
399 }
400 else if (dim == 3)
401 {
402 const double z = numbers::PI / 2. * p[2];
403 const double c2z = std::cos(2 * z);
404 const double s2z = std::sin(2 * z);
405 const double cz2 = .5 + .5 * c2z; // cos^2 z
406
407 values[0][k][0] = -.125 * numbers::PI * s2x * s2y * s2z;
408 values[0][k][1] = .25 * numbers::PI * cx2 * c2y * s2z;
409 values[0][k][2] = .25 * numbers::PI * cx2 * s2y * c2z;
410
411 values[1][k][0] = .25 * numbers::PI * c2x * cy2 * s2z;
412 values[1][k][1] = -.125 * numbers::PI * s2x * s2y * s2z;
413 values[1][k][2] = .25 * numbers::PI * s2x * cy2 * c2z;
414
415 values[2][k][0] = -.5 * numbers::PI * c2x * s2y * cz2;
416 values[2][k][1] = -.5 * numbers::PI * s2x * c2y * cz2;
417 values[2][k][2] = .25 * numbers::PI * s2x * s2y * s2z;
418
419 values[3][k][0] = .125 * numbers::PI * c2x * s2y * s2z;
420 values[3][k][1] = .125 * numbers::PI * s2x * c2y * s2z;
421 values[3][k][2] = .125 * numbers::PI * s2x * s2y * c2z;
422 }
423 else
424 {
426 }
427 }
428 }
429
430
431
432 template <int dim>
433 void
435 const std::vector<Point<dim>> &points,
436 std::vector<std::vector<double>> &values) const
437 {
438 unsigned int n = points.size();
439
440 Assert(values.size() == dim + 1,
441 ExcDimensionMismatch(values.size(), dim + 1));
442 for (unsigned int d = 0; d < dim + 1; ++d)
443 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
444
445 if (reaction != 0.)
446 {
447 vector_values(points, values);
448 for (unsigned int d = 0; d < dim; ++d)
449 for (double &point_value : values[d])
450 point_value *= -reaction;
451 }
452 else
453 {
454 for (unsigned int d = 0; d < dim; ++d)
455 std::fill(values[d].begin(), values[d].end(), 0.);
456 }
457
458
459 for (unsigned int k = 0; k < n; ++k)
460 {
461 const Point<dim> &p = points[k];
462 const double x = numbers::PI / 2. * p[0];
463 const double y = numbers::PI / 2. * p[1];
464 const double c2x = std::cos(2 * x);
465 const double c2y = std::cos(2 * y);
466 const double s2x = std::sin(2 * x);
467 const double s2y = std::sin(2 * y);
468 const double pi2 = .25 * numbers::PI * numbers::PI;
469
470 if (dim == 2)
471 {
472 values[0][k] += -viscosity * pi2 * (1. + 2. * c2x) * s2y -
473 numbers::PI / 4. * c2x * s2y;
474 values[1][k] += viscosity * pi2 * s2x * (1. + 2. * c2y) -
475 numbers::PI / 4. * s2x * c2y;
476 values[2][k] = 0.;
477 }
478 else if (dim == 3)
479 {
480 const double z = numbers::PI * p[2];
481 const double c2z = std::cos(2 * z);
482 const double s2z = std::sin(2 * z);
483
484 values[0][k] +=
485 -.5 * viscosity * pi2 * (1. + 2. * c2x) * s2y * s2z -
486 numbers::PI / 8. * c2x * s2y * s2z;
487 values[1][k] += .5 * viscosity * pi2 * s2x * (1. + 2. * c2y) * s2z -
488 numbers::PI / 8. * s2x * c2y * s2z;
489 values[2][k] +=
490 -.5 * viscosity * pi2 * s2x * s2y * (1. + 2. * c2z) -
491 numbers::PI / 8. * s2x * s2y * c2z;
492 values[3][k] = 0.;
493 }
494 else
495 {
497 }
498 }
499 }
500
501
502 //----------------------------------------------------------------------//
503
504 const double StokesLSingularity::lambda = 0.54448373678246;
505
507 : omega(3. / 2. * numbers::PI)
508 , coslo(std::cos(lambda * omega))
509 , lp(1. + lambda)
510 , lm(1. - lambda)
511 {}
512
513
514 double
515 StokesLSingularity::Psi(double phi) const
516 {
517 return coslo * (std::sin(lp * phi) / lp - std::sin(lm * phi) / lm) -
518 std::cos(lp * phi) + std::cos(lm * phi);
519 }
520
521
522 double
524 {
525 return coslo * (std::cos(lp * phi) - std::cos(lm * phi)) +
526 lp * std::sin(lp * phi) - lm * std::sin(lm * phi);
527 }
528
529
530 double
532 {
533 return coslo * (lm * std::sin(lm * phi) - lp * std::sin(lp * phi)) +
534 lp * lp * std::cos(lp * phi) - lm * lm * std::cos(lm * phi);
535 }
536
537
538 double
540 {
541 return coslo *
542 (lm * lm * std::cos(lm * phi) - lp * lp * std::cos(lp * phi)) +
543 lm * lm * lm * std::sin(lm * phi) -
544 lp * lp * lp * std::sin(lp * phi);
545 }
546
547
548 double
550 {
551 return coslo * (lp * lp * lp * std::sin(lp * phi) -
552 lm * lm * lm * std::sin(lm * phi)) +
553 lm * lm * lm * lm * std::cos(lm * phi) -
554 lp * lp * lp * lp * std::cos(lp * phi);
555 }
556
557
558 void
560 const std::vector<Point<2>> &points,
561 std::vector<std::vector<double>> &values) const
562 {
563 unsigned int n = points.size();
564
565 Assert(values.size() == 2 + 1, ExcDimensionMismatch(values.size(), 2 + 1));
566 for (unsigned int d = 0; d < 2 + 1; ++d)
567 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
568
569 for (unsigned int k = 0; k < n; ++k)
570 {
571 const Point<2> &p = points[k];
572 const double x = p[0];
573 const double y = p[1];
574
575 if ((x < 0) || (y < 0))
576 {
577 const double phi = std::atan2(y, -x) + numbers::PI;
578 const double r2 = x * x + y * y;
579 const double rl = std::pow(r2, lambda / 2.);
580 const double rl1 = std::pow(r2, lambda / 2. - .5);
581 values[0][k] =
582 rl * (lp * std::sin(phi) * Psi(phi) + std::cos(phi) * Psi_1(phi));
583 values[1][k] =
584 rl * (lp * std::cos(phi) * Psi(phi) - std::sin(phi) * Psi_1(phi));
585 values[2][k] = -rl1 * (lp * lp * Psi_1(phi) + Psi_3(phi)) / lm +
586 this->mean_pressure;
587 }
588 else
589 {
590 for (unsigned int d = 0; d < 3; ++d)
591 values[d][k] = 0.;
592 }
593 }
594 }
595
596
597
598 void
600 const std::vector<Point<2>> &points,
601 std::vector<std::vector<Tensor<1, 2>>> &values) const
602 {
603 unsigned int n = points.size();
604
605 Assert(values.size() == 2 + 1, ExcDimensionMismatch(values.size(), 2 + 1));
606 for (unsigned int d = 0; d < 2 + 1; ++d)
607 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
608
609 for (unsigned int k = 0; k < n; ++k)
610 {
611 const Point<2> &p = points[k];
612 const double x = p[0];
613 const double y = p[1];
614
615 if ((x < 0) || (y < 0))
616 {
617 const double phi = std::atan2(y, -x) + numbers::PI;
618 const double r2 = x * x + y * y;
619 const double r = std::sqrt(r2);
620 const double rl = std::pow(r2, lambda / 2.);
621 const double rl1 = std::pow(r2, lambda / 2. - .5);
622 const double rl2 = std::pow(r2, lambda / 2. - 1.);
623 const double psi = Psi(phi);
624 const double psi1 = Psi_1(phi);
625 const double psi2 = Psi_2(phi);
626 const double cosp = std::cos(phi);
627 const double sinp = std::sin(phi);
628
629 // Derivatives of u with respect to r, phi
630 const double udr = lambda * rl1 * (lp * sinp * psi + cosp * psi1);
631 const double udp = rl * (lp * cosp * psi + lp * sinp * psi1 -
632 sinp * psi1 + cosp * psi2);
633 // Derivatives of v with respect to r, phi
634 const double vdr = lambda * rl1 * (lp * cosp * psi - sinp * psi1);
635 const double vdp = rl * (lp * (cosp * psi1 - sinp * psi) -
636 cosp * psi1 - sinp * psi2);
637 // Derivatives of p with respect to r, phi
638 const double pdr =
639 -(lambda - 1.) * rl2 * (lp * lp * psi1 + Psi_3(phi)) / lm;
640 const double pdp = -rl1 * (lp * lp * psi2 + Psi_4(phi)) / lm;
641 values[0][k][0] = cosp * udr - sinp / r * udp;
642 values[0][k][1] = -sinp * udr - cosp / r * udp;
643 values[1][k][0] = cosp * vdr - sinp / r * vdp;
644 values[1][k][1] = -sinp * vdr - cosp / r * vdp;
645 values[2][k][0] = cosp * pdr - sinp / r * pdp;
646 values[2][k][1] = -sinp * pdr - cosp / r * pdp;
647 }
648 else
649 {
650 for (unsigned int d = 0; d < 3; ++d)
651 values[d][k] = 0.;
652 }
653 }
654 }
655
656
657
658 void
660 const std::vector<Point<2>> &points,
661 std::vector<std::vector<double>> &values) const
662 {
663 unsigned int n = points.size();
664 (void)n;
665 Assert(values.size() == 2 + 1, ExcDimensionMismatch(values.size(), 2 + 1));
666 for (unsigned int d = 0; d < 2 + 1; ++d)
667 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
668
669 for (auto &point_values : values)
670 std::fill(point_values.begin(), point_values.end(), 0.);
671 }
672
673
674 //----------------------------------------------------------------------//
675
676 Kovasznay::Kovasznay(double Re, bool stokes)
677 : Reynolds(Re)
678 , stokes(stokes)
679 {
680 long double r2 = Reynolds / 2.;
681 long double b = 4 * numbers::PI * numbers::PI;
682 long double l = -b / (r2 + std::sqrt(r2 * r2 + b));
683 lbda = l;
684 // mean pressure for a domain
685 // spreading from -.5 to 1.5 in
686 // x-direction
687 p_average = 1 / (8 * l) * (std::exp(3. * l) - std::exp(-l));
688 }
689
690
691
692 void
693 Kovasznay::vector_values(const std::vector<Point<2>> &points,
694 std::vector<std::vector<double>> &values) const
695 {
696 unsigned int n = points.size();
697
698 Assert(values.size() == 2 + 1, ExcDimensionMismatch(values.size(), 2 + 1));
699 for (unsigned int d = 0; d < 2 + 1; ++d)
700 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
701
702 for (unsigned int k = 0; k < n; ++k)
703 {
704 const Point<2> &p = points[k];
705 const double x = p[0];
706 const double y = 2. * numbers::PI * p[1];
707 const double elx = std::exp(lbda * x);
708
709 values[0][k] = 1. - elx * std::cos(y);
710 values[1][k] = .5 / numbers::PI * lbda * elx * std::sin(y);
711 values[2][k] = -.5 * elx * elx + p_average + this->mean_pressure;
712 }
713 }
714
715
716 void
718 const std::vector<Point<2>> &points,
719 std::vector<std::vector<Tensor<1, 2>>> &gradients) const
720 {
721 unsigned int n = points.size();
722
723 Assert(gradients.size() == 3, ExcDimensionMismatch(gradients.size(), 3));
724 Assert(gradients[0].size() == n,
725 ExcDimensionMismatch(gradients[0].size(), n));
726
727 for (unsigned int i = 0; i < n; ++i)
728 {
729 const double x = points[i][0];
730 const double y = points[i][1];
731
732 const double elx = std::exp(lbda * x);
733 const double cy = std::cos(2 * numbers::PI * y);
734 const double sy = std::sin(2 * numbers::PI * y);
735
736 // u
737 gradients[0][i][0] = -lbda * elx * cy;
738 gradients[0][i][1] = 2. * numbers::PI * elx * sy;
739 gradients[1][i][0] = lbda * lbda / (2 * numbers::PI) * elx * sy;
740 gradients[1][i][1] = lbda * elx * cy;
741 // p
742 gradients[2][i][0] = -lbda * elx * elx;
743 gradients[2][i][1] = 0.;
744 }
745 }
746
747
748
749 void
750 Kovasznay::vector_laplacians(const std::vector<Point<2>> &points,
751 std::vector<std::vector<double>> &values) const
752 {
753 unsigned int n = points.size();
754 Assert(values.size() == 2 + 1, ExcDimensionMismatch(values.size(), 2 + 1));
755 for (unsigned int d = 0; d < 2 + 1; ++d)
756 Assert(values[d].size() == n, ExcDimensionMismatch(values[d].size(), n));
757
758 if (stokes)
759 {
760 const double zp = 2. * numbers::PI;
761 for (unsigned int k = 0; k < n; ++k)
762 {
763 const Point<2> &p = points[k];
764 const double x = p[0];
765 const double y = zp * p[1];
766 const double elx = std::exp(lbda * x);
767 const double u = 1. - elx * std::cos(y);
768 const double ux = -lbda * elx * std::cos(y);
769 const double uy = elx * zp * std::sin(y);
770 const double v = lbda / zp * elx * std::sin(y);
771 const double vx = lbda * lbda / zp * elx * std::sin(y);
772 const double vy = zp * lbda / zp * elx * std::cos(y);
773
774 values[0][k] = u * ux + v * uy;
775 values[1][k] = u * vx + v * vy;
776 values[2][k] = 0.;
777 }
778 }
779 else
780 {
781 for (auto &point_values : values)
782 std::fill(point_values.begin(), point_values.end(), 0.);
783 }
784 }
785
786 double
788 {
789 return lbda;
790 }
791
792
793
794 template class FlowFunction<2>;
795 template class FlowFunction<3>;
796 template class PoisseuilleFlow<2>;
797 template class PoisseuilleFlow<3>;
798 template class StokesCosine<2>;
799 template class StokesCosine<3>;
800} // namespace Functions
801
802
803
*  *  iterator begin()
virtual void vector_value_list(const std::vector< Point< dim > > &points, std::vector< Vector< double > > &values) const override
void pressure_adjustment(double p)
virtual void vector_gradient_list(const std::vector< Point< dim > > &points, std::vector< std::vector< Tensor< 1, dim > > > &gradients) const override
virtual void vector_laplacian_list(const std::vector< Point< dim > > &points, std::vector< Vector< double > > &values) const override
virtual std::size_t memory_consumption() const override
virtual void vector_value(const Point< dim > &points, Vector< double > &value) const override
virtual double value(const Point< dim > &points, const unsigned int component) const override
Kovasznay(const double Re, bool Stokes=false)
virtual void vector_values(const std::vector< Point< 2 > > &points, std::vector< std::vector< double > > &values) const override
virtual void vector_gradients(const std::vector< Point< 2 > > &points, std::vector< std::vector< Tensor< 1, 2 > > > &gradients) const override
virtual void vector_laplacians(const std::vector< Point< 2 > > &points, std::vector< std::vector< double > > &values) const override
double lambda() const
The value of lambda.
PoisseuilleFlow(const double r, const double Re)
virtual void vector_gradients(const std::vector< Point< dim > > &points, std::vector< std::vector< Tensor< 1, dim > > > &gradients) const override
virtual void vector_values(const std::vector< Point< dim > > &points, std::vector< std::vector< double > > &values) const override
virtual void vector_laplacians(const std::vector< Point< dim > > &points, std::vector< std::vector< double > > &values) const override
virtual void vector_values(const std::vector< Point< dim > > &points, std::vector< std::vector< double > > &values) const override
StokesCosine(const double viscosity=1., const double reaction=0.)
void set_parameters(const double viscosity, const double reaction)
virtual void vector_gradients(const std::vector< Point< dim > > &points, std::vector< std::vector< Tensor< 1, dim > > > &gradients) const override
virtual void vector_laplacians(const std::vector< Point< dim > > &points, std::vector< std::vector< double > > &values) const override
virtual void vector_gradients(const std::vector< Point< 2 > > &points, std::vector< std::vector< Tensor< 1, 2 > > > &gradients) const override
virtual void vector_values(const std::vector< Point< 2 > > &points, std::vector< std::vector< double > > &values) const override
double Psi_1(double phi) const
The derivative of Psi()
double Psi(double phi) const
The auxiliary function Psi.
const double lp
Auxiliary variable 1+lambda.
const double lm
Auxiliary variable 1-lambda.
virtual void vector_laplacians(const std::vector< Point< 2 > > &points, std::vector< std::vector< double > > &values) const override
double Psi_3(double phi) const
The 3rd derivative of Psi()
StokesLSingularity()
Constructor setting up some data.
double Psi_4(double phi) const
The 4th derivative of Psi()
double Psi_2(double phi) const
The 2nd derivative of Psi()
const double coslo
Cosine of lambda times omega.
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
std::size_t size
Definition mpi.cc:733
constexpr double PI
Definition numbers.h:240
STL namespace.
::VectorizedArray< Number, width > exp(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)