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.