32     for (
auto &coord : x) {
 
   33       if (coord < 0.0) coord = 0.0;
 
   34       if (coord > 1.0) coord = 1.0;
 
   38     auto pgt_torus = std::dynamic_pointer_cast<const torus_geom_trans>(pgt);
 
   40       orig_pgt = pgt_torus ? pgt_torus->get_original_transformation()
 
   44     auto nb_simplices = pbasic_convex_ref->simplexified_convex()->nb_convex();
 
   46     if (nb_simplices == 1) { 
 
   47       auto sum_coordinates = 0.0;
 
   48       for (
const auto &coord : x) sum_coordinates += coord;
 
   50       if (sum_coordinates > 1.0) gmm::scale(x, 1.0 / sum_coordinates);
 
   52     else if (pgt->dim() == 3 && nb_simplices != 4) { 
 
   53       auto sum_coordinates = x[0] + x[1];
 
   54       if (sum_coordinates > 1.0) {
 
   55         x[0] /= sum_coordinates;
 
   56         x[1] /= sum_coordinates;
 
   63                                    bool project_into_element) {
 
   64     bool converged = 
true;
 
   65     return invert(n, n_ref, converged, IN_EPS, project_into_element);
 
   71                                    bool project_into_element) {
 
   73     n_ref.resize(pgt->structure()->dim());
 
   76       return invert_lin(n, n_ref, IN_EPS);
 
   78       return invert_nonlin(n, n_ref, IN_EPS, converged, 
false,
 
   79                            project_into_element);
 
   86     mult(transposed(B), y, n_ref);
 
   87     y = pgt->transform(n_ref, G);
 
   88     add(gmm::scaled(n, -1.0), y);
 
   90     return (pgt->convex_ref()->is_in(n_ref) < IN_EPS) &&
 
   91            (gmm::vect_norm2(y) < IN_EPS);
 
   94   void geotrans_inv_convex::update_B() {
 
   96       pgt->compute_K_matrix(G, pc, K);
 
   97       gmm::mult(gmm::transposed(K), K, CS);
 
   98       bgeot::lu_inverse(&(*(CS.begin())), P);
 
  104       base_matrix KT(K.nrows(), K.ncols());
 
  105       pgt->compute_K_matrix(G, pc, KT);
 
  108       bgeot::lu_inverse(&(*(K.begin())), P); B.swap(K);
 
  112   class geotrans_inv_convex_bfgs {
 
  113     geotrans_inv_convex &gic;
 
  116     geotrans_inv_convex_bfgs(geotrans_inv_convex &gic_,
 
  117                              const base_node &xr) : gic(gic_), xreal(xr) {}
 
  118     scalar_type operator()(
const base_node& x)
 const {
 
  119       base_node r = gic.pgt->transform(x, gic.G) - xreal;
 
  122     void operator()(
const base_node& x, base_small_vector& gr)
 const {
 
  123       gic.pgt->poly_vector_grad(x, gic.pc);
 
  125       base_node r = gic.pgt->transform(x, gic.G) - xreal;
 
  127       gmm::mult(gmm::transposed(gic.K), r, gr);
 
  131   void geotrans_inv_convex::update_linearization() {
 
  133     const convex_ind_ct &dir_pt_ind = pgt->structure()->ind_dir_points();
 
  134     const stored_point_tab &ref_nodes = pgt->geometric_nodes();
 
  136     has_linearized_approx = 
true;
 
  138     auto n_points = dir_pt_ind.size();
 
  139     auto N_ref = ref_nodes.begin()->size();
 
  141     std::vector<base_node> dir_pts, dir_pts_ref;
 
  142     for (
auto i : dir_pt_ind) {
 
  143       dir_pts.push_back(base_node(N));
 
  144       gmm::copy(mat_col(G, i), dir_pts.back());
 
  145       dir_pts_ref.push_back(ref_nodes[i]);
 
  148     base_matrix K_lin(N, n_points - 1),
 
  149                 B_transp_lin(n_points - 1, N),
 
  150                 K_ref_lin(N_ref, n_points - 1);
 
  153     P_ref_lin = dir_pts_ref[0];
 
  155     for (
size_type i = 1; i < n_points; ++i) {
 
  156       add(dir_pts[i], gmm::scaled(P_lin, -1.0), mat_col(K_lin, i - 1));
 
  157       add(dir_pts_ref[i], gmm::scaled(P_ref_lin, -1.0),
 
  158           mat_col(K_ref_lin, i - 1));
 
  161     if (K_lin.nrows() == K_lin.ncols()) {
 
  166       base_matrix temp(n_points - 1, n_points - 1);
 
  167       mult(transposed(K_lin), K_lin, temp);
 
  169       mult(temp, transposed(K_lin), B_transp_lin);
 
  172     K_ref_B_transp_lin.base_resize(N_ref, N);
 
  173     mult(K_ref_lin, B_transp_lin, K_ref_B_transp_lin);
 
  180   bool geotrans_inv_convex::invert_nonlin(
const base_node& xreal,
 
  181                                           base_node& x, scalar_type IN_EPS,
 
  184                                           bool project_into_element) {
 
  186     base_node x0_ref(P), diff(N);
 
  189       x0_ref = pgt->geometric_nodes()[0];
 
  191       for (
size_type j = 1; j < pgt->nb_points(); ++j) {
 
  195           x0_ref = pgt->geometric_nodes()[j];
 
  199       scalar_type res0 = std::numeric_limits<scalar_type>::max();
 
  200       if (has_linearized_approx) {
 
  202         add(xreal, gmm::scaled(P_lin, -1.0), diff);
 
  203         mult(K_ref_B_transp_lin, diff, x);
 
  206         if (project_into_element) project_into_convex(x, pgt);
 
  215     add(pgt->transform(x, G), gmm::scaled(xreal, -1.0), diff);
 
  217     scalar_type res0 = std::numeric_limits<scalar_type>::max();
 
  218     scalar_type factor = 1.0;
 
  220     base_node x0_real(N);
 
  221     while (res > IN_EPS/100.) {
 
  222       if ((gmm::abs(res - res0) < IN_EPS/100.) || (factor < IN_EPS)) {
 
  226         return (pgt->convex_ref()->is_in(x) < IN_EPS) && (res < IN_EPS);
 
  229         add(gmm::scaled(x0_ref, factor), x);
 
  230         x0_real = pgt->transform(x, G);
 
  231         add(x0_real, gmm::scaled(xreal, -1.0), diff);
 
  235         if (factor < 1.0-IN_EPS) factor *= 2.0;
 
  238       pgt->poly_vector_grad(x, pc);
 
  240       mult(transposed(B), diff, x0_ref);
 
  241       add(gmm::scaled(x0_ref, -factor), x);
 
  242       if (project_into_element) project_into_convex(x, pgt);
 
  243       x0_real = pgt->transform(x, G);
 
  244       add(x0_real, gmm::scaled(xreal, -1.0), diff);
 
  247     return (pgt->convex_ref()->is_in(x) < IN_EPS) && (res < IN_EPS);
 
Inversion of geometric transformations.
 
Mesh structure definition.
 
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 ...
 
void copy(const L1 &l1, L2 &l2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
 
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_maxnorm(const M &m)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
 
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2(const V1 &v1, const V2 &v2)
Euclidean distance between two vectors.
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
Implements BFGS (Broyden, Fletcher, Goldfarb, Shanno) algorithm.
 
size_t size_type
used as the common size type in the library
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.