G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsFunctionExpr.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsLinearAlgebra.h>
17 
18 /* ExprTk options */
19 
20 //This define will enable printing of debug information to stdout during
21 //the compilation process.
22 //#define exprtk_enable_debugging
23 
24 // This define will disable the ability for expressions to have comments.
25 // Expressions that have comments when parsed with a build that has this
26 // option, will result in a compilation failure.
27 #define exprtk_disable_comments
28 
29 // This define will disable the loop-wise 'break' and 'continue'
30 // capabilities. Any expression that contains those keywords will result
31 // in a compilation failure.
32 #define exprtk_disable_break_continue
33 
34 // This define will disable the short-circuit '&' (and) and '|' (or)
35 // operators
36 #define exprtk_disable_sc_andor
37 
38 // This define will disable all enhanced features such as strength
39 // reduction and special function optimisations and expression specific
40 // type instantiations. This feature will reduce compilation times and
41 // binary sizes but will also result in massive performance degradation
42 // of expression evaluations.
43 #if !defined(NDEBUG) || defined(__MINGW32__)
44 #define exprtk_disable_enhanced_features
45 #endif
46 
47 // This define will disable all string processing capabilities. Any
48 // expression that contains a string or string related syntax will result
49 // in a compilation failure.
50 #define exprtk_disable_string_capabilities
51 
52 #define exprtk_disable_rtl_io_file
53 #define exprtk_disable_rtl_vecops
54 
55 // The order in which header files are included is essential.
56 //
57 // It is important that all forward declaration file
58 // "exprtk_X_forward.hpp"" are included BEFORE the header file
59 // "exprtk.hpp" so that specializations for is_true(), is_false(),
60 // etcetera are not known for ALL types that should be supported. All
61 // adaptor files "exprtk_X_adaptor.hpp" have to be included AFTER the
62 // file "exprtk.hpp".
63 
64 #if defined(GISMO_WITH_ADIFF)
65 #define DScalar gismo::ad::DScalar2<real_t,-1>
66 #include <exprtk_ad_forward.hpp>
67 #endif
68 
69 #if defined(gsMpfr_ENABLED)
70 #include <exprtk_mpfr_forward.hpp>
71 #endif
72 
73 #if defined(gsGmp_ENABLED)
74 #include <exprtk_gmp_forward.hpp>
75 #endif
76 
77 #if defined(gsCoDiPack_ENABLED)
79 #endif
80 
81 #if defined(gsUniversal_ENABLED)
83 #endif
84 
85 #include <exprtk.hpp>
86 
87 #if defined(GISMO_WITH_ADIFF)
88 #include <exprtk_ad_adaptor.hpp>
89 #endif
90 
91 #if defined(gsMpfr_ENABLED)
92 #include <exprtk_mpfr_adaptor.hpp>
93 #endif
94 
95 #if defined(gsGmp_ENABLED)
96 #include <exprtk_gmp_adaptor.hpp>
97 #endif
98 
99 #if defined(gsCoDiPack_ENABLED)
101 #endif
102 
103 #if defined(gsUniversal_ENABLED)
105 #endif
106 
107 
108 #include <gsIO/gsXml.h>
109 
110 namespace
111 {
112 
113 // addition of mixed derivative for expressions
114 // see https://en.wikipedia.org/wiki/Finite_difference_coefficient
115 template <typename T>
116 T mixed_derivative(const exprtk::expression<T>& e,
117  T& x, T& y,
118  const double& h = 0.00001)
119 {
120  T num = (T)(0.0), tmp;
121  T x_init = x;
122  T y_init = y;
123 
124  x = x_init + (T)(2.0) * h;
125  y = y_init + (T)(2.0) * h;
126  num += e.value();
127  y = y_init - (T)(2.0) * h;
128  num -= e.value();
129  x = x_init - (T)(2.0) * h;
130  num += e.value();
131  y = y_init + (T)(2.0) * h;
132  num -= e.value();
133 
134  x = x_init + h;
135  y = y_init + h;
136  tmp = e.value();
137  y = y_init - h;
138  tmp -= e.value();
139  x = x_init - h;
140  tmp += e.value();
141  y = y_init + h;
142  tmp -= e.value();
143  num += (T)(64.0) * tmp;
144 
145  x = x_init + (T)(2.0) * h;
146  y = y_init - h;
147  tmp = e.value();
148  y = y_init + h;
149  tmp -= e.value();
150  x = x_init - (T)(2.0) * h;
151  tmp += e.value();
152  y = y_init - h;
153  tmp -= e.value();
154 
155  y = y_init + (T)(2.0) * h;
156  x = x_init - h;
157  tmp += e.value();
158  x = x_init + h;
159  tmp -= e.value();
160  y = y_init - (T)(2.0) * h;
161  tmp += e.value();
162  x = x_init - h;
163  tmp -= e.value();
164  num += (T)(8.0) * tmp;
165 
166  x = x_init;
167  y = y_init;
168  return num / ( (T)(144.0)*h*h );
169 }
170 
171 } //namespace
172 
173 #define N_VARS 7
174 
175 namespace gismo
176 {
177 
178 template<typename T> class gsFunctionExpr<T>::gsFunctionExprPrivate
179 {
180 public:
181 
182 #ifdef GISMO_WITH_ADIFF
183  typedef DScalar Numeric_t;
184 #else
185  typedef T Numeric_t;
186 #endif
187 
188  typedef exprtk::symbol_table<Numeric_t> SymbolTable_t;
189  typedef exprtk::expression<Numeric_t> Expression_t;
190  typedef exprtk::parser<Numeric_t> Parser_t;
191 
192 public:
193 
194  gsFunctionExprPrivate(const short_t _dim)
195  : vars(), dim(_dim)
196  {
197  GISMO_ENSURE( dim <= N_VARS, "The number of variables can be at most 7 (x,y,z,w,u,v,t)." );
198  init();
199  }
200 
201  gsFunctionExprPrivate(const gsFunctionExprPrivate & other)
202  : vars(), dim(other.dim)
203  {
204  GISMO_ASSERT ( string.size() == expression.size(), "Corrupted FunctionExpr");
205  init();
206  //copy_n(other.vars, N_VARS+1, vars);
207  string .reserve(string.size());
208  expression.reserve(string.size());
209  for (size_t i = 0; i!= other.string.size(); ++i)
210  addComponent(other.string[i]);
211  }
212 
213  void addComponent(const std::string & strExpression)
214  {
215  string.push_back( strExpression );// Keep string data
216  std::string & str = string.back();
217  str.erase(std::remove(str.begin(), str.end(),' '), str.end() );
218  gismo::util::string_replace(str, "**", "^");
219 
220  // String expression
221  expression.push_back(Expression_t());
222  Expression_t & expr = expression.back();
223  //expr.release();
224  expr.register_symbol_table(symbol_table);
225 
226  // Parser
227  Parser_t parser;
228  //Collect variable symbols
229  //parser.dec().collect_variables() = true;
230  bool success = parser.compile(str, expr);
231  if ( ! success )
232  gsWarn<<"gsFunctionExpr error: " <<parser.error() <<" while parsing "<<str<<"\n";
233  /*
234  typedef typename exprtk::parser_t::
235  dependent_entity_collector::symbol_t symbol_t;
236 
237  std::deque<symbol_t> symbol_list;
238  parser.dec().symbols(symbol_list);
239  for (size_t i = 0; i != symbol_list.size(); ++i)
240  {
241  symbol_t& symbol = symbol_list[i];
242  // do something
243  }
244  */
245  }
246 
247  void init()
248  {
249  //symbol_table.clear();
250  // Identify symbol table
251  symbol_table.add_variable("x",vars[0]);
252  symbol_table.add_variable("y",vars[1]);
253  symbol_table.add_variable("z",vars[2]);
254  symbol_table.add_variable("w",vars[3]);
255  symbol_table.add_variable("u",vars[4]);
256  symbol_table.add_variable("v",vars[5]);
257  symbol_table.add_variable("t",vars[6]);
258  //symbol_table.remove_variable("w",vars[3]);
259  symbol_table.add_pi();
260  //symbol_table.add_constant("C", 1);
261  }
262 
263 public:
264  mutable Numeric_t vars[N_VARS];
265  SymbolTable_t symbol_table;
266  std::vector<Expression_t> expression;
267  std::vector<std::string> string;
268  short_t dim;
269 
270 private:
271  gsFunctionExprPrivate();
272  gsFunctionExprPrivate operator= (const gsFunctionExprPrivate & other);
273 };
274 
275 /* / /AM: under construction
276 template<typename T> class gsSymbolListPrivate
277 {
278 public:
279  exprtk::symbol_table<T> symbol_table;
280  std::vector<T> vars ;
281  std::vector<T> params;
282 };
283 
284 template<typename T>
285 gsSymbolList<T>::gsSymbolList() : my(new gsSymbolListPrivate<T>) {}
286 
287 template<typename T>
288 gsSymbolList<T>::~gsSymbolList()
289 {
290 delete my;
291 }
292 
293 template<typename T>
294 void gsSymbolList<T>::setDefault()
295 {
296  my->symbol_table.clear();
297 
298  // Identify symbol table
299  my->symbol_table.add_variable("x",my->vars[0]);
300  my->symbol_table.add_variable("y",my->vars[1]);
301  my->symbol_table.add_variable("z",my->vars[2]);
302  my->symbol_table.add_variable("w",my->vars[3]);
303  my->symbol_table.add_variable("u",my->vars[4]);
304  my->symbol_table.add_variable("v",my->vars[5]);
305  //my->symbol_table.remove_variable("w",my->vars[3]);
306  my->symbol_table.add_pi();
307  //my->symbol_table.add_constant("C", 1);
308 }
309 
310 template<typename T>
311 bool gsSymbolList<T>::addConstant(const std::string & constant_name, const T& value)
312 {
313 return my->symbol_table.add_constant(constant_name, value);
314 }
315 
316 template<typename T>
317 bool gsSymbolList<T>::addVariable(const std::string & variable_name)
318 {
319  my->vars.push_back(0.0);
320  return my->symbol_table.add_variable(variable_name, my->vars.back() );
321 }
322 
323 template<typename T>
324 bool gsSymbolList<T>::addParameter(const std::string & variable_name)
325 {
326  my->params.push_back(0.0);
327  return my->symbol_table.add_variable(variable_name, my->params.back() );
328 }
329 
330 template<typename T>
331 bool gsSymbolList<T>::hasSymbol(const std::string& symbol_name)
332 {
333 return true;
334 }
335 */
336 
337 template<typename T>
338 gsFunctionExpr<T>::gsFunctionExpr() : my(new PrivateData_t(0))
339 { }
340 
341 template<typename T>
342 gsFunctionExpr<T>::gsFunctionExpr(const std::string & expression_string, short_t ddim)
343 : my(new PrivateData_t(ddim))
344 {
345  my->addComponent(expression_string);
346 }
347 
348 template<typename T>
349 gsFunctionExpr<T>::gsFunctionExpr(const std::string & expression_string1,
350  const std::string & expression_string2,
351  short_t ddim)
352 : my(new PrivateData_t(ddim))
353 {
354  my->addComponent(expression_string1);
355  my->addComponent(expression_string2);
356 }
357 
358 template<typename T>
359 gsFunctionExpr<T>::gsFunctionExpr(const std::string & expression_string1,
360  const std::string & expression_string2,
361  const std::string & expression_string3,
362  short_t ddim)
363 : my(new PrivateData_t(ddim))
364 {
365  my->addComponent(expression_string1);
366  my->addComponent(expression_string2);
367  my->addComponent(expression_string3);
368 }
369 
370 template<typename T>
371 gsFunctionExpr<T>::gsFunctionExpr(const std::string & expression_string1,
372  const std::string & expression_string2,
373  const std::string & expression_string3,
374  const std::string & expression_string4,
375  short_t ddim)
376 : my(new PrivateData_t(ddim))
377 {
378  my->addComponent(expression_string1);
379  my->addComponent(expression_string2);
380  my->addComponent(expression_string3);
381  my->addComponent(expression_string4);
382 }
383 
384 template<typename T>
385 gsFunctionExpr<T>::gsFunctionExpr(const std::string & expression_string1,
386  const std::string & expression_string2,
387  const std::string & expression_string3,
388  const std::string & expression_string4,
389  const std::string & expression_string5,
390  const std::string & expression_string6,
391  const std::string & expression_string7,
392  const std::string & expression_string8,
393  const std::string & expression_string9,
394  short_t ddim)
395 : my(new PrivateData_t(ddim))
396 {
397  my->addComponent(expression_string1);
398  my->addComponent(expression_string2);
399  my->addComponent(expression_string3);
400  my->addComponent(expression_string4);
401  my->addComponent(expression_string5);
402  my->addComponent(expression_string6);
403  my->addComponent(expression_string7);
404  my->addComponent(expression_string8);
405  my->addComponent(expression_string9);
406 }
407 
408 template<typename T>
409 gsFunctionExpr<T>::gsFunctionExpr(const std::vector<std::string> & expression_string,
410  short_t ddim)
411 : my(new PrivateData_t(ddim))
412 {
413  for (size_t i = 0; i!= expression_string.size(); ++i)
414  my->addComponent(expression_string[i]);
415 }
416 
417 template<typename T>
418 gsFunctionExpr<T>::gsFunctionExpr(const gsFunctionExpr & other)
419 {
420  my = new PrivateData_t(*other.my);
421 }
422 #if EIGEN_HAS_RVALUE_REFERENCES
423 
424 template<typename T>
425 gsFunctionExpr<T>::gsFunctionExpr(gsFunctionExpr && other)
426 {
427  my = other.my; other.my = NULL;
428 }
429 
430 template<typename T>
431 gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(const gsFunctionExpr& other)
432 {
433  if (this != &other)
434  {
435  delete my;
436  my = new PrivateData_t(*other.my);
437  }
438  return *this;
439 }
440 
441 template<typename T>
442 gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr&& other)
443 {
444  if (this != &other)
445  {
446  delete my;
447  my = other.my; other.my = NULL;
448  }
449  return *this;
450 }
451 
452 #else
453 template<typename T>
454 gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr other)
455 {
456  std::swap(my,other.my);
457  return *this;
458 }
459 #endif
460 
461 template<typename T>
462 gsFunctionExpr<T>::~gsFunctionExpr()
463 {
464  delete my;
465 }
466 
467 template<typename T>
469 {
470  return my->dim;
471 }
472 
473 template<typename T>
475 {
476  return static_cast<short_t>(my->string.size());
477 }
478 
479 template<typename T>
480 void gsFunctionExpr<T>::addComponent(const std::string & strExpression)
481 {
482  my->addComponent(strExpression);
483 }
484 
485 template<typename T>
486 const std::string & gsFunctionExpr<T>::expression(int i) const
487 {
488  return my->string[i];
489 }
490 
491 template<typename T>
492 void gsFunctionExpr<T>::set_x (T const & v) const { my->vars[0]= v; }
493 
494 template<typename T>
495 void gsFunctionExpr<T>::set_y (T const & v) const { my->vars[1]= v; }
496 
497 template<typename T>
498 void gsFunctionExpr<T>::set_z (T const & v) const { my->vars[2]= v; }
499 
500 template<typename T>
501 void gsFunctionExpr<T>::set_w (T const & v) const { my->vars[3]= v; }
502 
503 template<typename T>
504 void gsFunctionExpr<T>::set_u (T const & v) const { my->vars[4]= v; }
505 
506 template<typename T>
507 void gsFunctionExpr<T>::set_v (T const & v) const { my->vars[5]= v; }
508 
509 template<typename T>
510 void gsFunctionExpr<T>::set_t (T const & t) const { my->vars[6]= t; }
511 
512 template<typename T>
514 {
515  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point dimension (expected: "
516  << my->dim <<", got "<< u.rows() <<")\n"<< *this);
517 
518  const short_t n = targetDim();
519  result.resize(n, u.cols());
520 
521 #pragma omp critical (gsFunctionExpr_run)
522  for ( index_t p = 0; p!=u.cols(); p++ ) // for all evaluation points
523  {
524  copy_n(u.col(p).data(), my->dim, my->vars);
525 
526  for (short_t c = 0; c!= n; ++c) // for all components
527 # ifdef GISMO_WITH_ADIFF
528  result(c,p) = my->expression[c].value().getValue();
529 # else
530  result(c,p) = my->expression[c].value();
531 # endif
532  }
533 }
534 
535 template<typename T>
537 {
538  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point dimension (expected: "
539  << my->dim <<", got "<< u.rows() <<")");
540 
541  GISMO_ASSERT (comp < targetDim(),
542  "Given component number is higher then number of components");
543 
544  result.resize(1, u.cols());
545 # pragma omp critical (gsFunctionExpr_run)
546  for ( index_t p = 0; p!=u.cols(); ++p )
547  {
548  copy_n(u.col(p).data(), my->dim, my->vars);
549 
550 # ifdef GISMO_WITH_ADIFF
551  result(0,p) = my->expression[comp].value().getValue();
552 # else
553  result(0,p) = my->expression[comp].value();
554 # endif
555  }
556 }
557 
558 template<typename T>
560 {
561  //gsDebug<< "Using finite differences (gsFunctionExpr::deriv_into) for derivatives.\n";
562  const short_t d = domainDim();
563  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point dimension (expected: "
564  << my->dim <<", got "<< u.rows() <<")");
565 
566  const short_t n = targetDim();
567  result.resize(d*n, u.cols());
568 # pragma omp critical (gsFunctionExpr_run)
569  for ( index_t p = 0; p!=u.cols(); p++ ) // for all evaluation points
570  {
571 # ifdef GISMO_WITH_ADIFF
572  for (short_t k = 0; k!=d; ++k)
573  my->vars[k].setVariable(k,d,u(k,p));
574  for (short_t c = 0; c!= n; ++c) // for all components
575  my->expression[c].value().gradient_into(result.block(c*d,p,d,1));
576  //result.block(c*d,p,d,1) = my->expression[c].value().getGradient(); //fails on constants
577 # else
578  copy_n(u.col(p).data(), my->dim, my->vars);
579  for (short_t c = 0; c!= n; ++c) // for all components
580  for ( short_t j = 0; j!=d; j++ ) // for all variables
581  result(c*d + j, p) =
582  exprtk::derivative<T>(my->expression[c], my->vars[j], 0.00001 ) ;
583 # endif
584  }
585 }
586 
587 template<typename T>
589 {
590  const short_t d = domainDim();
591  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point dimension (expected: "
592  << my->dim <<", got "<< u.rows() <<")");
593 
594  const short_t n = targetDim();
595  const index_t stride = d + d*(d-1)/2;
596  result.resize(stride*n, u.cols() );
597 # pragma omp critical (gsFunctionExpr_run)
598  for ( index_t p = 0; p!=u.cols(); p++ ) // for all evaluation points
599  {
600 # ifndef GISMO_WITH_ADIFF
601  copy_n(u.col(p).data(), my->dim, my->vars);
602 # endif
603 
604  for (short_t c = 0; c!= n; ++c) // for all components
605  {
606 # ifdef GISMO_WITH_ADIFF
607  for (index_t v = 0; v!=d; ++v)
608  my->vars[v].setVariable(v,d,u(v,p));
609  const DScalar & ads = my->expression[c].value();
610  const DScalar::Hessian_t & Hmat = ads.getHessian(); // note: can fail
611 
612  for ( index_t k=0; k!=d; ++k)
613  {
614  result(k,p) = Hmat(k,k);
615  index_t m = d;
616  for ( index_t l=k+1; l<d; ++l)
617  result(m++,p) = Hmat(k,l);
618  }
619 # else
620  for (short_t k = 0; k!=d; ++k)
621  {
622  // H_{k,k}
623  result(k,p) = exprtk::
624  second_derivative<T>(my->expression[c], my->vars[k], 0.00001);
625 
626  short_t m = d;
627  for (short_t l=k+1; l<d; ++l)
628  {
629  // H_{k,l}
630  result(m++,p) =
631  mixed_derivative<T>( my->expression[c], my->vars[k],
632  my->vars[l], 0.00001 );
633  }
634  }
635 # endif
636  }
637  }
638 }
639 
640 template<typename T>
642 gsFunctionExpr<T>::hess(const gsMatrix<T>& u, unsigned coord) const
643 {
644  //gsDebug<< "Using finite differences (gsFunctionExpr::hess) for Hessian.\n";
645  GISMO_ENSURE(coord == 0, "Error, function is real");
646  GISMO_ASSERT ( u.cols() == 1, "Need a single evaluation point." );
647  const index_t d = u.rows();
648  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point dimension (expected: "
649  << my->dim <<", got "<< u.rows() <<")");
650 
651  gsMatrix<T> res(d, d);
652 
653 # pragma omp critical (gsFunctionExpr_run)
654 {
655 # ifdef GISMO_WITH_ADIFF
656  for (index_t v = 0; v!=d; ++v)
657  my->vars[v].setVariable(v, d, u(v,0) );
658  my->expression[coord].value().hessian_into(res);
659 # else
660  copy_n(u.data(), my->dim, my->vars);
661  for( index_t j=0; j!=d; ++j )
662  {
663  res(j,j) = exprtk::
664  second_derivative<T>( my->expression[coord], my->vars[j], 0.00001);
665 
666  for( index_t k = 0; k!=j; ++k )
667  res(k,j) = res(j,k) =
668  mixed_derivative<T>( my->expression[coord], my->vars[k],
669  my->vars[j], 0.00001 );
670  }
671 # endif
672 }
673  return res;
674 }
675 
676 template<typename T>
678  const index_t k,
679  const index_t j) const
680 {
681  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point size.");
682  const short_t n = targetDim();
683  gsMatrix<T> * res= new gsMatrix<T>(n,u.cols()) ;
684 
685 # pragma omp critical (gsFunctionExpr_run)
686  for( index_t p=0; p!=res->cols(); ++p )
687  {
688 # ifndef GISMO_WITH_ADIFF
689  copy_n(u.col(p).data(), my->dim, my->vars);
690 # endif
691 
692  for (short_t c = 0; c!= n; ++c) // for all components
693  {
694 # ifdef GISMO_WITH_ADIFF
695  for (index_t v = 0; v!=my->dim; ++v)
696  my->vars[v].setVariable(v, my->dim, u(v,p) );
697  (*res)(c,p) = my->expression[c].value().getHessian()(k,j); //note: can fail
698 # else
699  (*res)(c,p) =
700  mixed_derivative<T>( my->expression[c], my->vars[k], my->vars[j], 0.00001 ) ;
701 # endif
702  }
703  }
704  return res;
705 }
706 
707 template<typename T>
709 {
710  //gsDebug<< "Using finite differences (gsFunction::laplacian) for Laplacian.\n";
711  GISMO_ASSERT ( u.rows() == my->dim, "Inconsistent point size.");
712  const short_t n = targetDim();
713  gsMatrix<T> res(n,u.cols());
714 
715  # pragma omp critical (gsFunctionExpr_run)
716  for( index_t p = 0; p != res.cols(); ++p )
717  {
718 # ifndef GISMO_WITH_ADIFF
719  copy_n(u.col(p).data(), my->dim, my->vars);
720 # endif
721 
722  for (short_t c = 0; c!= n; ++c) // for all components
723  {
724 # ifdef GISMO_WITH_ADIFF
725  for (index_t v = 0; v!=my->dim; ++v)
726  my->vars[v].setVariable(v, my->dim, u(v,p) );
727  res(c,p) = my->expression[c].value().getHessian().trace();
728 # else
729  T & val = res(c,p);
730  for ( index_t j = 0; j!=my->dim; ++j )
731  val += exprtk::
732  second_derivative<T>( my->expression[c], my->vars[j], 0.00001 );
733 # endif
734  }
735  }
736  return res;
737 }
738 
739 template<typename T>
740 std::ostream & gsFunctionExpr<T>::print(std::ostream &os) const
741 {
742  os <<"[ ";
743  if( my->string.empty() )
744  os << "empty";
745  else
746  {
747  os << my->string[0];
748 
749  for (short_t k = 1; k<targetDim(); ++k)
750  os <<", " << my->string[k];
751  }
752  os <<" ]";
753  return os;
754 }
755 
756 namespace internal
757 {
758 
760 template<class T>
761 class gsXml< gsFunctionExpr<T> >
762 {
763 private:
764  gsXml() { }
765  typedef gsFunctionExpr<T> Object;
766 public:
767  GSXML_COMMON_FUNCTIONS(Object);
768  static std::string tag () { return "Function"; }
769  static std::string type () { return "FunctionExpr"; }
770 
771  GSXML_GET_POINTER(Object);
772 
773  static void get_into (gsXmlNode * node, Object & obj)
774  {
775  GISMO_ASSERT( node->first_attribute("dim"), "Reading gsFunctionExpr XML: No dim found" ) ;
776  const int d = atoi( node->first_attribute("dim")->value() );
777 
778  std::vector< std::string > expr_strings;
779 
780  gsXmlNode * child = node->first_node("c");
781 
782  if (child != NULL )
783  {
784  for (; child; child = child->next_sibling() )
785  expr_strings.push_back( child->value() );
786  }
787  else
788  expr_strings.push_back( node->value() );
789 
790  obj = gsFunctionExpr<T>( expr_strings, d );
791  }
792 
793  static gsXmlNode * put (const Object & obj,
794  gsXmlTree & data )
795  {
796  gsXmlNode * func = makeNode("Function", data);
797  func->append_attribute(makeAttribute("dim", obj.domainDim(), data));
798  func->append_attribute(makeAttribute("type", "FunctionExpr", data));
799 
800  const short_t tdim = obj.targetDim();
801 
802  if ( tdim == 1)
803  {
804  func->value( makeValue(obj.expression(), data) );
805  }
806  else
807  {
808  gsXmlNode * cnode;
809  for (short_t c = 0; c!=tdim; ++c)
810  {
811  cnode = makeNode("c", obj.expression(c), data);
812  func->append_node(cnode);
813  }
814  }
815 
816  return func;
817  }
818 };
819 
820 } // internal
821 
822 }; // namespace gismo
gsMatrix< T > laplacian(const gsMatrix< T > &u) const
Evaluate the Laplacian at points u.
Definition: gsFunctionExpr.hpp:708
virtual void eval_component_into(const gsMatrix< T > &u, const index_t comp, gsMatrix< T > &result) const
Evaluate the function for component comp in the target dimension at points u into result...
Definition: gsFunctionExpr.hpp:536
virtual void deriv2_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate second derivatives of the function at points u into result.
Definition: gsFunctionExpr.hpp:588
virtual void deriv_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate derivatives of the function at points u into result.
Definition: gsFunctionExpr.hpp:559
void set_z(T const &v) const
Sets the symbol &quot;z&quot; to a value.
Definition: gsFunctionExpr.hpp:498
short_t targetDim() const
Dimension of the target space.
Definition: gsFunctionExpr.hpp:474
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
#define short_t
Definition: gsConfig.h:35
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the function at points u into result.
Definition: gsFunctionExpr.hpp:513
void set_u(T const &v) const
Sets the symbol &quot;u&quot; to a value.
Definition: gsFunctionExpr.hpp:504
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
void string_replace(std::string &str, const std::string &oldStr, const std::string &newStr)
Replaces appearance of oldStr with newStr inside the string str.
Definition: gsUtils.h:171
void addComponent(const std::string &strExpression)
Adds another component to this (vector) function.
Definition: gsFunctionExpr.hpp:480
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
index_t size() const
size
Definition: gsFunction.h:295
void set_y(T const &v) const
Sets the symbol &quot;y&quot; to a value.
Definition: gsFunctionExpr.hpp:495
Provides an exprtk adaptor for the Unum Posit arithmetic type.
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void set_v(T const &v) const
Sets the symbol &quot;v&quot; to a value.
Definition: gsFunctionExpr.hpp:507
gsMatrix< T > * mderiv(const gsMatrix< T > &u, const index_t k, const index_t j) const
Mixed derivative wrt variables k and j.
Definition: gsFunctionExpr.hpp:677
#define gsWarn
Definition: gsDebug.h:50
short_t domainDim() const
Dimension of the (source) domain.
Definition: gsFunctionExpr.hpp:468
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition: gsXml.cpp:37
void copy_n(T begin, const size_t n, U *result)
Small wrapper for std::copy mimicking memcpy (or std::copy_n) for a raw pointer destination, copies n positions starting from begin into result. The latter is expected to have been allocated in advance.
Definition: gsMemory.h:368
Provides an exprtk adaptor for the Unum Posit arithmetic type.
void set_t(T const &t) const
Sets the symbol &quot;t&quot; to a value.
Definition: gsFunctionExpr.hpp:510
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition: gsXml.cpp:54
void set_x(T const &v) const
Sets the symbol &quot;x&quot; to a value.
Definition: gsFunctionExpr.hpp:492
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsFunctionExpr.hpp:740
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition: gsXml.cpp:32
Class defining a multivariate (real or vector) function given by a string mathematical expression...
Definition: gsFunctionExpr.h:51
This is the main header file that collects wrappers of Eigen for linear algebra.
gsFunctionExpr()
Default empty constructor.
Definition: gsFunctionExpr.hpp:338
Provides declaration of input/output XML utilities struct.
void set_w(T const &v) const
Sets the symbol &quot;w&quot; to a value.
Definition: gsFunctionExpr.hpp:501