MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
eltrans.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_ELEMENTTRANSFORM
13#define MFEM_ELEMENTTRANSFORM
14
15#include "../config/config.hpp"
16#include "../linalg/linalg.hpp"
17#include "intrules.hpp"
18#include "fe.hpp"
19
20#include "kernel_dispatch.hpp"
21
22namespace mfem
23{
24
25class GridFunction;
26
28{
29protected:
45
46 /** @brief Evaluate the Jacobian of the transformation at the IntPoint and
47 store it in dFdx. */
48 virtual const DenseMatrix &EvalJacobian() = 0;
49
50 /** @brief Evaluate the Hessian of the transformation at the IntPoint and
51 store it in d2Fdx2. */
52 virtual const DenseMatrix &EvalHessian() = 0;
53
58
59 /// @name Tolerance used for point comparisons
60 ///@{
61#ifdef MFEM_USE_DOUBLE
62 static constexpr real_t tol_0 = 1e-15;
63#elif defined(MFEM_USE_SINGLE)
64 static constexpr real_t tol_0 = 1e-7;
65#endif
66 ///@}
67
68public:
69
70 /** This enumeration declares the values stored in
71 ElementTransformation::ElementType and indicates which group of objects
72 the index stored in ElementTransformation::ElementNo refers:
73
74 | ElementType | Range of ElementNo
75 +-------------+-------------------------
76 | ELEMENT | [0, Mesh::GetNE() )
77 | BDR_ELEMENT | [0, Mesh::GetNBE() )
78 | EDGE | [0, Mesh::GetNEdges() )
79 | FACE | [0, Mesh::GetNFaces() )
80 | BDR_FACE | [0, Mesh::GetNBE() )
81 */
82 enum
83 {
86 EDGE = 3,
87 FACE = 4,
88 BDR_FACE = 5
89 };
90
92
93 /// The Mesh object containing the element.
94 /** If the element transformation belongs to a mesh, this will point to the
95 containing Mesh object. ElementNo will be the number of the element in
96 this Mesh. This will be NULL if the element does not belong to a mesh. */
97 const Mesh *mesh;
98
100
101 /** @brief Force the reevaluation of the Jacobian in the next call. */
102 void Reset() { EvalState = 0; }
103
104 /** @brief Set the integration point @a ip that weights and Jacobians will
105 be evaluated at. */
107 { IntPoint = ip; EvalState = 0; }
108
109 /** @brief Get a const reference to the currently set integration point. This
110 will return NULL if no integration point is set. */
112
113 /** @brief Transform integration point from reference coordinates to
114 physical coordinates and store them in the vector. */
115 virtual void Transform(const IntegrationPoint &, Vector &) = 0;
116
117 /** @brief Transform all the integration points from the integration rule
118 from reference coordinates to physical
119 coordinates and store them as column vectors in the matrix. */
120 virtual void Transform(const IntegrationRule &, DenseMatrix &) = 0;
121
122 /** @brief Transform all the integration points from the column vectors
123 of @a matrix from reference coordinates to physical
124 coordinates and store them as column vectors in @a result. */
125 virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result) = 0;
126
127 /** @brief Return the Jacobian matrix of the transformation at the currently
128 set IntegrationPoint, using the method SetIntPoint(). */
129 /** The dimensions of the Jacobian matrix are physical-space-dim by
130 reference-space-dim. The first column contains the x derivatives of the
131 transformation, the second -- the y derivatives, etc. */
133 { return (EvalState & JACOBIAN_MASK) ? dFdx : EvalJacobian(); }
134
135
136 /** @brief Return the Hessian matrix of the transformation at the currently
137 set IntegrationPoint, using the method SetIntPoint(). */
139 { return (EvalState & HESSIAN_MASK) ? d2Fdx2 : EvalHessian(); }
140
141 /** @brief Return the weight of the Jacobian matrix of the transformation
142 at the currently set IntegrationPoint.
143 The Weight evaluates to $ \sqrt{\lvert J^T J \rvert} $. */
145
146 /** @brief Return the adjugate of the Jacobian matrix of the transformation
147 at the currently set IntegrationPoint. */
150
151 /** @brief Return the transpose of the adjugate of the Jacobian matrix of
152 the transformation at the currently set IntegrationPoint. */
155
156 /** @brief Return the inverse of the Jacobian matrix of the transformation
157 at the currently set IntegrationPoint. */
160
161 /// Return the order of the current element we are using for the transformation.
162 virtual int Order() const = 0;
163
164 /// Return the order of the elements of the Jacobian of the transformation.
165 virtual int OrderJ() const = 0;
166
167 /** @brief Return the order of the determinant of the Jacobian (weight)
168 of the transformation. */
169 virtual int OrderW() const = 0;
170
171 /// Return the order of $ adj(J)^T \nabla fi $
172 virtual int OrderGrad(const FiniteElement *fe) const = 0;
173
174 /// Return the Geometry::Type of the reference element.
176
177 /// Return the topological dimension of the reference element.
178 int GetDimension() const { return Geometry::Dimension[geom]; }
179
180 /// Get the dimension of the target (physical) space.
181 /** We support 2D meshes embedded in 3D; in this case the function will
182 return "3". */
183 virtual int GetSpaceDim() const = 0;
184
185 /** @brief Transform a point @a pt from physical space to a point @a ip in
186 reference space and optionally can set a solver tolerance using @a phys_tol. */
187 /** Attempt to find the IntegrationPoint that is transformed into the given
188 point in physical space. If the inversion fails a non-zero value is
189 returned. This method is not 100 percent reliable for non-linear
190 transformations. */
191 virtual int TransformBack(const Vector &pt, IntegrationPoint &ip,
192 const real_t phys_tol = tol_0) = 0;
193
195};
196
197
198/// The inverse transformation of a given ElementTransformation.
200{
201public:
202 /// Algorithms for selecting an initial guess.
204 {
205 Center = 0, ///< Use the center of the reference element.
206 ClosestPhysNode = 1, /**<
207 Use the point returned by FindClosestPhysPoint() from a reference-space
208 grid of type and size controlled by SetInitGuessPointsType() and
209 SetInitGuessRelOrder(), respectively. */
210 ClosestRefNode = 2, /**<
211 Use the point returned by FindClosestRefPoint() from a reference-space
212 grid of type and size controlled by SetInitGuessPointsType() and
213 SetInitGuessRelOrder(), respectively. */
214 GivenPoint = 3, ///< Use a specific point, set with SetInitialGuess().
215 EdgeScan =
216 4, /**< Performs full solves on multiple points along the r/s/t=0 edges
217 of the element. It is recommended that SetInitGuessRelOrder() is
218 chosen such that max(trans_order+order,0)+1 <= 4 with
219 SetInitGuessPointsType() as Quadrature1D::ClosedUniform. @see
220 GeometryRefiner::EdgeScan */
221 };
222
223 /// Solution strategy.
225 {
226 Newton = 0, /**<
227 Use Newton's algorithm, without restricting the reference-space points
228 (iterates) to the reference element. */
229 NewtonSegmentProject = 1, /**<
230 Use Newton's algorithm, restricting the reference-space points to the
231 reference element by scaling back the Newton increments, i.e.
232 projecting new iterates, x_new, lying outside the element, to the
233 intersection of the line segment [x_old, x_new] with the boundary. */
234 NewtonElementProject = 2, /**<
235 Use Newton's algorithm, restricting the reference-space points to the
236 reference element by projecting new iterates, x_new, lying outside the
237 element, to the point on the boundary closest (in reference-space) to
238 x_new. */
239 };
240
241 /// Values returned by Transform().
243 {
244 Inside = 0, ///< The point is inside the element
245 Outside = 1, ///< The point is _probably_ outside the element
246 Unknown = 2 ///< The algorithm failed to determine where the point is
247 };
248
249protected:
250 // Pointer to the forward transformation. Not owned.
252
253 // Parameters of the inversion algorithms:
255 int init_guess_type; // algorithm to use
256 GeometryRefiner refiner; // geometry refiner for initial guess
257 int qpts_order; // num_1D_qpts = rel_qpts_order + 1, or < 0 to use
258 // rel_qpts_order.
259 int rel_qpts_order; // num_1D_qpts = max(trans_order+rel_qpts_order,0)+1
260 int solver_type; // solution strategy to use
261 int max_iter; // max. number of Newton iterations
262 real_t ref_tol; // reference space tolerance
263 real_t phys_rtol; // physical space tolerance (relative)
264 real_t ip_tol; // tolerance for checking if a point is inside the ref. elem.
266
267 void NewtonPrint(int mode, real_t val);
268 void NewtonPrintPoint(const char *prefix, const Vector &pt,
269 const char *suffix);
270 int NewtonSolve(const Vector &pt, IntegrationPoint &ip);
271
272public:
273 /// Construct the InverseElementTransformation with default parameters.
274 /** Some practical considerations regarding the choice of initial guess type
275 and solver type:
276 1. The combination of #Center and #NewtonSegmentProject provides the
277 fastest way to estimate if a point lies inside an element, assuming
278 that most queried elements are not very deformed, e.g. if most
279 elements are convex.
280 2. [Default] The combination of #Center and #NewtonElementProject
281 provides a somewhat slower alternative to 1 with the benefit of being
282 more reliable in the case when the query point is inside the element
283 but potentially slower in the case when the query point is outside the
284 element.
285 3. The combination of #ClosestPhysNode and #NewtonElementProject is
286 slower than 1 and 2 but much more reliable, especially in the case of
287 highly distorted elements which do not have very high aspect ratios.
288 4. The combination of #ClosestRefNode and #NewtonElementProject should
289 generally be the most reliable, coming at a bit higher computational
290 cost than 3 while performing better on distorted meshes with elements
291 having high aspect ratios.
292 @note None of these choices provide a guarantee that if a query point is
293 inside the element then it will be found. The only guarantee is that if
294 the Transform() method returns #Inside then the point lies inside the
295 element up to one of the specified physical- or reference-space
296 tolerances. */
298 : T(Trans),
300 refiner(Quadrature1D::OpenHalfUniform),
301 qpts_order(-1),
302 rel_qpts_order(-1),
304 max_iter(16),
305#ifdef MFEM_USE_DOUBLE
306 ref_tol(1e-15),
307 phys_rtol(4e-15),
308 ip_tol(1e-8),
309#elif defined(MFEM_USE_SINGLE)
310 ref_tol(4e-7),
311 phys_rtol(1e-6),
312 ip_tol(1e-4),
313#endif
314 print_level(-1)
315 { }
316
318
319 /// Set a new forward ElementTransformation, @a Trans.
320 void SetTransformation(ElementTransformation &Trans) { T = &Trans; }
321
322 /** @brief Choose how the initial guesses for subsequent calls to Transform()
323 will be selected. */
325
326 /** @brief Set the initial guess for subsequent calls to Transform(),
327 switching to the #GivenPoint #InitGuessType at the same time. */
329 { ip0 = init_ip; SetInitialGuessType(GivenPoint); }
330
331 /// Set the Quadrature1D type used for the `Closest*` and `EdgeScan` initial
332 /// guess types.
333 void SetInitGuessPointsType(int q_type) { refiner.SetType(q_type); }
334
335 /// Set the relative order used for the `Closest*` initial guess types.
336 /** The number of points in each spatial direction is given by the formula
337 max(trans_order+order,0)+1, where trans_order is the order of the current
338 ElementTransformation. */
339 void SetInitGuessRelOrder(int order)
340 {
341 qpts_order = -1;
342 rel_qpts_order = order;
343 }
344
345 /** The number of points in each spatial direction is given by the formula
346 order+1. */
347 void SetInitGuessOrder(int order)
348 {
349 qpts_order = order;
350 }
351
352 /** @brief Specify which algorithm to use for solving the transformation
353 equation, i.e. when calling the Transform() method. */
354 void SetSolverType(SolverType stype) { solver_type = stype; }
355
356 /// Set the maximum number of iterations when solving for a reference point.
357 void SetMaxIter(int max_it) { max_iter = max_it; }
358
359 /// Set the reference-space convergence tolerance.
360 void SetReferenceTol(real_t ref_sp_tol) { ref_tol = ref_sp_tol; }
361
362 /// Set the relative physical-space convergence tolerance.
363 void SetPhysicalRelTol(real_t phys_rel_tol) { phys_rtol = phys_rel_tol; }
364
365 /** @brief Set the tolerance used to determine if a point lies inside or
366 outside of the reference element. */
367 /** This tolerance is used only with the pure #Newton solver. */
368 void SetElementTol(real_t el_tol) { ip_tol = el_tol; }
369
370 /// Set the desired print level, useful for debugging.
371 /** The valid options are: -1 - never print (default); 0 - print only errors;
372 1 - print the first and last iterations; 2 - print every iteration;
373 and 3 - print every iteration including point coordinates. */
374 void SetPrintLevel(int pr_level) { print_level = pr_level; }
375
376 /** @brief Find the IntegrationPoint mapped closest to @a pt. */
377 /** This function uses the given IntegrationRule, @a ir, maps its points to
378 physical space and finds the one that is closest to the point @a pt.
379
380 @param pt The query point.
381 @param ir The IntegrationRule, i.e. the set of reference points to map
382 to physical space and check.
383 @return The index of the IntegrationPoint in @a ir whose mapped point is
384 closest to @a pt.
385 @see FindClosestRefPoint(). */
386 int FindClosestPhysPoint(const Vector& pt, const IntegrationRule &ir);
387
388 /** @brief Find the IntegrationPoint mapped closest to @a pt, using a norm
389 that approximates the (unknown) distance in reference coordinates. */
390 /** @see FindClosestPhysPoint(). */
391 int FindClosestRefPoint(const Vector& pt, const IntegrationRule &ir);
392
393 /** @brief Given a point, @a pt, in physical space, find its reference
394 coordinates, @a ip.
395
396 @returns A value of type #TransformResult. */
397 virtual int Transform(const Vector &pt, IntegrationPoint &ip);
398};
399
400/**
401 * @brief Performs batch inverse element transforms. Currently only supports
402 * non-mixed meshes with SEGMENT, SQUARE, or CUBE geometries. Mixed
403 * element order meshes are projected onto an equivalent uniform order mesh.
404 */
406{
407 // nodes grid function, not owned
408 const GridFunction *gf_ = nullptr;
409 // initial guess algorithm to use
412 int qpts_order = -1; // num_1D_qpts = rel_qpts_order + 1, or < 0 to use
413 // rel_qpts_order.
414 // num_1D_qpts = max(trans_order+rel_qpts_order,0)+1
415 int rel_qpts_order = 0;
416 // solution strategy to use
419 // basis type stored in points1d
420 int basis_type = BasisType::Invalid;
421 // initial guess points type. Quadrature1D::Invalid is used for match
422 // basis_type.
423 int guess_points_type = Quadrature1D::Invalid;
424 // max. number of Newton iterations
425 int max_iter = 16;
426 // internal element node locations cache
427 Vector node_pos;
428#ifdef MFEM_USE_DOUBLE
429 // reference space tolerance
430 real_t ref_tol = 1e-15;
431 // physical space tolerance (relative)
432 real_t phys_rtol = 4e-15;
433#else
434 // reference space tolerance
435 real_t ref_tol = 4e-7;
436 // physical space tolerance (relative)
437 real_t phys_rtol = 1e-6;
438#endif
439 // not owned, location of tensor product basis nodes in reference space
440 const Array<real_t> *points1d = nullptr;
441
442public:
443 /// Uninitialized BatchInverseElementTransformation. Users must call
444 /// UpdateNodes before Transform.
446 ///
447 /// Constructs a BatchInverseElementTransformation given @a nodes representing
448 /// the mesh nodes.
449 ///
452 ///
453 /// Constructs a BatchInverseElementTransformation for a given @a mesh.
454 /// mesh.GetNodes() must not be null.
455 ///
458
460
461 /** @brief Choose how the initial guesses for subsequent calls to Transform()
462 will be selected. ClosestRefNode is currently not supported. */
464 {
466 "ClosestRefNode is currently not supported");
467 init_guess_type = itype;
468 }
469
470 /// Set the Quadrature1D type used for the `Closest*` and `EdgeScan` initial
471 /// guess types.
472 void SetInitGuessPointsType(int q_type) { guess_points_type = q_type; }
473
474 /// Set the relative order used for the `Closest*` initial guess types.
475 /** The number of points in each spatial direction is given by the formula
476 max(trans_order+order,0)+1, where trans_order is the order of the
477 current ElementTransformation. */
478 void SetInitGuessRelOrder(int order)
479 {
480 qpts_order = -1;
481 rel_qpts_order = order;
482 }
483
484 /** The number of points in each spatial direction is given by the formula
485 order+1. */
486 void SetInitGuessOrder(int order) { qpts_order = order; }
487
488 /// @b Gets the basis type nodes are projected onto, or BasisType::Invalid if
489 /// uninitialized.
490 int GetBasisType() const { return basis_type; }
491
492 /** @brief Specify which algorithm to use for solving the transformation
493 equation, i.e. when calling the Transform() method. NewtonSegmentProject
494 is currently not supported. */
496 {
498 "NewtonSegmentProject is currently not supported");
499 solver_type = stype;
500 }
501
502 /// Set the maximum number of iterations when solving for a reference point.
503 void SetMaxIter(int max_it) { max_iter = max_it; }
504
505 /// Set the reference-space convergence tolerance.
506 void SetReferenceTol(real_t ref_sp_tol) { ref_tol = ref_sp_tol; }
507
508 /// Set the relative physical-space convergence tolerance.
509 void SetPhysicalRelTol(real_t phys_rel_tol) { phys_rtol = phys_rel_tol; }
510
511 /**
512 * @brief Updates internal datastructures if @a nodes change. Some version
513 * of UpdateNodes must be called at least once before calls to Transform if
514 * nodes have changed.
515 */
516 void UpdateNodes(const GridFunction &nodes,
518 /**
519 * @brief Updates internal datastructures if @a mesh nodes change. Some version
520 * of UpdateNodes must be called at least once before calls to Transform if
521 * mesh nodes have changed. mesh.GetNodes() must not be null.
522 */
523 void UpdateNodes(const Mesh &mesh, MemoryType d_mt = MemoryType::DEFAULT);
524
525 /** @brief Performs a batch request of a set of points belonging to the given
526 elements.
527 @a pts list of physical point coordinates ordered by
528 Ordering::Type::byNODES.
529 @a elems which element index to search for each corresponding point in
530 @a pts
531 @a types output search classification (@see
532 InverseElementTransformation::TransformResult).
533 @a refs result reference point coordinates ordered by
534 Ordering::Type::byNODES. If using InitGuessType::GivenPoint, this should
535 contain the initial guess for each point.
536 @a use_device hint for if device acceleration should be used.
537 Device acceleration is currently only implemented for meshes containing
538 only a single tensor product basis element type.
539 @a iters optional array storing how many iterations was spent on each
540 tested point
541 */
542 void Transform(const Vector &pts, const Array<int> &elems, Array<int> &types,
543 Vector &refs, bool use_device = true,
544 Array<int> *iters = nullptr) const;
545
546 using ClosestPhysPointKernelType = void (*)(int, int, int, int,
547 const real_t *, const real_t *,
548 const int *, const real_t *,
549 const real_t *, real_t *);
550
551 // specialization params: Geom, SDim, use_device
553 (int, int, bool));
554
555 using ClosestPhysDofKernelType = void (*)(int, int, int,
556 const real_t *, const real_t *,
557 const int *, const real_t *,
558 real_t *);
559
560 // specialization params: Geom, SDim, use_device
562 (int, int, bool));
563
564 using ClosestRefDofKernelType = void (*)(int, int, int, const real_t *,
565 const real_t *, const int *,
566 const real_t *, real_t *);
567
568 // specialization params: Geom, SDim, use_device
570 (int, int, bool));
571
572 using ClosestRefPointKernelType = void (*)(int, int, int, int, const real_t *,
573 const real_t *, const int *,
574 const real_t *, const real_t *,
575 real_t *);
576
577 // specialization params: Geom, SDim, use_device
579 (int, int, bool));
580
581 using NewtonKernelType = void (*)(real_t, real_t, int, int, int, int,
582 const real_t *, const real_t *,
583 const int *, const real_t *, int *, int*,
584 real_t *);
585
586 // specialization params: Geom, SDim, SolverType, use_device
589 bool));
590
591 using NewtonEdgeScanKernelType = void (*)(real_t, real_t, int, int, int, int,
592 const real_t *, const real_t *,
593 const int *, const real_t *,
594 const real_t *, int, int *, int *,
595 real_t *);
596
597 // specialization params: Geom, SDim, SolverType, use_device
600 bool));
601
602 struct Kernels { Kernels(); };
603
604 template <int Dim, int SDim>
606 {
607 FindClosestPhysPoint::Specialization<Dim, SDim, true>::Add();
608 FindClosestRefPoint::Specialization<Dim, SDim, true>::Add();
609 FindClosestPhysPoint::Specialization<Dim, SDim, false>::Add();
610 FindClosestRefPoint::Specialization<Dim, SDim, false>::Add();
611 FindClosestPhysDof::Specialization<Dim, SDim, true>::Add();
612 FindClosestRefDof::Specialization<Dim, SDim, true>::Add();
613 FindClosestPhysDof::Specialization<Dim, SDim, false>::Add();
614 FindClosestRefDof::Specialization<Dim, SDim, false>::Add();
615 }
616
617 template <int Dim, int SDim, InverseElementTransformation::SolverType SType>
619 {
620 NewtonSolve::Specialization<Dim, SDim, SType, true>::Add();
621 NewtonEdgeScan::Specialization<Dim, SDim, SType, true>::Add();
622 NewtonSolve::Specialization<Dim, SDim, SType, false>::Add();
623 NewtonEdgeScan::Specialization<Dim, SDim, SType, false>::Add();
624 }
625};
626
627/// A standard isoparametric element transformation
629{
630private:
631 DenseMatrix dshape, d2shape;
632 Vector shape;
633
634 const FiniteElement *FElem;
635 DenseMatrix PointMat; // dim x dof
636
637 /** @brief Evaluate the Jacobian of the transformation at the IntPoint and
638 store it in dFdx. */
639 const DenseMatrix &EvalJacobian() override;
640 // Evaluate the Hessian of the transformation at the IntPoint and store it
641 // in d2Fdx2.
642 const DenseMatrix &EvalHessian() override;
643
644public:
646
647 /// Set the element that will be used to compute the transformations
648 void SetFE(const FiniteElement *FE)
649 {
650 MFEM_ASSERT(FE != NULL, "Must provide a valid FiniteElement object!");
651 EvalState = (FE != FElem) ? 0 : EvalState;
652 FElem = FE; geom = FE->GetGeomType();
653 }
654
655 /// Get the current element used to compute the transformations
656 const FiniteElement* GetFE() const { return FElem; }
657
658 /// @brief Set the underlying point matrix describing the transformation.
659 /** The dimensions of the matrix are space-dim x dof. The transformation is
660 defined as
661 $ x = F( \hat x ) = P \phi( \hat x ) $
662
663 where $ \hat x $ is the reference point, @a x is the corresponding
664 physical point, @a P is the point matrix, and $ \phi( \hat x ) $ is
665 the column-vector of all basis functions evaluated at $ \hat x $ .
666 The columns of @a P represent the control points in physical space
667 defining the transformation. */
668 void SetPointMat(const DenseMatrix &pm) { PointMat = pm; EvalState = 0; }
669
670 /// Return the stored point matrix.
671 const DenseMatrix &GetPointMat() const { return PointMat; }
672
673 /// @brief Write access to the stored point matrix. Use with caution.
674 /** If the point matrix is altered using this member function the Reset
675 function should also be called to force the reevaluation of the
676 Jacobian, etc.. */
677 DenseMatrix &GetPointMat() { return PointMat; }
678
679 /// Set the FiniteElement Geometry for the reference elements being used.
681
682 /** @brief Transform integration point from reference coordinates to
683 physical coordinates and store them in the vector. */
684 void Transform(const IntegrationPoint &, Vector &) override;
685
686 /** @brief Transform all the integration points from the integration rule
687 from reference coordinates to physical
688 coordinates and store them as column vectors in the matrix. */
689 void Transform(const IntegrationRule &, DenseMatrix &) override;
690
691 /** @brief Transform all the integration points from the column vectors
692 of @a matrix from reference coordinates to physical
693 coordinates and store them as column vectors in @a result. */
694 void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
695
696 /// Return the order of the current element we are using for the transformation.
697 int Order() const override { return FElem->GetOrder(); }
698
699 /// Return the order of the elements of the Jacobian of the transformation.
700 int OrderJ() const override;
701
702 /** @brief Return the order of the determinant of the Jacobian (weight)
703 of the transformation. */
704 int OrderW() const override;
705
706 /// Return the order of $ adj(J)^T \nabla fi $
707 int OrderGrad(const FiniteElement *fe) const override;
708
709 int GetSpaceDim() const override { return PointMat.Height(); }
710
711 /** @brief Transform a point @a pt from physical space to a point @a ip in
712 reference space and optionally can set a solver tolerance using @a phys_tol. */
713 /** Attempt to find the IntegrationPoint that is transformed into the given
714 point in physical space. If the inversion fails a non-zero value is
715 returned. This method is not 100 percent reliable for non-linear
716 transformations. */
718 const real_t phys_rel_tol = tol_0) override
719 {
720 InverseElementTransformation inv_tr(this);
721 inv_tr.SetPhysicalRelTol(phys_rel_tol);
722 return inv_tr.Transform(v, ip);
723 }
724
726
727 MFEM_DEPRECATED void FinalizeTransformation() {}
728};
729
737
738/** @brief A specialized ElementTransformation class representing a face and
739 its two neighboring elements.
740
741 This class can be used as a container for the element transformation data
742 needed for integrating discontinuous fields on element interfaces in a
743 Discontinuous Galerkin (DG) context.
744
745 The secondary purpose of this class is to enable the
746 GridFunction::GetValue function, and various related functions, to properly
747 evaluate fields with limited continuity on boundary elements.
748*/
750{
751private:
752
753 // Bitwise OR of ConfigMasks
754 int mask;
755
756 IntegrationPoint eip1, eip2;
757
758protected: // interface for Mesh to be able to configure this object.
759
760 friend class Mesh;
761#ifdef MFEM_USE_MPI
762 friend class ParMesh;
763#endif
764
765 /// Set the mask indicating which portions of the object have been setup
766 /** The argument @a m is a bitmask used in
767 Mesh::GetFaceElementTransformations to indicate which portions of the
768 FaceElementTransformations object have been configured.
769
770 mask & 1: Elem1 is configured
771 mask & 2: Elem2 is configured
772 mask & 4: Loc1 is configured
773 mask & 8: Loc2 is configured
774 mask & 16: The Face transformation itself is configured
775 */
776 void SetConfigurationMask(int m) { mask = m; }
777
778public:
779
781 {
782 HAVE_ELEM1 = 1, ///< Element on side 1 is configured
783 HAVE_ELEM2 = 2, ///< Element on side 2 is configured
784 HAVE_LOC1 = 4, ///< Point transformation for side 1 is configured
785 HAVE_LOC2 = 8, ///< Point transformation for side 2 is configured
786 HAVE_FACE = 16 ///< Face transformation is configured
787 };
788
790 Geometry::Type &FaceGeom; ///< @deprecated Use GetGeometryType instead
792 ElementTransformation *Face; ///< @deprecated No longer necessary
794
796
797 /** @brief Method to set the geometry type of the face.
798
799 @note This method is designed to be used when
800 [Par]Mesh::GetFaceTransformation will not be called i.e. when the face
801 transformation will not be needed but the neighboring element
802 transformations will be. Using this method to override the GeometryType
803 should only be done with great care.
804 */
806
807 /** @brief Return the mask defining the configuration state.
808
809 The mask value indicates which portions of FaceElementTransformations
810 object have been configured.
811
812 mask & 1: Elem1 is configured
813 mask & 2: Elem2 is configured
814 mask & 4: Loc1 is configured
815 mask & 8: Loc2 is configured
816 mask & 16: The Face transformation itself is configured
817 */
818 int GetConfigurationMask() const { return mask; }
819
820 /** @brief Set the integration point in the Face and the two neighboring
821 elements, if present.
822
823 The point @a face_ip must be in the reference coordinate system of the
824 face.
825 */
826 void SetIntPoint(const IntegrationPoint *face_ip);
827
828 /** @brief Set the integration point in the Face and the two neighboring
829 elements, if present.
830
831 This is a more expressive member function name than SetIntPoint, which
832 in this special case, does the same thing. This function can be used for
833 greater code clarity.
834 */
835 inline void SetAllIntPoints(const IntegrationPoint *face_ip)
837
838 /** @brief Get a const reference to the integration point in neighboring
839 element 1 corresponding to the currently set integration point on the
840 face.
841
842 This IntegrationPoint object will only contain up-to-date data if
843 SetIntPoint or SetAllIntPoints has been called with the latest
844 integration point for the face and the appropriate point transformation
845 has been configured. */
846 const IntegrationPoint &GetElement1IntPoint() { return eip1; }
847
848 /** @brief Get a const reference to the integration point in neighboring
849 element 2 corresponding to the currently set integration point on the
850 face.
851
852 This IntegrationPoint object will only contain up-to-date data if
853 SetIntPoint or SetAllIntPoints has been called with the latest
854 integration point for the face and the appropriate point transformation
855 has been configured. */
856 const IntegrationPoint &GetElement2IntPoint() { return eip2; }
857
858 void Transform(const IntegrationPoint &, Vector &) override;
859 void Transform(const IntegrationRule &, DenseMatrix &) override;
860 void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
861
866
867 /** @brief Check for self-consistency: compares the result of mapping the
868 reference face vertices to physical coordinates using the three
869 transformations: face, element 1, and element 2.
870
871 @param[in] print_level If set to a positive number, print the physical
872 coordinates of the face vertices computed through
873 all available transformations: face, element 1,
874 and/or element 2.
875 @param[in,out] out The output stream to use for printing.
876
877 @returns A maximal distance between physical coordinates of face vertices
878 that should coincide. A successful check should return a small
879 number relative to the mesh extents. If less than 2 of the three
880 transformations are set, returns 0.
881
882 @warning This check will generally fail on periodic boundary faces.
883 */
884 real_t CheckConsistency(int print_level = 0,
885 std::ostream &out = mfem::out);
886};
887
888/** Elem1(Loc1(x)) = Face(x) = Elem2(Loc2(x))
889
890
891 Physical Space
892
893 *--------* ^ *--------*
894 Elem1No / / \ / \ / \ \ Elem2No
895 / / \ / \ / \ \
896 / / n \ / \ / \ \
897 *--------* ==> * ( ) * *--------*
898 \ \ / \ / \ / /
899 \ \ / \ / \ / /
900 \ \ / \ / \ / /
901 *--------* v *--------*
902
903 ^ ^
904 | ^ |
905 Elem1 | | | Elem2
906 | | Face |
907 |
908 *--------* *--------*
909 / /| / /|
910 1 *--------* | 1 *--------* 1 *--------* |
911 | | | Loc1 | | Loc2 | | |
912 | | * <----- | x | -----> | | *
913 | |/ | | | |/
914 *--------* *--------* *--------*
915 0 1 0 1 0 1
916
917 Reference Space
918*/
919
920}
921
922#endif
Performs batch inverse element transforms. Currently only supports non-mixed meshes with SEGMENT,...
Definition eltrans.hpp:406
void SetMaxIter(int max_it)
Set the maximum number of iterations when solving for a reference point.
Definition eltrans.hpp:503
void UpdateNodes(const GridFunction &nodes, MemoryType d_mt=MemoryType::DEFAULT)
Updates internal datastructures if nodes change. Some version of UpdateNodes must be called at least ...
MFEM_REGISTER_KERNELS(NewtonSolve, NewtonKernelType,(int, int, InverseElementTransformation::SolverType, bool))
MFEM_REGISTER_KERNELS(FindClosestRefDof, ClosestRefDofKernelType,(int, int, bool))
void SetSolverType(InverseElementTransformation::SolverType stype)
Specify which algorithm to use for solving the transformation equation, i.e. when calling the Transfo...
Definition eltrans.hpp:495
void SetInitGuessRelOrder(int order)
Set the relative order used for the Closest* initial guess types.
Definition eltrans.hpp:478
void(*)(real_t, real_t, int, int, int, int, const real_t *, const real_t *, const int *, const real_t *, const real_t *, int, int *, int *, real_t *) NewtonEdgeScanKernelType
Definition eltrans.hpp:591
MFEM_REGISTER_KERNELS(NewtonEdgeScan, NewtonEdgeScanKernelType,(int, int, InverseElementTransformation::SolverType, bool))
void(*)(int, int, int, int, const real_t *, const real_t *, const int *, const real_t *, const real_t *, real_t *) ClosestRefPointKernelType
Definition eltrans.hpp:572
void SetReferenceTol(real_t ref_sp_tol)
Set the reference-space convergence tolerance.
Definition eltrans.hpp:506
void SetInitialGuessType(InverseElementTransformation::InitGuessType itype)
Choose how the initial guesses for subsequent calls to Transform() will be selected....
Definition eltrans.hpp:463
void(*)(int, int, int, const real_t *, const real_t *, const int *, const real_t *, real_t *) ClosestRefDofKernelType
Definition eltrans.hpp:564
void SetPhysicalRelTol(real_t phys_rel_tol)
Set the relative physical-space convergence tolerance.
Definition eltrans.hpp:509
void Transform(const Vector &pts, const Array< int > &elems, Array< int > &types, Vector &refs, bool use_device=true, Array< int > *iters=nullptr) const
Performs a batch request of a set of points belonging to the given elements. pts list of physical poi...
MFEM_REGISTER_KERNELS(FindClosestRefPoint, ClosestRefPointKernelType,(int, int, bool))
void(*)(int, int, int, int, const real_t *, const real_t *, const int *, const real_t *, const real_t *, real_t *) ClosestPhysPointKernelType
Definition eltrans.hpp:546
void(*)(int, int, int, const real_t *, const real_t *, const int *, const real_t *, real_t *) ClosestPhysDofKernelType
Definition eltrans.hpp:555
void(*)(real_t, real_t, int, int, int, int, const real_t *, const real_t *, const int *, const real_t *, int *, int *, real_t *) NewtonKernelType
Definition eltrans.hpp:581
MFEM_REGISTER_KERNELS(FindClosestPhysPoint, ClosestPhysPointKernelType,(int, int, bool))
MFEM_REGISTER_KERNELS(FindClosestPhysDof, ClosestPhysDofKernelType,(int, int, bool))
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
const Mesh * mesh
The Mesh object containing the element.
Definition eltrans.hpp:97
virtual const DenseMatrix & EvalJacobian()=0
Evaluate the Jacobian of the transformation at the IntPoint and store it in dFdx.
virtual int Order() const =0
Return the order of the current element we are using for the transformation.
const DenseMatrix & TransposeAdjugateJacobian()
Return the transpose of the adjugate of the Jacobian matrix of the transformation at the currently se...
Definition eltrans.hpp:153
Geometry::Type GetGeometryType() const
Return the Geometry::Type of the reference element.
Definition eltrans.hpp:175
virtual void Transform(const IntegrationRule &, DenseMatrix &)=0
Transform all the integration points from the integration rule from reference coordinates to physical...
virtual int OrderGrad(const FiniteElement *fe) const =0
Return the order of .
const DenseMatrix & Hessian()
Return the Hessian matrix of the transformation at the currently set IntegrationPoint,...
Definition eltrans.hpp:138
const DenseMatrix & InverseJacobian()
Return the inverse of the Jacobian matrix of the transformation at the currently set IntegrationPoint...
Definition eltrans.hpp:158
const DenseMatrix & AdjugateJacobian()
Return the adjugate of the Jacobian matrix of the transformation at the currently set IntegrationPoin...
Definition eltrans.hpp:148
const IntegrationPoint & GetIntPoint()
Get a const reference to the currently set integration point. This will return NULL if no integration...
Definition eltrans.hpp:111
const DenseMatrix & EvalAdjugateJ()
Definition eltrans.cpp:38
static constexpr real_t tol_0
Definition eltrans.hpp:62
virtual int GetSpaceDim() const =0
Get the dimension of the target (physical) space.
real_t Weight()
Return the weight of the Jacobian matrix of the transformation at the currently set IntegrationPoint....
Definition eltrans.hpp:144
virtual int OrderJ() const =0
Return the order of the elements of the Jacobian of the transformation.
const IntegrationPoint * IntPoint
Definition eltrans.hpp:30
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint,...
Definition eltrans.hpp:132
int GetDimension() const
Return the topological dimension of the reference element.
Definition eltrans.hpp:178
virtual const DenseMatrix & EvalHessian()=0
Evaluate the Hessian of the transformation at the IntPoint and store it in d2Fdx2.
const DenseMatrix & EvalInverseJ()
Definition eltrans.cpp:59
virtual int OrderW() const =0
Return the order of the determinant of the Jacobian (weight) of the transformation.
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition eltrans.hpp:106
const DenseMatrix & EvalTransAdjugateJ()
Definition eltrans.cpp:48
virtual void Transform(const IntegrationPoint &, Vector &)=0
Transform integration point from reference coordinates to physical coordinates and store them in the ...
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result)=0
Transform all the integration points from the column vectors of matrix from reference coordinates to ...
virtual int TransformBack(const Vector &pt, IntegrationPoint &ip, const real_t phys_tol=tol_0)=0
Transform a point pt from physical space to a point ip in reference space and optionally can set a so...
void Reset()
Force the reevaluation of the Jacobian in the next call.
Definition eltrans.hpp:102
A specialized ElementTransformation class representing a face and its two neighboring elements.
Definition eltrans.hpp:750
ElementTransformation * Elem2
Definition eltrans.hpp:791
void SetIntPoint(const IntegrationPoint *face_ip)
Set the integration point in the Face and the two neighboring elements, if present.
Definition eltrans.cpp:609
ElementTransformation * Elem1
Definition eltrans.hpp:791
const IntegrationPoint & GetElement1IntPoint()
Get a const reference to the integration point in neighboring element 1 corresponding to the currentl...
Definition eltrans.hpp:846
ElementTransformation * Face
Definition eltrans.hpp:792
@ HAVE_ELEM2
Element on side 2 is configured.
Definition eltrans.hpp:783
@ HAVE_LOC1
Point transformation for side 1 is configured.
Definition eltrans.hpp:784
@ HAVE_ELEM1
Element on side 1 is configured.
Definition eltrans.hpp:782
@ HAVE_FACE
Face transformation is configured.
Definition eltrans.hpp:786
@ HAVE_LOC2
Point transformation for side 2 is configured.
Definition eltrans.hpp:785
int GetConfigurationMask() const
Return the mask defining the configuration state.
Definition eltrans.hpp:818
const IntegrationPoint & GetElement2IntPoint()
Get a const reference to the integration point in neighboring element 2 corresponding to the currentl...
Definition eltrans.hpp:856
IntegrationPointTransformation Loc1
Definition eltrans.hpp:793
IntegrationPointTransformation & GetIntPoint1Transformation()
Definition eltrans.cpp:648
void SetGeometryType(Geometry::Type g)
Method to set the geometry type of the face.
Definition eltrans.hpp:805
void SetAllIntPoints(const IntegrationPoint *face_ip)
Set the integration point in the Face and the two neighboring elements, if present.
Definition eltrans.hpp:835
ElementTransformation & GetElement1Transformation()
Definition eltrans.cpp:632
void Transform(const IntegrationPoint &, Vector &) override
Transform integration point from reference coordinates to physical coordinates and store them in the ...
Definition eltrans.cpp:663
void SetConfigurationMask(int m)
Set the mask indicating which portions of the object have been setup.
Definition eltrans.hpp:776
IntegrationPointTransformation Loc2
Definition eltrans.hpp:793
IntegrationPointTransformation & GetIntPoint2Transformation()
Definition eltrans.cpp:656
real_t CheckConsistency(int print_level=0, std::ostream &out=mfem::out)
Check for self-consistency: compares the result of mapping the reference face vertices to physical co...
Definition eltrans.cpp:687
ElementTransformation & GetElement2Transformation()
Definition eltrans.cpp:640
Abstract class for all finite elements.
Definition fe_base.hpp:244
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition fe_base.hpp:338
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition fe_base.hpp:331
void SetType(int t)
Set the Quadrature1D type of points to use for subdivision.
Definition geom.hpp:351
static const int Dimension[NumGeom]
Definition geom.hpp:51
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
IsoparametricTransformation Transf
Definition eltrans.hpp:733
void Transform(const IntegrationPoint &, IntegrationPoint &)
Definition eltrans.cpp:587
Class for integration point with weight.
Definition intrules.hpp:35
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
The inverse transformation of a given ElementTransformation.
Definition eltrans.hpp:200
virtual int Transform(const Vector &pt, IntegrationPoint &ip)
Given a point, pt, in physical space, find its reference coordinates, ip.
Definition eltrans.cpp:338
void SetPrintLevel(int pr_level)
Set the desired print level, useful for debugging.
Definition eltrans.hpp:374
InitGuessType
Algorithms for selecting an initial guess.
Definition eltrans.hpp:204
@ GivenPoint
Use a specific point, set with SetInitialGuess().
Definition eltrans.hpp:214
@ Center
Use the center of the reference element.
Definition eltrans.hpp:205
int FindClosestRefPoint(const Vector &pt, const IntegrationRule &ir)
Find the IntegrationPoint mapped closest to pt, using a norm that approximates the (unknown) distance...
Definition eltrans.cpp:98
InverseElementTransformation(ElementTransformation *Trans=NULL)
Construct the InverseElementTransformation with default parameters.
Definition eltrans.hpp:297
void SetInitGuessPointsType(int q_type)
Definition eltrans.hpp:333
void NewtonPrintPoint(const char *prefix, const Vector &pt, const char *suffix)
Definition eltrans.cpp:159
void SetElementTol(real_t el_tol)
Set the tolerance used to determine if a point lies inside or outside of the reference element.
Definition eltrans.hpp:368
void SetSolverType(SolverType stype)
Specify which algorithm to use for solving the transformation equation, i.e. when calling the Transfo...
Definition eltrans.hpp:354
void SetInitialGuess(const IntegrationPoint &init_ip)
Set the initial guess for subsequent calls to Transform(), switching to the GivenPoint InitGuessType ...
Definition eltrans.hpp:328
TransformResult
Values returned by Transform().
Definition eltrans.hpp:243
@ Outside
The point is probably outside the element.
Definition eltrans.hpp:245
@ Unknown
The algorithm failed to determine where the point is.
Definition eltrans.hpp:246
@ Inside
The point is inside the element.
Definition eltrans.hpp:244
void SetPhysicalRelTol(real_t phys_rel_tol)
Set the relative physical-space convergence tolerance.
Definition eltrans.hpp:363
int FindClosestPhysPoint(const Vector &pt, const IntegrationRule &ir)
Find the IntegrationPoint mapped closest to pt.
Definition eltrans.cpp:71
int NewtonSolve(const Vector &pt, IntegrationPoint &ip)
Definition eltrans.cpp:173
void SetMaxIter(int max_it)
Set the maximum number of iterations when solving for a reference point.
Definition eltrans.hpp:357
void SetReferenceTol(real_t ref_sp_tol)
Set the reference-space convergence tolerance.
Definition eltrans.hpp:360
void SetInitGuessRelOrder(int order)
Set the relative order used for the Closest* initial guess types.
Definition eltrans.hpp:339
void SetInitialGuessType(InitGuessType itype)
Choose how the initial guesses for subsequent calls to Transform() will be selected.
Definition eltrans.hpp:324
void NewtonPrint(int mode, real_t val)
Definition eltrans.cpp:130
void SetTransformation(ElementTransformation &Trans)
Set a new forward ElementTransformation, Trans.
Definition eltrans.hpp:320
ElementTransformation * T
Definition eltrans.hpp:251
A standard isoparametric element transformation.
Definition eltrans.hpp:629
void SetPointMat(const DenseMatrix &pm)
Set the underlying point matrix describing the transformation.
Definition eltrans.hpp:668
int OrderJ() const override
Return the order of the elements of the Jacobian of the transformation.
Definition eltrans.cpp:477
void SetFE(const FiniteElement *FE)
Set the element that will be used to compute the transformations.
Definition eltrans.hpp:648
int TransformBack(const Vector &v, IntegrationPoint &ip, const real_t phys_rel_tol=tol_0) override
Transform a point pt from physical space to a point ip in reference space and optionally can set a so...
Definition eltrans.hpp:717
const FiniteElement * GetFE() const
Get the current element used to compute the transformations.
Definition eltrans.hpp:656
int Order() const override
Return the order of the current element we are using for the transformation.
Definition eltrans.hpp:697
int GetSpaceDim() const override
Get the dimension of the target (physical) space.
Definition eltrans.hpp:709
int OrderGrad(const FiniteElement *fe) const override
Return the order of .
Definition eltrans.cpp:509
DenseMatrix & GetPointMat()
Write access to the stored point matrix. Use with caution.
Definition eltrans.hpp:677
void SetIdentityTransformation(Geometry::Type GeomType)
Set the FiniteElement Geometry for the reference elements being used.
Definition eltrans.cpp:417
const DenseMatrix & GetPointMat() const
Return the stored point matrix.
Definition eltrans.hpp:671
void Transform(const IntegrationPoint &, Vector &) override
Transform integration point from reference coordinates to physical coordinates and store them in the ...
Definition eltrans.cpp:532
MFEM_DEPRECATED void FinalizeTransformation()
Definition eltrans.hpp:727
int OrderW() const override
Return the order of the determinant of the Jacobian (weight) of the transformation.
Definition eltrans.cpp:493
Mesh data type.
Definition mesh.hpp:64
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
Class for parallel meshes.
Definition pmesh.hpp:34
A class container for 1D quadrature type constants.
Definition intrules.hpp:400
Vector data type.
Definition vector.hpp:82
IntegrationType itype
Definition ex38.cpp:46
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
float real_t
Definition config.hpp:43
MemoryType
Memory types supported by MFEM.
std::array< int, NCMesh::MaxFaceNodes > nodes
void pts(int iphi, int t, real_t x[])