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");
510 base_matrix crack_singular_xy_function::hess(scalar_type x, scalar_type y)
const {
511 scalar_type sgny = (y < 0 ? -1.0 : 1.0);
512 scalar_type r = sqrt(x*x + y*y);
515 GMM_WARNING0(
"Warning, point close to the singularity (r=" << r <<
")");
521 scalar_type sin2 = sqrt(gmm::abs(.5-x/(2*r))) * sgny;
522 scalar_type cos2 = sqrt(gmm::abs(.5+x/(2*r)));
524 base_matrix res(2,2);
527 res(0,0) = (-sin2*x*x + 2.0*cos2*x*y + sin2*y*y) / (4*pow(r, 3.5));
528 res(0,1) = (-cos2*x*x - 2.0*sin2*x*y + cos2*y*y) / (4*pow(r, 3.5));
529 res(1,0) = res(0, 1);
530 res(1,1) = (sin2*x*x - 2.0*cos2*x*y - sin2*y*y) / (4*pow(r, 3.5));
533 res(0,0) = (-cos2*x*x - 2.0*sin2*x*y + cos2*y*y) / (4*pow(r, 3.5));
534 res(0,1) = (sin2*x*x - 2.0*cos2*x*y - sin2*y*y) / (4*pow(r, 3.5));
535 res(1,0) = res(0, 1);
536 res(1,1) = (cos2*x*x + 2.0*sin2*x*y - cos2*y*y) / (4*pow(r, 3.5));
539 res(0,0) = 3.0*y*(sin2*x*x + 2.0*cos2*x*y - sin2*y*y) / (4*pow(r, 4.5));
540 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)
542 res(1,0) = res(0, 1);
543 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)
547 res(0,0) = 3.0*y*(cos2*x*x - 2.0*sin2*x*y - cos2*y*y) / (4*pow(r, 4.5));
548 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)
550 res(1,0) = res(0, 1);
551 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)
554 default: GMM_ASSERT2(
false,
"oups");
560 cutoff_xy_function::val(scalar_type x, scalar_type y)
const {
563 case EXPONENTIAL_CUTOFF: {
564 res = (a4>0) ? exp(-a4 * gmm::sqr(x*x+y*y)) : 1;
567 case POLYNOMIAL_CUTOFF: {
569 scalar_type r = gmm::sqrt(x*x+y*y);
571 if (r <= r1) res = 1;
572 else if (r >= r0) res = 0;
578 scalar_type c = 1./pow(r0-r1,3.0);
579 res = c*(r*(r*(2.0*r-3.0*(r0+r1))+6.0*r1*r0) + r0*r0*(r0-3.0*r1));
583 case POLYNOMIAL2_CUTOFF: {
585 scalar_type r = gmm::sqrt(x*x+y*y);
586 if (r <= r1) res = scalar_type(1);
587 else if (r >= r0) res = scalar_type(0);
599 res = (r*(r*(r*(r*(-6.0*r + 15.0*(r0+r1))
600 - 10.0*(r0*r0 + 4.0*r1*r0 + r1*r1))
601 + 30.0 * r0*r1*(r0+r1)) - 30.0*r1*r1*r0*r0)
602 + r0*r0*r0*(r0*r0-5.0*r1*r0+10*r1*r1)) / pow(r0-r1, 5.0);
612 cutoff_xy_function::grad(scalar_type x, scalar_type y)
const {
613 base_small_vector res(2);
615 case EXPONENTIAL_CUTOFF: {
616 scalar_type r2 = x*x+y*y, ratio = -4.*exp(-a4*r2*r2)*a4*r2;
621 case POLYNOMIAL_CUTOFF: {
622 scalar_type r = gmm::sqrt(x*x+y*y);
623 scalar_type ratio = 0;
625 if ( r > r1 && r < r0 ) {
628 ratio = 6.*(r - r0)*(r - r1)/pow(r0-r1, 3.);
634 case POLYNOMIAL2_CUTOFF: {
635 scalar_type r = gmm::sqrt(x*x+y*y);
636 scalar_type ratio = 0;
637 if (r > r1 && r < r0) {
643 ratio = -30.0*gmm::sqr(r-r0)*gmm::sqr(r-r1) / pow(r0-r1, 5.0);
657 cutoff_xy_function::hess(scalar_type x, scalar_type y)
const {
658 base_matrix res(2,2);
660 case EXPONENTIAL_CUTOFF: {
661 scalar_type r2 = x*x+y*y, r4 = r2*r2;
662 res(0,0) = 4.0*a4*(-3.0*x*x - y*y + 4.0*a4*x*x*r4)*exp(-a4*r4);
663 res(1,0) = 8.0*a4*x*y*(-1.0 + 2.0*a4*r4)*exp(-a4*r4);
665 res(1,1) = 4.0*a4*(-3.0*y*y - x*x + 4.0*a4*y*y*r4)*exp(-a4*r4);
668 case POLYNOMIAL_CUTOFF: {
669 scalar_type r2 = x*x+y*y, r = gmm::sqrt(r2), c=6./(pow(r0-r1,3.)*r*r2);
670 if ( r > r1 && r < r0 ) {
671 res(0,0) = c*(x*x*r2 + r1*r0*y*y - r*r2*(r0+r1) + r2*r2);
672 res(1,0) = c*x*y*(r2 - r1*r0);
674 res(1,1) = c*(y*y*r2 + r1*r0*x*x - r*r2*(r0+r1) + r2*r2);
678 case POLYNOMIAL2_CUTOFF: {
679 scalar_type r2 = x*x+y*y, r = gmm::sqrt(r2), r3 = r*r2;
680 if (r > r1 && r < r0) {
681 scalar_type dp = -30.0*(r1-r)*(r1-r)*(r0-r)*(r0-r) / pow(r0-r1, 5.0);
682 scalar_type ddp = 60.0*(r1-r)*(r0-r)*(r0+r1-2.0*r) / pow(r0-r1, 5.0);
683 scalar_type rx= x/r, ry= y/r, rxx= y*y/r3, rxy= -x*y/r3, ryy= x*x/r3;
684 res(0,0) = ddp*rx*rx + dp*rxx;
685 res(1,0) = ddp*rx*ry + dp*rxy;
687 res(1,1) = ddp*ry*ry + dp*ryy;
695 cutoff_xy_function::cutoff_xy_function(
int fun_num, scalar_type r,
696 scalar_type r1_, scalar_type r0_)
701 if (r > 0) a4 = pow(2.7/r,4.);
705 struct global_function_on_levelsets_2D_ :
706 public global_function,
public context_dependencies {
707 const std::vector<level_set> dummy_lsets;
708 const std::vector<level_set> &lsets;
710 mutable pmesher_signed_distance mls_x, mls_y;
718 if (lsets.size() == 0) {
719 mls_x = ls.mls_of_convex(cv, 1);
720 mls_y = ls.mls_of_convex(cv, 0);
723 scalar_type d = scalar_type(-2);
724 for (
const auto &ls_ : lsets) {
725 pmesher_signed_distance mls_xx, mls_yy;
726 mls_xx = ls_.mls_of_convex(cv, 1);
727 mls_yy = ls_.mls_of_convex(cv, 0);
728 scalar_type x = (*mls_xx)(pt), y = (*mls_yy)(pt);
729 scalar_type d2 = gmm::sqr(x) + gmm::sqr(y);
730 if (d < scalar_type(-1) || d2 < d) {
740 virtual scalar_type val(
const fem_interpolation_context& c)
const {
741 update_mls(c.convex_num(), c.xref().size());
742 scalar_type x = (*mls_x)(c.xref());
743 scalar_type y = (*mls_y)(c.xref());
744 if (c.xfem_side() > 0 && y <= 1E-13) y = 1E-13;
745 if (c.xfem_side() < 0 && y >= -1E-13) y = -1E-13;
748 virtual void grad(
const fem_interpolation_context& c,
749 base_small_vector &g)
const {
751 base_small_vector dx(P), dy(P), dfr(2);
753 update_mls(c.convex_num(), P);
754 scalar_type x = mls_x->grad(c.xref(), dx);
755 scalar_type y = mls_y->grad(c.xref(), dy);
756 if (c.xfem_side() > 0 && y <= 0) y = 1E-13;
757 if (c.xfem_side() < 0 && y >= 0) y = -1E-13;
759 base_small_vector gfn = fn->grad(x,y);
760 gmm::mult(c.B(), gfn[0]*dx + gfn[1]*dy, g);
762 virtual void hess(
const fem_interpolation_context&c,
763 base_matrix &h)
const {
764 size_type P = c.xref().size(), N = c.N();
765 base_small_vector dx(P), dy(P), dfr(2), dx_real(N), dy_real(N);
767 update_mls(c.convex_num(), P);
768 scalar_type x = mls_x->grad(c.xref(), dx);
769 scalar_type y = mls_y->grad(c.xref(), dy);
770 if (c.xfem_side() > 0 && y <= 0) y = 1E-13;
771 if (c.xfem_side() < 0 && y >= 0) y = -1E-13;
773 base_small_vector gfn = fn->grad(x,y);
774 base_matrix hfn = fn->hess(x,y);
776 base_matrix hx, hy, hx_real(N*N, 1), hy_real(N*N, 1);
777 mls_x->hess(c.xref(), hx);
778 mls_x->hess(c.xref(), hy);
782 gmm::mult(c.B3(), hx, hx_real);
783 gmm::mult(c.B32(), gmm::scaled(dx, -1.0), gmm::mat_col(hx_real, 0));
784 gmm::mult(c.B3(), hy, hy_real);
785 gmm::mult(c.B32(), gmm::scaled(dy, -1.0), gmm::mat_col(hy_real, 0));
786 gmm::mult(c.B(), dx, dx_real);
787 gmm::mult(c.B(), dy, dy_real);
791 h(i, j) = hfn(0,0) * dx_real[i] * dx_real[j]
792 + hfn(0,1) * dx_real[i] * dy_real[j]
793 + hfn(1,0) * dy_real[i] * dx_real[j]
794 + hfn(1,1) * dy_real[i] * dy_real[j]
795 + gfn[0] * hx_real(i * N + j, 0) + gfn[1] * hy_real(i*N+j,0);
799 void update_from_context()
const { cv =
size_type(-1); }
801 global_function_on_levelsets_2D_(
const std::vector<level_set> &lsets_,
802 const pxy_function &fn_)
803 : global_function(2), dummy_lsets(0, dummy_level_set()),
804 lsets(lsets_), ls(dummy_level_set()), fn(fn_) {
805 GMM_ASSERT1(lsets.size() > 0,
"The list of level sets should" 806 " contain at least one level set.");
808 for (
size_type i = 0; i < lsets.size(); ++i)
809 this->add_dependency(lsets[i]);
812 global_function_on_levelsets_2D_(
const level_set &ls_,
813 const pxy_function &fn_)
814 : global_function(2), dummy_lsets(0, dummy_level_set()),
815 lsets(dummy_lsets), ls(ls_), fn(fn_) {
822 global_function_on_level_sets(
const std::vector<level_set> &lsets,
823 const pxy_function &fn) {
824 return std::make_shared<global_function_on_levelsets_2D_>(lsets, fn);
828 global_function_on_level_set(
const level_set &ls,
829 const pxy_function &fn) {
830 return std::make_shared<global_function_on_levelsets_2D_>(ls, fn);
835 interpolator_on_mesh_fem::interpolator_on_mesh_fem
836 (
const mesh_fem &mf_,
const std::vector<scalar_type> &U_)
839 if (mf.is_reduced()) {
841 gmm::mult(mf.extension_matrix(), U_, U);
843 base_node bmin, bmax;
844 scalar_type EPS=1E-13;
847 for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
848 bounding_box(bmin, bmax, mf.linked_mesh().points_of_convex(cv),
849 mf.linked_mesh().trans_of_convex(cv));
850 for (
auto&& val : bmin) val -= EPS;
851 for (
auto&& val : bmax) val += EPS;
852 boxtree.add_box(bmin, bmax, cv);
856 bool interpolator_on_mesh_fem::find_a_point(
const base_node &pt,
860 if (cv_stored !=
size_type(-1) && gic.
invert(pt, ptr, gt_invertible)) {
866 boxtree.find_boxes_at_point(pt, boxlst);
867 for (
const auto &box : boxlst) {
872 if (gic.
invert(pt, ptr, gt_invertible)) {
880 bool interpolator_on_mesh_fem::eval(
const base_node &pt, base_vector &val,
881 base_matrix &grad)
const {
886 if (find_a_point(pt, ptref, cv)) {
891 vectors_to_base_matrix(G, mf.
linked_mesh().points_of_convex(cv));
892 fem_interpolation_context fic(pgt, pf, ptref, G, cv,
short_type(-1));
898 pf->interpolation(fic, coeff, val, q);
900 pf->interpolation_grad(fic, coeff, grad, q);
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.
Definition of global functions to be used as base or enrichment functions in fem. ...
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash! us...
ref_convex convex(size_type ic) const
return a bgeot::convex object for the convex number ic.
does the inversion of the geometric transformation for a given convex
size_t size_type
used as the common size type in the library
virtual dim_type get_qdim() const
Return the Q dimension.
bool invert(const base_node &n, base_node &n_ref, scalar_type IN_EPS=1e-12)
given the node on the real element, returns the node on the reference element (even if it is outside ...
GEneric Tool for Finite Element Methods.
void reshape(M &v, size_type m, size_type n)
*/
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
void clear(L &l)
clear (fill with zeros) a vector or matrix.
gmm::uint16_type short_type
used as the common short type integer in the library
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
void resize(M &v, size_type m, size_type n)
*/
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation