35 n_ref.resize(pgt->structure()->dim());
36 bool converged =
true;
37 if (pgt->is_linear()) {
38 return invert_lin(n, n_ref,IN_EPS);
40 return invert_nonlin(n, n_ref,IN_EPS,converged,
true);
48 n_ref.resize(pgt->structure()->dim());
50 if (pgt->is_linear()) {
51 return invert_lin(n, n_ref,IN_EPS);
52 }
else return invert_nonlin(n, n_ref,IN_EPS,converged,
false);
60 return (geoTrans.
convex_ref()->is_in(x) < IN_EPS) && (res < IN_EPS);
67 mult(transposed(B), y, n_ref);
68 y = pgt->transform(n_ref, G);
69 add(scaled(n, -1.0), y);
71 return point_in_convex(*pgt, n_ref,
vect_norm2(y), IN_EPS);
74 void geotrans_inv_convex::update_B() {
76 pgt->compute_K_matrix(G, pc, K);
77 gmm::mult(gmm::transposed(K), K, CS);
78 bgeot::lu_inverse(&(*(CS.begin())), P);
84 base_matrix KT(K.nrows(), K.ncols());
85 pgt->compute_K_matrix(G, pc, KT);
86 gmm::copy(gmm::transposed(KT), K);
88 bgeot::lu_inverse(&(*(K.begin())), P); B.swap(K);
92 void geotrans_inv_convex::set_projection_into_element(
bool active){
93 nonlinear_storage.project_into_element = active;
96 class geotrans_inv_convex_bfgs {
101 const base_node &xr) : gic(gic_), xreal(xr) {}
102 scalar_type operator()(
const base_node& x)
const {
103 base_node r = gic.pgt->transform(x, gic.G) - xreal;
107 gic.pgt->poly_vector_grad(x, gic.pc);
109 base_node r = gic.pgt->transform(x, gic.G) - xreal;
111 gmm::mult(gmm::transposed(gic.K), r, gr);
115 nonlinear_storage_struct::linearised_structure::linearised_structure
116 (
const convex_ind_ct &direct_points_indices,
118 const std::vector<base_node> &real_nodes) :
119 diff(real_nodes.begin()->size()), diff_ref(direct_points_indices.size()-1) {
120 auto n_points = direct_points_indices.size();
121 std::vector<base_node> direct_points;
122 std::vector<base_node> direct_points_ref;
123 direct_points.reserve(n_points);
124 direct_points_ref.reserve(n_points);
126 for (
auto i : direct_points_indices) {
127 direct_points.push_back(real_nodes[i]);
128 direct_points_ref.push_back(reference_nodes[i]);
131 auto N = direct_points.begin()->size();
132 auto N_ref = direct_points_ref.begin()->size();
133 base_matrix K_linear(N, n_points - 1);
134 B_linear.base_resize(N, n_points - 1);
135 K_ref_linear.base_resize(N_ref, n_points - 1);
136 P_linear = direct_points[0];
137 P_ref_linear = direct_points_ref[0];
139 for (
size_type i = 1; i < n_points; ++i) {
140 add(direct_points[i], scaled(P_linear, -1.0), mat_col(K_linear, i - 1));
141 add(direct_points_ref[i], scaled(P_ref_linear, -1.0),
142 mat_col(K_ref_linear, i - 1));
145 if (K_linear.nrows() == K_linear.ncols()) {
146 lu_inverse(K_linear);
147 copy(transposed(K_linear), B_linear);
150 base_matrix temp(n_points - 1, n_points - 1);
151 mult(transposed(K_linear), K_linear, temp);
153 mult(K_linear, temp, B_linear);
157 void nonlinear_storage_struct::linearised_structure::invert
159 add(x_real, scaled(P_linear, -1.0), diff);
160 mult(transposed(B_linear), diff, diff_ref);
161 mult(K_ref_linear, diff_ref, x_ref);
162 add(P_ref_linear, x_ref);
167 if (project ==
false)
return;
169 auto dim = pgeo_trans->
dim();
171 for (
auto d = 0; d < dim; ++d) {
172 if (x[d] < 0.0) x[d] = 0.0;
173 if (x[d] > 1.0) x[d] = 1.0;
176 auto poriginal_trans = pgeo_trans;
178 if (
auto ptorus_trans = dynamic_cast<const torus_geom_trans*>(pgeo_trans)) {
179 poriginal_trans = ptorus_trans->get_original_transformation().get();
183 auto nb_simplices = pbasic_convex_ref->simplexified_convex()->nb_convex();
185 if (nb_simplices == 1) {
186 auto sum_coordinates = 0.0;
188 for (
auto d = 0; d < dim; ++d) sum_coordinates += x[d];
190 if (sum_coordinates > 1.0) scale(x, 1.0 / sum_coordinates);
192 else if ((dim == 3) && (nb_simplices != 4)) {
193 auto sum_coordinates = x[0] + x[1];
195 if (sum_coordinates > 1.0) {
196 x[0] /= sum_coordinates;
197 x[1] /= sum_coordinates;
203 nonlinear_storage_struct &storage,
205 const base_matrix &G,
207 scalar_type IN_EPS) {
221 res0 = std::numeric_limits<scalar_type>::max();
223 if (storage.plinearised_structure !=
nullptr) {
224 storage.plinearised_structure->invert(xreal, x, IN_EPS);
225 project_into_convex(x, pgt, storage.project_into_element);
229 if (res < res0)
copy(storage.x_ref, x);
237 bool geotrans_inv_convex::invert_nonlin(
const base_node& xreal,
239 bool &converged,
bool ) {
241 find_initial_guess(x, nonlinear_storage, xreal, G, pgt.get(), IN_EPS);
242 add(pgt->
transform(x, G), scaled(xreal, -1.0), nonlinear_storage.diff);
243 auto res =
vect_norm2(nonlinear_storage.diff);
244 auto res0 = std::numeric_limits<scalar_type>::max();
247 while (res > IN_EPS) {
248 if ((abs(res - res0) < IN_EPS) || (factor < IN_EPS)) {
250 return point_in_convex(*pgt, x, res, IN_EPS);
254 add(scaled(nonlinear_storage.x_ref, factor), x);
255 nonlinear_storage.x_real = pgt->
transform(x, G);
256 add(nonlinear_storage.x_real, scaled(xreal, -1.0),
257 nonlinear_storage.diff);
261 if (factor < 1.0-IN_EPS) factor = 2.0;
266 mult(transposed(B), nonlinear_storage.diff, nonlinear_storage.x_ref);
267 add(scaled(nonlinear_storage.x_ref, -1.0 * factor), x);
268 project_into_convex(x, pgt.get(), nonlinear_storage.project_into_element);
269 nonlinear_storage.x_real = pgt->
transform(x, G);
270 add(nonlinear_storage.x_real, scaled(xreal, -1.0),
271 nonlinear_storage.diff);
275 return point_in_convex(*pgt, x, res, IN_EPS);
virtual void poly_vector_grad(const base_node &pt, base_matrix &val) const =0
Gives the gradient of the functions vector at a certain point.
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
Description of a geometric transformation between a reference element and a real element.
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
does the inversion of the geometric transformation for a given convex
base_node transform(const base_node &pt, const CONT &PTAB) const
Apply the geometric transformation to point pt, PTAB contains the points of the real convex...
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2(const V1 &v1, const V2 &v2)
Euclidean distance between two vectors.
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
size_t size_type
used as the common size type in the library
Inversion of geometric transformations.
void copy(const L1 &l1, L2 &l2)
*/
size_type nb_points() const
Number of geometric nodes.
Mesh structure definition.
const stored_point_tab & geometric_nodes() const
Gives the array of geometric nodes (on reference convex)
pconvex_ref convex_ref() const
Pointer on the convex of reference.
Implements BFGS (Broyden, Fletcher, Goldfarb, Shanno) algorithm.
dim_type dim() const
Dimension of the reference element.
void add(const L1 &l1, L2 &l2)
*/