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());
75 gmm::copy(t.as_vector(), g);
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());
85 gmm::copy(t.as_vector(), h.as_vector());
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) {
97 gmm::fill(pt_, scalar_type(0));
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();
279 gmm::fill(pt_, scalar_type(0));
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());
331 gmm::copy(t.as_vector(), res);
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 auto &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);
783 gmm::mult(c.B3(), hx, hx_real);
784 gmm::mult(c.B32(), gmm::scaled(dx, -1.0), gmm::mat_col(hx_real, 0));
785 gmm::mult(c.B3(), hy, hy_real);
786 gmm::mult(c.B32(), gmm::scaled(dy, -1.0), gmm::mat_col(hy_real, 0));
787 gmm::mult(c.B(), dx, dx_real);
788 gmm::mult(c.B(), dy, dy_real);
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 (
size_type i = 0; i < lsets.size(); ++i)
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_) {
823 global_function_on_level_sets(
const std::vector<level_set> &lsets,
824 const pxy_function &fn) {
825 return std::make_shared<global_function_on_levelsets_2D_>(lsets, fn);
829 global_function_on_level_set(
const level_set &ls,
830 const pxy_function &fn) {
831 return std::make_shared<global_function_on_levelsets_2D_>(ls, fn);
836 interpolator_on_mesh_fem::interpolator_on_mesh_fem
837 (
const mesh_fem &mf_,
const std::vector<scalar_type> &U_)
840 if (mf.is_reduced()) {
842 gmm::mult(mf.extension_matrix(), U_, U);
844 base_node bmin, bmax;
845 scalar_type EPS=1E-13;
848 for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
849 bounding_box(bmin, bmax, mf.linked_mesh().points_of_convex(cv),
850 mf.linked_mesh().trans_of_convex(cv));
851 for (
auto&& val : bmin) val -= EPS;
852 for (
auto&& val : bmax) val += EPS;
853 boxtree.add_box(bmin, bmax, cv);
855 boxtree.build_tree();
858 bool interpolator_on_mesh_fem::find_a_point(
const base_node &pt,
862 if (cv_stored !=
size_type(-1) && gic.invert(pt, ptr, gt_invertible)) {
868 boxtree.find_boxes_at_point(pt, boxlst);
869 for (
const auto &box : boxlst) {
871 (mf.linked_mesh().convex(box->id),
872 mf.linked_mesh().trans_of_convex(box->id));
874 if (gic.invert(pt, ptr, gt_invertible)) {
882 bool interpolator_on_mesh_fem::eval(
const base_node &pt, base_vector &val,
883 base_matrix &grad)
const {
887 dim_type q = mf.get_qdim(), N = mf.linked_mesh().dim();
888 if (find_a_point(pt, ptref, cv)) {
889 pfem pf = mf.fem_of_element(cv);
891 mf.linked_mesh().trans_of_convex(cv);
893 vectors_to_base_matrix(G, mf.linked_mesh().points_of_convex(cv));
894 fem_interpolation_context fic(pgt, pf, ptref, G, cv,
short_type(-1));
900 pf->interpolation(fic, coeff, val, q);
902 pf->interpolation_grad(fic, coeff, grad, q);