Dune Core Modules (2.6.0)

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
31 template <class TestGeometry>
32 bool checkGeometry ( const TestGeometry& geometry )
33 {
34 bool pass = true;
35
37 // Extract all static information
39
40 // dimension of the corresponding reference element
41 static const int mydim = TestGeometry::mydimension;
42
43 // dimension of the world space
44 static const int coorddim = TestGeometry::coorddimension;
45
46 // type used for coordinate coefficients
47 typedef typename TestGeometry::ctype ctype;
48
49 // vector type used for points in the domain
50 typedef typename TestGeometry::LocalCoordinate LocalCoordinate DUNE_UNUSED;
51
52 // vector type used for image points
53 typedef typename TestGeometry::GlobalCoordinate GlobalCoordinate DUNE_UNUSED;
54
55 // Matrix-like type for the return value of the jacobianTransposed method
56 typedef typename TestGeometry::JacobianTransposed JacobianTransposed;
57
58 // Matrix-like type for the return value of the jacobianInverseTransposed method
59 typedef typename TestGeometry::JacobianInverseTransposed JacobianInverseTransposed;
60
61 const ctype tolerance = std::sqrt( std::numeric_limits< ctype >::epsilon() );
62
64
65 const int corners = geometry.corners();
66 if( corners == 0 )
67 DUNE_THROW( Exception, "A geometry must have at least one corner." );
68
69 GlobalCoordinate cornerAvg ( 0 );
70 for( int i = 0; i < corners; ++i )
71 cornerAvg += geometry.corner( i );
72 cornerAvg /= ctype( corners );
73
74 const GlobalCoordinate center = geometry.center();
75
76 if( corners > 1 )
77 {
78 // if we have more than one corner, no corner may coincide with their average or the center
79 for( int i = 0; i < corners; ++i )
80 {
81 const GlobalCoordinate corner = geometry.corner( i );
82 if( (corner - center).two_norm() <= tolerance )
83 {
84 std::cerr << "Error: Geometry has multiple corners, but one corner coincides with the center." << std::endl;
85 pass = false;
86 }
87
88 if( (corner - cornerAvg).two_norm() <= tolerance )
89 {
90 std::cerr << "Error: Geometry has multiple corners, but one corner coincides with their average." << std::endl;
91 pass = false;
92 }
93 }
94 }
95 else
96 {
97 // the single corner must coincide with the center
98 if( (center - cornerAvg).two_norm() > tolerance )
99 {
100 std::cerr << "Error: Geometry has a single corner (" << cornerAvg << "), but it does not coincide with the center (" << center << ")." << std::endl;
101 pass = false;
102 }
103 }
104
105 const ctype volume = geometry.volume();
106 if( volume < tolerance )
107 {
108 std::cerr << "Error: Geometry has nearly vanishing volume (" << volume << ")" << std::endl;
109 pass = false;
110 }
111
113
114 const GeometryType type = geometry.type();
115 if( type.isNone() )
116 return pass;
117
118 // make sure the reference element type lookup works
119 ReferenceElement< TestGeometry > refElement = referenceElement( geometry );
120
121 // Test whether the return value of the method 'center' corresponds to the center of the
122 // reference element. That is the current definition of the method.
123 if( (center - geometry.global( refElement.position( 0, 0 ) )).two_norm() > tolerance )
124 DUNE_THROW( Exception, "center() is not consistent with global(refElem.position(0,0))." );
125
127 // Test whether the number and placement of the corners is consistent
128 // with the corners of the corresponding reference element.
130
131 if( refElement.size( mydim ) == corners )
132 {
133 for( int i = 0; i < geometry.corners(); ++i )
134 {
135 if( (geometry.corner( i ) - geometry.global( refElement.position( i, mydim ) )).two_norm() > tolerance )
136 {
137 std::cerr << "Error: Methods corner and global are inconsistent." << std::endl;
138 pass = false;
139 }
140 }
141 }
142 else
143 {
144 std::cerr << "Error: Incorrect number of corners (" << geometry.corners() << ", should be " << refElement.size( mydim ) << ")." << std::endl;
145 pass = false;
146 }
147
149 // Use a quadrature rule as a set of test points and loop over them
152 for (const auto& ip : quadrature)
153 {
154 const typename TestGeometry::LocalCoordinate &x = ip.position();
155
156 // Test whether the methods 'local' and 'global' are inverse to each other
157 if ( (x - geometry.local( geometry.global( x ) )).two_norm() > 1e-8 ) {
158 std::cerr << "Error: global and local are not inverse to each other." << std::endl;
159 pass = false;
160 }
161
162 // Test whether the methods 'jacobianTransposed' and 'jacobianInverseTransposed'
163 // return matrices that are inverse to each other.
164 const JacobianTransposed &jt = geometry.jacobianTransposed( x );
165 const JacobianInverseTransposed &jit = geometry.jacobianInverseTransposed( x );
166
167 // Transform to FieldMatrix, so we can have coefficent access and other goodies
168 // We need some black magic for the transformation, because there is no
169 // official easy way yet.
170 // The following code does the transformation by multiplying jt and jit from
171 // the right by identity matrices. That way, only the mv method is used.
173 for (int j=0; j<coorddim; j++) {
174
175 FieldVector<ctype,coorddim> idColumn(0);
176 idColumn[j] = 1;
177
179 jt.mv(idColumn,column);
180
181 for (int k=0; k<mydim; k++)
182 jtAsFieldMatrix[k][j] = column[k];
183
184 }
185
187 for (int j=0; j<mydim; j++) {
188
189 FieldVector<ctype,mydim> idColumn(0);
190 idColumn[j] = 1;
191
193 jit.mv(idColumn,column);
194
195 for (int k=0; k<coorddim; k++)
196 jitAsFieldMatrix[k][j] = column[k];
197
198 }
199
200
202 FMatrixHelp::multMatrix( jtAsFieldMatrix, jitAsFieldMatrix, id );
203 bool isId = true;
204 for( int j = 0; j < mydim; ++j )
205 for( int k = 0; k < mydim; ++k )
206 isId &= (std::abs( id[ j ][ k ] - (j == k ? 1 : 0) ) < 1e-8);
207 if( !isId)
208 {
209 std::cerr << "Error: jacobianTransposed and jacobianInverseTransposed are not inverse to each other." << std::endl;
210 std::cout << " id != [ ";
211 for( int j = 0; j < mydim; ++j )
212 std::cout << (j > 0 ? " | " : "") << id[ j ];
213 std::cout << " ]" << std::endl;
214 pass = false;
215 }
216
217 // Test whether integrationElement returns something nonnegative
218 if( geometry.integrationElement( x ) < 0 ) {
219 std::cerr << "Error: Negative integrationElement found." << std::endl;
220 pass = false;
221 }
222
224 for( int i = 0; i < mydim; ++i )
225 for( int j = 0; j < mydim; ++j )
226 for( int k = 0; k < coorddim; ++k )
227 jtj[ i ][ j ] += jtAsFieldMatrix[ i ][ k ] * jtAsFieldMatrix[ j ][ k ];
228
229 if( std::abs( std::sqrt( jtj.determinant() ) - geometry.integrationElement( x ) ) > 1e-8 ) {
230 std::cerr << "Error: integrationElement is not consistent with jacobianTransposed." << std::endl;
231 pass = false;
232 }
233 if (geometry.affine())
234 if( std::abs( geometry.volume() - refElement.volume()*geometry.integrationElement( x ) ) > 1e-8 ) {
235 std::cerr << "Error: volume is not consistent with jacobianTransposed." << std::endl;
236 pass = false;
237 }
238 }
239
240 return pass;
241 }
242
243}
244
245#endif // #ifndef DUNE_CHECK_GEOMETRY_HH
field_type determinant() const
calculates the determinant of this matrix
Base class for Dune-Exceptions.
Definition: exceptions.hh:94
vector space out of a tensor product of fields.
Definition: fvector.hh:93
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:277
constexpr bool isNone() const
Return true if entity is a singular of any dimension.
Definition: type.hh:567
generic geometry implementation based on corner coordinates
Definition: multilineargeometry.hh:179
static const int mydimension
geometry dimension
Definition: multilineargeometry.hh:187
Dune::GeometryType type() const
obtain the name of the reference element
Definition: multilineargeometry.hh:259
JacobianTransposed jacobianTransposed(const LocalCoordinate &local) const
obtain the transposed of the Jacobian
Definition: multilineargeometry.hh:358
GlobalCoordinate global(const LocalCoordinate &local) const
evaluate the mapping
Definition: multilineargeometry.hh:280
GlobalCoordinate center() const
obtain the centroid of the mapping's image
Definition: multilineargeometry.hh:272
GlobalCoordinate corner(int i) const
obtain coordinates of the i-th corner
Definition: multilineargeometry.hh:265
ct ctype
coordinate type
Definition: multilineargeometry.hh:184
static const int coorddimension
coordinate dimension
Definition: multilineargeometry.hh:189
int corners() const
obtain number of corners of the corresponding reference element
Definition: multilineargeometry.hh:262
ctype volume() const
obtain the volume of the mapping's image
Definition: multilineargeometry.hh:344
ctype integrationElement(const LocalCoordinate &local) const
obtain the integration element
Definition: multilineargeometry.hh:331
JacobianInverseTransposed jacobianInverseTransposed(const LocalCoordinate &local) const
obtain the transposed of the Jacobian's inverse
Definition: multilineargeometry.hh:671
bool affine() const
is this mapping affine?
Definition: multilineargeometry.hh:252
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
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_UNUSED
A macro for marking variables that the compiler mistakenly flags as unused, which sometimes happens d...
Definition: unused.hh:16
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
unspecified value type referenceElement(T &&... t)
Returns a reference element for the objects t....
unspecified-type ReferenceElement
Returns the type of reference element for the argument type T.
Definition: referenceelements.hh:495
Dune namespace.
Definition: alignedallocator.hh:10
bool checkGeometry(const TestGeometry &geometry)
Static and dynamic checks for all features of a Geometry.
Definition: checkgeometry.hh:32
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)