/usr/include/dune/grid/test/checkjacobians.hh is in libdune-grid-dev 2.5.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_GRID_TEST_CHECKJACOBIANS_HH
#define DUNE_GRID_TEST_CHECKJACOBIANS_HH
#include <dune/common/dynvector.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/common/typetraits.hh>
#include <dune/common/unused.hh>
/* Interface check for Jacobian related return types
* -------------------------------------------------
*
* The Dune grid interface allows for implementation-defined return types
* of the Dune::Geometry member functions:
* JacobianInverseTransposed &jacobianInverseTransposed ( const LocalCoordinate &local );
* JacobianTransposed &jacobianTransposed ( const LocalCoordinate &local );
*
* The return types 'JacobianInverseTransposed', 'JacobianTransposed'
* are expected to implement the following interface:
\code
struct Jacobian
{
// field type
typedef ImplementationDefined field_type;
// size type
typedef ImplementationDefined size_type;
// number of rows
static const int rows = implementationDefined;
// number of cols
static const int cols = implementationDefined;
// linear operations
template< class X, class Y >
void mv ( const X &x, Y &y ) const;
template< class X, class Y >
void mtv ( const X &x, Y &y ) const;
template< class X, class Y >
void umv ( const X &x, Y &y ) const;
template< class X, class Y >
void umtv ( const X &x, Y &y ) const;
template< class X, class Y >
void umhv ( const X &x, Y &y ) const;
template< class X, class Y >
void mmv ( const X &x, Y &y ) const;
template< class X, class Y >
void mmtv ( const X &x, Y &y ) const;
template< class X, class Y >
void mmhv ( const X &x, Y &y ) const;
template< class X, class Y >
void usmv ( const field_type &alpha, const X &x, Y &y ) const;
template< class X, class Y >
void usmtv ( const field_type &alpha, const X &x, Y &y ) const;
template< class X, class Y >
void usmhv ( const field_type &alpha, const X &x, Y &y ) const;
// norms
typename FieldTraits< field_type >::real_type frobenius_norm () const;
typename FieldTraits< field_type >::real_type frobenius_norm2 () const;
typename FieldTraits< field_type >::real_type infinity_norm () const;
typename FieldTraits< field_type >::real_type infinity_norm_real () const;
// cast to FieldMatrix
operator FieldMatrix< field_type, rows, cols > () const;
};
\endcode
*
* Note that a FieldMatrix itself is a valid return type.
*/
namespace Dune
{
namespace
{
// CheckJacobianInterface
// ----------------------
template< class ctype, int dimRange, int dimDomain, class Jacobian,
bool isFieldMatrix = std::is_same< Jacobian, FieldMatrix< ctype, dimRange, dimDomain > >::value
>
struct CheckJacobianInterface
{
// the interface check always holds if jacobian type is a FieldMatrix
static void apply ( const Jacobian &jacobian ) {}
};
template< class ctype, int dimRange, int dimDomain, class Jacobian >
struct CheckJacobianInterface< ctype, dimRange, dimDomain, Jacobian, false >
{
// field type
typedef typename Jacobian::field_type field_type;
static_assert((Conversion< ctype, field_type >::isTwoWay),
"Field type not compatible with geometry's coordinate type");
// size type
typedef typename Jacobian::size_type size_type;
// number of rows
static const int rows = Jacobian::rows;
static_assert((rows == dimRange), "Number of rows and range dimension do not coincide");
// number of cols
static const int cols = Jacobian::cols;
static_assert((cols == dimDomain), "Number of columns and domain dimension do not coincide");
static void apply ( const Jacobian &jacobian )
{
// call matrix-vector operations; methods must accept any dense
// vector implementation
{
FieldVector< field_type, cols > x( field_type ( 0 ) );
FieldVector< field_type, rows > y( field_type( 0 ) );
callMappings( jacobian, x, y );
}
{
DynamicVector< field_type > x( cols, field_type( 0 ) );
DynamicVector< field_type > y( rows, field_type( 0 ) );
callMappings( jacobian, x, y );
}
// call norms
DUNE_UNUSED typename FieldTraits< field_type >::real_type frobenius_norm
= jacobian.frobenius_norm();
DUNE_UNUSED typename FieldTraits< field_type >::real_type frobenius_norm2
= jacobian.frobenius_norm2();
DUNE_UNUSED typename FieldTraits< field_type >::real_type infinity_norm
= jacobian.infinity_norm();
DUNE_UNUSED typename FieldTraits< field_type >::real_type infinity_norm_real
= jacobian.infinity_norm_real();
// cast to FieldMatrix
FieldMatrix< field_type, rows, cols > A( jacobian );
FieldMatrix< field_type, rows, cols > B;
B = jacobian;
// check consistency with matrix-vector multiplication
assemble( jacobian, B );
A -= B;
if( A.frobenius_norm() > 1e-12 )
DUNE_THROW( MathError, "Cast to field matrix is inconsistent with matrix-vector multiplication" );
}
private:
// call matrix-vector multiplication methods
template< class Domain, class Range >
static void callMappings ( const Jacobian &jacobian, Domain &x, Range &y )
{
field_type alpha( 1 );
jacobian.mv( x, y );
jacobian.mtv( y, x );
jacobian.umv( x, y );
jacobian.umtv( y, x );
jacobian.umhv( y, x );
jacobian.mmv( x, y );
jacobian.mmtv( y, x );
jacobian.mmhv( y, x );
jacobian.usmv( alpha, x, y );
jacobian.usmtv( alpha, y, x );
jacobian.usmhv( alpha, y, x );
}
// use matrix-vector multiplication to assemble field matrix
static void assemble ( const Jacobian &jacobian, FieldMatrix< field_type, rows, cols > &fieldMatrix )
{
for( int j = 0; j < cols; ++j )
{
// i-th standard basis vector
FieldVector< field_type, cols > e( 0 );
e[ j ] = 1;
// compute i-th row
FieldVector< field_type, rows > x;
jacobian.mv( e, x );
for( int i = 0; i < rows; ++i )
fieldMatrix[ i ][ j ] = x[ i ];
}
}
};
} // namespace
// checkJacobians
// --------------
template< class Geometry >
void checkJacobians ( const Geometry &geometry )
{
typedef typename Geometry::ctype ctype;
const int mydimension = Geometry::mydimension;
const int coorddimension = Geometry::coorddimension;
const typename Geometry::LocalCoordinate local = geometry.local( geometry.center() );
// check jacobian inverse transposed
typedef typename Geometry::JacobianInverseTransposed JacobianInverseTransposed;
CheckJacobianInterface< ctype, coorddimension, mydimension, JacobianInverseTransposed >
::apply( geometry.jacobianInverseTransposed( local ) );
// check jacobian transposed
typedef typename Geometry::JacobianTransposed JacobianTransposed;
CheckJacobianInterface< ctype, mydimension, coorddimension, JacobianTransposed >
::apply( geometry.jacobianTransposed( local ) );
}
} // namespace Dune
#endif // #ifndef DUNE_GRID_TEST_CHECKJACOBIANS_HH
|