23 #include "getfem/getfem_generic_assembly_functions_and_operators.h" 24 #include "getfem/getfem_generic_assembly_compile_and_exec.h" 31 #if defined(_MSC_VER) && _MSC_VER < 1800 32 #include <boost/math/special_functions/acosh.hpp> 33 #include <boost/math/special_functions/asinh.hpp> 34 #include <boost/math/special_functions/atanh.hpp> 35 #include <boost/math/special_functions/erf.hpp> 36 typedef double (*BoostMathFunction)(double);
37 BoostMathFunction
const acosh = boost::math::acosh<double>;
38 BoostMathFunction
const asinh = boost::math::asinh<double>;
39 BoostMathFunction
const atanh = boost::math::atanh<double>;
40 BoostMathFunction
const erf = boost::math::erf<double>;
41 BoostMathFunction
const erfc = boost::math::erfc<double>;
46 base_matrix& __mat_aux1()
48 DEFINE_STATIC_THREAD_LOCAL(base_matrix, m);
58 scalar_type ga_predef_function::operator()(scalar_type t_,
59 scalar_type u_)
const {
63 return (*f2_)(t_, u_);
68 t.thrd_cast()[0] = t_; u.thrd_cast()[0] = u_;
69 workspace.thrd_cast().assembled_potential() = scalar_type(0);
70 ga_function_exec(*gis);
71 return workspace.thrd_cast().assembled_potential();
77 bool ga_predef_function::is_affine(
const std::string &varname)
const {
79 for (
size_type i = 0; i < workspace.thrd_cast().nb_trees(); ++i) {
80 const ga_workspace::tree_description &
81 td = workspace.thrd_cast().tree_info(i);
82 if (!(ga_is_affine(*(td.ptree), workspace, varname,
"")))
91 static scalar_type ga_Heaviside(scalar_type t) {
return (t >= 0.) ? 1.: 0.; }
92 static scalar_type ga_pos_part(scalar_type t) {
return (t >= 0.) ? t : 0.; }
93 static scalar_type ga_reg_pos_part(scalar_type t, scalar_type eps)
94 {
return (t >= eps) ? t-eps/2. : ((t <= 0) ? 0. : t*t/(2.*eps)); }
95 static scalar_type ga_der_reg_pos_part(scalar_type t, scalar_type eps)
96 {
return (t >= eps) ? 1. : ((t <= 0) ? 0. : t/eps); }
97 static scalar_type ga_der2_reg_pos_part(scalar_type t, scalar_type eps)
98 {
return (t >= eps) ? 0. : ((t <= 0) ? 0. : 1./eps); }
101 static scalar_type ga_half_sqr_pos_part(scalar_type t)
102 {
return (t >= 0.) ? 0.5*t*t : 0.; }
103 static scalar_type ga_neg_part(scalar_type t) {
return (t >= 0.) ? 0. : -t; }
104 static scalar_type ga_half_sqr_neg_part(scalar_type t)
105 {
return (t >= 0.) ? 0. : 0.5*t*t; }
106 static scalar_type ga_sinc(scalar_type t) {
107 if (gmm::abs(t) < 1E-4) {
108 scalar_type t2 = t*t;
109 return 1-t2/6.+ t2*t2/120.;
114 static scalar_type ga_sqr(scalar_type t) {
return t*t; }
115 static scalar_type ga_max(scalar_type t, scalar_type u)
116 {
return std::max(t,u); }
117 static scalar_type ga_min(scalar_type t, scalar_type u)
118 {
return std::min(t,u); }
119 static scalar_type ga_abs(scalar_type t) {
return gmm::abs(t); }
120 static scalar_type ga_sign(scalar_type t) {
return (t >= 0.) ? 1.: -1.; }
123 static scalar_type ga_der_sinc(scalar_type t) {
124 if (gmm::abs(t) < 1E-4) {
125 scalar_type t2 = t*t;
126 return -t/3. + t*t2/30. -t*t2*t2/840.;
128 return (t*cos(t) - sin(t))/(t*t);
131 static scalar_type ga_der2_sinc(scalar_type t) {
132 if (gmm::abs(t) < 1E-4) {
133 scalar_type t2 = t*t;
134 return -1./3. + t2/10. -t2*t2/168.;
136 return ((2. - t*t)*sin(t) - 2.*t*cos(t))/(t*t*t);
139 static scalar_type ga_der_sqrt(scalar_type t) {
return 0.5/sqrt(t); }
141 static scalar_type ga_der_t_pow(scalar_type t, scalar_type u)
142 {
return u*pow(t,u-1.); }
143 static scalar_type ga_der_u_pow(scalar_type t, scalar_type u)
144 {
return pow(t,u)*log(gmm::abs(t)); }
145 static scalar_type ga_der_log(scalar_type t) {
return 1./t; }
146 static scalar_type ga_der_log10(scalar_type t) {
return 1./(t*log(10.)); }
147 static scalar_type ga_der_tanh(scalar_type t)
148 {
return 1.-gmm::sqr(tanh(t)); }
149 static scalar_type ga_der_asinh(scalar_type t)
150 {
return 1./(sqrt(t*t+1.)); }
151 static scalar_type ga_der_acosh(scalar_type t)
152 {
return 1./(sqrt(t*t-1.)); }
153 static scalar_type ga_der_atanh(scalar_type t)
154 {
return 1./(1.-t*t); }
155 static scalar_type ga_der_cos(scalar_type t)
157 static scalar_type ga_der_tan(scalar_type t)
158 {
return 1.+gmm::sqr(tan(t)); }
159 static scalar_type ga_der_asin(scalar_type t)
160 {
return 1./(sqrt(1.-t*t)); }
161 static scalar_type ga_der_acos(scalar_type t)
162 {
return -1./(sqrt(1.-t*t)); }
163 static scalar_type ga_der_atan(scalar_type t)
164 {
return 1./(1.+t*t); }
165 static scalar_type ga_der_t_atan2(scalar_type t, scalar_type u)
166 {
return u/(t*t+u*u); }
167 static scalar_type ga_der_u_atan2(scalar_type t, scalar_type u)
168 {
return -t/(t*t+u*u); }
169 static scalar_type ga_der_erf(scalar_type t)
170 {
return exp(-t*t)*2./sqrt(M_PI); }
171 static scalar_type ga_der_erfc(scalar_type t)
172 {
return -exp(-t*t)*2./sqrt(M_PI); }
173 static scalar_type ga_der_neg_part(scalar_type t)
174 {
return (t >= 0) ? 0. : -1.; }
175 static scalar_type ga_der_t_max(scalar_type t, scalar_type u)
176 {
return (t-u >= 0) ? 1. : 0.; }
177 static scalar_type ga_der_u_max(scalar_type t, scalar_type u)
178 {
return (u-t >= 0) ? 1. : 0.; }
186 static void ga_init_scalar(bgeot::multi_index &mi) { mi.resize(0); }
187 static void ga_init_square_matrix(bgeot::multi_index &mi,
size_type N)
188 { mi.resize(2); mi[0] = mi[1] = N; }
191 struct norm_operator :
public ga_nonlinear_operator {
192 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
193 if (args.size() != 1 || args[0]->sizes().size() > 2)
return false;
194 ga_init_scalar(sizes);
198 void value(
const arg_list &args, base_tensor &result)
const 202 void derivative(
const arg_list &args,
size_type,
203 base_tensor &result)
const {
205 if (no == scalar_type(0))
208 gmm::copy(gmm::scaled(args[0]->as_vector(), scalar_type(1)/no),
214 base_tensor &result)
const {
215 const base_tensor &t = *args[0];
218 scalar_type no3 = no*no*no;
220 if (no < 1E-25) no = 1E-25;
224 result[j*N+i] = - t[i]*t[j] / no3;
225 if (i == j) result[j*N+i] += scalar_type(1)/no;
231 struct norm_sqr_operator :
public ga_nonlinear_operator {
232 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
233 if (args.size() != 1 || args[0]->sizes().size() > 2)
return false;
234 ga_init_scalar(sizes);
238 void value(
const arg_list &args, base_tensor &result)
const 242 void derivative(
const arg_list &args,
size_type,
243 base_tensor &result)
const {
244 gmm::copy(gmm::scaled(args[0]->as_vector(), scalar_type(2)),
250 base_tensor &result)
const {
251 const base_tensor &t = *args[0];
255 result[i*N+i] = scalar_type(2);
260 struct det_operator :
public ga_nonlinear_operator {
261 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
262 if (args.size() != 1 || args[0]->sizes().size() != 2
263 || args[0]->sizes()[0] != args[0]->sizes()[1])
return false;
264 ga_init_scalar(sizes);
268 void value(
const arg_list &args, base_tensor &result)
const {
273 result[0] = bgeot::lu_det(&(*(args[0]->begin())), N);
277 void derivative(
const arg_list &args,
size_type,
278 base_tensor &result)
const {
281 __mat_aux1().base_resize(N, N);
282 gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
283 scalar_type det = bgeot::lu_inverse(__mat_aux1());
284 if (det == scalar_type(0))
287 auto it = result.begin();
288 auto ita = __mat_aux1().begin();
289 for (
size_type j = 0; j < N; ++j, ++ita) {
291 *it = (*itaa) * det; ++it;
293 { itaa += N; *it = (*itaa) * det; }
295 GA_DEBUG_ASSERT(it == result.end(),
"Internal error");
302 base_tensor &result)
const {
304 __mat_aux1().base_resize(N, N);
305 gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
306 scalar_type det = bgeot::lu_inverse(__mat_aux1());
307 if (det == scalar_type(0))
310 auto it = result.begin();
311 auto ita = __mat_aux1().begin(), ita_l = ita;
312 for (
size_type l = 0; l < N; ++l, ++ita_l) {
313 auto ita_lk = ita_l, ita_jk = ita;
314 for (
size_type k = 0; k < N; ++k, ita_lk += N, ita_jk += N) {
316 for (
size_type j = 0; j < N; ++j, ++ita_j, ++ita_jk) {
317 auto ita_ji = ita_j, ita_li = ita_l;
318 for (
size_type i = 0; i < N; ++i, ++it, ita_ji += N, ita_li += N)
319 *it = ((*ita_ji) * (*ita_lk) - (*ita_jk) * (*ita_li)) * det;
323 GA_DEBUG_ASSERT(it == result.end(),
"Internal error");
329 struct inverse_operator :
public ga_nonlinear_operator {
330 bool result_size(
const arg_list &args, bgeot::multi_index &sizes)
const {
331 if (args.size() != 1 || args[0]->sizes().size() != 2
332 || args[0]->sizes()[0] != args[0]->sizes()[1])
return false;
333 ga_init_square_matrix(sizes, args[0]->sizes()[0]);
338 void value(
const arg_list &args, base_tensor &result)
const {
340 __mat_aux1().base_resize(N, N);
341 gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
342 bgeot::lu_inverse(__mat_aux1());
343 gmm::copy(__mat_aux1().as_vector(), result.as_vector());
347 void derivative(
const arg_list &args,
size_type,
348 base_tensor &result)
const {
350 __mat_aux1().base_resize(N, N);
351 gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
352 bgeot::lu_inverse(__mat_aux1());
353 auto it = result.begin();
354 auto ita = __mat_aux1().begin(), ita_l = ita;
355 for (
size_type l = 0; l < N; ++l, ++ita_l) {
357 for (
size_type k = 0; k < N; ++k, ita_k += N) {
359 for (
size_type j = 0; j < N; ++j, ++ita_lj) {
361 for (
size_type i = 0; i < N; ++i, ++it, ++ita_ik)
362 *it = -(*ita_ik) * (*ita_lj);
366 GA_DEBUG_ASSERT(it == result.end(),
"Internal error");
373 base_tensor &result)
const {
375 __mat_aux1().base_resize(N, N);
376 gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
377 bgeot::lu_inverse(__mat_aux1());
378 base_tensor::iterator it = result.begin();
385 *it = __mat_aux1()(i,k)*__mat_aux1()(l,m)*__mat_aux1()(n,j)
386 + __mat_aux1()(i,m)*__mat_aux1()(m,k)*__mat_aux1()(l,j);
387 GA_DEBUG_ASSERT(it == result.end(),
"Internal error");
395 ga_predef_function::ga_predef_function()
396 : expr_(
""), derivative1_(
""), derivative2_(
""), gis(nullptr) {}
398 ga_predef_function::ga_predef_function(pscalar_func_onearg f,
400 const std::string &der)
401 : ftype_(0), dtype_(dtype__), nbargs_(1), f1_(f), expr_(
""),
402 derivative1_(der), derivative2_(
"") {}
403 ga_predef_function::ga_predef_function(pscalar_func_twoargs f,
405 const std::string &der1,
406 const std::string &der2)
407 : ftype_(0), dtype_(dtype__), nbargs_(2), f2_(f),
408 expr_(
""), derivative1_(der1), derivative2_(der2), gis(nullptr) {}
409 ga_predef_function::ga_predef_function(
const std::string &expr__)
410 : ftype_(1), dtype_(3), nbargs_(1), expr_(expr__),
411 derivative1_(
""), derivative2_(
""), t(1, 0.), u(1, 0.), gis(nullptr) {}
414 ga_predef_function_tab::ga_predef_function_tab() {
416 ga_predef_function_tab &PREDEF_FUNCTIONS = *
this;
419 PREDEF_FUNCTIONS[
"sqrt"] = ga_predef_function(sqrt, 1,
"DER_PDFUNC_SQRT");
420 PREDEF_FUNCTIONS[
"sqr"] = ga_predef_function(ga_sqr, 2,
"2*t");
421 PREDEF_FUNCTIONS[
"pow"] = ga_predef_function(pow, 1,
"DER_PDFUNC1_POW",
424 PREDEF_FUNCTIONS[
"DER_PDFUNC_SQRT"] =
425 ga_predef_function(ga_der_sqrt, 2,
"-0.25/(t*sqrt(t))");
426 PREDEF_FUNCTIONS[
"DER_PDFUNC1_POW"] =
427 ga_predef_function(ga_der_t_pow, 2,
"u*(u-1)*pow(t,u-2)",
428 "pow(t,u-1)*(u*log(t)+1)");
429 PREDEF_FUNCTIONS[
"DER_PDFUNC2_POW"] =
430 ga_predef_function(ga_der_u_pow, 2,
"pow(t,u-1)*(u*log(t)+1)",
431 "pow(t,u)*sqr(log(t))");
434 PREDEF_FUNCTIONS[
"exp"] = ga_predef_function(exp, 1,
"exp");
435 PREDEF_FUNCTIONS[
"log"] = ga_predef_function(log, 1,
"DER_PDFUNC_LOG");
436 PREDEF_FUNCTIONS[
"log10"] =
437 ga_predef_function(log10, 1,
"DER_PDFUNC_LOG10");
438 PREDEF_FUNCTIONS[
"sinh"] = ga_predef_function(sinh, 1,
"cosh");
439 PREDEF_FUNCTIONS[
"cosh"] = ga_predef_function(cosh, 1,
"sinh");
440 PREDEF_FUNCTIONS[
"tanh"] = ga_predef_function(tanh, 1,
"DER_PDFUNC_TANH");
441 PREDEF_FUNCTIONS[
"asinh"] =
442 ga_predef_function(asinh, 1,
"DER_PDFUNC_ASINH");
443 PREDEF_FUNCTIONS[
"acosh"] =
444 ga_predef_function(acosh, 1,
"DER_PDFUNC_ACOSH");
445 PREDEF_FUNCTIONS[
"atanh"] =
446 ga_predef_function(atanh, 1,
"DER_PDFUNC_ATANH");
449 PREDEF_FUNCTIONS[
"DER_PDFUNC_LOG"] =
450 ga_predef_function(ga_der_log, 2,
"-1/sqr(t)");
451 PREDEF_FUNCTIONS[
"DER_PDFUNC_LOG10"] =
452 ga_predef_function(ga_der_log10, 2,
"-1/(sqr(t)*log(10))");
453 PREDEF_FUNCTIONS[
"DER_PDFUNC_TANH"] =
454 ga_predef_function(ga_der_tanh, 2,
"2*tanh(t)*(sqr(tanh(t))-1)");
455 PREDEF_FUNCTIONS[
"DER_PDFUNC_ASINH"] =
456 ga_predef_function(ga_der_asinh, 2,
"-t/(pow(t*t+1,1.5))");
457 PREDEF_FUNCTIONS[
"DER_PDFUNC_ACOSH"] =
458 ga_predef_function(ga_der_acosh, 2,
"-t/(pow(t*t-1,1.5))");
459 PREDEF_FUNCTIONS[
"DER_PDFUNC_ATANH"] =
460 ga_predef_function(ga_der_atanh, 2,
"2*t/sqr(1-t*t)");
464 PREDEF_FUNCTIONS[
"sin"] = ga_predef_function(sin, 1,
"cos");
465 PREDEF_FUNCTIONS[
"cos"] = ga_predef_function(cos, 1,
"DER_PDFUNC_COS");
466 PREDEF_FUNCTIONS[
"tan"] = ga_predef_function(tan, 1,
"DER_PDFUNC_TAN");
467 PREDEF_FUNCTIONS[
"asin"] = ga_predef_function(asin, 1,
"DER_PDFUNC_ASIN");
468 PREDEF_FUNCTIONS[
"acos"] = ga_predef_function(acos, 1,
"DER_PDFUNC_ACOS");
469 PREDEF_FUNCTIONS[
"atan"] = ga_predef_function(atan, 1,
"DER_PDFUNC_ATAN");
470 PREDEF_FUNCTIONS[
"atan2"] = ga_predef_function(atan2,1,
"DER_PDFUNC1_ATAN2",
471 "DER_PDFUNC2_ATAN2");
472 PREDEF_FUNCTIONS[
"sinc"] = ga_predef_function(ga_sinc, 1,
474 PREDEF_FUNCTIONS[
"DER_PDFUNC_SINC"] =ga_predef_function(ga_der_sinc, 1,
476 PREDEF_FUNCTIONS[
"DER2_PDFUNC_SINC"] = ga_predef_function(ga_der2_sinc);
479 PREDEF_FUNCTIONS[
"DER_PDFUNC_COS"] =
480 ga_predef_function(ga_der_cos, 2,
"-cos(t)");
481 PREDEF_FUNCTIONS[
"DER_PDFUNC_TAN"] =
482 ga_predef_function(ga_der_tan, 2,
"2*tan(t)/sqr(cos(t))");
485 PREDEF_FUNCTIONS[
"DER_PDFUNC_ASIN"] =
486 ga_predef_function(ga_der_asin, 2,
"t/(pow(1-t*t,1.5))");
487 PREDEF_FUNCTIONS[
"DER_PDFUNC_ACOS"] =
488 ga_predef_function(ga_der_acos, 2,
"-t/(pow(1-t*t,1.5))");
489 PREDEF_FUNCTIONS[
"DER_PDFUNC_ATAN"] =
490 ga_predef_function(ga_der_atan, 2,
"-2*t/sqr(1+t*t)");
491 PREDEF_FUNCTIONS[
"DER_PDFUNC1_ATAN2"] =
492 ga_predef_function(ga_der_t_atan2, 2,
"-2*t*u/sqr(sqr(u)+sqr(t))",
493 "(sqrt(t)-sqr(u))/sqr(sqr(u)+sqr(t))");
494 PREDEF_FUNCTIONS[
"DER_PDFUNC2_ATAN2"] =
495 ga_predef_function(ga_der_u_atan2, 2,
496 "(sqrt(t)-sqr(u))/sqr(sqr(u)+sqr(t))",
497 "2*t*u/sqr(sqr(u)+sqr(t))");
501 PREDEF_FUNCTIONS[
"erf"]
502 = ga_predef_function(erf, 1,
"DER_PDFUNC_ERF");
503 PREDEF_FUNCTIONS[
"erfc"]
504 = ga_predef_function(erfc, 1,
"DER_PDFUNC_ERFC");
506 PREDEF_FUNCTIONS[
"DER_PDFUNC_ERF"] =
507 ga_predef_function(ga_der_erf, 2,
"exp(-t*t)*2/sqrt(pi)");
508 PREDEF_FUNCTIONS[
"DER_PDFUNC_ERFC"] =
509 ga_predef_function(ga_der_erfc, 2,
"-exp(-t*t)*2/sqrt(pi)");
514 PREDEF_FUNCTIONS[
"Heaviside"] = ga_predef_function(ga_Heaviside);
515 PREDEF_FUNCTIONS[
"sign"] = ga_predef_function(ga_sign);
516 PREDEF_FUNCTIONS[
"abs"] = ga_predef_function(ga_abs, 1,
"sign");
517 PREDEF_FUNCTIONS[
"pos_part"]
518 = ga_predef_function(ga_pos_part, 1,
"Heaviside");
519 PREDEF_FUNCTIONS[
"half_sqr_pos_part"]
520 = ga_predef_function(ga_half_sqr_pos_part, 1,
"pos_part");
521 PREDEF_FUNCTIONS[
"neg_part"]
522 = ga_predef_function(ga_neg_part, 1,
"DER_PDFUNC_NEG_PART");
523 PREDEF_FUNCTIONS[
"half_sqr_neg_part"]
524 = ga_predef_function(ga_half_sqr_neg_part, 2,
"-neg_part(t)");
525 PREDEF_FUNCTIONS[
"reg_pos_part"]
526 = ga_predef_function(ga_reg_pos_part, 1,
"DER_REG_POS_PART",
"");
527 PREDEF_FUNCTIONS[
"DER_REG_POS_PART"]
528 = ga_predef_function(ga_der_reg_pos_part, 1,
"DER2_REG_POS_PART",
"");
529 PREDEF_FUNCTIONS[
"DER_REG_POS_PART"]
530 = ga_predef_function(ga_der2_reg_pos_part);
532 PREDEF_FUNCTIONS[
"max"]
533 = ga_predef_function(ga_max, 1,
"DER_PDFUNC1_MAX",
"DER_PDFUNC2_MAX");
534 PREDEF_FUNCTIONS[
"min"]
535 = ga_predef_function(ga_min, 1,
"DER_PDFUNC2_MAX",
"DER_PDFUNC1_MAX");
537 PREDEF_FUNCTIONS[
"DER_PDFUNC_NEG_PART"]
538 = ga_predef_function(ga_der_neg_part, 2,
"-Heaviside(-t)");
539 PREDEF_FUNCTIONS[
"DER_PDFUNC1_MAX"] = ga_predef_function(ga_der_t_max);
540 PREDEF_FUNCTIONS[
"DER_PDFUNC2_MAX"] = ga_predef_function(ga_der_u_max);
544 ga_spec_function_tab::ga_spec_function_tab() {
546 ga_spec_function_tab &SPEC_FUNCTIONS = *
this;
548 SPEC_FUNCTIONS.insert(
"pi");
549 SPEC_FUNCTIONS.insert(
"meshdim");
550 SPEC_FUNCTIONS.insert(
"timestep");
551 SPEC_FUNCTIONS.insert(
"qdim");
552 SPEC_FUNCTIONS.insert(
"qdims");
553 SPEC_FUNCTIONS.insert(
"Id");
556 ga_spec_op_tab::ga_spec_op_tab() {
558 ga_spec_op_tab &SPEC_OP = *
this;
560 SPEC_OP.insert(
"element_size");
561 SPEC_OP.insert(
"element_K");
562 SPEC_OP.insert(
"element_B");
563 SPEC_OP.insert(
"Normal");
564 SPEC_OP.insert(
"Sym");
565 SPEC_OP.insert(
"Skew");
566 SPEC_OP.insert(
"Def");
567 SPEC_OP.insert(
"Trace");
568 SPEC_OP.insert(
"Deviator");
569 SPEC_OP.insert(
"Interpolate");
570 SPEC_OP.insert(
"Interpolate_filter");
571 SPEC_OP.insert(
"Elementary_transformation");
572 SPEC_OP.insert(
"Xfem_plus");
573 SPEC_OP.insert(
"Xfem_minus");
574 SPEC_OP.insert(
"Print");
575 SPEC_OP.insert(
"Reshape");
576 SPEC_OP.insert(
"Swap_indices");
577 SPEC_OP.insert(
"Index_move_last");
578 SPEC_OP.insert(
"Contract");
579 SPEC_OP.insert(
"Diff");
580 SPEC_OP.insert(
"Grad");
584 ga_predef_operator_tab::ga_predef_operator_tab(
void) {
586 ga_predef_operator_tab &PREDEF_OPERATORS = *
this;
588 PREDEF_OPERATORS.add_method(
"Norm", std::make_shared<norm_operator>());
589 PREDEF_OPERATORS.add_method(
"Norm_sqr",
590 std::make_shared<norm_sqr_operator>());
591 PREDEF_OPERATORS.add_method(
"Det", std::make_shared<det_operator>());
592 PREDEF_OPERATORS.add_method(
"Inv", std::make_shared<inverse_operator>());
597 bool ga_function_exists(
const std::string &name) {
598 const ga_predef_function_tab &PREDEF_FUNCTIONS
600 return PREDEF_FUNCTIONS.find(name) != PREDEF_FUNCTIONS.end();
604 void ga_define_function(
const std::string &name,
size_type nbargs,
605 const std::string &expr,
const std::string &der1,
606 const std::string &der2) {
607 auto guard = omp_guard{};
610 if(PREDEF_FUNCTIONS.find(name) != PREDEF_FUNCTIONS.end())
return;
611 GMM_ASSERT1(nbargs >= 1 && nbargs <= 2,
"Generic assembly only allows " 612 "the definition of scalar function with one or two arguments");
615 ga_workspace workspace;
616 workspace.add_fixed_size_variable(
"t", gmm::sub_interval(0,1), t);
618 workspace.add_fixed_size_variable(
"u", gmm::sub_interval(0,1), t);
619 workspace.add_function_expression(expr);
622 PREDEF_FUNCTIONS[name] = ga_predef_function(expr);
623 ga_predef_function &F = PREDEF_FUNCTIONS[name];
624 F.gis = std::make_unique<instruction_set>();
625 for (
size_type thread = 0; thread < num_threads(); ++thread)
627 F.workspace(thread).add_fixed_size_variable(
"t", gmm::sub_interval(0,1),
630 F.workspace(thread).add_fixed_size_variable(
"u", gmm::sub_interval(0,1),
632 F.workspace(thread).add_function_expression(expr);
633 ga_compile_function(F.workspace(thread), (*F.gis)(thread),
true);
637 if (der1.size()) { F.derivative1_ = der1; F.dtype_ = 2; }
639 if (der1.size() && der2.size()) {
640 F.derivative1_ = der1; F.derivative2_ = der2; F.dtype_ = 2;
645 void ga_define_function(
const std::string &name, pscalar_func_onearg f,
646 const std::string &der) {
647 ga_predef_function_tab &PREDEF_FUNCTIONS
649 PREDEF_FUNCTIONS[name] = ga_predef_function(f, 1, der);
650 ga_predef_function &F = PREDEF_FUNCTIONS[name];
651 if (der.size() == 0) F.dtype_ = 0;
652 else if (!(ga_function_exists(der))) F.dtype_ = 2;
655 void ga_define_function(
const std::string &name, pscalar_func_twoargs f,
656 const std::string &der1,
const std::string &der2) {
657 ga_predef_function_tab &PREDEF_FUNCTIONS
659 PREDEF_FUNCTIONS[name] = ga_predef_function(f, 1, der1, der2);
660 ga_predef_function &F = PREDEF_FUNCTIONS[name];
661 if (der1.size() == 0 || der2.size() == 0)
663 else if (!(ga_function_exists(der1)) || !(ga_function_exists(der2)))
667 void ga_undefine_function(
const std::string &name) {
668 ga_predef_function_tab &PREDEF_FUNCTIONS
670 ga_predef_function_tab::iterator it = PREDEF_FUNCTIONS.find(name);
671 if (it != PREDEF_FUNCTIONS.end()) {
672 PREDEF_FUNCTIONS.erase(name);
673 std::string name0 =
"DER_PDFUNC_" + name;
674 ga_undefine_function(name0);
675 std::string name1 =
"DER_PDFUNC1_" + name;
676 ga_undefine_function(name1);
677 std::string name2 =
"DER_PDFUNC2_" + name;
678 ga_undefine_function(name2);
686 ga_function::ga_function(
const ga_workspace &workspace_,
687 const std::string &e)
688 : local_workspace(true, workspace_), expr(e), gis(0) {}
690 ga_function::ga_function(
const model &md,
const std::string &e)
691 : local_workspace(md), expr(e), gis(0) {}
693 ga_function::ga_function(
const std::string &e)
694 : local_workspace(), expr(e), gis(0) {}
696 ga_function::ga_function(
const ga_function &gaf)
697 : local_workspace(gaf.local_workspace), expr(gaf.expr), gis(0)
698 {
if (gaf.gis) compile(); }
700 void ga_function::compile()
const {
702 gis =
new ga_instruction_set;
703 local_workspace.clear_expressions();
704 local_workspace.add_function_expression(expr);
705 ga_compile_function(local_workspace, *gis,
false);
708 ga_function &ga_function::operator =(
const ga_function &gaf) {
711 local_workspace = gaf.local_workspace;
713 if (gaf.gis) compile();
717 ga_function::~ga_function() {
if (gis)
delete gis; gis = 0; }
719 const base_tensor &ga_function::eval()
const {
720 GMM_ASSERT1(gis,
"Uncompiled function");
721 gmm::clear(local_workspace.assembled_tensor().as_vector());
722 ga_function_exec(*gis);
723 return local_workspace.assembled_tensor();
726 void ga_function::derivative(
const std::string &var) {
727 GMM_ASSERT1(gis,
"Uncompiled function");
728 if (local_workspace.nb_trees()) {
729 ga_tree tree = *(local_workspace.tree_info(0).ptree);
730 ga_derivative(tree, local_workspace, *((
const mesh *)(0)), var,
"", 1);
732 ga_semantic_analysis(tree, local_workspace, *((
const mesh *)(0)),
741 expr = ga_tree_to_string(tree);
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
Semantic analysis of assembly trees and semantic manipulations.
static T & instance()
Instance from the current thread.
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
size_t size_type
used as the common size type in the library
GEneric Tool for Finite Element Methods.
void clear(L &l)
clear (fill with zeros) a vector or matrix.