GetFEM  5.5
bgeot_geotrans_inv.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2000-2026 Yves Renard
5 
6  This file is a part of GetFEM
7 
8  GetFEM is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program. If not, see https://www.gnu.org/licenses/.
19 
20  As a special exception, you may use this file as it is a part of a free
21  software library without restriction. Specifically, if other files
22  instantiate templates or use macros or inline functions from this file,
23  or you compile this file and link it with other files to produce an
24  executable, this file does not by itself cause the resulting executable
25  to be covered by the GNU Lesser General Public License. This exception
26  does not however invalidate any other reasons why the executable file
27  might be covered by the GNU Lesser General Public License.
28 
29 ===========================================================================*/
30 
31 /**@file bgeot_geotrans_inv.h
32  @author Yves Renard <Yves.Renard@insa-lyon.fr>
33  @date December 20, 2000.
34  @brief Inversion of geometric transformations.
35 
36  Inversion means: given a set of convexes and a point, find:
37 
38  - a subset of candidate convexes, which are likely to contain the
39  point (using bgeot::kdtree).
40 
41  - on these candidate convexes, invert the geometric
42  transformation, i.e. find the corresponding coordinates on the
43  reference element.
44 
45  Inversion of a geometric transformation is not a trivial task,
46  especially with non-linear geometric transformations. This is the
47  central part of interpolation routines from a getfem::mesh_fem onto
48  another.
49 */
50 
51 #ifndef BGEOT_GEOTRANS_INV_H__
52 #define BGEOT_GEOTRANS_INV_H__
53 
54 #include "bgeot_geometric_trans.h"
55 #include "bgeot_small_vector.h"
56 #include "bgeot_kdtree.h"
57 
58 namespace bgeot {
59 
60  /**
61  does the inversion of the geometric transformation for a given convex
62  */
64  size_type N, P;
65  base_matrix G, pc, K, B, CS;
66  pgeometric_trans pgt = nullptr;
67  scalar_type EPS;
68 
69  bool has_linearized_approx = false;
70  base_matrix K_ref_B_transp_lin;
71  base_node P_lin, P_ref_lin;
72 
73  public:
74  const base_matrix &get_G() const { return G; }
75 
76  geotrans_inv_convex(scalar_type e=10e-12)
77  : N(0), P(0), pgt(0), EPS(e) {}
78 
79  template<class TAB> geotrans_inv_convex(const convex<base_node, TAB> &cv,
80  pgeometric_trans pgt_,
81  scalar_type e=10e-12)
82  : N(0), P(0), pgt(0), EPS(e)
83  {
84  init(cv.points(), pgt_);
85  }
86 
87  geotrans_inv_convex(const std::vector<base_node> &nodes,
88  pgeometric_trans pgt_,
89  scalar_type e=10e-12)
90  : N(0), P(0), pgt(0), EPS(e)
91  {
92  init(nodes, pgt_);
93  }
94 
95  template<class TAB> void init(const TAB &nodes, pgeometric_trans pgt_);
96 
97  /**
98  given the node on the real element, returns the node on the
99  reference element (even if it is outside of the ref. convex).
100 
101  If the geometric transformation is not invertible at point n,
102  an exception is thrown.
103 
104  @return true if the n is inside the convex
105 
106  @param n node on the real element
107 
108  @param n_ref computed node on the reference convex
109 
110  @param IN_EPS a threshold.
111  */
112  bool invert(const base_node& n, base_node& n_ref,
113  scalar_type IN_EPS=1e-12, bool project_into_element=false);
114 
115  /**
116  given the node on the real element, returns the node
117  on the reference element (even if it is outside of the ref. convex).
118 
119  This version will not throw an exception if the geometric
120  transformation is not invertible at point n.
121 
122  @return true if the n is inside the convex
123 
124  @param n node on the real element
125 
126  @param n_ref computed node on the reference convex
127 
128  @param converged on output, will be set to true if the
129  geometric transformation could be inverted.
130 
131  @param IN_EPS a threshold.
132  */
133  bool invert(const base_node& n, base_node& n_ref, bool &converged,
134  scalar_type IN_EPS=1e-12, bool project_into_element=false);
135  private:
136  bool invert_lin(const base_node& n, base_node& n_ref, scalar_type IN_EPS);
137  bool invert_nonlin(const base_node& n, base_node& n_ref,
138  scalar_type IN_EPS, bool &converged, bool throw_except,
139  bool project_into_element);
140  bool update_B(); // returns true if successful
141  void update_linearization(); // TODO: return success state
142 
143  friend class geotrans_inv_convex_bfgs;
144  };
145 
146  template<class TAB>
147  void geotrans_inv_convex::init(const TAB &nodes, pgeometric_trans pgt_) {
148  bool geotrans_changed = (pgt != pgt_); if (geotrans_changed) pgt = pgt_;
149  GMM_ASSERT3(!nodes.empty(), "empty points!");
150  if (N != nodes[0].size())
151  { N = nodes[0].size(); geotrans_changed = true; }
152  if (geotrans_changed) {
153  P = pgt->structure()->dim();
154  pc.resize(pgt->nb_points() , P);
155  K.resize(N,P);
156  B.resize(N,P);
157  CS.resize(P,P);
158  G.resize(N, pgt->nb_points());
159  }
160  vectors_to_base_matrix(G, nodes);
161  if (pgt->is_linear()) {
162  if (geotrans_changed) {
163  base_node Dummy(P);
164  pgt->poly_vector_grad(Dummy, pc);
165  }
166  // computation of the pseudo inverse
167  update_B();
168  } else if (pgt->complexity() > 1)
169  update_linearization();
170  }
171 
172 
173  /**
174  handles the geometric inversion for a given (supposedly quite large)
175  set of points
176  */
178  {
179  protected :
180  mutable kdtree tree;
181  scalar_type EPS;
183  public :
184  void clear() { tree.clear(); }
185  /// Add the points contained in c to the list of points.
186  template<class CONT> void add_points(const CONT &c) {
187  tree.reserve(std::distance(c.begin(),c.end()));
188  typename CONT::const_iterator it = c.begin(), ite = c.end();
189  for (; it != ite; ++it) tree.add_point(*it);
190  }
191 
192  /// Number of points.
193  size_type nb_points() const { return tree.nb_points(); }
194  /// Add point p to the list of points.
195  size_type add_point(base_node p) { return tree.add_point(p); }
196  void add_point_with_id(base_node p,size_type id)
197  { tree.add_point_with_id(p,id); }
198 
199  /// Find all the points present in the box between min and max.
201  const base_node &min,
202  const base_node &max) const {
203  tree.points_in_box(ipts, min, max);
204  return ipts.size();
205  }
206 
207  /** Search all the points in the convex cv, which is the transformation
208  * of the convex cref via the geometric transformation pgt.
209  *
210  * IMPORTANT : It is assumed that the whole convex is included in the
211  * minmax box of its nodes times a factor 1.2. If the transformation is
212  * linear, the factor is 1.0.
213  *
214  * @param cv the convex points (as given by getfem_mesh::convex(ic)).
215  *
216  * @param pgt the geometric trans (as given by
217  * getfem_mesh::trans_of_convex(ic)).
218  *
219  * @param pftab container for the coordinates of points in the reference
220  * convex (should be of size nb_points())
221  *
222  * @param itab the indices of points found in the convex.
223  *
224  * @param bruteforce use a brute force search(only for debugging purposes).
225  *
226  * @return the number of points in the convex (i.e. the size of itab,
227  * and pftab)
228  */
229  template<class TAB, class CONT1, class CONT2>
231  pgeometric_trans pgt,
232  CONT1 &pftab, CONT2 &itab,
233  bool bruteforce=false);
234 
235  geotrans_inv(scalar_type EPS_ = 10E-12) : EPS(EPS_) {}
236  };
237 
238 
239 
240  template<class TAB, class CONT1, class CONT2>
242  pgeometric_trans pgt,
243  CONT1 &pftab, CONT2 &itab,
244  bool bruteforce) {
245  base_node min, max; /* bound of the box enclosing the convex */
246  size_type nbpt = 0; /* nb of points in the convex */
247  kdtree_tab_type boxpts;
248  bounding_box(min, max, cv.points(), pgt);
249  for (size_type k=0; k < min.size(); ++k) { min[k] -= EPS; max[k] += EPS; }
250  gic.init(cv.points(),pgt);
251  /* get the points in a box enclosing the convex */
252  if (!bruteforce) points_in_box(boxpts, min, max);
253  else boxpts = tree.points();
254  /* and invert the geotrans, and check if the obtained point is
255  inside the reference convex */
256  for (size_type l = 0; l < boxpts.size(); ++l) {
257  // base_node pt_ref;
258  if (gic.invert(boxpts[l].n, pftab[nbpt], EPS)) {
259  itab[nbpt++] = boxpts[l].i;
260  }
261  }
262  return nbpt;
263  }
264 
265 
266 
267 
268 
269 } /* end of namespace bgeot. */
270 
271 
272 #endif /* BGEOT_GEOMETRIC_TRANSFORMATION_H__ */
Geometric transformations on convexes.
Simple implementation of a KD-tree.
Small (dim < 8) vectors.
generic definition of a convex ( bgeot::convex_structure + vertices coordinates )
Definition: bgeot_convex.h:49
does the inversion of the geometric transformation for a given convex
bool invert(const base_node &n, base_node &n_ref, scalar_type IN_EPS=1e-12, bool project_into_element=false)
given the node on the real element, returns the node on the reference element (even if it is outside ...
handles the geometric inversion for a given (supposedly quite large) set of points
void add_points(const CONT &c)
Add the points contained in c to the list of points.
size_type points_in_box(kdtree_tab_type &ipts, const base_node &min, const base_node &max) const
Find all the points present in the box between min and max.
size_type nb_points() const
Number of points.
size_type add_point(base_node p)
Add point p to the list of points.
size_type points_in_convex(const convex< base_node, TAB > &cv, pgeometric_trans pgt, CONT1 &pftab, CONT2 &itab, bool bruteforce=false)
Search all the points in the convex cv, which is the transformation of the convex cref via the geomet...
Balanced tree over a set of points.
Definition: bgeot_kdtree.h:101
void add_point_with_id(const base_node &n, size_type i)
insert a new point, with an associated number.
Definition: bgeot_kdtree.h:119
size_type add_point(const base_node &n)
insert a new point
Definition: bgeot_kdtree.h:115
void clear()
reset the tree, remove all points
Definition: bgeot_kdtree.h:112
Basic Geometric Tools.
std::vector< index_node_pair > kdtree_tab_type
store a set of points with associated indexes.
Definition: bgeot_kdtree.h:67
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation