libMesh
Static Public Member Functions | List of all members
libMesh::InfFEMap Class Reference

Class that encapsulates mapping (i.e. More...

#include <inf_fe_map.h>

Static Public Member Functions

static Point map (const unsigned int dim, const Elem *inf_elem, const Point &reference_point)
 
static Point inverse_map (const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
 
static void inverse_map (const unsigned int dim, const Elem *elem, const std::vector< Point > &physical_points, std::vector< Point > &reference_points, const Real tolerance=TOLERANCE, const bool secure=true)
 Takes a number points in physical space (in the physical_points vector) and finds their location on the reference element for the input element elem. More...
 
static Real eval (Real v, Order o, unsigned int i)
 
static Real eval_deriv (Real v, Order o, unsigned int i)
 

Detailed Description

Class that encapsulates mapping (i.e.

from physical space to reference space and vice-versa) operations on infinite elements.

Definition at line 47 of file inf_fe_map.h.

Member Function Documentation

◆ eval()

Real libMesh::InfFEMap::eval ( Real  v,
Order  o,
unsigned int  i 
)
static
Returns
The value of the \( i^{th} \) polynomial evaluated at v. This method provides the approximation in radial direction for the overall shape functions, which is defined in InfFE::shape(). This method is allowed to be static, since it is independent of dimension and base_family. It is templated, though, w.r.t. to radial FEFamily.
The value of the \( i^{th} \) mapping shape function in radial direction evaluated at v when T_radial == INFINITE_MAP. Currently, only one specific mapping shape is used. Namely the one by Marques JMMC, Owen DRJ: Infinite elements in quasi-static materially nonlinear problems, Computers and Structures, 1984.

Definition at line 27 of file inf_fe_map_eval.C.

28 {
29  libmesh_assert (-1.-1.e-5 <= v && v < 1.);
30 
31  switch (i)
32  {
33  case 0:
34  return -2.*v/(1.-v);
35  case 1:
36  return (1.+v)/(1.-v);
37 
38  default:
39  libmesh_error_msg("bad index i = " << i);
40  }
41 }

References libMesh::libmesh_assert().

Referenced by libMesh::InfFE< Dim, T_radial, T_map >::eval(), libMesh::InfFE< Dim, T_radial, T_map >::init_radial_shape_functions(), and map().

◆ eval_deriv()

Real libMesh::InfFEMap::eval_deriv ( Real  v,
Order  o,
unsigned int  i 
)
static
Returns
The value of the first derivative of the \( i^{th} \) polynomial at coordinate v. See eval for details.

Definition at line 45 of file inf_fe_map_eval.C.

46 {
47  libmesh_assert (-1.-1.e-5 <= v && v < 1.);
48 
49  switch (i)
50  {
51  case 0:
52  return -2./((1.-v)*(1.-v));
53  case 1:
54  return 2./((1.-v)*(1.-v));
55 
56  default:
57  libmesh_error_msg("bad index i = " << i);
58  }
59 }

References libMesh::libmesh_assert().

Referenced by libMesh::InfFE< Dim, T_radial, T_map >::eval_deriv(), and libMesh::InfFE< Dim, T_radial, T_map >::init_radial_shape_functions().

◆ inverse_map() [1/2]

Point libMesh::InfFEMap::inverse_map ( const unsigned int  dim,
const Elem elem,
const Point p,
const Real  tolerance = TOLERANCE,
const bool  secure = true 
)
static
Returns
The location (on the reference element) of the point p located in physical space. First, the location in the base face is computed. This requires inverting the (possibly nonlinear) transformation map in the base, so it is not trivial. The optional parameter tolerance defines how close is "good enough." The map inversion iteration computes the sequence \( \{ p_n \} \), and the iteration is terminated when \( \|p - p_n\| < \mbox{\texttt{tolerance}} \). Once the base face point is determined, the radial local coordinate is directly evaluated. If interpolated is true, the interpolated distance from the base element to the infinite element origin is used for the map in radial direction.

Definition at line 88 of file inf_fe_map.C.

93 {
94  libmesh_assert(inf_elem);
95  libmesh_assert_greater_equal (tolerance, 0.);
96  libmesh_assert(dim > 0);
97 
98  // Start logging the map inversion.
99  LOG_SCOPE("inverse_map()", "InfFEMap");
100 
101  // The strategy is:
102  // compute the intersection of the line
103  // physical_point - origin with the base element,
104  // find its internal coordinatels using FEMap::inverse_map():
105  // The radial part can then be computed directly later on.
106 
107  // 1.)
108  // build a base element to do the map inversion in the base face
109  std::unique_ptr<Elem> base_elem (InfFEBase::build_elem (inf_elem));
110 
111  // The point on the reference element (which we are looking for).
112  // start with an invalid guess:
113  Point p;
114  p(dim-1)=-2.;
115 
116  // 2.)
117  // Now find the intersection of a plane represented by the base
118  // element nodes and the line given by the origin of the infinite
119  // element and the physical point.
120  Point intersection;
121 
122  // the origin of the infinite element
123  const Point o = inf_elem->origin();
124 
125  switch (dim)
126  {
127  // unnecessary for 1D
128  case 1:
129  break;
130 
131  case 2:
132  libmesh_error_msg("ERROR: InfFE::inverse_map is not yet implemented in 2d");
133 
134  case 3:
135  {
136  // references to the nodal points of the base element
137  const Point & p0 = base_elem->point(0);
138  const Point & p1 = base_elem->point(1);
139  const Point & p2 = base_elem->point(2);
140 
141  // a reference to the physical point
142  const Point & fp = physical_point;
143 
144  // The intersection of the plane and the line is given by
145  // can be computed solving a linear 3x3 system
146  // a*({p1}-{p0})+b*({p2}-{p0})-c*({fp}-{o})={fp}-{p0}.
147  const Real c_factor = -(p1(0)*fp(1)*p0(2)-p1(0)*fp(2)*p0(1)
148  +fp(0)*p1(2)*p0(1)-p0(0)*fp(1)*p1(2)
149  +p0(0)*fp(2)*p1(1)+p2(0)*fp(2)*p0(1)
150  -p2(0)*fp(1)*p0(2)-fp(0)*p2(2)*p0(1)
151  +fp(0)*p0(2)*p2(1)+p0(0)*fp(1)*p2(2)
152  -p0(0)*fp(2)*p2(1)-fp(0)*p0(2)*p1(1)
153  +p0(2)*p2(0)*p1(1)-p0(1)*p2(0)*p1(2)
154  -fp(0)*p1(2)*p2(1)+p2(1)*p0(0)*p1(2)
155  -p2(0)*fp(2)*p1(1)-p1(0)*fp(1)*p2(2)
156  +p2(2)*p1(0)*p0(1)+p1(0)*fp(2)*p2(1)
157  -p0(2)*p1(0)*p2(1)-p2(2)*p0(0)*p1(1)
158  +fp(0)*p2(2)*p1(1)+p2(0)*fp(1)*p1(2))/
159  (fp(0)*p1(2)*p0(1)-p1(0)*fp(2)*p0(1)
160  +p1(0)*fp(1)*p0(2)-p1(0)*o(1)*p0(2)
161  +o(0)*p2(2)*p0(1)-p0(0)*fp(2)*p2(1)
162  +p1(0)*o(1)*p2(2)+fp(0)*p0(2)*p2(1)
163  -fp(0)*p1(2)*p2(1)-p0(0)*o(1)*p2(2)
164  +p0(0)*fp(1)*p2(2)-o(0)*p0(2)*p2(1)
165  +o(0)*p1(2)*p2(1)-p2(0)*fp(2)*p1(1)
166  +fp(0)*p2(2)*p1(1)-p2(0)*fp(1)*p0(2)
167  -o(2)*p0(0)*p1(1)-fp(0)*p0(2)*p1(1)
168  +p0(0)*o(1)*p1(2)+p0(0)*fp(2)*p1(1)
169  -p0(0)*fp(1)*p1(2)-o(0)*p1(2)*p0(1)
170  -p2(0)*o(1)*p1(2)-o(2)*p2(0)*p0(1)
171  -o(2)*p1(0)*p2(1)+o(2)*p0(0)*p2(1)
172  -fp(0)*p2(2)*p0(1)+o(2)*p2(0)*p1(1)
173  +p2(0)*o(1)*p0(2)+p2(0)*fp(1)*p1(2)
174  +p2(0)*fp(2)*p0(1)-p1(0)*fp(1)*p2(2)
175  +p1(0)*fp(2)*p2(1)-o(0)*p2(2)*p1(1)
176  +o(2)*p1(0)*p0(1)+o(0)*p0(2)*p1(1));
177 
178 
179  // Check whether the above system is ill-posed. It should
180  // only happen when \p physical_point is not in \p
181  // inf_elem. In this case, any point that is not in the
182  // element is a valid answer.
183  if (libmesh_isinf(c_factor))
184  return p;
185 
186  // The intersection should always be between the origin and the physical point.
187  // It can become positive close to the border, but should
188  // be only very small.
189  // So as in the case above, we can be sufficiently sure here
190  // that \p fp is not in this element:
191  if (c_factor > 0.01)
192  return p;
193 
194  // Compute the intersection with
195  // {intersection} = {fp} + c*({fp}-{o}).
196  intersection.add_scaled(fp,1.+c_factor);
197  intersection.add_scaled(o,-c_factor);
198 
199  break;
200  }
201 
202  default:
203  libmesh_error_msg("Invalid dim = " << dim);
204  }
205 
206  // 3.)
207  // Now we have the intersection-point (projection of physical point onto base-element).
208  // Lets compute its internal coordinates (being p(0) and p(1)):
209  p= FEMap::inverse_map(dim-1, base_elem.get(), intersection,
210  tolerance, secure);
211 
212  // 4.
213  // Now that we have the local coordinates in the base,
214  // we compute the radial distance with Newton iteration.
215 
216  // distance from the physical point to the ifem origin
217  const Real fp_o_dist = Point(o-physical_point).norm();
218 
219  // the distance from the intersection on the
220  // base to the origin
221  const Real a_dist = Point(o-intersection).norm();
222 
223  // element coordinate in radial direction
224 
225  // fp_o_dist is at infinity.
226  if (libmesh_isinf(fp_o_dist))
227  {
228  p(dim-1)=1;
229  return p;
230  }
231 
232  // when we are somewhere in this element:
233  Real v = 0;
234 
235  // For now we're sticking with T_map == CARTESIAN
236  // if (T_map == CARTESIAN)
237  v = 1.-2.*a_dist/fp_o_dist;
238  // else
239  // libmesh_not_implemented();
240 
241  // do not put the point back into the element, otherwise the contains_point-function
242  // gives false positives!
243  //if (v <= -1.-1e-5)
244  // v=-1.;
245  //if (v >= 1.)
246  // v=1.-1e-5;
247 
248  p(dim-1)=v;
249 #ifdef DEBUG
250  // first check whether we are in the reference-element:
251  if (-1.-1.e-5 < v && v < 1.)
252  {
253  const Point check = map (dim, inf_elem, p);
254  const Point diff = physical_point - check;
255 
256  if (diff.norm() > tolerance)
257  libmesh_warning("WARNING: diff is " << diff.norm());
258  }
259 #endif
260 
261  return p;
262 }

References libMesh::TypeVector< T >::add_scaled(), libMesh::InfFEBase::build_elem(), dim, libMesh::FEMap::inverse_map(), libMesh::libmesh_assert(), libMesh::libmesh_isinf(), map(), libMesh::TypeVector< T >::norm(), libMesh::Elem::origin(), and libMesh::Real.

Referenced by libMesh::InfQuad4::contains_point(), libMesh::InfPrism::contains_point(), libMesh::InfHex::contains_point(), inverse_map(), libMesh::FEMap::inverse_map(), and libMesh::InfFE< Dim, T_radial, T_map >::inverse_map().

◆ inverse_map() [2/2]

void libMesh::InfFEMap::inverse_map ( const unsigned int  dim,
const Elem elem,
const std::vector< Point > &  physical_points,
std::vector< Point > &  reference_points,
const Real  tolerance = TOLERANCE,
const bool  secure = true 
)
static

Takes a number points in physical space (in the physical_points vector) and finds their location on the reference element for the input element elem.

The values on the reference element are returned in the vector reference_points

Definition at line 266 of file inf_fe_map.C.

272 {
273  // The number of points to find the
274  // inverse map of
275  const std::size_t n_points = physical_points.size();
276 
277  // Resize the vector to hold the points
278  // on the reference element
279  reference_points.resize(n_points);
280 
281  // Find the coordinates on the reference
282  // element of each point in physical space
283  for (unsigned int p=0; p<n_points; p++)
284  reference_points[p] =
285  inverse_map (dim, elem, physical_points[p], tolerance, secure);
286 }

References dim, inverse_map(), and libMesh::TypeVector< T >::size().

◆ map()

Point libMesh::InfFEMap::map ( const unsigned int  dim,
const Elem inf_elem,
const Point reference_point 
)
static
Returns
The location (in physical space) of the point p located on the reference element.

Definition at line 40 of file inf_fe_map.C.

43 {
44  libmesh_assert(inf_elem);
45  libmesh_assert_not_equal_to (dim, 0);
46 
47  std::unique_ptr<Elem> base_elem (InfFEBase::build_elem (inf_elem));
48 
49  const Order radial_mapping_order (InfFERadial::mapping_order());
50  const Real v (reference_point(dim-1));
51 
52  // map in the base face
53  Point base_point;
54  switch (dim)
55  {
56  case 1:
57  base_point = inf_elem->point(0);
58  break;
59  case 2:
60  case 3:
61  base_point = FEMap::map (dim-1, base_elem.get(), reference_point);
62  break;
63  default:
64 #ifdef DEBUG
65  libmesh_error_msg("Unknown dim = " << dim);
66 #endif
67  break;
68  }
69 
70 
71  // map in the outer node face not necessary. Simply
72  // compute the outer_point = base_point + (base_point-origin)
73  const Point outer_point (base_point * 2. - inf_elem->origin());
74 
75  Point p;
76 
77  // there are only two mapping shapes in radial direction
78  p.add_scaled (base_point, eval (v, radial_mapping_order, 0));
79  p.add_scaled (outer_point, eval (v, radial_mapping_order, 1));
80 
81  return p;
82 }

References libMesh::TypeVector< T >::add_scaled(), libMesh::InfFEBase::build_elem(), dim, eval(), libMesh::libmesh_assert(), libMesh::FEMap::map(), libMesh::InfFERadial::mapping_order(), libMesh::Elem::origin(), libMesh::Elem::point(), and libMesh::Real.

Referenced by inverse_map(), libMesh::FEMap::map(), and libMesh::InfFE< Dim, T_radial, T_map >::map().


The documentation for this class was generated from the following files:
libMesh::InfFERadial::mapping_order
static Order mapping_order()
Definition: inf_fe.h:93
libMesh::Order
Order
Definition: enum_order.h:40
libMesh::FEMap::map
static Point map(const unsigned int dim, const Elem *elem, const Point &reference_point)
Definition: fe_map.C:2043
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::InfFEMap::inverse_map
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: inf_fe_map.C:88
libMesh::InfFEMap::eval
static Real eval(Real v, Order o, unsigned int i)
Definition: inf_fe_map_eval.C:27
libMesh::FEMap::inverse_map
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: fe_map.C:1622
libMesh::libmesh_isinf
bool libmesh_isinf(T x)
Definition: libmesh_common.h:185
libMesh::InfFEMap::map
static Point map(const unsigned int dim, const Elem *inf_elem, const Point &reference_point)
Definition: inf_fe_map.C:40
libMesh::InfFEBase::build_elem
static Elem * build_elem(const Elem *inf_elem)
Build the base element of an infinite element.
Definition: inf_fe_base_radial.C:35
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121