DUNE PDELab (2.7)

test-localfe.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_LOCALFUNCTIONS_TEST_TEST_LOCALFE_HH
4#define DUNE_LOCALFUNCTIONS_TEST_TEST_LOCALFE_HH
5
14#include <iomanip>
15#include <iostream>
16#include <typeinfo>
17
20#include <dune/geometry/referenceelements.hh>
21
22#include <dune/localfunctions/common/virtualinterface.hh>
23#include <dune/localfunctions/common/virtualwrappers.hh>
24
25double TOL = 1e-9;
26// The FD approximation used for checking the Jacobian uses half of the
27// precision -- so we have to be a little bit more tolerant here.
28double jacobianTOL = 1e-5; // sqrt(TOL)
29
30// This class wraps one shape function of a local finite element as a function
31// that can be feed to the LocalInterpolation::interpolate method.
32template<class FE>
33class ShapeFunctionAsFunction :
34 // public Dune::LocalFiniteElementFunctionBase<FE>::type
35 public Dune::LocalFiniteElementFunctionBase<FE>::FunctionBase
36 // public Dune::LocalFiniteElementFunctionBase<FE>::VirtualFunctionBase
37{
38public:
39 typedef typename FE::Traits::LocalBasisType::Traits::DomainType DomainType;
40 typedef typename FE::Traits::LocalBasisType::Traits::RangeType RangeType;
42
43 typedef typename FE::Traits::LocalBasisType::Traits::RangeFieldType CT;
44
45 ShapeFunctionAsFunction(const FE& fe, int shapeFunction) :
46 fe_(fe),
47 shapeFunction_(shapeFunction)
48 {}
49
50 void evaluate (const DomainType& x, RangeType& y) const
51 {
52 std::vector<RangeType> yy;
53 fe_.localBasis().evaluateFunction(x, yy);
54 y = yy[shapeFunction_];
55 }
56
57private:
58 const FE& fe_;
59 int shapeFunction_;
60};
61
62// This class wraps one shape function of a local finite element as a callable
63// that can be fed to the LocalInterpolation::interpolate method.
64template<class FE>
65class ShapeFunctionAsCallable
66{
67 // These types are deliberately private: They are not part of a Callable API
68 typedef typename FE::Traits::LocalBasisType::Traits::DomainType DomainType;
69 typedef typename FE::Traits::LocalBasisType::Traits::RangeType RangeType;
70public:
71
72 ShapeFunctionAsCallable(const FE& fe, int shapeFunction) :
73 fe_(fe),
74 shapeFunction_(shapeFunction)
75 {}
76
77 RangeType operator() (DomainType x) const
78 {
79 std::vector<RangeType> yy;
80 fe_.localBasis().evaluateFunction(x, yy);
81 return yy[shapeFunction_];
82 }
83
84private:
85 const FE& fe_;
86 int shapeFunction_;
87};
88
89
90// Check whether the degrees of freedom computed by LocalInterpolation
91// are dual to the shape functions. See Ciarlet, "The Finite Element Method
92// for Elliptic Problems", 1978, for details.
93template<class FE>
94bool testLocalInterpolation(const FE& fe)
95{
96 std::vector<typename ShapeFunctionAsFunction<FE>::CT> coeff;
97 for(size_t i=0; i<fe.size(); ++i)
98 {
100 // Part A: Feed the shape functions to the 'interpolate' method in form of
101 // a class derived from FunctionBase.
102 // This way is deprecated since dune-localfunctions 2.7.
104
105 // The i-th shape function as a function that 'interpolate' can deal with
106 ShapeFunctionAsFunction<FE> f(fe, i);
107
108 // Compute degrees of freedom for that shape function
109 // We expect the result to be the i-th unit vector
110 fe.localInterpolation().interpolate(f, coeff);
111
112 // Check size of weight vector
113 if (coeff.size() != fe.localBasis().size())
114 {
115 std::cout << "Bug in LocalInterpolation for finite element type "
116 << Dune::className(fe) << std::endl;
117 std::cout << " Interpolation produces " << coeff.size() << " degrees of freedom" << std::endl;
118 std::cout << " Basis has size " << fe.localBasis().size() << std::endl;
119 std::cout << std::endl;
120 return false;
121 }
122
123 // Check if interpolation weights are equal to coefficients
124 for(std::size_t j=0; j<coeff.size(); ++j)
125 {
126 if ( std::abs(coeff[j] - (i==j)) > TOL)
127 {
128 std::cout << std::setprecision(16);
129 std::cout << "Bug in LocalInterpolation for finite element type "
130 << Dune::className(fe) << std::endl;
131 std::cout << " Degree of freedom " << j << " applied to shape function " << i
132 << " yields value " << coeff[j] << ", not the expected value " << (i==j) << std::endl;
133 std::cout << std::endl;
134 return false;
135 }
136 }
137
138
140 // Part B: Redo the same test, but feed the shape functions to the
141 // 'interpolate' method in form of a callable.
143
144 // The i-th shape function as a function that 'interpolate' can deal with
145 ShapeFunctionAsCallable<FE> sfAsCallable(fe, i);
146
147 // Compute degrees of freedom for that shape function
148 // We expect the result to be the i-th unit vector
149 fe.localInterpolation().interpolate(sfAsCallable, coeff);
150
151 // Check size of weight vector
152 if (coeff.size() != fe.localBasis().size())
153 {
154 std::cout << "Bug in LocalInterpolation for finite element type "
155 << Dune::className(fe) << std::endl;
156 std::cout << " Interpolation produces " << coeff.size() << " degrees of freedom" << std::endl;
157 std::cout << " Basis has size " << fe.localBasis().size() << std::endl;
158 std::cout << std::endl;
159 return false;
160 }
161
162 // Check if interpolation weights are equal to coefficients
163 for(std::size_t j=0; j<coeff.size(); ++j)
164 {
165 if ( std::abs(coeff[j] - (i==j)) > TOL)
166 {
167 std::cout << std::setprecision(16);
168 std::cout << "Bug in LocalInterpolation for finite element type "
169 << Dune::className(fe) << std::endl;
170 std::cout << " Degree of freedom " << j << " applied to shape function " << i
171 << " yields value " << coeff[j] << ", not the expected value " << (i==j) << std::endl;
172 std::cout << std::endl;
173 return false;
174 }
175 }
176 }
177 return true;
178}
179
180
181// check whether Jacobian agrees with FD approximation
182template<class FE>
183bool testJacobian(const FE& fe, unsigned order = 2)
184{
185 typedef typename FE::Traits::LocalBasisType LB;
186
187 bool success = true;
188
189 // ////////////////////////////////////////////////////////////
190 // Check the partial derivatives by comparing them
191 // to finite difference approximations
192 // ////////////////////////////////////////////////////////////
193
194 // A set of test points
197
198 // Loop over all quadrature points
199 for (size_t i=0; i<quad.size(); i++) {
200
201 // Get a test point
203 quad[i].position();
204
205 // Get the shape function derivatives there
206 std::vector<typename LB::Traits::JacobianType> jacobians;
207 fe.localBasis().evaluateJacobian(testPoint, jacobians);
208 if(jacobians.size() != fe.localBasis().size()) {
209 std::cout << "Bug in evaluateJacobian() for finite element type "
210 << Dune::className(fe) << std::endl;
211 std::cout << " Jacobian vector has size " << jacobians.size()
212 << std::endl;
213 std::cout << " Basis has size " << fe.localBasis().size()
214 << std::endl;
215 std::cout << std::endl;
216 return false;
217 }
218
219 // Loop over all directions
220 for (int k=0; k<LB::Traits::dimDomain; k++) {
221
222 // Compute an approximation to the derivative by finite differences
225
226 upPos[k] += jacobianTOL;
227 downPos[k] -= jacobianTOL;
228
229 std::vector<typename LB::Traits::RangeType> upValues, downValues;
230
231 fe.localBasis().evaluateFunction(upPos, upValues);
232 fe.localBasis().evaluateFunction(downPos, downValues);
233
234 // Loop over all shape functions in this set
235 for (unsigned int j=0; j<fe.localBasis().size(); ++j) {
236 //Loop over all components
237 for(int l=0; l < LB::Traits::dimRange; ++l) {
238
239 // The current partial derivative, just for ease of notation
240 double derivative = jacobians[j][l][k];
241
242 double finiteDiff = (upValues[j][l] - downValues[j][l])
243 / (2*jacobianTOL);
244
245 // Check
246 if ( std::abs(derivative-finiteDiff) >
247 TOL/jacobianTOL*((std::abs(finiteDiff)>1) ? std::abs(finiteDiff) : 1.) )
248 {
249 std::cout << std::setprecision(16);
250 std::cout << "Bug in evaluateJacobian() for finite element type "
251 << Dune::className(fe) << std::endl;
252 std::cout << " Shape function derivative does not agree with "
253 << "FD approximation" << std::endl;
254 std::cout << " Shape function " << j << " component " << l
255 << " at position " << testPoint << ": derivative in "
256 << "direction " << k << " is " << derivative << ", but "
257 << finiteDiff << " is expected." << std::endl;
258 std::cout << std::endl;
259 success = false;
260 }
261 } //Loop over all components
262 } // Loop over all shape functions in this set
263 } // Loop over all directions
264 } // Loop over all quadrature points
265
266 return success;
267}
268
274{
275 template <class FE>
276 static bool test(const FE& fe,
277 double eps, double delta, unsigned int diffOrder, std::size_t order = 2)
278 {
279 bool success = true;
280
281 if (diffOrder > 2)
282 std::cout << "No test for differentiability orders larger than 2!" << std::endl;
283
284 if (diffOrder >= 2)
285 success = success and testOrder2(fe, eps, delta, order);
286
287 if (diffOrder >= 1)
288 success = success and testOrder1(fe, eps, delta, order);
289
290 success = success and testOrder0(fe, eps, delta, order);
291
292 return success;
293 }
294
296 template <class FE>
297 static bool testOrder0(const FE& fe,
298 double eps,
299 double delta,
300 std::size_t order = 2)
301 {
302 typedef typename FE::Traits::LocalBasisType::Traits::RangeType RangeType;
303 constexpr auto dimDomain = FE::Traits::LocalBasisType::Traits::dimDomain;
304
305 bool success = true;
306
308 // Check the partial derivatives by comparing them
309 // to finite difference approximations
311
312 // A set of test points
313 const auto& quad = Dune::QuadratureRules<double, dimDomain>::rule(fe.type(),
314 order);
315
316 // Loop over all quadrature points
317 for (size_t i = 0; i < quad.size(); i++)
318 {
319 // Get a test point
320 const Dune::FieldVector<double, dimDomain>& testPoint = quad[i].position();
321
322 // Get the shape function values there using the 'partial' method
323 std::vector<RangeType> partialValues;
324 std::array<unsigned int, dimDomain> multiIndex;
325 std::fill(multiIndex.begin(), multiIndex.end(), 0);
326
327 fe.localBasis().partial(multiIndex, testPoint, partialValues);
328
329 if (partialValues.size() != fe.localBasis().size())
330 {
331 std::cout << "Bug in partial() for finite element type "
332 << Dune::className(fe) << std::endl;
333 std::cout << " values vector has size "
334 << partialValues.size() << std::endl;
335 std::cout << " Basis has size " << fe.localBasis().size()
336 << std::endl;
337 std::cout << std::endl;
338 return false;
339 }
340
341 // Get reference values
342 std::vector<RangeType> referenceValues;
343 fe.localBasis().evaluateFunction(testPoint, referenceValues);
344
345 // Loop over all shape functions in this set
346 for (unsigned int j = 0; j < fe.localBasis().size(); ++j)
347 {
348 // Loop over all components
349 for (int l = 0; l < FE::Traits::LocalBasisType::Traits::dimRange; ++l)
350 {
351 // Check the 'partial' method
352 if (std::abs(partialValues[j][l] - referenceValues[j][l])
353 > TOL / jacobianTOL
354 * ((std::abs(referenceValues[j][l]) > 1) ? std::abs(referenceValues[j][l]) : 1.))
355 {
356 std::cout << std::setprecision(16);
357 std::cout << "Bug in partial() for finite element type "
358 << Dune::className(fe) << std::endl;
359 std::cout << " Shape function value does not agree with "
360 << "output of method evaluateFunction." << std::endl;
361 std::cout << " Shape function " << j << " component " << l
362 << " at position " << testPoint << ": value is " << partialValues[j][l]
363 << ", but " << referenceValues[j][l] << " is expected." << std::endl;
364 std::cout << std::endl;
365 success = false;
366 }
367
368 } //Loop over all components
369 } // Loop over all shape functions in this set
370 } // Loop over all quadrature points
371
372 return success;
373 }
374
376 template <class FE>
377 static bool testOrder1(const FE& fe,
378 double eps,
379 double delta,
380 std::size_t order = 2)
381 {
382 typedef typename FE::Traits::LocalBasisType LB;
383 typedef typename LB::Traits::RangeFieldType RangeField;
384
385 bool success = true;
386
388 // Check the partial derivatives by comparing them
389 // to finite difference approximations
391
392 // A set of test points
395 order);
396
397 // Loop over all quadrature points
398 for (size_t i = 0; i < quad.size(); i++)
399 {
400 // Get a test point
401 const Dune::FieldVector<double, LB::Traits::dimDomain>& testPoint = quad[i].position();
402
403 // Loop over all directions
404 for (int k = 0; k < LB::Traits::dimDomain; k++)
405 {
406 // Get the shape function derivatives there using the 'partial' method
407 std::vector<typename LB::Traits::RangeType> firstPartialDerivatives;
408 std::array<unsigned int, LB::Traits::dimDomain> multiIndex;
409 std::fill(multiIndex.begin(), multiIndex.end(), 0);
410 multiIndex[k]++;
411 fe.localBasis().partial(multiIndex, testPoint, firstPartialDerivatives);
412 if (firstPartialDerivatives.size() != fe.localBasis().size())
413 {
414 std::cout << "Bug in partial() for finite element type "
415 << Dune::className(fe) << std::endl;
416 std::cout << " firstPartialDerivatives vector has size "
417 << firstPartialDerivatives.size() << std::endl;
418 std::cout << " Basis has size " << fe.localBasis().size()
419 << std::endl;
420 std::cout << std::endl;
421 return false;
422 }
423
424 // Compute an approximation to the derivative by finite differences
427
428 upPos[k] += jacobianTOL;
429 downPos[k] -= jacobianTOL;
430
431 std::vector<typename LB::Traits::RangeType> upValues, downValues;
432
433 fe.localBasis().evaluateFunction(upPos, upValues);
434 fe.localBasis().evaluateFunction(downPos, downValues);
435
436 // Loop over all shape functions in this set
437 for (unsigned int j = 0; j < fe.localBasis().size(); ++j)
438 {
439 // Loop over all components
440 for (int l = 0; l < LB::Traits::dimRange; ++l)
441 {
442 RangeField finiteDiff = (upValues[j][l] - downValues[j][l])
443 / (2 * jacobianTOL);
444
445 // Check the 'partial' method
446 RangeField partialDerivative = firstPartialDerivatives[j][l];
447 if (std::abs(partialDerivative - finiteDiff)
448 > TOL / jacobianTOL
449 * ((std::abs(finiteDiff) > 1) ? std::abs(finiteDiff) : 1.))
450 {
451 std::cout << std::setprecision(16);
452 std::cout << "Bug in partial() for finite element type "
453 << Dune::className(fe) << std::endl;
454 std::cout << " Shape function derivative does not agree with "
455 << "FD approximation" << std::endl;
456 std::cout << " Shape function " << j << " component " << l
457 << " at position " << testPoint << ": derivative in "
458 << "direction " << k << " is " << partialDerivative << ", but "
459 << finiteDiff << " is expected." << std::endl;
460 std::cout << std::endl;
461 success = false;
462 }
463
464 } // Loop over all directions
465 } // Loop over all shape functions in this set
466 } //Loop over all components
467 } // Loop over all quadrature points
468
469 return success;
470 }
471
473 template <class FE>
474 static bool testOrder2(const FE& fe,
475 double eps,
476 double delta,
477 std::size_t order = 2)
478 {
479 typedef typename FE::Traits::LocalBasisType LocalBasis;
480 typedef typename LocalBasis::Traits::DomainFieldType DF;
481 typedef typename LocalBasis::Traits::DomainType Domain;
482 static const int dimDomain = LocalBasis::Traits::dimDomain;
483
484 static const std::size_t dimR = LocalBasis::Traits::dimRange;
485 typedef typename LocalBasis::Traits::RangeType Range;
486 typedef typename LocalBasis::Traits::RangeFieldType RangeField;
487
488 bool success = true;
489
491 // Check the partial derivatives by comparing them
492 // to finite difference approximations
494
495 // A set of test points
498
499 // Loop over all quadrature points
500 for (std::size_t i = 0; i < quad.size(); i++)
501 {
502 // Get a test point
503 const Domain& testPoint = quad[i].position();
504
505 // For testing the 'partial' method
506 std::array<std::vector<Dune::FieldMatrix<RangeField, dimDomain, dimDomain> >, dimR> partialHessians;
507 for (size_t k = 0; k < dimR; k++)
508 partialHessians[k].resize(fe.size());
509
510 //loop over all local directions
511 for (int dir0 = 0; dir0 < dimDomain; dir0++)
512 {
513 for (int dir1 = 0; dir1 < dimDomain; dir1++)
514 {
515 // Get the shape function derivatives there using the 'partial' method
516 std::vector<Range> secondPartialDerivative;
517 std::array<unsigned int,dimDomain> multiIndex;
518 std::fill(multiIndex.begin(), multiIndex.end(), 0);
519 multiIndex[dir0]++;
520 multiIndex[dir1]++;
521 fe.localBasis().partial(multiIndex, testPoint, secondPartialDerivative);
522
523 if (secondPartialDerivative.size() != fe.localBasis().size())
524 {
525 std::cout << "Bug in partial() for finite element type "
526 << Dune::className<FE>() << ":" << std::endl;
527 std::cout << " return vector has size " << secondPartialDerivative.size()
528 << std::endl;
529 std::cout << " Basis has size " << fe.localBasis().size()
530 << std::endl;
531 std::cout << std::endl;
532 return false;
533 }
534
535 //combine to Hesse matrices
536 for (size_t k = 0; k < dimR; k++)
537 for (std::size_t j = 0; j < fe.localBasis().size(); ++j)
538 partialHessians[k][j][dir0][dir1] = secondPartialDerivative[j][k];
539
540 }
541 } //loop over all directions
542
543 // Loop over all local directions
544 for (std::size_t dir0 = 0; dir0 < dimDomain; ++dir0)
545 {
546 for (unsigned int dir1 = 0; dir1 < dimDomain; dir1++)
547 {
548 // Compute an approximation to the derivative by finite differences
549 std::array<Domain,4> neighbourPos;
550 std::fill(neighbourPos.begin(), neighbourPos.end(), testPoint);
551
552 neighbourPos[0][dir0] += delta;
553 neighbourPos[0][dir1] += delta;
554 neighbourPos[1][dir0] -= delta;
555 neighbourPos[1][dir1] += delta;
556 neighbourPos[2][dir0] += delta;
557 neighbourPos[2][dir1] -= delta;
558 neighbourPos[3][dir0] -= delta;
559 neighbourPos[3][dir1] -= delta;
560
561 std::array<std::vector<Range>, 4> neighbourValues;
562 for (int k = 0; k < 4; k++)
563 fe.localBasis().evaluateFunction(neighbourPos[k],
564 neighbourValues[k]);
565
566 // Loop over all shape functions in this set
567 for (std::size_t j = 0; j < fe.localBasis().size(); ++j)
568 {
569 //Loop over all components
570 for (std::size_t k = 0; k < dimR; ++k)
571 {
572 RangeField finiteDiff = (neighbourValues[0][j][k]
573 - neighbourValues[1][j][k] - neighbourValues[2][j][k]
574 + neighbourValues[3][j][k]) / (4 * delta * delta);
575
576 // The current partial derivative, just for ease of notation, evaluated by the 'partial' method
577 RangeField partialDerivative = partialHessians[k][j][dir0][dir1];
578
579 // Check
580 if (std::abs(partialDerivative - finiteDiff)
581 > eps / delta * (std::max(std::abs(finiteDiff), 1.0)))
582 {
583 std::cout << std::setprecision(16);
584 std::cout << "Bug in partial() for finite element type "
585 << Dune::className<FE>() << ":" << std::endl;
586 std::cout << " Second shape function derivative does not agree with "
587 << "FD approximation" << std::endl;
588 std::cout << " Shape function " << j << " component " << k
589 << " at position " << testPoint << ": derivative in "
590 << "local direction (" << dir0 << ", " << dir1 << ") is "
591 << partialDerivative << ", but " << finiteDiff
592 << " is expected." << std::endl;
593 std::cout << std::endl;
594 success = false;
595 }
596
597 } //Loop over all components
598 }
599 } // Loop over all local directions
600 } // Loop over all shape functions in this set
601 } // Loop over all quadrature points
602
603 return success;
604 }
605
606};
607
608// Flags for disabling parts of testFE
609enum {
610 DisableNone = 0,
611 DisableLocalInterpolation = 1,
612 DisableVirtualInterface = 2,
613 DisableJacobian = 4,
614 DisableEvaluate = 8
615};
616
617// call tests for given finite element
618template<class FE>
619bool testFE(const FE& fe, char disabledTests = DisableNone, unsigned int diffOrder = 0)
620{
621 // Order of the quadrature rule used to generate test points
622 unsigned int quadOrder = 2;
623
624 bool success = true;
625
626 if (FE::Traits::LocalBasisType::Traits::dimDomain != fe.type().dim())
627 {
628 std::cout << "Bug in type() for finite element type "
629 << Dune::className(fe) << std::endl;
630 std::cout << " Coordinate dimension is " << FE::Traits::LocalBasisType::Traits::dimDomain << std::endl;
631 std::cout << " but GeometryType is " << fe.type() << " with dimension " << fe.type().dim() << std::endl;
632 success = false;
633 }
634
635 if (fe.size() != fe.localBasis().size())
636 {
637 std::cout << "Bug in finite element type "
638 << Dune::className(fe) << std::endl;
639 std::cout << " Size reported by LocalFiniteElement is " << fe.size() << std::endl;
640 std::cout << " but size reported by LocalBasis is " << fe.localBasis().size() << std::endl;
641 success = false;
642 }
643
644 // Make sure evaluateFunction returns the correct number of values
645 std::vector<typename FE::Traits::LocalBasisType::Traits::RangeType> values;
646 fe.localBasis().evaluateFunction(Dune::ReferenceElements<double,FE::Traits::LocalBasisType::Traits::dimDomain>::general(fe.type()).position(0,0), values);
647
648 if (values.size() != fe.size())
649 {
650 std::cout << "Bug in finite element type "
651 << Dune::className(fe) << std::endl;
652 std::cout << " LocalFiniteElement.size() returns " << fe.size() << "," << std::endl;
653 std::cout << " but LocalBasis::evaluateFunction returns " << values.size() << " values!" << std::endl;
654 success = false;
655 }
656
657 if (fe.size() != fe.localCoefficients().size())
658 {
659 std::cout << "Bug in finite element type "
660 << Dune::className(fe) << std::endl;
661 std::cout << " Size reported by LocalFiniteElement is " << fe.size() << std::endl;
662 std::cout << " but size reported by LocalCoefficients is " << fe.localCoefficients().size() << std::endl;
663 success = false;
664 }
665
666 const auto& lc = fe.localCoefficients();
667 for(size_t i=0; i<lc.size(); i++)
668 {
669 const auto& lk = lc.localKey(i);
670 if (lk.codim() > fe.type().dim())
671 {
672 std::cout << "Bug in finite element type "
673 << Dune::className(fe) << std::endl;
674 std::cout << " Codimension reported by localKey(" << i << ") is " << lk.codim() << std::endl;
675 std::cout << " but geometry is " << fe.type() << " with dimension " << fe.type().dim() << std::endl;
676 success = false;
677 }
678 }
679
680 if (not (disabledTests & DisableLocalInterpolation))
681 {
682 success = testLocalInterpolation<FE>(fe) and success;
683 }
684 if (not (disabledTests & DisableJacobian))
685 {
686 success = testJacobian<FE>(fe, quadOrder) and success;
687 }
688 else
689 {
690 // make sure diffOrder is 0
691 success = (diffOrder == 0) and success;
692 }
693
694 if (not (disabledTests & DisableEvaluate))
695 {
696 success = TestPartial::test(fe, TOL, jacobianTOL, diffOrder, quadOrder) and success;
697 }
698
699 if (not (disabledTests & DisableVirtualInterface))
700 {
701 typedef typename FE::Traits::LocalBasisType::Traits ImplementationLBTraits;
703 typedef typename Dune::LocalFiniteElementVirtualImp<FE> VirtualFEImp;
704
705 const VirtualFEImp virtualFE(fe);
706 if (not (disabledTests & DisableLocalInterpolation))
707 success = testLocalInterpolation<VirtualFEInterface>(virtualFE) and success;
708 if (not (disabledTests & DisableJacobian))
709 {
710 success = testJacobian<VirtualFEInterface>(virtualFE) and success;
711 }
712 else
713 {
714 // make sure diffOrder is 0
715 success = (diffOrder == 0) and success;
716 }
717 }
718
719 return success;
720}
721
722#define TEST_FE(A) { bool b = testFE(A); std::cout << "testFE(" #A ") " << (b?"succeeded\n":"failed\n"); success &= b; }
723#define TEST_FE2(A,B) { bool b = testFE(A, B); std::cout << "testFE(" #A ", " #B ") " << (b?"succeeded\n":"failed\n"); success &= b; }
724#define TEST_FE3(A,B,C) { bool b = testFE(A, B, C); std::cout << "testFE(" #A ", " #B ", " #C ") " << (b?"succeeded\n":"failed\n"); success &= b; }
725
726#endif // DUNE_LOCALFUNCTIONS_TEST_TEST_LOCALFE_HH
vector space out of a tensor product of fields.
Definition: fvector.hh:96
void evaluate(const typename Traits::DomainType &x, typename Traits::RangeType &y) const
Function evaluation.
Return a proper base class for functions to use with LocalInterpolation.
Definition: virtualinterface.hh:37
class for wrapping a finite element using the virtual interface
Definition: virtualwrappers.hh:240
virtual base class for local finite elements with functions
Definition: virtualinterface.hh:260
Abstract base class for quadrature rules.
Definition: quadraturerules.hh:126
static const QuadratureRule & rule(const GeometryType &t, int p, QuadratureType::Enum qt=QuadratureType::GaussLegendre)
select the appropriate QuadratureRule for GeometryType t and order p
Definition: quadraturerules.hh:254
A free function to provide the demangled class name of a given object or type as a string.
TrigonometricFunction< K, -cosFactor, sinFactor > derivative(const TrigonometricFunction< K, sinFactor, cosFactor > &f)
Obtain derivative of TrigonometricFunction function.
Definition: trigonometricfunction.hh:39
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:79
std::string className()
Provide the demangled class name of a type T as a string.
Definition: classname.hh:44
Class providing access to the singletons of the reference elements.
Definition: referenceelements.hh:168
Helper class to test the 'partial' method.
Definition: test-localfe.hh:274
static bool testOrder0(const FE &fe, double eps, double delta, std::size_t order=2)
Test the 'partial' method for zero-order partial derivatives, i.e., values.
Definition: test-localfe.hh:297
static bool testOrder2(const FE &fe, double eps, double delta, std::size_t order=2)
Test second-order partial derivatives.
Definition: test-localfe.hh:474
static bool testOrder1(const FE &fe, double eps, double delta, std::size_t order=2)
Test the 'partial' method for first-order partial derivatives.
Definition: test-localfe.hh:377
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)