1#ifndef MOAB_ELEM_UTIL_HPP2#define MOAB_ELEM_UTIL_HPP34#include"moab/CartVect.hpp"5#include<vector>6#include"moab/Matrix3.hpp"78// to access data structures for spectral elements910extern"C" {
11#include"moab/FindPtFuncs.h"12 }
1314namespace moab
15 {
16namespace ElemUtil
17 {
1819boolnat_coords_trilinear_hex( const CartVect* hex_corners, const CartVect& x, CartVect& xi, double tol );
20boolpoint_in_trilinear_hex( const CartVect* hex_corners, const CartVect& xyz, double etol );
2122boolpoint_in_trilinear_hex( const CartVect* hex_corners,
23const CartVect& xyz,
24const CartVect& box_min,
25const CartVect& box_max,
26double etol );
2728// wrapper to hex_findpt29voidnat_coords_trilinear_hex2( const CartVect* hex_corners, const CartVect& x, CartVect& xi, double til );
3031voidhex_findpt( double* xm[3], int n, CartVect xyz, CartVect& rst, double& dist );
3233voidhex_eval( double* field, int n, CartVect rst, double& value );
3435boolintegrate_trilinear_hex( const CartVect* hex_corners, double* corner_fields, double& field_val, int num_pts );
3637 } // namespace ElemUtil3839namespace Element
40 {
41/**\brief Class representing a map (diffeomorphism) F parameterizing a 3D element by its
42 * canonical preimage.*/43/*
44 Shape functions on the element can obtained by a pushforward (pullback by the inverse map)
45 of the shape functions on the canonical element. This is done by extending this class.
46
47 We further assume that the parameterizing map is defined by the location of n vertices,
48 which can be set and retrieved on a Map instance. The number of vertices is fixed at
49 compile time.
50 */51classMap52 {
53public:
54/**\brief Construct a Map defined by the given std::vector of vertices. */55Map( const std::vector< CartVect >& v )
56 {
57this->vertex.resize( v.size() );
58this->set_vertices( v );
59 };
60/**\brief Construct a Map defined by n vertices. */61Map( constunsignedint n )
62 {
63this->vertex = std::vector< CartVect >( n );
64 };
65virtual ~Map();
66/**\brief Evaluate the map on \f$x_i\f$ (calculate \f$\vec x = F($\vec \xi)\f$ )*/67virtual CartVect evaluate( const CartVect& xi )const= 0;
68/**\brief Evaluate the inverse map (calculate \f$\vec \xi = F^-1($\vec x)\f$ to given
69 * tolerance)*/70virtual CartVect ievaluate( const CartVect& x, double tol = 1e-6, const CartVect& x0 = CartVect( 0.0 ) )const;
71/**\brief decide if within the natural param space, with a tolerance*/72virtualboolinside_nat_space( const CartVect& xi, double& tol )const= 0;
73/* FIX: should evaluate and ievaluate return both the value and the Jacobian (first jet)? */74/**\brief Evaluate the map's Jacobi matrix. */75virtual Matrix3 jacobian( const CartVect& xi )const= 0;
76/* FIX: should this be evaluated in real coordinates and be obtained as part of a Newton
77 * solve? */78/**\brief Evaluate the inverse of the Jacobi matrix. */79virtual Matrix3 ijacobian( const CartVect& xi )const
80 {
81returnthis->jacobian( xi ).inverse();
82 };
83/* det_jacobian and det_ijacobian should be overridden for efficiency. */84/**\brief Evaluate the determinate of the Jacobi matrix. */85virtualdoubledet_jacobian( const CartVect& xi )const
86 {
87returnthis->jacobian( xi ).determinant();
88 };
89/* FIX: should this be evaluated in real coordinates and be obtained as part of a Newton
90 * solve? */91/**\brief Evaluate the determinate of the inverse Jacobi matrix. */92virtualdoubledet_ijacobian( const CartVect& xi )const
93 {
94returnthis->jacobian( xi ).inverse().determinant();
95 };
9697/**\brief Evaluate a scalar field at a point given field values at the vertices. */98virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const= 0;
99/**\brief Integrate a scalar field over the element given field values at the vertices. */100virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const= 0;
101102/**\brief Size of the vertices vector. */103unsignedintsize()
104 {
105returnthis->vertex.size();
106 }
107/**\brief Retrieve vertices. */108const std::vector< CartVect >& get_vertices();
109/**\brief Set vertices. */110virtualvoidset_vertices( const std::vector< CartVect >& v );
111112// will look at the box formed by vertex coordinates, and before doing any NR, bail out if113// necessary114virtualboolinside_box( const CartVect& xi, double& tol )const;
115116/* Exception thrown when an evaluation fails (e.g., ievaluate fails to converge). */117classEvaluationError118 {
119public:
120EvaluationError( const CartVect& x, const std::vector< CartVect >& verts ) : p( x ), vertices( verts )
121 {
122#ifndef NDEBUG123 std::cout << "p:" << p << "\n vertices.size() " << vertices.size() << "\n";
124for( size_t i = 0; i < vertices.size(); i++ )
125 std::cout << vertices[i] << "\n";
126#endif127 };
128129private:
130 CartVect p;
131 std::vector< CartVect > vertices;
132 }; // class EvaluationError133134/* Exception thrown when a bad argument is encountered. */135classArgError136 {
137public:
138ArgError(){};
139 }; // class ArgError140protected:
141 std::vector< CartVect > vertex;
142 }; // class Map143144/**\brief Shape function space for trilinear hexahedron, obtained by a pushforward of the
145 * canonical linear (affine) functions. */146classLinearHex : public Map
147 {
148public:
149LinearHex( const std::vector< CartVect >& vertices ) : Map( vertices ){};
150LinearHex();
151virtual ~LinearHex();
152153virtual CartVect evaluate( const CartVect& xi )const;
154// virtual CartVect ievaluate(const CartVect& x, double tol) const ;155virtualboolinside_nat_space( const CartVect& xi, double& tol )const;
156157virtual Matrix3 jacobian( const CartVect& xi )const;
158virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
159virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const;
160161protected:
162/* Preimages of the vertices -- "canonical vertices" -- are known as "corners". */163staticconstdouble corner[8][3];
164staticconstdouble gauss[2][2];
165staticconstunsignedint corner_count = 8;
166staticconstunsignedint gauss_count = 2;
167168 }; // class LinearHex169170/**\brief Shape function space for trilinear hexahedron, obtained by a pushforward of the
171 * canonical linear (affine) functions. */172classQuadraticHex : public Map
173 {
174public:
175QuadraticHex( const std::vector< CartVect >& vertices ) : Map( vertices ){};
176QuadraticHex();
177virtual ~QuadraticHex();
178virtual CartVect evaluate( const CartVect& xi )const;
179// virtual CartVect ievaluate(const CartVect& x, double tol) const ;180virtualboolinside_nat_space( const CartVect& xi, double& tol )const;
181182virtual Matrix3 jacobian( const CartVect& xi )const;
183virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
184virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const;
185186protected:
187/* Preimages of the vertices -- "canonical vertices" -- are known as "corners".
188 * there are 27 vertices for a tri-quadratic xes*/189staticconstint corner[27][3];
190staticconstdouble gauss[8][2]; // TODO fix me191staticconstunsignedint corner_count = 27;
192staticconstunsignedint gauss_count = 2; // TODO fix me193194 }; // class QuadraticHex195/**\brief Shape function space for a linear tetrahedron, obtained by a pushforward of the
196 * canonical affine shape functions. */197classLinearTet : public Map
198 {
199public:
200LinearTet( const std::vector< CartVect >& vertices ) : Map( vertices )
201 {
202set_vertices( vertex );
203 };
204LinearTet();
205virtual ~LinearTet();
206/* Override the evaluation routines to take advantage of the properties of P1. */207virtual CartVect evaluate( const CartVect& xi )const
208 {
209returnthis->vertex[0] + this->T * xi;
210 };
211virtual CartVect ievaluate( const CartVect& x, double tol = 1e-6, const CartVect& x0 = CartVect( 0.0 ) )const;
212virtual Matrix3 jacobian( const CartVect& )const
213 {
214returnthis->T;
215 };
216virtual Matrix3 ijacobian( const CartVect& )const
217 {
218returnthis->T_inverse;
219 };
220virtualdoubledet_jacobian( const CartVect& )const
221 {
222returnthis->det_T;
223 };
224virtualdoubledet_ijacobian( const CartVect& )const
225 {
226returnthis->det_T_inverse;
227 };
228//229virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
230virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const;
231//232/* Override set_vertices so we can precompute the matrices effecting the mapping to and from
233 * the canonical simplex. */234virtualvoidset_vertices( const std::vector< CartVect >& v );
235virtualboolinside_nat_space( const CartVect& xi, double& tol )const;
236237protected:
238staticconstdouble corner[4][3];
239 Matrix3 T, T_inverse;
240double det_T, det_T_inverse;
241 }; // class LinearTet242243classSpectralHex : public Map
244 {
245public:
246SpectralHex( const std::vector< CartVect >& vertices ) : Map( vertices )
247 {
248 _xyz[0] = _xyz[1] = _xyz[2] = NULL;
249 };
250SpectralHex( int order, double* x, double* y, double* z );
251SpectralHex( int order );
252SpectralHex();
253virtual ~SpectralHex();
254voidset_gl_points( double* x, double* y, double* z );
255virtual CartVect evaluate( const CartVect& xi )const;
256virtual CartVect ievaluate( const CartVect& x, double tol = 1e-6, const CartVect& x0 = CartVect( 0.0 ) )const;
257virtual Matrix3 jacobian( const CartVect& xi )const;
258doubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
259doubleintegrate_scalar_field( constdouble* field_vertex_values )const;
260boolinside_nat_space( const CartVect& xi, double& tol )const;
261262// to compute the values that need to be cached for each element of order n263voidInit( int order );
264voidfreedata();
265266protected:
267/* values that depend only on the order of the element , cached */268/* the order in 3 directions */269staticint _n;
270static realType* _z[3];
271static lagrange_data _ld[3];
272static opt_data_3 _data;
273static realType* _odwork; // work area274275// flag for initialization of data276staticbool _init;
277278 realType* _xyz[3];
279280 }; // class SpectralHex281282/**\brief Shape function space for bilinear quadrilateral, obtained from the canonical linear
283 * (affine) functions. */284classLinearQuad : public Map
285 {
286public:
287LinearQuad( const std::vector< CartVect >& vertices ) : Map( vertices ){};
288LinearQuad();
289virtual ~LinearQuad();
290virtual CartVect evaluate( const CartVect& xi )const;
291// virtual CartVect ievaluate(const CartVect& x, double tol) const ;292virtualboolinside_nat_space( const CartVect& xi, double& tol )const;
293294virtual Matrix3 jacobian( const CartVect& xi )const;
295virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
296virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const;
297298protected:
299/* Preimages of the vertices -- "canonical vertices" -- are known as "corners". */300staticconstdouble corner[4][3];
301staticconstdouble gauss[1][2];
302staticconstunsignedint corner_count = 4;
303staticconstunsignedint gauss_count = 1;
304305 }; // class LinearQuad306307/**\brief Shape function space for bilinear quadrilateral on sphere, obtained from the
308 * canonical linear (affine) functions.
309 * It is mapped using gnomonic projection to a plane tangent at the first vertex
310 * It works well for edges that are great circle arcs; RLL meshes do not have this property,
311 * but HOMME or MPAS meshes do have it */312classSphericalQuad : public LinearQuad
313 {
314public:
315SphericalQuad( const std::vector< CartVect >& vertices );
316virtual ~SphericalQuad(){};
317virtualboolinside_box( const CartVect& pos, double& tol )const;
318CartVect ievaluate( const CartVect& x, double tol = 1e-6, const CartVect& x0 = CartVect( 0.0 ) )const;
319320protected:
321 CartVect v1;
322 Matrix3 transf; // so will have a lot of stuff, including the transf to a coordinate system323// double tangent_plane; // at first vertex; normal to the plane is first vertex324325 }; // class SphericalQuad326327/**\brief Shape function space for linear triangle, similar to linear tet. */328classLinearTri : public Map
329 {
330public:
331LinearTri( const std::vector< CartVect >& vertices ) : Map( vertices )
332 {
333set_vertices( vertex );
334 };
335LinearTri();
336virtual ~LinearTri();
337/* Override the evaluation routines to take advantage of the properties of P1. */338/* similar to tets */339virtual CartVect evaluate( const CartVect& xi )const
340 {
341returnthis->vertex[0] + this->T * xi;
342 };
343virtual CartVect ievaluate( const CartVect& x, double tol = 1e-6, const CartVect& x0 = CartVect( 0.0 ) )const;
344virtual Matrix3 jacobian( const CartVect& )const
345 {
346returnthis->T;
347 };
348virtual Matrix3 ijacobian( const CartVect& )const
349 {
350returnthis->T_inverse;
351 };
352virtualdoubledet_jacobian( const CartVect& )const
353 {
354returnthis->det_T;
355 };
356virtualdoubledet_ijacobian( const CartVect& )const
357 {
358returnthis->det_T_inverse;
359 };
360361/* Override set_vertices so we can precompute the matrices effecting the mapping to and from
362 * the canonical simplex. */363virtualvoidset_vertices( const std::vector< CartVect >& v );
364virtualboolinside_nat_space( const CartVect& xi, double& tol )const;
365366virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
367virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const;
368369protected:
370/* Preimages of the vertices -- "canonical vertices" -- are known as "corners". */371staticconstdouble corner[3][3];
372 Matrix3 T, T_inverse;
373double det_T, det_T_inverse;
374375 }; // class LinearTri376377/**\brief Shape function space for linear triangle on sphere, obtained from the
378 * canonical linear (affine) functions.
379 * It is mapped using gnomonic projection to a plane tangent at the first vertex
380 * It works well for edges that are great circle arcs; RLL meshes do not have this property,
381 * but HOMME or MPAS meshes do have it */382classSphericalTri : public LinearTri
383 {
384public:
385SphericalTri( const std::vector< CartVect >& vertices );
386virtual ~SphericalTri(){};
387virtualboolinside_box( const CartVect& pos, double& tol )const;
388CartVect ievaluate( const CartVect& x, double tol = 1e-6, const CartVect& x0 = CartVect( 0.0 ) )const;
389390protected:
391 CartVect v1;
392 Matrix3 transf; // so will have a lot of stuff, including the transf to a coordinate system393// double tangent_plane; // at first vertex; normal to the plane is first vertex394395 }; // class SphericalTri396397/**\brief Shape function space for bilinear quadrilateral, obtained from the canonical linear
398 * (affine) functions. */399classLinearEdge : public Map
400 {
401public:
402LinearEdge( const std::vector< CartVect >& vertices ) : Map( vertices ){};
403LinearEdge();
404virtual CartVect evaluate( const CartVect& xi )const;
405// virtual CartVect ievaluate(const CartVect& x, double tol) const ;406virtualboolinside_nat_space( const CartVect& xi, double& tol )const;
407408virtual Matrix3 jacobian( const CartVect& xi )const;
409virtualdoubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
410virtualdoubleintegrate_scalar_field( constdouble* field_vertex_values )const;
411412protected:
413/* Preimages of the vertices -- "canonical vertices" -- are known as "corners". */414staticconstdouble corner[2][3];
415staticconstdouble gauss[1][2];
416staticconstunsignedint corner_count = 2;
417staticconstunsignedint gauss_count = 1;
418419 }; // class LinearEdge420421classSpectralQuad : public Map
422 {
423public:
424SpectralQuad( const std::vector< CartVect >& vertices ) : Map( vertices )
425 {
426 _xyz[0] = _xyz[1] = _xyz[2] = NULL;
427 };
428SpectralQuad( int order, double* x, double* y, double* z );
429SpectralQuad( int order );
430SpectralQuad();
431virtual ~SpectralQuad();
432voidset_gl_points( double* x, double* y, double* z );
433virtual CartVect evaluate( const CartVect& xi )const; // a 2d, so 3rd component is 0, always434virtual CartVect ievaluate(
435const CartVect& x,
436double tol = 1e-6,
437const CartVect& x0 = CartVect( 0.0 ) )const; // a 2d, so 3rd component is 0, always438virtual Matrix3 jacobian( const CartVect& xi )const;
439doubleevaluate_scalar_field( const CartVect& xi, constdouble* field_vertex_values )const;
440doubleintegrate_scalar_field( constdouble* field_vertex_values )const;
441boolinside_nat_space( const CartVect& xi, double& tol )const;
442443// to compute the values that need to be cached for each element of order n444voidInit( int order );
445voidfreedata();
446// this will take node, vertex positions and compute the gl points447voidcompute_gl_positions();
448voidget_gl_points( double*& x, double*& y, double*& z, int& size );
449450protected:
451/* values that depend only on the order of the element , cached */452/* the order in all 3 directions ; it is also np in HOMME lingo*/453staticint _n;
454static realType* _z[2];
455static lagrange_data _ld[2];
456static opt_data_2 _data; // we should use only 2nd component457static realType* _odwork; // work area458459// flag for initialization of data460staticbool _init;
461static realType* _glpoints; // it is a space we can use to store gl positions for elements462// on the fly; we do not have a tag yet for them, as in Nek5000 application463// also, these positions might need to be moved on the sphere, for HOMME grids464// do we project them or how do we move them on the sphere?465466 realType* _xyz[3]; // these are gl points; position?467468 }; // class SpectralQuad469470 } // namespace Element471472 } // namespace moab473474#endif/*MOAB_ELEM_UTIL_HPP*/