31   scalar_type global_function_simple::val
 
   32   (
const fem_interpolation_context &c)
 const {
 
   33     base_node pt = c.xreal();
 
   34     GMM_ASSERT1(pt.size() == dim_, 
"Point of wrong size (" << pt.size() << 
") " 
   35                 << 
"passed to a global function of dim = "<< dim_ <<
".");
 
   39   void global_function_simple::grad
 
   40   (
const fem_interpolation_context &c, base_small_vector &g)
 const {
 
   41     base_node pt = c.xreal();
 
   42     GMM_ASSERT1(pt.size() == dim_, 
"Point of wrong size (" << pt.size() << 
") " 
   43                 << 
"passed to a global function of dim = "<< dim_ <<
".");
 
   47   void global_function_simple::hess
 
   48   (
const fem_interpolation_context &c, base_matrix &h)
 const {
 
   49     base_node pt = c.xreal();
 
   50     GMM_ASSERT1(pt.size() == dim_, 
"Point of wrong size (" << pt.size() << 
") " 
   51                 << 
"passed to a global function of dim = "<< dim_ <<
".");
 
   57   scalar_type global_function_parser::val(
const base_node &pt)
 const {
 
   58     const bgeot::base_tensor &t = tensor_val(pt);
 
   59     GMM_ASSERT1(t.size() == 1, 
"Wrong size of expression result " 
   60                 << f_val.expression());
 
   64   const base_tensor &global_function_parser::tensor_val(
const base_node &pt)
 const {
 
   69   void global_function_parser::grad(
const base_node &pt, base_small_vector &g)
 const {
 
   72     const bgeot::base_tensor &t = f_grad.eval();
 
   73     GMM_ASSERT1(t.size() == dim_, 
"Wrong size of expression result " 
   74                 << f_grad.expression());
 
   79   void global_function_parser::hess(
const base_node &pt, base_matrix &h)
 const {
 
   82     const bgeot::base_tensor &t = f_hess.eval();
 
   83     GMM_ASSERT1(t.size() == 
size_type(dim_*dim_),
 
   84                 "Wrong size of expression result " << f_hess.expression());
 
   88   global_function_parser::global_function_parser(dim_type dim__,
 
   89                                                  const std::string &sval,
 
   90                                                  const std::string &sgrad,
 
   91                                                  const std::string &shess)
 
   92     : global_function_simple(dim__),
 
   93       f_val(gw, sval), f_grad(gw, sgrad), f_hess(gw, shess) {
 
   98     gw.add_fixed_size_variable(
"X", gmm::sub_interval(0, N), pt_);
 
   99     if (N >= 1) gw.add_macro(
"x", 
"X(1)");
 
  100     if (N >= 2) gw.add_macro(
"y", 
"X(2)");
 
  101     if (N >= 3) gw.add_macro(
"z", 
"X(3)");
 
  102     if (N >= 4) gw.add_macro(
"w", 
"X(4)");
 
  111   scalar_type global_function_sum::val
 
  112   (
const fem_interpolation_context &c)
 const {
 
  114     for (
const auto &f : functions)
 
  119   void global_function_sum::grad
 
  120   (
const fem_interpolation_context &c, base_small_vector &g)
 const {
 
  123     base_small_vector gg(dim_);
 
  124     for (
const auto &f : functions) {
 
  130   void global_function_sum::hess
 
  131   (
const fem_interpolation_context &c, base_matrix &h)
 const {
 
  132     h.resize(dim_, dim_);
 
  134     base_matrix hh(dim_, dim_);
 
  135     for (
const auto &f : functions) {
 
  137       gmm::add(hh.as_vector(), h.as_vector());
 
  141   bool global_function_sum::is_in_support(
const base_node &p)
 const {
 
  142     for (
const auto &f : functions)
 
  143       if (f->is_in_support(p)) 
return true;
 
  147   void global_function_sum::bounding_box
 
  148   (base_node &bmin_, base_node &bmax_)
 const {
 
  149     if (functions.size() > 0)
 
  150       functions[0]->bounding_box(bmin_, bmax_);
 
  151     base_node bmin0(dim()), bmax0(dim());
 
  152     for (
const auto &f : functions) {
 
  153       f->bounding_box(bmin0, bmax0);
 
  155         if (bmin0[i] < bmin_[i]) bmin_[i] = bmin0[i];
 
  156         if (bmax0[i] > bmax_[i]) bmax_[i] = bmax0[i];
 
  161   global_function_sum::global_function_sum(
const std::vector<pglobal_function> &funcs)
 
  162     : global_function((funcs.size() > 0) ? funcs[0]->dim() : 0), functions(funcs) {
 
  163     for (
const auto &f : functions)
 
  164       GMM_ASSERT1(f->dim() == dim(), 
"Incompatible dimensions among the provided" 
  165                                      " global functions");
 
  168   global_function_sum::global_function_sum(pglobal_function f1, pglobal_function f2)
 
  169     : global_function(f1->dim()), functions(2) {
 
  172     GMM_ASSERT1(f1->dim() == dim() && f2->dim() == dim(),
 
  173                 "Incompatible dimensions between the provided global functions");
 
  176   global_function_sum::global_function_sum(pglobal_function f1, pglobal_function f2,
 
  178     : global_function(f1->dim()), functions(3) {
 
  182     GMM_ASSERT1(f1->dim() == dim() && f2->dim() == dim() && f3->dim() == dim(),
 
  183                 "Incompatible dimensions between the provided global functions");
 
  186   global_function_sum::global_function_sum(pglobal_function f1, pglobal_function f2,
 
  187                                            pglobal_function f3, pglobal_function f4)
 
  188     : global_function(f1->dim()), functions(4) {
 
  193     GMM_ASSERT1(f1->dim() == dim() && f2->dim() == dim() && f3->dim() == dim(),
 
  194                 "Incompatible dimensions between the provided global functions");
 
  200   scalar_type global_function_product::val
 
  201   (
const fem_interpolation_context &c)
 const {
 
  202     return f1->val(c) * f2->val(c);
 
  205   void global_function_product::grad
 
  206   (
const fem_interpolation_context &c, base_small_vector &g)
 const {
 
  208     base_small_vector gg(dim_);
 
  210     gmm::copy(gmm::scaled(gg, f2->val(c)), g);
 
  212     gmm::add(gmm::scaled(gg, f1->val(c)), g);
 
  215   void global_function_product::hess
 
  216   (
const fem_interpolation_context &c, base_matrix &h)
 const {
 
  217     h.resize(dim_, dim_);
 
  219     base_matrix hh(dim_, dim_);
 
  221     gmm::copy(gmm::scaled(hh, f2->val(c)), h);
 
  223     gmm::add(gmm::scaled(hh, f1->val(c)), h);
 
  224     base_small_vector g1(dim_), g2(dim_);
 
  227     gmm::rank_one_update(h, g1, g2);
 
  228     gmm::rank_one_update(h, g2, g1);
 
  231   bool global_function_product::is_in_support(
const base_node &p)
 const {
 
  232     return f1->is_in_support(p) && f2->is_in_support(p);
 
  235   void global_function_product::bounding_box
 
  236   (base_node &bmin_, base_node &bmax_)
 const {
 
  237     base_node bmin0(dim()), bmax0(dim());
 
  238     f1->bounding_box(bmin0, bmax0);
 
  239     f2->bounding_box(bmin_, bmax_);
 
  241       if (bmin0[i] > bmin_[i]) bmin_[i] = bmin0[i];
 
  242       if (bmax0[i] < bmax_[i]) bmax_[i] = bmax0[i];
 
  243       if (bmin_[i] > bmax_[i])
 
  244         GMM_WARNING1(
"Global function product with vanishing basis function");
 
  248   global_function_product::global_function_product(pglobal_function f1_, pglobal_function f2_)
 
  249     : global_function(f1_->dim()), f1(f1_), f2(f2_) {
 
  250     GMM_ASSERT1(f2->dim() == dim(), 
"Incompatible dimensions between the provided" 
  251                                     " global functions");
 
  257   bool global_function_bounded::is_in_support(
const base_node &pt)
 const {
 
  260       const bgeot::base_tensor &t = f_val.eval();
 
  261       GMM_ASSERT1(t.size() == 1, 
"Wrong size of expression result " 
  262                   << f_val.expression());
 
  263       return (t[0] > scalar_type(0));
 
  268   global_function_bounded::global_function_bounded(pglobal_function f_,
 
  269                                                    const base_node &bmin_,
 
  270                                                    const base_node &bmax_,
 
  271                                                    const std::string &is_in_expr)
 
  272     : global_function(f_->dim()), f(f_), bmin(bmin_), bmax(bmax_),
 
  273       f_val(gw, is_in_expr) {
 
  275     has_expr = !is_in_expr.empty();
 
  280       gw.add_fixed_size_variable(
"X", gmm::sub_interval(0, N), pt_);
 
  281       if (N >= 1) gw.add_macro(
"x", 
"X(1)");
 
  282       if (N >= 2) gw.add_macro(
"y", 
"X(2)");
 
  283       if (N >= 3) gw.add_macro(
"z", 
"X(3)");
 
  284       if (N >= 4) gw.add_macro(
"w", 
"X(4)");
 
  291   parser_xy_function::parser_xy_function(
const std::string &sval,
 
  292                                          const std::string &sgrad,
 
  293                                          const std::string &shess)
 
  294     : f_val(gw, sval), f_grad(gw, sgrad), f_hess(gw, shess),
 
  295       ptx(1), pty(1), ptr(1), ptt(1) {
 
  297     gw.add_fixed_size_constant(
"x", ptx);
 
  298     gw.add_fixed_size_constant(
"y", pty);
 
  299     gw.add_fixed_size_constant(
"r", ptr);
 
  300     gw.add_fixed_size_constant(
"theta", ptt);
 
  308   parser_xy_function::val(scalar_type x, scalar_type y)
 const {
 
  311     ptr[0] = double(sqrt(fabs(x*x+y*y))); 
 
  312     ptt[0] = double(atan2(y,x));          
 
  314     const bgeot::base_tensor &t = f_val.eval();
 
  315     GMM_ASSERT1(t.size() == 1, 
"Wrong size of expression result " 
  316                 << f_val.expression());
 
  321   parser_xy_function::grad(scalar_type x, scalar_type y)
 const {
 
  324     ptr[0] = double(sqrt(fabs(x*x+y*y))); 
 
  325     ptt[0] = double(atan2(y,x));          
 
  327     base_small_vector res(2);
 
  328     const bgeot::base_tensor &t = f_grad.eval();
 
  329     GMM_ASSERT1(t.size() == 2, 
"Wrong size of expression result " 
  330                 << f_grad.expression());
 
  336   parser_xy_function::hess(scalar_type x, scalar_type y)
 const {
 
  339     ptr[0] = double(sqrt(fabs(x*x+y*y))); 
 
  340     ptt[0] = double(atan2(y,x));          
 
  342     base_matrix res(2,2);
 
  343     const bgeot::base_tensor &t = f_hess.eval();
 
  344     GMM_ASSERT1(t.size() == 4, 
"Wrong size of expression result " 
  345                 << f_hess.expression());
 
  346     gmm::copy(t.as_vector(), res.as_vector());
 
  352   crack_singular_xy_function::val(scalar_type x, scalar_type y)
 const {
 
  353     scalar_type sgny = (y < 0 ? -1.0 : 1.0);
 
  354     scalar_type r = sqrt(x*x + y*y);
 
  355     if (r < 1e-10)  
return 0;
 
  360     scalar_type sin2 = sqrt(gmm::abs(.5-x/(2*r))) * sgny;
 
  361     scalar_type cos2 = sqrt(gmm::abs(.5+x/(2*r)));
 
  368       case 0 : res = sqrt(r)*sin2; 
break;
 
  369       case 1 : res = sqrt(r)*cos2; 
break;
 
  370       case 2 : res = sin2*y/sqrt(r); 
break;
 
  371       case 3 : res = cos2*y/sqrt(r); 
break;
 
  375       case 4 : res = sqrt(r)*r*sin2; 
break;
 
  376       case 5 : res = sqrt(r)*r*cos2; 
break;
 
  377       case 6 : res = sin2*cos2*cos2*r*sqrt(r); 
break;
 
  378       case 7 : res = cos2*cos2*cos2*r*sqrt(r); 
break;
 
  382       case 8 : res = -sin2/sqrt(r); 
break;
 
  383       case 9 : res = cos2/sqrt(r); 
break;
 
  387       case 10 : res = sin2*sqrt(r); 
break; 
 
  388       case 11 : res = cos2*sqrt(r); 
break;
 
  392       case 12 : res = r*sin2*sin2; 
break;
 
  393       case 13 : res = sqrt(r)*sin2; 
break;
 
  397       case 14 : res = sin2/r; 
break;
 
  398       case 15 : res = cos2/r; 
break;
 
  400     default: GMM_ASSERT2(
false, 
"arg");
 
  407   crack_singular_xy_function::grad(scalar_type x, scalar_type y)
 const {
 
  408     scalar_type sgny = (y < 0 ? -1.0 : 1.0);
 
  409     scalar_type r = sqrt(x*x + y*y);
 
  412       GMM_WARNING0(
"Warning, point close to the singularity (r=" << r << 
")");
 
  418     scalar_type sin2 = sqrt(gmm::abs(.5-x/(2*r))) * sgny;
 
  419     scalar_type cos2 = sqrt(gmm::abs(.5+x/(2*r)));
 
  421     base_small_vector res(2);
 
  425       res[0] = -sin2/(2*sqrt(r));
 
  426       res[1] = cos2/(2*sqrt(r));
 
  429       res[0] = cos2/(2*sqrt(r));
 
  430       res[1] = sin2/(2*sqrt(r));
 
  433       res[0] = cos2*((-5*cos2*cos2) + 1. + 4*(cos2*cos2*cos2*cos2))/sqrt(r);
 
  434       res[1] = sin2*((-3*cos2*cos2) + 1. + 4*(cos2*cos2*cos2*cos2))/sqrt(r);
 
  437       res[0] = -cos2*cos2*sin2*((4*cos2*cos2) - 3.)/sqrt(r);
 
  438       res[1] = cos2*((4*cos2*cos2*cos2*cos2) + 2. - (5*cos2*cos2))/sqrt(r);
 
  443       res[0] = sin2 *((4*cos2*cos2)-3.)*sqrt(r)/2.;
 
  444       res[1] = cos2*(5. - (4*cos2*cos2))*sqrt(r)/2. ;
 
  447       res[0] = cos2*((4*cos2*cos2)-1.)*sqrt(r)/2.;
 
  448       res[1] = sin2*((4*cos2*cos2)+1.)*sqrt(r)/2. ;
 
  452       res[0] = sin2*cos2*cos2*sqrt(r)/2.;
 
  453       res[1] = cos2*(2. - (cos2*cos2))*sqrt(r)/2.;
 
  456       res[0] = 3*cos2*cos2*cos2*sqrt(r)/2.;
 
  457       res[1] = 3*sin2*cos2*cos2*sqrt(r)/2.;
 
  463       res[0] =sin2*((4*cos2*cos2)-1.)/(2*sqrt(r)*r);
 
  464       res[1] =-cos2*((4*cos2*cos2)-3.)/(2*sqrt(r)*r);
 
  467       res[0] =-cos2*((2*cos2*cos2) - 3.)/(2*sqrt(r)*r);
 
  468       res[1] =-sin2*((4*cos2*cos2)-1.)/(2*sqrt(r)*r);
 
  473       res[0] = -sin2/(2*sqrt(r));
 
  474       res[1] =  cos2/(2*sqrt(r));
 
  477       res[0] = cos2/(2*sqrt(r));
 
  478       res[1] = sin2/(2*sqrt(r));
 
  485       res[1] = 0.5*cos2*sin2;
 
  488       res[0] = -sin2/(2*sqrt(r));
 
  489       res[1] = cos2/(2*sqrt(r));
 
  501       res[1] = -sin2/(2*r);
 
  505     default: GMM_ASSERT2(
false, 
"oups");
 
  511   crack_singular_xy_function::hess(scalar_type x, scalar_type y)
 const {
 
  512     scalar_type sgny = (y < 0 ? -1.0 : 1.0);
 
  513     scalar_type r = sqrt(x*x + y*y);
 
  516       GMM_WARNING0(
"Warning, point close to the singularity (r=" << r << 
")");
 
  522     scalar_type sin2 = sqrt(gmm::abs(.5-x/(2*r))) * sgny;
 
  523     scalar_type cos2 = sqrt(gmm::abs(.5+x/(2*r)));
 
  525     base_matrix res(2,2);
 
  528       res(0,0) = (-sin2*x*x + 2.0*cos2*x*y + sin2*y*y) / (4*pow(r, 3.5));
 
  529       res(0,1) = (-cos2*x*x - 2.0*sin2*x*y + cos2*y*y) / (4*pow(r, 3.5));
 
  530       res(1,0) = res(0, 1);
 
  531       res(1,1) = (sin2*x*x - 2.0*cos2*x*y - sin2*y*y) / (4*pow(r, 3.5));
 
  534       res(0,0) = (-cos2*x*x - 2.0*sin2*x*y + cos2*y*y) / (4*pow(r, 3.5));
 
  535       res(0,1) = (sin2*x*x - 2.0*cos2*x*y - sin2*y*y) / (4*pow(r, 3.5));
 
  536       res(1,0) = res(0, 1);
 
  537       res(1,1) = (cos2*x*x + 2.0*sin2*x*y - cos2*y*y) / (4*pow(r, 3.5));
 
  540       res(0,0) = 3.0*y*(sin2*x*x + 2.0*cos2*x*y - sin2*y*y) / (4*pow(r, 4.5));
 
  541       res(0,1) = (-2.0*sin2*x*x*x - 5.0*cos2*y*x*x + 4.0*sin2*y*y*x + cos2*y*y*y)
 
  543       res(1,0) = res(0, 1);
 
  544       res(1,1) = (4.0*cos2*x*x*x - 7.0*sin2*y*x*x - 2.0*cos2*y*y*x - sin2*y*y*y)
 
  548       res(0,0) = 3.0*y*(cos2*x*x - 2.0*sin2*x*y - cos2*y*y) / (4*pow(r, 4.5));
 
  549       res(0,1) = (-2.0*cos2*x*x*x + 5.0*sin2*y*x*x + 4.0*cos2*y*y*x - sin2*y*y*y)
 
  551       res(1,0) = res(0, 1);
 
  552       res(1,1) = (-4.0*sin2*x*x*x - 7.0*cos2*y*x*x + 2.0*sin2*y*y*x - cos2*y*y*y)
 
  555     default: GMM_ASSERT2(
false, 
"oups");
 
  561   cutoff_xy_function::val(scalar_type x, scalar_type y)
 const {
 
  564       case EXPONENTIAL_CUTOFF: {
 
  565         res = (a4>0) ? exp(-a4 * gmm::sqr(x*x+y*y)) : 1;
 
  568       case POLYNOMIAL_CUTOFF: {
 
  570         scalar_type r = gmm::sqrt(x*x+y*y);
 
  572         if (r <= r1) res = 1;
 
  573         else if (r >= r0) res = 0;
 
  579           scalar_type c = 1./pow(r0-r1,3.0);
 
  580           res = c*(r*(r*(2.0*r-3.0*(r0+r1))+6.0*r1*r0) + r0*r0*(r0-3.0*r1));
 
  584       case POLYNOMIAL2_CUTOFF: {
 
  586         scalar_type r = gmm::sqrt(x*x+y*y);
 
  587         if (r <= r1) res = scalar_type(1);
 
  588         else if (r >= r0) res = scalar_type(0);
 
  600           res = (r*(r*(r*(r*(-6.0*r + 15.0*(r0+r1))
 
  601                            - 10.0*(r0*r0 + 4.0*r1*r0 + r1*r1))
 
  602                         + 30.0 * r0*r1*(r0+r1)) - 30.0*r1*r1*r0*r0)
 
  603                   + r0*r0*r0*(r0*r0-5.0*r1*r0+10*r1*r1)) / pow(r0-r1, 5.0);
 
  613   cutoff_xy_function::grad(scalar_type x, scalar_type y)
 const {
 
  614     base_small_vector res(2);
 
  616     case EXPONENTIAL_CUTOFF: {
 
  617       scalar_type r2 = x*x+y*y, ratio = -4.*exp(-a4*r2*r2)*a4*r2;
 
  622     case POLYNOMIAL_CUTOFF: {
 
  623       scalar_type r = gmm::sqrt(x*x+y*y);
 
  624       scalar_type ratio = 0;
 
  626       if ( r > r1 && r < r0 ) {
 
  629         ratio = 6.*(r - r0)*(r - r1)/pow(r0-r1, 3.);
 
  635     case POLYNOMIAL2_CUTOFF: {
 
  636       scalar_type r = gmm::sqrt(x*x+y*y);
 
  637       scalar_type ratio = 0;
 
  638       if (r > r1 && r < r0) {
 
  644         ratio = -30.0*gmm::sqr(r-r0)*gmm::sqr(r-r1) / pow(r0-r1, 5.0);
 
  658   cutoff_xy_function::hess(scalar_type x, scalar_type y)
 const {
 
  659     base_matrix res(2,2);
 
  661     case EXPONENTIAL_CUTOFF: {
 
  662       scalar_type r2 = x*x+y*y, r4 = r2*r2;
 
  663       res(0,0) = 4.0*a4*(-3.0*x*x - y*y + 4.0*a4*x*x*r4)*exp(-a4*r4);
 
  664       res(1,0) = 8.0*a4*x*y*(-1.0 + 2.0*a4*r4)*exp(-a4*r4);
 
  666       res(1,1) = 4.0*a4*(-3.0*y*y - x*x + 4.0*a4*y*y*r4)*exp(-a4*r4);
 
  669     case POLYNOMIAL_CUTOFF: {
 
  670       scalar_type r2 = x*x+y*y, r = gmm::sqrt(r2), c=6./(pow(r0-r1,3.)*r*r2);
 
  671       if ( r > r1 && r < r0 ) {
 
  672         res(0,0) = c*(x*x*r2 + r1*r0*y*y - r*r2*(r0+r1) + r2*r2);
 
  673         res(1,0) = c*x*y*(r2 - r1*r0);
 
  675         res(1,1) = c*(y*y*r2 + r1*r0*x*x - r*r2*(r0+r1) + r2*r2);
 
  679     case POLYNOMIAL2_CUTOFF: {
 
  680       scalar_type r2 = x*x+y*y, r = gmm::sqrt(r2), r3 = r*r2;
 
  681       if (r > r1 && r < r0) {
 
  682         scalar_type dp = -30.0*(r1-r)*(r1-r)*(r0-r)*(r0-r) / pow(r0-r1, 5.0);
 
  683         scalar_type ddp = 60.0*(r1-r)*(r0-r)*(r0+r1-2.0*r) / pow(r0-r1, 5.0);
 
  684         scalar_type rx= x/r, ry= y/r, rxx= y*y/r3, rxy= -x*y/r3, ryy= x*x/r3;
 
  685         res(0,0) = ddp*rx*rx + dp*rxx;
 
  686         res(1,0) = ddp*rx*ry + dp*rxy;
 
  688         res(1,1) = ddp*ry*ry + dp*ryy;
 
  696   cutoff_xy_function::cutoff_xy_function(
int fun_num, scalar_type r,
 
  697                                          scalar_type r1_, scalar_type r0_)
 
  702     if (r > 0) a4 = pow(2.7/r,4.);
 
  706   struct global_function_on_levelsets_2D_ :
 
  707     public global_function, 
public context_dependencies {
 
  708     const std::vector<level_set> dummy_lsets;
 
  709     const std::vector<level_set> &lsets;
 
  711     mutable pmesher_signed_distance mls_x, mls_y;
 
  719         if (lsets.size() == 0) {
 
  720           mls_x = ls.mls_of_convex(cv, 1);
 
  721           mls_y = ls.mls_of_convex(cv, 0);
 
  724           scalar_type d = scalar_type(-2);
 
  725           for (
const level_set &ls_ : lsets) {
 
  726             pmesher_signed_distance mls_xx, mls_yy;
 
  727             mls_xx = ls_.mls_of_convex(cv, 1);
 
  728             mls_yy = ls_.mls_of_convex(cv, 0);
 
  729             scalar_type x = (*mls_xx)(pt), y = (*mls_yy)(pt);
 
  730             scalar_type d2 = gmm::sqr(x) + gmm::sqr(y);
 
  731             if (d < scalar_type(-1) || d2 < d) {
 
  741     virtual scalar_type val(
const fem_interpolation_context& c)
 const {
 
  742       update_mls(c.convex_num(), c.xref().size());
 
  743       scalar_type x = (*mls_x)(c.xref());
 
  744       scalar_type y = (*mls_y)(c.xref());
 
  745       if (c.xfem_side() > 0 && y <= 1E-13) y = 1E-13;
 
  746       if (c.xfem_side() < 0 && y >= -1E-13) y = -1E-13;
 
  749     virtual void grad(
const fem_interpolation_context& c,
 
  750                       base_small_vector &g)
 const {
 
  752       base_small_vector dx(P), dy(P), dfr(2);
 
  754       update_mls(c.convex_num(), P);
 
  755       scalar_type x = mls_x->grad(c.xref(), dx);
 
  756       scalar_type y = mls_y->grad(c.xref(), dy);
 
  757       if (c.xfem_side() > 0 && y <= 0) y = 1E-13;
 
  758       if (c.xfem_side() < 0 && y >= 0) y = -1E-13;
 
  760       base_small_vector gfn = fn->grad(x,y);
 
  761       gmm::mult(c.B(), gfn[0]*dx + gfn[1]*dy, g);
 
  763     virtual void hess(
const fem_interpolation_context&c,
 
  764                       base_matrix &h)
 const {
 
  765       size_type P = c.xref().size(), N = c.N();
 
  766       base_small_vector dx(P), dy(P), dfr(2),  dx_real(N), dy_real(N);
 
  768       update_mls(c.convex_num(), P);
 
  769       scalar_type x = mls_x->grad(c.xref(), dx);
 
  770       scalar_type y = mls_y->grad(c.xref(), dy);
 
  771       if (c.xfem_side() > 0 && y <= 0) y = 1E-13;
 
  772       if (c.xfem_side() < 0 && y >= 0) y = -1E-13;
 
  774       base_small_vector gfn = fn->grad(x,y);
 
  775       base_matrix hfn = fn->hess(x,y);
 
  777       base_matrix hx, hy, hx_real(N*N, 1), hy_real(N*N, 1);
 
  778       mls_x->hess(c.xref(), hx);
 
  779       mls_x->hess(c.xref(), hy);
 
  784       gmm::mult(c.B32(), gmm::scaled(dx, -1.0), gmm::mat_col(hx_real, 0));
 
  786       gmm::mult(c.B32(), gmm::scaled(dy, -1.0), gmm::mat_col(hy_real, 0));
 
  792           h(i, j) = hfn(0,0) * dx_real[i] * dx_real[j]
 
  793             + hfn(0,1) * dx_real[i] * dy_real[j]
 
  794             + hfn(1,0) * dy_real[i] * dx_real[j]
 
  795             + hfn(1,1) * dy_real[i] * dy_real[j]
 
  796             + gfn[0] * hx_real(i * N + j, 0) + gfn[1] * hy_real(i*N+j,0);
 
  800     void update_from_context()
 const { cv =  
size_type(-1); }
 
  802     global_function_on_levelsets_2D_(
const std::vector<level_set> &lsets_,
 
  803                                      const pxy_function &fn_)
 
  804       : global_function(2), dummy_lsets(0, dummy_level_set()),
 
  805         lsets(lsets_), ls(dummy_level_set()), fn(fn_) {
 
  806       GMM_ASSERT1(lsets.size() > 0, 
"The list of level sets should" 
  807                                     " contain at least one level set.");
 
  809       for (
const level_set &ls_ : lsets)
 
  813     global_function_on_levelsets_2D_(
const level_set &ls_,
 
  814                                      const pxy_function &fn_)
 
  815       : global_function(2), dummy_lsets(0, dummy_level_set()),
 
  816         lsets(dummy_lsets), ls(ls_), fn(fn_) {
 
  824   global_function_on_level_sets(
const std::vector<level_set> &lsets,
 
  825                                 const pxy_function &fn) {
 
  826     return std::make_shared<global_function_on_levelsets_2D_>(lsets, fn);
 
  830   global_function_on_level_set(
const level_set &ls,
 
  831                                const pxy_function &fn) {
 
  832     return std::make_shared<global_function_on_levelsets_2D_>(ls, fn);
 
  839   const scalar_type eps(1e-12);
 
  842   scalar_type bsp3_01(scalar_type t) {
 
  843     return (t >= -eps && t < 1) ? pow(1.-t,2)
 
  846   scalar_type bsp3_01_der(scalar_type t) {
 
  847     return (t >= -eps && t < 1) ? 2.*t-2.
 
  850   scalar_type bsp3_01_der2(scalar_type t) {
 
  851     return (t >= eps && t <= 1.-eps) ? 2.
 
  854   scalar_type bsp3_01_der2_with_hint(scalar_type t, scalar_type t_hint) {
 
  855     return (t > -eps && t < 1.+eps && t_hint > 0 && t_hint < 1) ? 2.
 
  858   scalar_type bsp3_02(scalar_type t) {
 
  861         return (-1.5*t+2.)*t;
 
  863         return 0.5*pow(2.-t,2);
 
  867   scalar_type bsp3_02_der(scalar_type t) {
 
  876   scalar_type bsp3_02_der2(scalar_type t) {
 
  882       else if (t <= 2.-eps)
 
  887   scalar_type bsp3_03(scalar_type t) {
 
  901   scalar_type bsp3_03_der(scalar_type t) {
 
  914   scalar_type bsp3_03_der2(scalar_type t) {
 
  918       else if (t <= 1.-eps)
 
  922       else if (t <= 2.-eps)
 
  926       else if (t <= 3.-eps)
 
  935   scalar_type bsp4_01(scalar_type t) {
 
  936     return (t >= -eps && t < 1) ? pow(1.-t,3)
 
  939   scalar_type bsp4_01_der(scalar_type t) {
 
  940     return (t >= -eps && t < 1) ? -3*pow(1.-t,2)
 
  943   scalar_type bsp4_01_der2(scalar_type t) {
 
  944     return (t >= -eps && t < 1) ? 6*(1.-t)
 
  947   scalar_type bsp4_02(scalar_type t) {
 
  950         return ((7./4.*t-9./2.)*t+3.)*t;
 
  952         return 1./4.*pow(2.-t,3);
 
  957   scalar_type bsp4_02_der(scalar_type t) {
 
  960         return (21./4.*t-9.)*t+3.;
 
  962         return -3./4.*pow(2.-t,2);
 
  967   scalar_type bsp4_02_der2(scalar_type t) {
 
  977   scalar_type bsp4_03(scalar_type t) {
 
  980         return (-11./12.*t+3./2.)*t*t;
 
  983         return ((7./12.*t-5./4.)*t+1./4.)*t+7./12.;
 
  985         return 1./6.*pow(3.-t,3);
 
  990   scalar_type bsp4_03_der(scalar_type t) {
 
  993         return (-11./4.*t+3.)*t;
 
  996         return (7./4.*t-5./2.)*t+1./4.;
 
  998         return -1./2.*pow(3.-t,2);
 
 1003   scalar_type bsp4_03_der2(scalar_type t) {
 
 1006         return -11./2.*t+3.;
 
 1009         return 7./2.*t-5./2.;
 
 1016   scalar_type bsp4_04(scalar_type t) {
 
 1022         return 1./6.*pow(t,3);
 
 1023       } 
else if (t <= 2) {
 
 1025         return ((-1./2.*t+1./2.)*t+1./2.)*t+1./6.;
 
 1030   scalar_type bsp4_04_der(scalar_type t) {
 
 1038         return 1./2.*pow(t,2)*sgn;
 
 1041         return ((-3./2.*t+1.)*t+1./2.)*sgn;
 
 1046   scalar_type bsp4_04_der2(scalar_type t) {
 
 1063   scalar_type bsp5_01(scalar_type t) {
 
 1064     return (t >= -eps && t < 1) ? pow(1.-t,4)
 
 1067   scalar_type bsp5_01_der(scalar_type t) {
 
 1068     return (t >= -eps && t < 1) ? -4.*pow(1.-t,3)
 
 1071   scalar_type bsp5_01_der2(scalar_type t) {
 
 1072     return (t >= -eps && t < 1) ? 12.*pow(1.-t,2)
 
 1075   scalar_type bsp5_02(scalar_type t) {
 
 1078         return (((-15./8.*t+7.)*t-9.)*t+4.)*t;
 
 1080         return 1./8.*pow(2.-t,4);
 
 1085   scalar_type bsp5_02_der(scalar_type t) {
 
 1088         return ((-15./2.*t+21.)*t-18.)*t+4.;
 
 1090         return -1./2.*pow(2.-t,3);
 
 1095   scalar_type bsp5_02_der2(scalar_type t) {
 
 1098         return (-45./2.*t+42.)*t-18.;
 
 1100         return 3./2.*pow(2.-t,2);
 
 1105   scalar_type bsp5_03(scalar_type t) {
 
 1108         return ((85./72.*t-11./3.)*t+3.)*t*t;
 
 1111         return (((-23./72*t+2./9.)*t+1./3.)*t+2./9.)*t+1./18.;
 
 1113         return 1./18.*pow(3.-t,4);
 
 1118   scalar_type bsp5_03_der(scalar_type t) {
 
 1121         return ((85./18.*t-11.)*t+6.)*t;
 
 1124         return -(((-23./18*t+2./3.)*t+2./3.)*t+2./9.);
 
 1126         return -2./9.*pow(3.-t,3);
 
 1131   scalar_type bsp5_03_der2(scalar_type t) {
 
 1134         return (85./6.*t-22.)*t+6.;
 
 1137         return (-23./6*t+4./3.)*t+2./3.;
 
 1139         return 2./3.*pow(3.-t,2);
 
 1144   scalar_type bsp5_04(scalar_type t) {
 
 1147         return (-25./72.*t+2./3.)*t*t*t;
 
 1150         return (((23./72.*t-5./9.)*t-1./3.)*t+4./9.)*t+4./9.;
 
 1153         return (((-13./72.*t+5./9.)*t-1./3.)*t-4./9.)*t+4./9.;
 
 1155         return 1./24.*pow(4.-t,4);
 
 1160   scalar_type bsp5_04_der(scalar_type t) {
 
 1163         return (-25./18.*t+2.)*t*t;
 
 1166         return -(((23./18.*t-5./3.)*t-2./3.)*t+4./9.);
 
 1169         return ((-13./18.*t+5./3.)*t-2./3.)*t-4./9.;
 
 1171         return -1./6.*pow(4.-t,3);
 
 1176   scalar_type bsp5_04_der2(scalar_type t) {
 
 1179         return (-25./6.*t+4.)*t;
 
 1182         return (23./6.*t-10./3.)*t-2./3.;
 
 1185         return -((-13./6.*t+10./3.)*t-2./3.);
 
 1187         return 1./2.*pow(4.-t,2);
 
 1192   scalar_type bsp5_05(scalar_type t) {
 
 1193     if (t > scalar_type(2.5)) {
 
 1198         return 1./24.*pow(t,4);
 
 1201         return (((-1./6.*t+1./6.)*t+1./4.)*t+1./6.)*t+1./24.;
 
 1204         return (1./4.*t-5./8.)*t+115./192.;
 
 1209   scalar_type bsp5_05_der(scalar_type t) {
 
 1211     if (t > scalar_type(2.5)) {
 
 1217         return 1./6.*pow(t,3)*sgn;
 
 1220         return (((-2./3.*t+1./2.)*t+1./2)*t+1./6.)*sgn;
 
 1223         return (t*t-5./4.)*t*sgn;
 
 1228   scalar_type bsp5_05_der2(scalar_type t) {
 
 1229     if (t > scalar_type(2.5)) {
 
 1234         return 1./2.*pow(t,2);
 
 1237         return (-2.*t+1.)*t+1./2;
 
 1248   class global_function_x_bspline_
 
 1249     : 
public global_function_simple, 
public context_dependencies {
 
 1250     scalar_type xmin, xmax, xscale;
 
 1251     std::function<scalar_type(scalar_type)> fx, fx_der, fx_der2;
 
 1253     void update_from_context()
 const {}
 
 1255     virtual scalar_type val(
const base_node &pt)
 const 
 1257       return fx(xscale*(pt[0]-xmin));
 
 1259     virtual void grad(
const base_node &pt, base_small_vector &g)
 const 
 1261       scalar_type dx = xscale*(pt[0]-xmin);
 
 1263       g[0] = xscale * fx_der(dx);
 
 1265     virtual void hess(
const base_node &pt, base_matrix &h)
 const 
 1267       scalar_type dx = xscale*(pt[0]-xmin);
 
 1268       h.resize(dim_, dim_);
 
 1270       h(0,0) = xscale*xscale * fx_der2(dx);
 
 1273     virtual bool is_in_support(
const base_node &pt)
 const {
 
 1274       scalar_type dx = pt[0]-(xmin+xmax)/2;
 
 1275       return (gmm::abs(dx)+1e-9 < gmm::abs(xmax-xmin)/2);
 
 1278     virtual void bounding_box(base_node &bmin, base_node &bmax)
 const {
 
 1279       GMM_ASSERT1(bmin.size() == dim_ && bmax.size() == dim_,
 
 1280                   "Wrong dimensions");
 
 1281       bmin[0] = std::min(xmin,xmax);
 
 1282       bmax[0] = std::max(xmin,xmax);
 
 1285     global_function_x_bspline_(
const scalar_type &xmin_, 
const scalar_type &xmax_,
 
 1287     : global_function_simple(1), xmin(xmin_), xmax(xmax_),
 
 1288       xscale(scalar_type(xtype)/(xmax-xmin))
 
 1290       GMM_ASSERT1(order >= 3 && order <= 5, 
"Only orders 3 to 5 are supported");
 
 1291       GMM_ASSERT1(xtype >= 1 && xtype <= order, 
"Wrong input");
 
 1294           fx = bsp3_01;   fx_der = bsp3_01_der;   fx_der2 = bsp3_01_der2;
 
 1295         } 
else if (xtype == 2) {
 
 1296           fx = bsp3_02;   fx_der = bsp3_02_der;   fx_der2 = bsp3_02_der2;
 
 1297         } 
else if (xtype == 3) {
 
 1298           fx = bsp3_03;   fx_der = bsp3_03_der;   fx_der2 = bsp3_03_der2;
 
 1300       } 
else if (order == 4) {
 
 1302           fx = bsp4_01;   fx_der = bsp4_01_der;   fx_der2 = bsp4_01_der2;
 
 1303         } 
else if (xtype == 2) {
 
 1304           fx = bsp4_02;   fx_der = bsp4_02_der;   fx_der2 = bsp4_02_der2;
 
 1305         } 
else if (xtype == 3) {
 
 1306           fx = bsp4_03;   fx_der = bsp4_03_der;   fx_der2 = bsp4_03_der2;
 
 1307         } 
else if (xtype == 4) {
 
 1308           fx = bsp4_04;   fx_der = bsp4_04_der;   fx_der2 = bsp4_04_der2;
 
 1310       } 
else if (order == 5) {
 
 1312           fx = bsp5_01;   fx_der = bsp5_01_der;   fx_der2 = bsp5_01_der2;
 
 1313         } 
else if (xtype == 2) {
 
 1314           fx = bsp5_02;   fx_der = bsp5_02_der;   fx_der2 = bsp5_02_der2;
 
 1315         } 
else if (xtype == 3) {
 
 1316           fx = bsp5_03;   fx_der = bsp5_03_der;   fx_der2 = bsp5_03_der2;
 
 1317         } 
else if (xtype == 4) {
 
 1318           fx = bsp5_04;   fx_der = bsp5_04_der;   fx_der2 = bsp5_04_der2;
 
 1319         } 
else if (xtype == 5) {
 
 1320           fx = bsp5_05;   fx_der = bsp5_05_der;   fx_der2 = bsp5_05_der2;
 
 1325     virtual ~global_function_x_bspline_()
 
 1326     { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this, 
"Global function x bspline"); }
 
 1331   class global_function_xy_bspline_
 
 1332     : 
public global_function_simple, 
public context_dependencies {
 
 1333     scalar_type xmin, ymin, xmax, ymax, xscale, yscale;
 
 1334     std::function<scalar_type(scalar_type)>
 
 1335       fx, fy, fx_der, fy_der, fx_der2, fy_der2;
 
 1337     void update_from_context()
 const {}
 
 1339     virtual scalar_type val(
const base_node &pt)
 const 
 1341       return fx(xscale*(pt[0]-xmin))
 
 1342              * fy(yscale*(pt[1]-ymin));
 
 1344     virtual void grad(
const base_node &pt, base_small_vector &g)
 const 
 1346       scalar_type dx = xscale*(pt[0]-xmin),
 
 1347                   dy = yscale*(pt[1]-ymin);
 
 1349       g[0] = xscale * fx_der(dx) * fy(dy);
 
 1350       g[1] = fx(dx) * yscale * fy_der(dy);
 
 1352     virtual void hess(
const base_node &pt, base_matrix &h)
 const 
 1354       scalar_type dx = xscale*(pt[0]-xmin),
 
 1355                   dy = yscale*(pt[1]-ymin);
 
 1356       h.resize(dim_, dim_);
 
 1358       h(0,0) = xscale*xscale * fx_der2(dx) * fy(dy);
 
 1359       h(0,1) = h(1,0) = xscale * fx_der(dx) * yscale * fy_der(dy);
 
 1360       h(1,1) = fx(dx) * yscale*yscale * fy_der2(dy);
 
 1363     virtual bool is_in_support(
const base_node &pt)
 const {
 
 1364       scalar_type dx = pt[0]-(xmin+xmax)/2,
 
 1365                   dy = pt[1]-(ymin+ymax)/2;
 
 1366       return (gmm::abs(dx)+1e-9 < gmm::abs(xmax-xmin)/2) &&
 
 1367              (gmm::abs(dy)+1e-9 < gmm::abs(ymax-ymin)/2);
 
 1370     virtual void bounding_box(base_node &bmin, base_node &bmax)
 const {
 
 1371       GMM_ASSERT1(bmin.size() == dim_ && bmax.size() == dim_,
 
 1372                   "Wrong dimensions");
 
 1373       bmin[0] = std::min(xmin,xmax);
 
 1374       bmin[1] = std::min(ymin,ymax);
 
 1375       bmax[0] = std::max(xmin,xmax);
 
 1376       bmax[1] = std::max(ymin,ymax);
 
 1379     global_function_xy_bspline_(
const scalar_type &xmin_, 
const scalar_type &xmax_,
 
 1380                                 const scalar_type &ymin_, 
const scalar_type &ymax_,
 
 1383     : global_function_simple(2), xmin(xmin_), ymin(ymin_), xmax(xmax_), ymax(ymax_),
 
 1384       xscale(scalar_type(xtype)/(xmax-xmin)), yscale(scalar_type(ytype)/(ymax-ymin))
 
 1386       GMM_ASSERT1(order >= 3 && order <= 5, 
"Wrong input");
 
 1387       GMM_ASSERT1(xtype >= 1 && xtype <= order &&
 
 1388                   ytype >= 1 && ytype <= order, 
"Wrong input");
 
 1391           fx = bsp3_01;   fx_der = bsp3_01_der;   fx_der2 = bsp3_01_der2;
 
 1392         } 
else if (xtype == 2) {
 
 1393           fx = bsp3_02;   fx_der = bsp3_02_der;   fx_der2 = bsp3_02_der2;
 
 1394         } 
else if (xtype == 3) {
 
 1395           fx = bsp3_03;   fx_der = bsp3_03_der;   fx_der2 = bsp3_03_der2;
 
 1399           fy = bsp3_01;   fy_der = bsp3_01_der;   fy_der2 = bsp3_01_der2;
 
 1400         } 
else if (ytype == 2) {
 
 1401           fy = bsp3_02;   fy_der = bsp3_02_der;   fy_der2 = bsp3_02_der2;
 
 1402         } 
else if (ytype == 3) {
 
 1403           fy = bsp3_03;   fy_der = bsp3_03_der;   fy_der2 = bsp3_03_der2;
 
 1405       } 
else if (order == 4) {
 
 1407           fx = bsp4_01;   fx_der = bsp4_01_der;   fx_der2 = bsp4_01_der2;
 
 1408         } 
else if (xtype == 2) {
 
 1409           fx = bsp4_02;   fx_der = bsp4_02_der;   fx_der2 = bsp4_02_der2;
 
 1410         } 
else if (xtype == 3) {
 
 1411           fx = bsp4_03;   fx_der = bsp4_03_der;   fx_der2 = bsp4_03_der2;
 
 1412         } 
else if (xtype == 4) {
 
 1413           fx = bsp4_04;   fx_der = bsp4_04_der;   fx_der2 = bsp4_04_der2;
 
 1417           fy = bsp4_01;   fy_der = bsp4_01_der;   fy_der2 = bsp4_01_der2;
 
 1418         } 
else if (ytype == 2) {
 
 1419           fy = bsp4_02;   fy_der = bsp4_02_der;   fy_der2 = bsp4_02_der2;
 
 1420         } 
else if (ytype == 3) {
 
 1421           fy = bsp4_03;   fy_der = bsp4_03_der;   fy_der2 = bsp4_03_der2;
 
 1422         } 
else if (ytype == 4) {
 
 1423           fy = bsp4_04;   fy_der = bsp4_04_der;   fy_der2 = bsp4_04_der2;
 
 1426       } 
else if (order == 5) {
 
 1428           fx = bsp5_01;   fx_der = bsp5_01_der;   fx_der2 = bsp5_01_der2;
 
 1429         } 
else if (xtype == 2) {
 
 1430           fx = bsp5_02;   fx_der = bsp5_02_der;   fx_der2 = bsp5_02_der2;
 
 1431         } 
else if (xtype == 3) {
 
 1432           fx = bsp5_03;   fx_der = bsp5_03_der;   fx_der2 = bsp5_03_der2;
 
 1433         } 
else if (xtype == 4) {
 
 1434           fx = bsp5_04;   fx_der = bsp5_04_der;   fx_der2 = bsp5_04_der2;
 
 1435         } 
else if (xtype == 5) {
 
 1436           fx = bsp5_05;   fx_der = bsp5_05_der;   fx_der2 = bsp5_05_der2;
 
 1440           fy = bsp5_01;   fy_der = bsp5_01_der;   fy_der2 = bsp5_01_der2;
 
 1441         } 
else if (ytype == 2) {
 
 1442           fy = bsp5_02;   fy_der = bsp5_02_der;   fy_der2 = bsp5_02_der2;
 
 1443         } 
else if (ytype == 3) {
 
 1444           fy = bsp5_03;   fy_der = bsp5_03_der;   fy_der2 = bsp5_03_der2;
 
 1445         } 
else if (ytype == 4) {
 
 1446           fy = bsp5_04;   fy_der = bsp5_04_der;   fy_der2 = bsp5_04_der2;
 
 1447         } 
else if (ytype == 5) {
 
 1448           fy = bsp5_05;   fy_der = bsp5_05_der;   fy_der2 = bsp5_05_der2;
 
 1453     virtual ~global_function_xy_bspline_()
 
 1454     { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this, 
"Global function xy bspline"); }
 
 1458   class global_function_xyz_bspline_
 
 1459     : 
public global_function_simple, 
public context_dependencies {
 
 1460     scalar_type xmin, ymin, zmin, xmax, ymax, zmax, xscale, yscale, zscale;
 
 1461     std::function<scalar_type(scalar_type)>
 
 1462       fx, fy, fz, fx_der, fy_der, fz_der, fx_der2, fy_der2, fz_der2;
 
 1464     void update_from_context()
 const {}
 
 1466     virtual scalar_type val(
const base_node &pt)
 const 
 1468       return fx(xscale*(pt[0]-xmin))
 
 1469              * fy(yscale*(pt[1]-ymin))
 
 1470                * fz(zscale*(pt[2]-zmin));
 
 1472     virtual void grad(
const base_node &pt, base_small_vector &g)
 const 
 1474       scalar_type dx = xscale*(pt[0]-xmin),
 
 1475                   dy = yscale*(pt[1]-ymin),
 
 1476                   dz = zscale*(pt[2]-zmin);
 
 1478       g[0] = xscale * fx_der(dx) * fy(dy) * fz(dz);
 
 1479       g[1] = fx(dx) * yscale * fy_der(dy) * fz(dz);
 
 1480       g[2] = fx(dx) * fy(dy) * zscale * fz_der(dz);
 
 1482     virtual void hess(
const base_node &pt, base_matrix &h)
 const 
 1484       scalar_type dx = xscale*(pt[0]-xmin),
 
 1485                   dy = yscale*(pt[1]-ymin),
 
 1486                   dz = zscale*(pt[2]-zmin);
 
 1487       h.resize(dim_, dim_);
 
 1489       h(0,0) = xscale*xscale * fx_der2(dx) * fy(dy) * fz(dz);
 
 1490       h(1,1) = fx(dx) * yscale*yscale * fy_der2(dy) * fz(dz);
 
 1491       h(2,2) = fx(dx) * fy(dy) * zscale*zscale * fz_der2(dz);
 
 1492       h(0,1) = h(1,0) = xscale * fx_der(dx) * yscale * fy_der(dy) * fz(dz);
 
 1493       h(0,2) = h(2,0) = xscale * fx_der(dx) * fy(dy) * zscale * fz_der(dz);
 
 1494       h(1,2) = h(2,1) = fx(dx) * yscale * fy_der(dy) * zscale * fz_der(dz);
 
 1497     virtual bool is_in_support(
const base_node &pt)
 const {
 
 1498       scalar_type dx = pt[0]-(xmin+xmax)/2,
 
 1499                   dy = pt[1]-(ymin+ymax)/2,
 
 1500                   dz = pt[2]-(zmin+zmax)/2;
 
 1501       return (gmm::abs(dx)+1e-9 < gmm::abs(xmax-xmin)/2) &&
 
 1502              (gmm::abs(dy)+1e-9 < gmm::abs(ymax-ymin)/2) &&
 
 1503              (gmm::abs(dz)+1e-9 < gmm::abs(zmax-zmin)/2);
 
 1506     virtual void bounding_box(base_node &bmin, base_node &bmax)
 const {
 
 1507       GMM_ASSERT1(bmin.size() == dim_ && bmax.size() == dim_,
 
 1508                   "Wrong dimensions");
 
 1509       bmin[0] = std::min(xmin,xmax);
 
 1510       bmin[1] = std::min(ymin,ymax);
 
 1511       bmin[2] = std::min(zmin,zmax);
 
 1512       bmax[0] = std::max(xmin,xmax);
 
 1513       bmax[1] = std::max(ymin,ymax);
 
 1514       bmax[2] = std::max(zmin,zmax);
 
 1517     global_function_xyz_bspline_(
const scalar_type &xmin_, 
const scalar_type &xmax_,
 
 1518                                  const scalar_type &ymin_, 
const scalar_type &ymax_,
 
 1519                                  const scalar_type &zmin_, 
const scalar_type &zmax_,
 
 1524     : global_function_simple(3), xmin(xmin_), ymin(ymin_), zmin(zmin_),
 
 1525                                  xmax(xmax_), ymax(ymax_), zmax(zmax_),
 
 1526       xscale(scalar_type(xtype)/(xmax-xmin)),
 
 1527       yscale(scalar_type(ytype)/(ymax-ymin)),
 
 1528       zscale(scalar_type(ztype)/(zmax-zmin))
 
 1530       GMM_ASSERT1(order >= 3 && order <= 5, 
"Wrong input");
 
 1531       GMM_ASSERT1(xtype >= 1 && xtype <= order &&
 
 1532                   ytype >= 1 && ytype <= order &&
 
 1533                   ztype >= 1 && ztype <= order, 
"Wrong input");
 
 1537           fx = bsp3_01;   fx_der = bsp3_01_der;   fx_der2 = bsp3_01_der2;
 
 1538         } 
else if (xtype == 2) {
 
 1539           fx = bsp3_02;   fx_der = bsp3_02_der;   fx_der2 = bsp3_02_der2;
 
 1540         } 
else if (xtype == 3) {
 
 1541           fx = bsp3_03;   fx_der = bsp3_03_der;   fx_der2 = bsp3_03_der2;
 
 1545           fy = bsp3_01;   fy_der = bsp3_01_der;   fy_der2 = bsp3_01_der2;
 
 1546         } 
else if (ytype == 2) {
 
 1547           fy = bsp3_02;   fy_der = bsp3_02_der;   fy_der2 = bsp3_02_der2;
 
 1548         } 
else if (ytype == 3) {
 
 1549           fy = bsp3_03;   fy_der = bsp3_03_der;   fy_der2 = bsp3_03_der2;
 
 1553           fz = bsp3_01;   fz_der = bsp3_01_der;   fz_der2 = bsp3_01_der2;
 
 1554         } 
else if (ztype == 2) {
 
 1555           fz = bsp3_02;   fz_der = bsp3_02_der;   fz_der2 = bsp3_02_der2;
 
 1556         } 
else if (ztype == 3) {
 
 1557           fz = bsp3_03;   fz_der = bsp3_03_der;   fz_der2 = bsp3_03_der2;
 
 1560       } 
else if (order == 4) {
 
 1563           fx = bsp4_01;   fx_der = bsp4_01_der;   fx_der2 = bsp4_01_der2;
 
 1564         } 
else if (xtype == 2) {
 
 1565           fx = bsp4_02;   fx_der = bsp4_02_der;   fx_der2 = bsp4_02_der2;
 
 1566         } 
else if (xtype == 3) {
 
 1567           fx = bsp4_03;   fx_der = bsp4_03_der;   fx_der2 = bsp4_03_der2;
 
 1568         } 
else if (xtype == 4) {
 
 1569           fx = bsp4_04;   fx_der = bsp4_04_der;   fx_der2 = bsp4_04_der2;
 
 1573           fy = bsp4_01;   fy_der = bsp4_01_der;   fy_der2 = bsp4_01_der2;
 
 1574         } 
else if (ytype == 2) {
 
 1575           fy = bsp4_02;   fy_der = bsp4_02_der;   fy_der2 = bsp4_02_der2;
 
 1576         } 
else if (ytype == 3) {
 
 1577           fy = bsp4_03;   fy_der = bsp4_03_der;   fy_der2 = bsp4_03_der2;
 
 1578         } 
else if (ytype == 4) {
 
 1579           fy = bsp4_04;   fy_der = bsp4_04_der;   fy_der2 = bsp4_04_der2;
 
 1583           fz = bsp4_01;   fz_der = bsp4_01_der;   fz_der2 = bsp4_01_der2;
 
 1584         } 
else if (ztype == 2) {
 
 1585           fz = bsp4_02;   fz_der = bsp4_02_der;   fz_der2 = bsp4_02_der2;
 
 1586         } 
else if (ztype == 3) {
 
 1587           fz = bsp4_03;   fz_der = bsp4_03_der;   fz_der2 = bsp4_03_der2;
 
 1588         } 
else if (ztype == 4) {
 
 1589           fz = bsp4_04;   fz_der = bsp4_04_der;   fz_der2 = bsp4_04_der2;
 
 1592       } 
else if (order == 5) {
 
 1595           fx = bsp5_01;   fx_der = bsp5_01_der;   fx_der2 = bsp5_01_der2;
 
 1596         } 
else if (xtype == 2) {
 
 1597           fx = bsp5_02;   fx_der = bsp5_02_der;   fx_der2 = bsp5_02_der2;
 
 1598         } 
else if (xtype == 3) {
 
 1599           fx = bsp5_03;   fx_der = bsp5_03_der;   fx_der2 = bsp5_03_der2;
 
 1600         } 
else if (xtype == 4) {
 
 1601           fx = bsp5_04;   fx_der = bsp5_04_der;   fx_der2 = bsp5_04_der2;
 
 1602         } 
else if (xtype == 5) {
 
 1603           fx = bsp5_05;   fx_der = bsp5_05_der;   fx_der2 = bsp5_05_der2;
 
 1607           fy = bsp5_01;   fy_der = bsp5_01_der;   fy_der2 = bsp5_01_der2;
 
 1608         } 
else if (ytype == 2) {
 
 1609           fy = bsp5_02;   fy_der = bsp5_02_der;   fy_der2 = bsp5_02_der2;
 
 1610         } 
else if (ytype == 3) {
 
 1611           fy = bsp5_03;   fy_der = bsp5_03_der;   fy_der2 = bsp5_03_der2;
 
 1612         } 
else if (ytype == 4) {
 
 1613           fy = bsp5_04;   fy_der = bsp5_04_der;   fy_der2 = bsp5_04_der2;
 
 1614         } 
else if (ytype == 5) {
 
 1615           fy = bsp5_05;   fy_der = bsp5_05_der;   fy_der2 = bsp5_05_der2;
 
 1619           fz = bsp5_01;   fz_der = bsp5_01_der;   fz_der2 = bsp5_01_der2;
 
 1620         } 
else if (ztype == 2) {
 
 1621           fz = bsp5_02;   fz_der = bsp5_02_der;   fz_der2 = bsp5_02_der2;
 
 1622         } 
else if (ztype == 3) {
 
 1623           fz = bsp5_03;   fz_der = bsp5_03_der;   fz_der2 = bsp5_03_der2;
 
 1624         } 
else if (ztype == 4) {
 
 1625           fz = bsp5_04;   fz_der = bsp5_04_der;   fz_der2 = bsp5_04_der2;
 
 1626         } 
else if (ztype == 5) {
 
 1627           fz = bsp5_05;   fz_der = bsp5_05_der;   fz_der2 = bsp5_05_der2;
 
 1633     virtual ~global_function_xyz_bspline_()
 
 1634     { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this, 
"Global function xyz bspline"); }
 
 1639   global_function_bspline(
const scalar_type xmin, 
const scalar_type xmax,
 
 1641     return std::make_shared<global_function_x_bspline_>
 
 1642                            (xmin, xmax, order, xtype);
 
 1646   global_function_bspline(
const scalar_type xmin, 
const scalar_type xmax,
 
 1647                           const scalar_type ymin, 
const scalar_type ymax,
 
 1650     return std::make_shared<global_function_xy_bspline_>
 
 1651                            (xmin, xmax, ymin, ymax, order, xtype, ytype);
 
 1655   global_function_bspline(
const scalar_type xmin, 
const scalar_type xmax,
 
 1656                           const scalar_type ymin, 
const scalar_type ymax,
 
 1657                           const scalar_type zmin, 
const scalar_type zmax,
 
 1662     return std::make_shared<global_function_xyz_bspline_>
 
 1663                            (xmin, xmax, ymin, ymax, zmin, zmax, order,
 
 1664                             xtype, ytype, ztype);
 
 1671   interpolator_on_mesh_fem::interpolator_on_mesh_fem
 
 1672   (
const mesh_fem &mf_, 
const std::vector<scalar_type> &U_)
 
 1675     if (mf.is_reduced()) {
 
 1677       gmm::mult(mf.extension_matrix(), U_, U);
 
 1679     base_node bmin, bmax;
 
 1680     scalar_type EPS=1E-13;
 
 1683     for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
 
 1684       bounding_box(bmin, bmax, mf.linked_mesh().points_of_convex(cv),
 
 1685                    mf.linked_mesh().trans_of_convex(cv));
 
 1686       for (
auto&& val : bmin) val -= EPS;
 
 1687       for (
auto&& val : bmax) val += EPS;
 
 1688       boxtree.add_box(bmin, bmax, cv);
 
 1690     boxtree.build_tree();
 
 1693   bool interpolator_on_mesh_fem::find_a_point(
const base_node &pt,
 
 1697     if (cv_stored != 
size_type(-1) && gic.invert(pt, ptr, gt_invertible)) {
 
 1703     boxtree.find_boxes_at_point(pt, boxlst);
 
 1704     for (
const auto &box : boxlst) {
 
 1706         (mf.linked_mesh().convex(box->id),
 
 1707          mf.linked_mesh().trans_of_convex(box->id));
 
 1708       cv_stored = box->id;
 
 1709       if (gic.invert(pt, ptr, gt_invertible)) {
 
 1717   bool interpolator_on_mesh_fem::eval(
const base_node &pt, base_vector &val,
 
 1718                                       base_matrix &grad)
 const {
 
 1722     dim_type q = mf.get_qdim(), N = mf.linked_mesh().dim();
 
 1723     if (find_a_point(pt, ptref, cv)) {
 
 1724       pfem pf = mf.fem_of_element(cv);
 
 1726         mf.linked_mesh().trans_of_convex(cv);
 
 1728       vectors_to_base_matrix(G, mf.linked_mesh().points_of_convex(cv));
 
 1729       fem_interpolation_context fic(pgt, pf, ptref, G, cv, 
short_type(-1));
 
 1735       pf->interpolation(fic, coeff, val, q);
 
 1737       pf->interpolation_grad(fic, coeff, grad, q);
 
does the inversion of the geometric transformation for a given convex
 
Definition of global functions to be used as base or enrichment functions in fem.
 
void reshape(M &v, size_type m, size_type n)
*/
 
void copy(const L1 &l1, L2 &l2)
*/
 
void fill(L &l, typename gmm::linalg_traits< L >::value_type x)
*/
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void resize(V &v, size_type n)
*/
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
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
 
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
 
GEneric Tool for Finite Element Methods.
 
void slice_vector_on_basic_dof_of_element(const mesh_fem &mf, const VEC1 &vec, size_type cv, VEC2 &coeff, size_type qmult1=size_type(-1), size_type qmult2=size_type(-1))
Given a mesh_fem.