Dune Core Modules (2.4.1)

checkgeometry.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4#ifndef DUNE_CHECK_GEOMETRY_HH
5#define DUNE_CHECK_GEOMETRY_HH
6
7#include <limits>
8
12
13#include <dune/geometry/referenceelements.hh>
15#include <dune/geometry/referenceelements.hh>
16
17namespace Dune
18{
19
30 template <class TestGeometry>
31 bool checkGeometry ( const TestGeometry& geometry )
32 {
33 bool pass = true;
34
36 // Extract all static information
38
39 // dimension of the corresponding reference element
40 static const int mydim = TestGeometry::mydimension;
41
42 // dimension of the world space
43 static const int coorddim = TestGeometry::coorddimension;
44
45 // type used for coordinate coefficients
46 typedef typename TestGeometry::ctype ctype;
47
48 // vector type used for points in the domain
49 typedef typename TestGeometry::LocalCoordinate LocalCoordinate DUNE_UNUSED;
50
51 // vector type used for image points
52 typedef typename TestGeometry::GlobalCoordinate GlobalCoordinate DUNE_UNUSED;
53
54 // Matrix-like type for the return value of the jacobianTransposed method
55 typedef typename TestGeometry::JacobianTransposed JacobianTransposed;
56
57 // Matrix-like type for the return value of the jacobianInverseTransposed method
58 typedef typename TestGeometry::JacobianInverseTransposed JacobianInverseTransposed;
59
61
62 GeometryType type = geometry.type();
63
65
66 // Test whether the return value of the method 'center' corresponds to the center of the
67 // reference element. That is the current definition of the method.
68 const FieldVector<ctype, coorddim> center = geometry.global(refElement.position(0,0));
69 if( std::abs( (geometry.center() - center).two_norm() ) > 1e-8 )
70 DUNE_THROW(Exception, "center() is not consistent with global(refElem.position(0,0)).");
71
73 // Test whether the number and placement of the corners is consistent
74 // with the corners of the corresponding reference element.
76
77 if( refElement.size( mydim ) == geometry.corners() )
78 {
79 for( int i = 0; i < geometry.corners(); ++i )
80 {
81 if( (geometry.corner( i ) - geometry.global( refElement.position( i, mydim ) )).two_norm() > 1e-8 ) {
82 std::cerr << "Error: Methods corner and global are inconsistent." << std::endl;
83 pass = false;
84 }
85 }
86 }
87 else {
88 std::cerr << "Error: Incorrect number of corners (" << geometry.corners() << ", should be " << refElement.size( mydim ) << ")." << std::endl;
89 pass = false;
90 }
91
93 // Use a quadrature rule as a set of test points and loop over them
96 for (size_t i = 0; i < quadrature.size(); ++i)
97 {
98 const typename TestGeometry::LocalCoordinate &x = quadrature[i].position();
99
100 // Test whether the methods 'local' and 'global' are inverse to each other
101 if ( (x - geometry.local( geometry.global( x ) )).two_norm() > 1e-8 ) {
102 std::cerr << "Error: global and local are not inverse to each other." << std::endl;
103 pass = false;
104 }
105
106 // Test whether the methods 'jacobianTransposed' and 'jacobianInverseTransposed'
107 // return matrices that are inverse to each other.
108 const JacobianTransposed &jt = geometry.jacobianTransposed( x );
109 const JacobianInverseTransposed &jit = geometry.jacobianInverseTransposed( x );
110
111 // Transform to FieldMatrix, so we can have coefficent access and other goodies
112 // We need some black magic for the transformation, because there is no
113 // official easy way yet.
114 // The following code does the transformation by multiplying jt and jit from
115 // the right by identity matrices. That way, only the mv method is used.
117 for (int j=0; j<coorddim; j++) {
118
119 FieldVector<ctype,coorddim> idColumn(0);
120 idColumn[j] = 1;
121
123 jt.mv(idColumn,column);
124
125 for (int k=0; k<mydim; k++)
126 jtAsFieldMatrix[k][j] = column[k];
127
128 }
129
131 for (int j=0; j<mydim; j++) {
132
133 FieldVector<ctype,mydim> idColumn(0);
134 idColumn[j] = 1;
135
137 jit.mv(idColumn,column);
138
139 for (int k=0; k<coorddim; k++)
140 jitAsFieldMatrix[k][j] = column[k];
141
142 }
143
144
146 FMatrixHelp::multMatrix( jtAsFieldMatrix, jitAsFieldMatrix, id );
147 bool isId = true;
148 for( int j = 0; j < mydim; ++j )
149 for( int k = 0; k < mydim; ++k )
150 isId &= (std::abs( id[ j ][ k ] - (j == k ? 1 : 0) ) < 1e-8);
151 if( !isId)
152 {
153 std::cerr << "Error: jacobianTransposed and jacobianInverseTransposed are not inverse to each other." << std::endl;
154 std::cout << " id != [ ";
155 for( int j = 0; j < mydim; ++j )
156 std::cout << (j > 0 ? " | " : "") << id[ j ];
157 std::cout << " ]" << std::endl;
158 pass = false;
159 }
160
161 // Test whether integrationElement returns something nonnegative
162 if( geometry.integrationElement( x ) < 0 ) {
163 std::cerr << "Error: Negative integrationElement found." << std::endl;
164 pass = false;
165 }
166
168 for( int i = 0; i < mydim; ++i )
169 for( int j = 0; j < mydim; ++j )
170 for( int k = 0; k < coorddim; ++k )
171 jtj[ i ][ j ] += jtAsFieldMatrix[ i ][ k ] * jtAsFieldMatrix[ j ][ k ];
172
173 if( std::abs( std::sqrt( jtj.determinant() ) - geometry.integrationElement( x ) ) > 1e-8 ) {
174 std::cerr << "Error: integrationElement is not consistent with jacobianTransposed." << std::endl;
175 pass = false;
176 }
177 if (geometry.affine())
178 if( std::abs( geometry.volume() - refElement.volume()*geometry.integrationElement( x ) ) > 1e-8 ) {
179 std::cerr << "Error: volume is not consistent with jacobianTransposed." << std::endl;
180 pass = false;
181 }
182 }
183
184 return pass;
185 }
186
187}
188
189#endif // #ifndef DUNE_CHECK_GEOMETRY_HH
field_type determinant() const
calculates the determinant of this matrix
Base class for Dune-Exceptions.
Definition: exceptions.hh:91
A dense n x m matrix.
Definition: fmatrix.hh:67
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:25
Abstract base class for quadrature rules.
Definition: quadraturerules.hh:97
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:225
This class provides access to geometric and topological properties of a reference element.
Definition: referenceelements.hh:55
int size(int c) const
number of subentities of codimension c
Definition: referenceelements.hh:82
const FieldVector< ctype, dim > & position(int i, int c) const
position of the barycenter of entity (i,c)
Definition: referenceelements.hh:150
ctype volume() const
obtain the volume of the reference element
Definition: referenceelements.hh:210
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
Dune namespace.
Definition: alignment.hh:10
bool checkGeometry(const TestGeometry &geometry)
Static and dynamic checks for all features of a Geometry.
Definition: checkgeometry.hh:31
static const ReferenceElement< ctype, dim > & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:484
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 22, 23:33, 2024)