MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
spacing.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#include "spacing.hpp"
13
14namespace mfem
15{
16
17std::unique_ptr<SpacingFunction> GetSpacingFunction(const SpacingType
18 spacingType,
19 Array<int> const& ipar,
20 Vector const& dpar)
21{
22 Array<int> iparsub, relN;
23
24 switch (spacingType)
25 {
27 MFEM_VERIFY(ipar.Size() == 1 &&
28 dpar.Size() == 0, "Invalid spacing function parameters");
29 return std::unique_ptr<SpacingFunction>(
30 new UniformSpacingFunction(ipar[0]));
32 MFEM_VERIFY(ipar.Size() == 3 &&
33 dpar.Size() == 1, "Invalid spacing function parameters");
34 return std::unique_ptr<SpacingFunction>(
35 new LinearSpacingFunction(ipar[0], (bool) ipar[1], dpar[0],
36 (bool) ipar[2]));
38 MFEM_VERIFY(ipar.Size() == 3 &&
39 dpar.Size() == 1, "Invalid spacing function parameters");
40 return std::unique_ptr<SpacingFunction>(
41 new GeometricSpacingFunction(ipar[0], (bool) ipar[1],
42 dpar[0], (bool) ipar[2]));
44 MFEM_VERIFY(ipar.Size() == 3 &&
45 dpar.Size() == 2, "Invalid spacing function parameters");
46 return std::unique_ptr<SpacingFunction>(
47 new BellSpacingFunction(ipar[0], (bool) ipar[1], dpar[0],
48 dpar[1], (bool) ipar[2]));
50 MFEM_VERIFY(ipar.Size() == 3 &&
51 dpar.Size() == 2, "Invalid spacing function parameters");
52 return std::unique_ptr<SpacingFunction>(
53 new GaussianSpacingFunction(ipar[0], (bool) ipar[1], dpar[0],
54 dpar[1], (bool) ipar[2]));
56 MFEM_VERIFY(ipar.Size() == 3 &&
57 dpar.Size() == 1, "Invalid spacing function parameters");
58 return std::unique_ptr<SpacingFunction>(
59 new LogarithmicSpacingFunction(ipar[0], (bool) ipar[1],
60 (bool) ipar[2], dpar[0]));
62 MFEM_VERIFY(ipar.Size() >= 3, "Invalid spacing function parameters");
63 ipar.GetSubArray(3, ipar[1], relN);
64 ipar.GetSubArray(3 + ipar[1], ipar.Size() - 3 - ipar[1], iparsub);
65 return std::unique_ptr<SpacingFunction>(
66 new PiecewiseSpacingFunction(ipar[0], ipar[1],
67 (bool) ipar[2], relN, iparsub,
68 dpar));
70 MFEM_VERIFY(ipar.Size() >= 8, "Invalid spacing function parameters");
71 ipar.GetSubArray(8, ipar.Size() - 8, iparsub);
72 return std::unique_ptr<SpacingFunction>(
73 new PartialSpacingFunction(ipar[0], ipar[1], ipar[2],
74 ipar[3], ipar[4], iparsub,
75 dpar, (SpacingType) ipar[5]));
76 default:
77 MFEM_ABORT("Unknown spacing type \"" << int(spacingType) << "\"");
78 break;
79 }
80
81 MFEM_ABORT("Unknown spacing type");
82 return std::unique_ptr<SpacingFunction>(nullptr);
83}
84
85std::unique_ptr<SpacingFunction> SpacingFunction::Clone() const
86{
87 MFEM_ABORT("Base class SpacingFunction should not be cloned");
88 return std::unique_ptr<SpacingFunction>(nullptr);
89}
90
91void GeometricSpacingFunction::CalculateSpacing()
92{
93 // GeometricSpacingFunction requires more than 1 interval. If only 1
94 // interval is requested, just use uniform spacing.
95 if (n == 1) { return; }
96
97 // Find the root of g(r) = s * (r^n - 1) - r + 1 by Newton's method.
98
99 constexpr real_t convTol = 1.0e-8;
100 constexpr int maxIter = 100;
101
102 const real_t s_unif = 1.0 / ((real_t) n);
103
104 r = s < s_unif ? 1.5 : 0.5; // Initial guess
105
106 bool converged = false;
107 for (int iter=0; iter<maxIter; ++iter)
108 {
109 const real_t g = (s * (std::pow(r,n) - 1.0)) - r + 1.0;
110 const real_t dg = (n * s * std::pow(r,n-1)) - 1.0;
111 r -= g / dg;
112
113 if (std::abs(g / dg) < convTol)
114 {
115 converged = true;
116 break;
117 }
118 }
119
120 MFEM_VERIFY(converged, "Convergence failure in GeometricSpacingFunction");
121}
122
123void BellSpacingFunction::CalculateSpacing()
124{
125 s.SetSize(n);
126
127 // Bell spacing requires at least 3 intervals. If fewer than 3 are
128 // requested, we simply use uniform spacing.
129 if (n < 3)
130 {
131 s = 1.0 / ((real_t) n);
132 return;
133 }
134
135 MFEM_VERIFY(s0 + s1 < 1.0, "Sum of first and last Bell spacings must be"
136 << " less than 1");
137
138 s[0] = s0;
139 s[n-1] = s1;
140
141 // If there are only 3 intervals, the calculation is linear and trivial.
142 if (n == 3)
143 {
144 s[1] = 1.0 - s0 - s1;
145 return;
146 }
147
148 // For more than 3 intervals, solve a system iteratively.
149 real_t urk = 1.0;
150
151 // Initialize unknown entries of s.
152 real_t initialGuess = (1.0 - s0 - s1) / ((real_t) (n - 2));
153 for (int i=1; i<n-1; ++i)
154 {
155 s[i] = initialGuess;
156 }
157
158 Vector wk(7);
159 wk = 0.0;
160
161 Vector s_new(n);
162
163 Vector a(n+2);
164 Vector b(n+2);
165 Vector alpha(n+2);
166 Vector beta(n+2);
167 Vector gamma(n+2);
168
169 a = 0.5;
170 a[0] = 0.0;
171 a[1] = 0.0;
172
173 b = a;
174
175 alpha = 0.0;
176 beta = 0.0;
177 gamma = 0.0;
178
179 gamma[1] = s0;
180
181 constexpr int maxIter = 100;
182 constexpr real_t convTol = 1.0e-10;
183 bool converged = false;
184 for (int iter=0; iter<maxIter; ++iter)
185 {
186 int j;
187 for (j = 1; j <= n - 3; j++)
188 {
189 wk[0] = (s[j] + s[j+1]) * (s[j] + s[j+1]);
190 wk[1] = s[j-1];
191 wk[2] = (s[j-1] + s[j]) * (s[j-1] + s[j]) * (s[j-1] + s[j]);
192 wk[3] = s[j + 2];
193 wk[4] = (s[j+2] + s[j+1]) * (s[j+2] + s[j+1]) * (s[j+2] + s[j+1]);
194 wk[5] = wk[0] * wk[1] / wk[2];
195 wk[6] = wk[0] * wk[3] / wk[4];
196 a[j+1] = a[j+1] + urk*(wk[5] - a[j+1]);
197 b[j+1] = b[j+1] + urk*(wk[6] - b[j+1]);
198 }
199
200 for (j = 2; j <= n - 2; j++)
201 {
202 wk[0] = a[j]*(1.0 - 2.0*alpha[j - 1] + alpha[j - 1]*alpha[j - 2]
203 + beta[j - 2]) + b[j] + 2.0 - alpha[j - 1];
204 wk[1] = 1.0 / wk[0];
205 alpha[j] = wk[1]*(a[j]*beta[j - 1]*(2.0 - alpha[j - 2]) +
206 2.0*b[j] + beta[j - 1] + 1.0);
207 beta[j] = -b[j]*wk[1];
208 gamma[j] = wk[1]*(a[j]*(2.0*gamma[j - 1] - gamma[j - 2] -
209 alpha[j - 2]*gamma[j - 1]) + gamma[j - 1]);
210 }
211
212 s_new[0] = s[0];
213 for (j=1; j<n; ++j)
214 {
215 s_new[j] = s_new[j-1] + s[j];
216 }
217
218 for (j = n - 3; j >= 1; j--)
219 {
220 s_new[j] = alpha[j+1]*s_new[j + 1] +
221 beta[j+1]*s_new[j + 2] + gamma[j+1];
222 }
223
224 // Convert back from points to spacings
225 for (j=n-1; j>0; --j)
226 {
227 s_new[j] = s_new[j] - s_new[j-1];
228 }
229
230 wk[5] = wk[6] = 0.0;
231 for (j = n - 2; j >= 2; j--)
232 {
233 wk[5] = wk[5] + s_new[j]*s_new[j];
234 wk[6] = wk[6] + pow(s_new[j] - s[j], 2);
235 }
236
237 s = s_new;
238
239 const real_t res = sqrt(wk[6] / wk[5]);
240 if (res < convTol)
241 {
242 converged = true;
243 break;
244 }
245 }
246
247 MFEM_VERIFY(converged, "Convergence failure in BellSpacingFunction");
248}
249
250void GaussianSpacingFunction::CalculateSpacing()
251{
252 s.SetSize(n);
253 // Gaussian spacing requires at least 3 intervals. If fewer than 3 are
254 // requested, we simply use uniform spacing.
255 if (n < 3)
256 {
257 s = 1.0 / ((real_t) n);
258 return;
259 }
260
261 s[0] = s0;
262 s[n-1] = s1;
263
264 // If there are only 3 intervals, the calculation is linear and trivial.
265 if (n == 3)
266 {
267 s[1] = 1.0 - s0 - s1;
268 return;
269 }
270
271 // For more than 3 intervals, solve a system iteratively.
272
273 const real_t lnz01 = log(s0 / s1);
274
275 const real_t h = 1.0 / ((real_t) n-1);
276
277 // Determine concavity by first determining linear spacing and comparing
278 // the total spacing to 1.
279 // Linear formula: z_i = z0 + (i*h) * (z1-z0), 0 <= i <= n-1
280 // \sum_{i=0}^{nzones-1} z_i = n * z0 + h * (z1-z0) * nz * (nz-1) / 2
281
282 const real_t slinear = n * (s0 + (h * (s1 - s0) * 0.5 * (n-1)));
283
284 MFEM_VERIFY(std::abs(slinear - 1.0) > 1.0e-8, "Bell distribution is too "
285 << "close to linear.");
286
287 const real_t u = slinear < 1.0 ? 1.0 : -1.0;
288
289 real_t c = 0.3; // Initial guess
290
291 // Newton iterations
292 constexpr int maxIter = 10;
293 constexpr real_t convTol = 1.0e-8;
294 bool converged = false;
295 for (int iter=0; iter<maxIter; ++iter)
296 {
297 const real_t c2 = c * c;
298
299 const real_t m = 0.5 * (1.0 - (u * c2 * lnz01));
300 const real_t dmdc = -u * c * lnz01;
301
302 real_t r = 0.0; // Residual
303 real_t drdc = 0.0; // Derivative of residual
304
305 for (int i=0; i<n; ++i)
306 {
307 const real_t x = i * h;
308 const real_t ti = exp((-(x * x) + (2.0 * x * m)) * u / c2); // Gaussian
309 r += ti;
310
311 // Derivative of Gaussian
312 drdc += ((-2.0 * (-(x * x) + (2.0 * x * m)) / (c2 * c)) +
313 ((2.0 * x * dmdc) / c2)) * ti;
314 }
315
316 r *= s0;
317 r -= 1.0; // Sum of spacings should equal 1.
318
319 if (std::abs(r) < convTol)
320 {
321 converged = true;
322 break;
323 }
324
325 drdc *= s0 * u;
326
327 // Newton update is -r / drdc, limited by factors of 1/2 and 2.
328 real_t dc = std::max(-r / drdc, (real_t) -0.5*c);
329 dc = std::min(dc, (real_t) 2.0*c);
330
331 c += dc;
332 }
333
334 MFEM_VERIFY(converged, "Convergence failure in GaussianSpacingFunction");
335
336 const real_t c2 = c * c;
337 const real_t m = 0.5 * (1.0 - (u * c2 * lnz01));
338 const real_t q = s0 * exp(u*m*m / c2);
339
340 for (int i=0; i<n; ++i)
341 {
342 const real_t x = (i * h) - m;
343 s[i] = q * exp(-u*x*x / c2);
344 }
345}
346
347void LogarithmicSpacingFunction::CalculateSpacing()
348{
349 MFEM_VERIFY(n > 0 && logBase > 1.0,
350 "Invalid parameters in LogarithmicSpacingFunction");
351
352 if (sym) { CalculateSymmetric(); }
353 else { CalculateNonsymmetric(); }
354}
355
356void LogarithmicSpacingFunction::CalculateSymmetric()
357{
358 s.SetSize(n);
359
360 const bool odd = (n % 2 == 1);
361
362 const int M0 = n / 2;
363 const int M = odd ? (M0 + 1) : M0;
364
365 const real_t h = 1.0 / ((real_t) M);
366
367 real_t p = 1.0; // Initialize at right endpoint of [0,1].
368
369 for (int i=M-2; i>=0; --i)
370 {
371 const real_t p_i = (pow(logBase, (i+1)*h) - 1.0) / (logBase - 1.0);
372 s[i+1] = p - p_i;
373 p = p_i;
374 }
375
376 s[0] = p;
377
378 // Even case for spacing: [s[0], ..., s[M-1], s[M-1], s[M-2], ..., s[0]]
379 // covers interval [0,2]
380 // Odd case for spacing: [s[0], ..., s[M-1], s[M-2], ..., s[0]]
381 // covers interval [0,2-s[M-1]]
382
383 const real_t t = odd ? 1.0 / (2.0 - s[M-1]) : 0.5;
384
385 for (int i=0; i<M; ++i)
386 {
387 s[i] *= t;
388
389 if (i < (M-1) || !odd)
390 {
391 s[n - i - 1] = s[i];
392 }
393 }
394}
395
396void LogarithmicSpacingFunction::CalculateNonsymmetric()
397{
398 s.SetSize(n);
399
400 const real_t h = 1.0 / ((real_t) n);
401
402 real_t p = 1.0; // Initialize at right endpoint of [0,1].
403
404 for (int i=n-2; i>=0; --i)
405 {
406 const real_t p_i = (pow(logBase, (i+1)*h) - 1.0) / (logBase - 1.0);
407 s[i+1] = p - p_i;
408 p = p_i;
409 }
410
411 s[0] = p;
412}
413
415 Vector const& dpar)
416{
417 MFEM_VERIFY(partition.Size() == np - 1, "");
418 bool validPartition = true;
419
420 // Verify that partition has ascending numbers in (0,1).
421 for (int i=0; i<np-1; ++i)
422 {
423 partition[i] = dpar[i];
424
425 if (partition[i] <= 0.0 || partition[i] >= 1.0)
426 {
427 validPartition = false;
428 }
429
430 if (i > 0 && partition[i] <= partition[i-1])
431 {
432 validPartition = false;
433 }
434 }
435
436 MFEM_VERIFY(validPartition, "");
437
438 pieces.resize(np);
439
440 Array<int> ipar_p;
441 Vector dpar_p;
442
443 int osi = 0;
444 int osd = np - 1;
445 int n_total = 0;
446 for (int p=0; p<np; ++p)
447 {
448 // Setup piece p
449 const SpacingType type = (SpacingType) ipar[osi];
450 const int numIntParam = ipar[osi+1];
451 const int numDoubleParam = ipar[osi+2];
452
453 ipar_p.SetSize(numIntParam);
454 dpar_p.SetSize(numDoubleParam);
455
456 for (int i=0; i<numIntParam; ++i)
457 {
458 ipar_p[i] = ipar[osi + 3 + i];
459 }
460
461 for (int i=0; i<numDoubleParam; ++i)
462 {
463 dpar_p[i] = dpar[osd + i];
464 }
465
466 pieces[p] = GetSpacingFunction(type, ipar_p, dpar_p);
467
468 osi += 3 + numIntParam;
469 osd += numDoubleParam;
470 n_total += npartition[p];
471
472 MFEM_VERIFY(pieces[p]->Size() >= 1, "");
473 }
474
475 MFEM_VERIFY(osi == ipar.Size() && osd == dpar.Size(), "");
476 n0 = n_total;
477}
478
480{
481 for (auto &p : pieces) { p->ScaleParameters(a); }
482}
483
484void PiecewiseSpacingFunction::Print(std::ostream &os) const
485{
486 // SpacingType numIntParam numDoubleParam npartition {int params} {double params}
487 int inum = 3 + np;
488 int dnum = np-1;
489 for (auto& p : pieces)
490 {
491 // Add three for the type and the integer and double parameter counts.
492 inum += p->NumIntParameters() + 3;
493 dnum += p->NumDoubleParameters();
494 }
495
496 os << int(SpacingType::PIECEWISE) << " " << inum << " " << dnum << " "
497 << n << " " << np << " " << (int) reverse << "\n";
498
499 for (auto n : npartition)
500 {
501 os << n << " ";
502 }
503
504 // Write integer parameters for all pieces.
505 Array<int> ipar;
506 for (auto& p : pieces)
507 {
508 MFEM_VERIFY(p->GetSpacingType() != SpacingType::PIECEWISE,
509 "Piecewise spacings should not be composed");
510 os << "\n" << int(p->GetSpacingType()) << " " << p->NumIntParameters()
511 << " " << p->NumDoubleParameters();
512
513 p->GetIntParameters(ipar);
514
515 for (auto& ip : ipar)
516 {
517 os << " " << ip;
518 }
519 }
520
521 os << "\n";
522 for (auto p : partition)
523 {
524 os << p << " ";
525 }
526
527 // Write double parameters for all pieces.
528 Vector dpar;
529 for (auto& p : pieces)
530 {
531 p->GetDoubleParameters(dpar);
532
533 if (dpar.Size() > 0)
534 {
535 os << "\n";
536 for (auto dp : dpar)
537 {
538 os << dp << " ";
539 }
540 }
541 }
542
543 os << "\n";
544}
545
546void PiecewiseSpacingFunction::CalculateSpacing()
547{
548 MFEM_VERIFY(n >= 1 && (n % n0 == 0 || n < n0), "");
549 const int ref = n / n0; // Refinement factor
550 const int cf = n0 / n; // Coarsening factor
551
552 s.SetSize(n);
553
554 bool coarsen = cf > 1 && n > 1;
555 // If coarsening, check whether all pieces have size divisible by cf.
556 if (coarsen)
557 {
558 for (int p=0; p<np; ++p)
559 {
560 const int csize = pieces[p]->Size() / cf;
561 if (pieces[p]->Size() != cf * csize)
562 {
563 coarsen = false;
564 }
565 }
566 }
567
568 if (n == 1)
569 {
570 s[0] = 1.0;
571 for (auto& p : pieces) { p->SetSize(1); }
572 return;
573 }
574
575 MFEM_VERIFY(coarsen || n >= n0,
576 "Invalid case in PiecewiseSpacingFunction::CalculateSpacing");
577
578 int n_total = 0;
579 for (int p=0; p<np; ++p)
580 {
581 // Calculate spacing for piece p.
582
583 if (coarsen)
584 {
585 pieces[p]->SetSize(npartition[p] / cf);
586 }
587 else
588 {
589 pieces[p]->SetSize(ref * npartition[p]);
590 }
591
592 const real_t p0 = (p == 0) ? 0.0 : partition[p-1];
593 const real_t p1 = (p == np - 1) ? 1.0 : partition[p];
594 const real_t h_p = p1 - p0;
595
596 for (int i=0; i<pieces[p]->Size(); ++i)
597 {
598 s[n_total + i] = h_p * pieces[p]->Eval(i);
599 }
600
601 n_total += pieces[p]->Size();
602 }
603
604 MFEM_VERIFY(n_total == n, "");
605}
606
608{
609 for (const auto &p : pieces)
610 {
611 if (!p->Nested())
612 {
613 return false;
614 }
615 }
616
617 return true;
618}
619
621 Array<int> const& ipar,
622 Vector const& dpar)
623{
624 fullSpacing = GetSpacingFunction(typeFull, ipar, dpar);
625}
626
627void PartialSpacingFunction::CalculateSpacing()
628{
629 s.SetSize(n);
630
631 if (n == 1)
632 {
633 s[0] = 1.0;
634 fullSpacing->SetSize(1);
635 return;
636 }
637
638 const int ref = n / num_elems;
639 MFEM_VERIFY(ref * num_elems == n, "Invalid number of elements");
640
641 fullSpacing->SetSize(ref * num_elems_full);
642
643 const int os = ref * first_elem;
644 for (int i = 0; i < n; ++i)
645 {
646 s[i] = fullSpacing->Eval(os + i);
647 }
648
649 // Normalize
650 const double d1 = s.Sum();
651 for (int i = 0; i < n; ++i)
652 {
653 s[i] /= d1;
654 }
655}
656
658{
659 fullSpacing->ScaleParameters(a);
660}
661
662void PartialSpacingFunction::Print(std::ostream &os) const
663{
664 os << int(SpacingType::PARTIAL) << " " << NumIntParameters() << " "
665 << NumDoubleParameters() << " " << n << " " << (int) reverse << "\n"
666 << first_elem << " " << num_elems << " " << num_elems_full << "\n";
667
668 // Write integer parameters for the full spacing.
669 Array<int> ipar;
670 os << int(fullSpacing->GetSpacingType()) << " "
671 << fullSpacing->NumIntParameters() << " "
672 << fullSpacing->NumDoubleParameters();
673
674 fullSpacing->GetIntParameters(ipar);
675
676 for (auto& ip : ipar)
677 {
678 os << " " << ip;
679 }
680
681 os << "\n";
682
683 // Write double parameters for the full spacing.
684 Vector dpar;
685 fullSpacing->GetDoubleParameters(dpar);
686
687 if (dpar.Size() > 0)
688 {
689 for (auto dp : dpar)
690 {
691 os << dp << " ";
692 }
693 }
694
695 os << "\n";
696}
697
698} // namespace mfem
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:840
int Size() const
Return the logical size of the array.
Definition array.hpp:166
Bell spacing function, which produces spacing resembling a Bell curve.
Definition spacing.hpp:368
Gaussian spacing function of the general form g(x) = a exp(-(x-m)^2 / c^2) for some scalar parameters...
Definition spacing.hpp:459
Geometric spacing function.
Definition spacing.hpp:287
Linear spacing function, defining the width of interval i as s + i * d.
Definition spacing.hpp:191
Logarithmic spacing function, uniform in log base 10 by default.
Definition spacing.hpp:547
Partial spacing function, defined as part of an existing spacing function.
Definition spacing.hpp:791
void Print(std::ostream &os) const override
Prints all the data necessary to define the spacing function and its current state (size and other pa...
Definition spacing.cpp:662
void SetupFull(SpacingType typeFull, Array< int > const &ipar, Vector const &dpar)
Definition spacing.cpp:620
int NumDoubleParameters() const override
Returns the number of double parameters defining the spacing function.
Definition spacing.hpp:848
int NumIntParameters() const override
Returns the number of integer parameters defining the spacing function.
Definition spacing.hpp:847
void ScaleParameters(real_t a) override
Scales parameters by the factor a associated with Size().
Definition spacing.cpp:657
Piecewise spacing function, with spacing functions defining spacing within arbitarily many fixed subi...
Definition spacing.hpp:628
void ScaleParameters(real_t a) override
Scales parameters by the factor a associated with Size().
Definition spacing.cpp:479
void Print(std::ostream &os) const override
Prints all the data necessary to define the spacing function and its current state (size and other pa...
Definition spacing.cpp:484
bool Nested() const override
Returns true if the spacing function is nested during refinement.
Definition spacing.cpp:607
void SetupPieces(Array< int > const &ipar, Vector const &dpar)
Definition spacing.cpp:414
int Size() const
Returns the size, or number of intervals (elements).
Definition spacing.hpp:42
virtual std::unique_ptr< SpacingFunction > Clone() const
Returns a clone (deep-copy) of this spacing function.
Definition spacing.cpp:85
bool reverse
Whether to reverse the spacing.
Definition spacing.hpp:115
int n
Size, or number of intervals (elements)
Definition spacing.hpp:114
Uniform spacing function, dividing the unit interval into Size() equally spaced intervals (elements).
Definition spacing.hpp:124
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
real_t Sum() const
Return the sum of the vector entries.
Definition vector.cpp:1246
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
const real_t alpha
Definition ex15.cpp:369
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
mfem::real_t real_t
MFEM_HOST_DEVICE dual< value_type, gradient_type > log(dual< value_type, gradient_type > a)
implementation of the natural logarithm function for dual numbers
Definition dual.hpp:366
MFEM_HOST_DEVICE dual< value_type, gradient_type > sqrt(dual< value_type, gradient_type > x)
implementation of square root for dual numbers
Definition dual.hpp:288
MFEM_HOST_DEVICE dual< value_type, gradient_type > pow(dual< value_type, gradient_type > a, dual< value_type, gradient_type > b)
implementation of a (dual) raised to the b (dual) power
Definition dual.hpp:374
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
std::unique_ptr< SpacingFunction > GetSpacingFunction(const SpacingType spacingType, Array< int > const &ipar, Vector const &dpar)
Returns a new SpacingFunction instance defined by the type and parameters.
Definition spacing.cpp:17
SpacingType
Definition spacing.hpp:23
float real_t
Definition config.hpp:46
real_t p(const Vector &x, real_t t)
MFEM_HOST_DEVICE Complex exp(const Complex &q)