MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
bounds.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// Implementation of bounds
13
14#include "bounds.hpp"
15
16#include <limits>
17#include <cstring>
18#include <string>
19#include <cmath>
20#include <iostream>
21#include <algorithm>
22
23namespace mfem
24{
25
26using namespace std;
27
28void PLBound::Setup(const int nb_i, const int ncp_i,
29 const int b_type_i, const int cp_type_i,
30 const real_t tol_i)
31{
32 MFEM_VERIFY(b_type_i >= 0 && b_type_i <= 2, "Bases not supported. "
33 "Please read class description to see supported types.");
34 MFEM_VERIFY(cp_type_i == 0 || cp_type_i == 1,
35 "Control point type not supported. Please read class "
36 "description to see supported types.");
37 nb = nb_i;
38 ncp = ncp_i;
39 b_type = b_type_i;
40 cp_type = cp_type_i;
41 tol = tol_i;
42 lbound.SetSize(nb, ncp);
43 ubound.SetSize(nb, ncp);
44 nodes.SetSize(nb);
45 weights.SetSize(nb);
46 control_points.SetSize(ncp);
47
48 auto scalenodes = [](const Vector &in, const real_t a, const real_t b) -> Vector
49 {
50 Vector outVec(in.Size());
51 real_t maxv = in.Max();
52 real_t minv = in.Min();
53 for (int i = 0; i < in.Size(); i++)
54 {
55 outVec(i) = a + (b-a)*(in(i)-minv)/(maxv-minv);
56 }
57 return outVec;
58 };
59 MFEM_VERIFY(ncp >= 2,"At least 2 control points are required.");
60
61 if (cp_type == 0) // GL + End Point
62 {
63 control_points(0) = 0.0;
64 control_points(ncp-1) = 1.0;
65 if (ncp > 2)
66 {
67 const real_t *x = poly1d.GetPoints(ncp-3, 0);
68 MFEM_VERIFY(x, "Error in getting points.");
69 for (int i = 0; i < ncp-2; i++)
70 {
71 control_points(i+1) = x[i];
72 }
73 }
74 }
75 else if (cp_type == 1) // Chebyshev
76 {
77 auto GetChebyshevNodes = [](int n) -> Vector
78 {
79 Vector cheb(n);
80 for (int i = 0; i < n; ++i)
81 {
82 cheb(i) = -cos(M_PI * (static_cast<real_t>(i) / (n - 1)));
83 }
84 return cheb;
85 };
86 control_points = GetChebyshevNodes(ncp);
87 }
88 else
89 {
90 MFEM_ABORT("Unsupported interval points. Use [0,1].\n");
91 }
92 control_points = scalenodes(control_points, 0.0, 1.0); // rescale to [0,1]
93
94 Poly_1D::Basis &basis1d(poly1d.GetBasis(nb-1, b_type));
95
96 // Initialize bounds
97 lbound = 0.0;
98 ubound = 0.0;
99
100 Vector bmv(nb), bpv(nb), bv(nb); // basis values
101 Vector bdmv(nb), bdpv(nb), bdv(nb); // basis derivative values
102 Vector vals(3);
103
104 // See Section 3.1.1 of https://arxiv.org/pdf/2501.12349 for explanation of
105 // procedure below.
106 for (int j = 0; j < ncp; j++)
107 {
108 real_t x = control_points(j);
109 real_t xm = x;
110 if (j != 0)
111 {
112 xm = 0.5*(control_points(j-1)+control_points(j));
113 }
114 real_t xp = x;
115 if (j != ncp-1)
116 {
117 xp = 0.5*(control_points(j)+control_points(j+1));
118 }
119 basis1d.Eval(xm, bmv, bdmv);
120 basis1d.Eval(xp, bpv, bdpv);
121 basis1d.Eval(x, bv);
122 real_t dm = x-xm;
123 real_t dp = x-xp;
124 for (int i = 0; i < nb; i++)
125 {
126 if (j == 0)
127 {
128 lbound(i, j) = bv(i);
129 ubound(i, j) = bv(i);
130 }
131 else if (j == ncp-1)
132 {
133 lbound(i, j) = bv(i);
134 ubound(i, j) = bv(i);
135 }
136 else
137 {
138 vals(0) = bv(i);
139 vals(1) = bmv(i) + dm*bdmv(i);
140 vals(2) = bpv(i) + dp*bdpv(i);
141 lbound(i, j) = vals.Min()-tol; // tolerance for good measure
142 ubound(i, j) = vals.Max()+tol; // tolerance for good measure
143 }
144 }
145 }
146
147 IntegrationRule irule(nb);
148 if (b_type == 0)
149 {
151 for (int i = 0; i < nb; i++)
152 {
153 weights(i) = irule.IntPoint(i).weight;
154 nodes(i) = irule.IntPoint(i).x;
155 }
156 }
157 else if (b_type == 1)
158 {
160 for (int i = 0; i < nb; i++)
161 {
162 weights(i) = irule.IntPoint(i).weight;
163 nodes(i) = irule.IntPoint(i).x;
164 }
165 }
166 else if (b_type == 2)
167 {
169 for (int i = 0; i < nb; i++)
170 {
171 weights(i) = irule.IntPoint(i).weight;
172 nodes(i) = irule.IntPoint(i).x;
173 }
174 }
175
176 if (b_type == 2)
177 {
178 nodes_int.SetSize(nb);
179 weights_int.SetSize(nb);
180 IntegrationRule irule_int(nb);
181 {
183 for (int i = 0; i < nb; i++)
184 {
185 weights_int(i) = irule_int.IntPoint(i).weight;
186 nodes_int(i) = irule_int.IntPoint(i).x;
187 }
188 }
189
190 SetupBernsteinBasisMat(basisMatNodes, nodes);
191 // Setup memory for lu factors
192 basisMatLU = basisMatNodes;
193 lu_ip.SetSize(nb);
194 // Compute lu factors
195 LUFactors lu(basisMatLU.GetData(), lu_ip.GetData());
196 bool factor = lu.Factor(nb);
197 MFEM_VERIFY(factor,"Failure in LU factorization in PLBound.");
198
199 // Setup the Bernstein basis matrix for the GLL integration points. This
200 // is used to compute linear fit.
201 SetupBernsteinBasisMat(basisMatInt, nodes_int);
202 }
203 else
204 {
205 nodes_int.SetDataAndSize(nodes.GetData(), nb);
206 weights_int.SetDataAndSize(weights.GetData(), nb);
207 }
208}
209
210PLBound::PLBound(const FiniteElementSpace *fes, const int ncp_i,
211 const int cp_type_i)
212{
213 MFEM_VERIFY(!fes->IsVariableOrder(),
214 "Variable order meshes not yet supported.");
215 const char *name = fes->FEColl()->Name();
216 string cname = name;
217
218 cp_type = cp_type_i;
219 b_type = BasisType::Invalid;
220 nb = fes->GetMaxElementOrder()+1;
221 tol = 0.0;
222
223 int minncp = 2;
224 if (nb > 12)
225 {
226 minncp = 2*nb;
227 }
228 else if (!strncmp(name, "H1_", 3) && strncmp(name, "H1_Trace_", 9))
229 {
230 // H1 GLL
232 minncp = min_ncp_gll_x[cp_type][nb-2];
233 }
234 else if (!strncmp(name, "H1Pos_", 6) && strncmp(name, "H1Pos_Trace_", 12))
235 {
236 // H1 Positive
237 b_type = BasisType::Positive;
238 minncp = min_ncp_pos_x[cp_type][nb-2];
239 }
240 else if (!strncmp(name, "L2_", 3) && strncmp(name, "L2_T", 4))
241 {
242 // L2 Gauss-Legendre
244 minncp = min_ncp_gl_x[cp_type][nb-2];
245 }
246 else if (!strncmp(name, "L2_T1", 5))
247 {
248 // L2 GLL
250 minncp = min_ncp_gll_x[cp_type][nb-2];
251 }
252 else if (!strncmp(name, "L2_T2", 5))
253 {
254 // L2 Positive
255 b_type = BasisType::Positive;
256 minncp = min_ncp_pos_x[cp_type][nb-2];
257 }
258 else
259 {
260 MFEM_ABORT("Only H1 GLL/Positive & L2 GL/GLL/Positive bases supported.");
261 }
262
263 ncp = std::max(minncp, ncp_i);
264
265 Setup(nb, ncp, b_type, cp_type, tol);
266}
267
268void PLBound::Get1DBounds(const Vector &coeff, Vector &intmin,
269 Vector &intmax) const
270{
271 real_t x,w;
272 intmin.SetSize(ncp);
273 intmax.SetSize(ncp);
274 intmin = 0.0;
275 intmax = 0.0;
276 Vector coeffm(nb);
277 coeffm = 0.0;
278
279 real_t a0 = 0.0;
280 real_t a1 = 0.0;
281
282 Vector nodal_vals, nodal_integ_vals;
283 if (b_type == 2) // compute values at equispaced nodes and GLL nodes
284 {
285 nodal_vals.SetSize(nb);
286 nodal_integ_vals.SetSize(nb);
287 Vector shape(nb);
288 for (int i = 0; i < nb; i++)
289 {
290 basisMatNodes.GetRow(i, shape);
291 nodal_vals(i) = shape*coeff;
292 basisMatInt.GetRow(i, shape);
293 nodal_integ_vals(i) = shape*coeff;
294 }
295 }
296 else
297 {
298 nodal_vals.SetDataAndSize(coeff.GetData(), nb);
299 nodal_integ_vals.SetDataAndSize(coeff.GetData(), nb);
300 }
301
302 // compute L2 projection for linear bases: a0 + a1*x
303 if (proj)
304 {
305 for (int i = 0; i < nb; i++)
306 {
307 x = 2.0*nodes_int(i)-1;
308 w = 2.0*weights_int(i);
309 a0 += 0.5*nodal_integ_vals(i)*w;
310 a1 += 1.5*nodal_integ_vals(i)*w*x;
311 }
312
313 // offset the linear fit from nodal values
314 for (int i = 0; i < nb; i++)
315 {
316 x = 2.0*nodes(i)-1;
317 coeffm(i) = nodal_vals(i) - a0 - a1*x;
318 }
319
320 // compute coefficients for Bernstein
321 if (b_type == 2)
322 {
323 LUFactors lu(basisMatLU.GetData(), lu_ip.GetData());
324 lu.Solve(nb, 1, coeffm.GetData());
325 }
326
327 // initialize the bounds to be the linear fit
328 for (int j = 0; j < ncp; j++)
329 {
330 x = 2.0*control_points(j)-1;
331 intmin(j) = a0 + a1*x;
332 intmax(j) = intmin(j);
333 }
334 }
335 else
336 {
337 coeffm.SetDataAndSize(coeff.GetData(), nb);
338 }
339
340 for (int i = 0; i < nb; i++)
341 {
342 real_t c = coeffm(i);
343 for (int j = 0; j < ncp; j++)
344 {
345 intmin(j) += min(lbound(i,j)*c, ubound(i,j)*c);
346 intmax(j) += max(lbound(i,j)*c, ubound(i,j)*c);
347 }
348 }
349}
350
351void PLBound::Get2DBounds(const Vector &coeff, Vector &intmin,
352 Vector &intmax) const
353{
354 intmin.SetSize(ncp*ncp);
355 intmax.SetSize(ncp*ncp);
356 intmin = 0.0;
357 intmax = 0.0;
358 Vector intminT(ncp*nb);
359 Vector intmaxT(ncp*nb);
360 // Get bounds for each row of the solution
361 for (int i = 0; i < nb; i++)
362 {
363 Vector solcoeff(coeff.GetData()+i*nb, nb);
364 Vector intminrow(intminT.GetData()+i*ncp, ncp);
365 Vector intmaxrow(intmaxT.GetData()+i*ncp, ncp);
366 Get1DBounds(solcoeff, intminrow, intmaxrow);
367 }
368 Vector intminT2 = intminT;
369
370 // Compute a0 and a1 for each column of nodes
371 Vector a0V(ncp), a1V(ncp);
372 a0V = 0.0;
373 a1V = 0.0;
374 real_t x,w,t;
375 if (proj)
376 {
377 if (b_type == 2)
378 {
379 // Note: DenseMatrix uses column-major ordering so we will need to
380 // transpose the matrix.
381 DenseMatrix intminTM(intminT.GetData(), ncp, nb),
382 intmaxTM(intmaxT.GetData(), ncp, nb),
383 intmeanTM(ncp, nb);
384 DenseMatrix minvalsM(nb, ncp), maxvalsM(nb, ncp), meanintvalsM(nb, ncp);
385 MultABt(basisMatNodes, intminTM, minvalsM);
386 MultABt(basisMatNodes, intmaxTM, maxvalsM);
387 intmeanTM = intminTM;
388 intmeanTM += intmaxTM;
389 intmeanTM *= 0.5;
390 MultABt(basisMatInt, intmeanTM, meanintvalsM);
391
392 // Compute the linear fit along each column and then offset it from
393 // the bounds on the coefficient.
394 // Note: Since Bernstein bases are positive, we can use the lower
395 // bounds to compute the lower bounding polynomial and subtract the
396 // linear fit before finding the Bernstein coefficients corresponding
397 // to the perturbation. Same for upper bounds. If the bases were not
398 // always positive, it is not yet clear if the perturbation
399 // coefficients will be this straightforward to compute.
400 for (int j = 0; j < ncp; j++) // row of interval points
401 {
402 for (int i = 0; i < nb; i++)
403 {
404 x = 2.0*nodes_int(i)-1; // x-coordinate
405 w = 2.0*weights_int(i); // weight
406 t = meanintvalsM(i,j);
407 a0V(j) += 0.5*t*w;
408 a1V(j) += 1.5*t*w*x;
409 }
410 // Offset linear fit
411 for (int i = 0; i < nb; i++)
412 {
413 x = 2.0*nodes(i)-1; // x-coordinate
414 minvalsM(i,j) -= a0V(j) + a1V(j)*x;
415 maxvalsM(i,j) -= a0V(j) + a1V(j)*x;
416 }
417 // Compute Bernstein coefficients
418 LUFactors lu(basisMatLU.GetData(), lu_ip.GetData());
419 lu.Solve(nb, 1, minvalsM.GetColumn(j));
420 lu.Solve(nb, 1, maxvalsM.GetColumn(j));
421 for (int i = 0; i < nb; i++)
422 {
423 intminT(i*ncp+j) = minvalsM(i,j);
424 intmaxT(i*ncp+j) = maxvalsM(i,j);
425 }
426 }
427 }
428 else
429 {
430 for (int j = 0; j < nb; j++) // row of nodes
431 {
432 x = 2.0*nodes(j)-1; // x-coordinate
433 w = 2.0*weights(j); // weight
434 for (int i = 0; i < ncp; i++) // column of interval points
435 {
436 t = 0.5*(intminT(j*ncp+i)+intmaxT(j*ncp+i));
437 a0V(i) += 0.5*t*w;
438 a1V(i) += 1.5*t*w*x;
439 }
440 }
441 // offset the linear fit from nodal values
442 for (int j = 0; j < nb; j++) // row of nodes
443 {
444 x = 2.0*nodes(j)-1; // x-coordinate
445 for (int i = 0; i < ncp; i++) // column of interval points
446 {
447 t = a0V(i) + a1V(i)*x;
448 intminT(j*ncp+i) -= t;
449 intmaxT(j*ncp+i) -= t;
450 }
451 }
452 }
453
454 // Initialize bounds using a0 and a1 values
455 for (int j = 0; j < ncp; j++) // row j
456 {
457 x = 2.0*control_points(j)-1;
458 for (int i = 0; i < ncp; i++) // column i
459 {
460 intmin(j*ncp+i) = a0V(i) + a1V(i)*x;
461 intmax(j*ncp+i) = intmin(j*ncp+i);
462 }
463 }
464 }
465
466 // Compute bounds
467 int id1 = 0, id2 = 0;
468 Vector vals(4);
469 for (int j = 0; j < nb; j++)
470 {
471 for (int i = 0; i < ncp; i++) // ith column
472 {
473 real_t w0 = intminT(id1++);
474 real_t w1 = intmaxT(id2++);
475 for (int k = 0; k < ncp; k++) // kth row
476 {
477 vals(0) = w0*lbound(j,k);
478 vals(1) = w0*ubound(j,k);
479 vals(2) = w1*lbound(j,k);
480 vals(3) = w1*ubound(j,k);
481 intmin(k*ncp+i) += vals.Min();
482 intmax(k*ncp+i) += vals.Max();
483 }
484 }
485 }
486}
487
488void PLBound::Get3DBounds(const Vector &coeff, Vector &intmin,
489 Vector &intmax) const
490{
491 int nb2 = nb*nb,
492 ncp2 = ncp*ncp,
493 ncp3 = ncp*ncp*ncp;
494
495 intmin.SetSize(ncp3);
496 intmax.SetSize(ncp3);
497 intmin = 0.0;
498 intmax = 0.0;
499 Vector intminT(ncp2*nb);
500 Vector intmaxT(ncp2*nb);
501
502 // Get bounds for each slice of the solution
503 for (int i = 0; i < nb; i++)
504 {
505 Vector solcoeff(coeff.GetData()+i*nb2, nb2);
506 Vector intminrow(intminT.GetData()+i*ncp2, ncp2);
507 Vector intmaxrow(intmaxT.GetData()+i*ncp2, ncp2);
508 Get2DBounds(solcoeff, intminrow, intmaxrow);
509 }
510 DenseMatrix intminTM(intminT.GetData(), ncp2, nb),
511 intmaxTM(intmaxT.GetData(), ncp2, nb);
512
513 // Compute a0 and a1 for each tower of nodes
514 Vector a0V(ncp2), a1V(ncp2);
515 a0V = 0.0;
516 a1V = 0.0;
517 real_t x,w,t;
518 if (proj)
519 {
520 if (b_type == 2) // Bernstein bases
521 {
522 // Compute the mean coefficients along each tower.
523 for (int j = 0; j < ncp2; j++) // slice of interval points
524 {
525 Vector meanBounds(nb), minBounds(nb), maxBounds(nb);
526 intminTM.GetRow(j, minBounds);
527 intmaxTM.GetRow(j, maxBounds);
528 for (int i = 0; i < nb; i++) // column of nodes
529 {
530 meanBounds(i) = 0.5*(minBounds(i)+maxBounds(i));
531 }
532 Vector meanNodalIntVals(nb);
533 Vector minNodalVals(nb);
534 Vector maxNodalVals(nb);
535 Vector row(nb);
536 for (int i = 0; i < nb; i++)
537 {
538 basisMatNodes.GetRow(i, row);
539 minNodalVals(i) = row*minBounds;
540 maxNodalVals(i) = row*maxBounds;
541 basisMatInt.GetRow(i, row);
542 meanNodalIntVals(i) = row*meanBounds;
543 }
544 // linear fit along each tower
545 for (int i = 0; i < nb; i++)
546 {
547 x = 2.0*nodes_int(i)-1; // x-coordinate
548 w = 2.0*weights_int(i); // weight
549 a0V(j) += 0.5*meanNodalIntVals(i)*w;
550 a1V(j) += 1.5*meanNodalIntVals(i)*w*x;
551 }
552 // offset the linear fit from bounding coefficients
553 for (int i = 0; i < nb; i++)
554 {
555 x = 2.0*nodes(i)-1; // x-coordinate
556 minBounds(i) -= a0V(j) + a1V(j)*x;
557 maxBounds(i) -= a0V(j) + a1V(j)*x;
558 }
559 // Compute Bernstein coefficients
560 LUFactors lu(basisMatLU.GetData(), lu_ip.GetData());
561 lu.Solve(nb, 1, minBounds.GetData());
562 lu.Solve(nb, 1, maxBounds.GetData());
563 for (int i = 0; i < nb; i++)
564 {
565 intminT(i*ncp2+j) = minBounds(i);
566 intmaxT(i*ncp2+j) = maxBounds(i);
567 }
568 }
569 }
570 else
571 {
572 // nodal bases
573 for (int j = 0; j < nb; j++) // tower of nodes
574 {
575 x = 2.0*nodes(j)-1; // x-coordinate
576 w = 2.0*weights(j); // weight
577 for (int i = 0; i < ncp2; i++) // slice of interval points
578 {
579 t = 0.5*(intminT(j*ncp2+i)+intmaxT(j*ncp2+i));
580 a0V(i) += 0.5*t*w;
581 a1V(i) += 1.5*t*w*x;
582 }
583 }
584 // offset the linear fit from nodal values
585 for (int j = 0; j < nb; j++) // row of nodes
586 {
587 x = 2.0*nodes(j)-1; // x-coordinate
588 for (int i = 0; i < ncp2; i++) // column of interval points
589 {
590 t = a0V(i) + a1V(i)*x;
591 intminT(j*ncp2+i) -= t;
592 intmaxT(j*ncp2+i) -= t;
593 }
594 }
595 }
596
597 // Initialize bounds using a0 and a1 values
598 for (int j = 0; j < ncp; j++) // slice j
599 {
600 x = 2.0*control_points(j)-1;
601 for (int i = 0; i < ncp2; i++) // tower i
602 {
603 intmin(j*ncp2+i) = a0V(i) + a1V(i)*x;
604 intmax(j*ncp2+i) = a0V(i) + a1V(i)*x;
605 }
606 }
607 }
608
609 // Compute bounds
610 int id1 = 0, id2 = 0;
611 Vector vals(4);
612 for (int j = 0; j < nb; j++)
613 {
614 for (int i = 0; i < ncp2; i++) // ith tower
615 {
616 real_t w0 = intminT(id1++);
617 real_t w1 = intmaxT(id2++);
618 for (int k = 0; k < ncp; k++) // kth slice
619 {
620 vals(0) = w0*lbound(j,k);
621 vals(1) = w0*ubound(j,k);
622 vals(2) = w1*lbound(j,k);
623 vals(3) = w1*ubound(j,k);
624 intmin(k*ncp2+i) += vals.Min();
625 intmax(k*ncp2+i) += vals.Max();
626 }
627 }
628 }
629}
630
631void PLBound::GetNDBounds(const int rdim, const Vector &coeff,
632 Vector &intmin, Vector &intmax) const
633{
634 if (rdim == 1)
635 {
636 Get1DBounds(coeff, intmin, intmax);
637 }
638 else if (rdim == 2)
639 {
640 Get2DBounds(coeff, intmin, intmax);
641 }
642 else if (rdim == 3)
643 {
644 Get3DBounds(coeff, intmin, intmax);
645 }
646 else
647 {
648 MFEM_ABORT("Currently not supported.");
649 }
650}
651
652void PLBound::SetupBernsteinBasisMat(DenseMatrix &basisMat,
653 Vector &nodesBern) const
654{
655 const int nbern = nodesBern.Size();
656 L2_SegmentElement el(nbern-1, 2); // we use L2 to leverage lexicographic order
657 Array<int> ordering = el.GetLexicographicOrdering();
658 basisMat.SetSize(nbern, nbern);
659 Vector shape(nbern);
661 for (int i = 0; i < nbern; i++)
662 {
663 ip.x = nodesBern(i);
664 el.CalcShape(ip, shape);
665 basisMat.SetRow(i, shape);
666 }
667}
668
669constexpr int PLBound::min_ncp_gl_x[2][11];
670constexpr int PLBound::min_ncp_gll_x[2][11];
671constexpr int PLBound::min_ncp_pos_x[2][11];
672
673int PLBound::GetMinimumPointsForGivenBases(int nb_i, int b_type_i,
674 int cp_type_i) const
675{
676 MFEM_VERIFY(b_type_i >= 0 && b_type_i <= 2, "Invalid node type. Specify 0 "
677 "for GL, 1 for GLL, and 2 for positive " "bases.");
678 MFEM_VERIFY(cp_type_i == 0 || cp_type_i == 1, "Invalid control point type. "
679 "Specify 0 for GL+end points, 1 for Chebyshev.");
680 if (nb_i > 12)
681 {
682 MFEM_ABORT("GetMinimumPointsForGivenBases can only be used for maximum "
683 "order = 11, i.e. nb=12. 2*nb points should be sufficient to "
684 "bound the bases up to nb = 30.");
685 }
686 else if (b_type_i == 0)
687 {
688 return min_ncp_gl_x[cp_type_i][nb_i-2];
689 }
690 else if (b_type_i == 1)
691 {
692 return min_ncp_gll_x[cp_type_i][nb_i-2];
693 }
694 else if (b_type_i == 2)
695 {
696 return min_ncp_pos_x[cp_type_i][nb_i-2];
697 }
698 return 0;
699}
700
701void PLBound::Print(std::ostream &outp) const
702{
703 outp << "PLBound nb: " << nb << std::endl;
704 outp << "PLBound ncp: " << ncp << std::endl;
705 outp << "PLBound b_type: " << b_type << std::endl;
706 outp << "PLBound cp_type: " << cp_type << std::endl;
707 outp << "Print nodes: " << std::endl;
708 nodes.Print(outp);
709 outp << "Print weights: " << std::endl;
710 weights.Print(outp);
711 outp << "Print control_points: " << std::endl;
712 control_points.Print(outp);
713 outp << "Print lower bounds: " << std::endl;
714 lbound.Print(outp);
715 outp << "Print upper bounds: " << std::endl;
716 ubound.Print(outp);
717}
718
719}
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:840
T * GetData()
Returns the data.
Definition array.hpp:140
@ GaussLobatto
Closed type.
Definition fe_base.hpp:36
@ GaussLegendre
Open type.
Definition fe_base.hpp:35
@ Positive
Bernstein polynomials.
Definition fe_base.hpp:37
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void SetRow(int r, const real_t *row)
real_t * GetData() const
Returns the matrix data array. Warning: this method casts away constness.
Definition densemat.hpp:126
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:116
void Print(std::ostream &out=mfem::out, int width_=4) const override
Prints matrix to stream out.
void GetRow(int r, Vector &row) const
virtual const char * Name() const
Definition fe_coll.hpp:79
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:208
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Definition fespace.hpp:678
const FiniteElementCollection * FEColl() const
Definition fespace.hpp:856
virtual int GetMaxElementOrder() const
Return the maximum polynomial order over all elements.
Definition fespace.hpp:674
Class for integration point with weight.
Definition intrules.hpp:35
Arbitrary order L2 elements in 1D on a segment.
Definition fe_l2.hpp:23
void GetNDBounds(const int rdim, const Vector &coeff, Vector &intmin, Vector &intmax) const
Definition bounds.cpp:631
void Print(std::ostream &outp=mfem::out) const
Definition bounds.cpp:701
PLBound(const int nb_i, const int ncp_i, const int b_type_i, const int cp_type_i, const real_t tol_i)
Definition bounds.hpp:85
int GetMinimumPointsForGivenBases(int nb_i, int b_type_i, int cp_type_i) const
Definition bounds.cpp:673
const real_t * GetPoints(const int p, const int btype, bool on_device=false)
Get the coordinates of the points of the given BasisType, btype.
Definition fe_base.hpp:1109
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
Definition fe_base.cpp:2395
static void GaussLegendre(const int np, IntegrationRule *ir)
Definition intrules.cpp:424
static void ClosedUniform(const int np, IntegrationRule *ir)
Definition intrules.cpp:660
static void GaussLobatto(const int np, IntegrationRule *ir)
Definition intrules.cpp:512
Vector data type.
Definition vector.hpp:82
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition vector.cpp:870
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
Definition vector.hpp:191
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
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 > cos(dual< value_type, gradient_type > a)
implementation of cosine for dual numbers
Definition dual.hpp:296
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
float real_t
Definition config.hpp:46
Poly_1D poly1d
Definition fe.cpp:28