G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsFunctionExpr.hpp
Go to the documentation of this file.
1
14#pragma once
15
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
110namespace
111{
112
113// addition of mixed derivative for expressions
114// see https://en.wikipedia.org/wiki/Finite_difference_coefficient
115template <typename T>
116T 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
175namespace gismo
176{
177
178template<typename T> class gsFunctionExpr<T>::gsFunctionExprPrivate
179{
180public:
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
192public:
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
263public:
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
270private:
271 gsFunctionExprPrivate();
272 gsFunctionExprPrivate operator= (const gsFunctionExprPrivate & other);
273};
274
275/* / /AM: under construction
276template<typename T> class gsSymbolListPrivate
277{
278public:
279 exprtk::symbol_table<T> symbol_table;
280 std::vector<T> vars ;
281 std::vector<T> params;
282};
283
284template<typename T>
285gsSymbolList<T>::gsSymbolList() : my(new gsSymbolListPrivate<T>) {}
286
287template<typename T>
288gsSymbolList<T>::~gsSymbolList()
289{
290delete my;
291}
292
293template<typename T>
294void 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
310template<typename T>
311bool gsSymbolList<T>::addConstant(const std::string & constant_name, const T& value)
312{
313return my->symbol_table.add_constant(constant_name, value);
314}
315
316template<typename T>
317bool 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
323template<typename T>
324bool 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
330template<typename T>
331bool gsSymbolList<T>::hasSymbol(const std::string& symbol_name)
332{
333return true;
334}
335*/
336
337template<typename T>
338gsFunctionExpr<T>::gsFunctionExpr() : my(new PrivateData_t(0))
339{ }
340
341template<typename T>
342gsFunctionExpr<T>::gsFunctionExpr(const std::string & expression_string, short_t ddim)
343: my(new PrivateData_t(ddim))
344{
345 my->addComponent(expression_string);
346}
347
348template<typename T>
349gsFunctionExpr<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
358template<typename T>
359gsFunctionExpr<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
370template<typename T>
371gsFunctionExpr<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
384template<typename T>
385gsFunctionExpr<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
408template<typename T>
409gsFunctionExpr<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
417template<typename T>
418gsFunctionExpr<T>::gsFunctionExpr(const gsFunctionExpr & other)
419{
420 my = new PrivateData_t(*other.my);
421}
422#if EIGEN_HAS_RVALUE_REFERENCES
423
424template<typename T>
425gsFunctionExpr<T>::gsFunctionExpr(gsFunctionExpr && other)
426{
427 my = other.my; other.my = NULL;
428}
429
430template<typename T>
431gsFunctionExpr<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
441template<typename T>
442gsFunctionExpr<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
453template<typename T>
454gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr other)
455{
456 std::swap(my,other.my);
457 return *this;
458}
459#endif
460
461template<typename T>
462gsFunctionExpr<T>::~gsFunctionExpr()
463{
464 delete my;
465}
466
467template<typename T>
469{
470 return my->dim;
471}
472
473template<typename T>
475{
476 return static_cast<short_t>(my->string.size());
477}
478
479template<typename T>
480void gsFunctionExpr<T>::addComponent(const std::string & strExpression)
481{
482 my->addComponent(strExpression);
483}
484
485template<typename T>
486const std::string & gsFunctionExpr<T>::expression(int i) const
487{
488 return my->string[i];
489}
490
491template<typename T>
492void gsFunctionExpr<T>::set_x (T const & v) const { my->vars[0]= v; }
493
494template<typename T>
495void gsFunctionExpr<T>::set_y (T const & v) const { my->vars[1]= v; }
496
497template<typename T>
498void gsFunctionExpr<T>::set_z (T const & v) const { my->vars[2]= v; }
499
500template<typename T>
501void gsFunctionExpr<T>::set_w (T const & v) const { my->vars[3]= v; }
502
503template<typename T>
504void gsFunctionExpr<T>::set_u (T const & v) const { my->vars[4]= v; }
505
506template<typename T>
507void gsFunctionExpr<T>::set_v (T const & v) const { my->vars[5]= v; }
508
509template<typename T>
510void gsFunctionExpr<T>::set_t (T const & t) const { my->vars[6]= t; }
511
512template<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
535template<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
558template<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
587template<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(c*stride + k,p) = Hmat(k,k);
615 index_t m = d;
616 for ( index_t l=k+1; l<d; ++l)
617 result(c*stride + m++,p) = Hmat(k,l);
618 }
619# else
620 for (short_t k = 0; k!=d; ++k)
621 {
622 // H_{k,k}
623 result(c*stride + 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(c*stride + 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
640template<typename T>
642gsFunctionExpr<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
676template<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
707template<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
739template<typename T>
740std::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
756namespace internal
757{
758
760template<class T>
761class gsXml< gsFunctionExpr<T> >
762{
763private:
764 gsXml() { }
765 typedef gsFunctionExpr<T> Object;
766public:
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
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
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
gsMatrix< T > laplacian(const gsMatrix< T > &u) const
Evaluate the Laplacian at points u.
Definition gsFunctionExpr.hpp:708
void set_w(T const &v) const
Sets the symbol "w" to a value.
Definition gsFunctionExpr.hpp:501
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
void addComponent(const std::string &strExpression)
Adds another component to this (vector) function.
Definition gsFunctionExpr.hpp:480
void set_v(T const &v) const
Sets the symbol "v" to a value.
Definition gsFunctionExpr.hpp:507
short_t targetDim() const
Dimension of the target space.
Definition gsFunctionExpr.hpp:474
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_z(T const &v) const
Sets the symbol "z" to a value.
Definition gsFunctionExpr.hpp:498
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
short_t domainDim() const
Dimension of the (source) domain.
Definition gsFunctionExpr.hpp:468
void set_u(T const &v) const
Sets the symbol "u" to a value.
Definition gsFunctionExpr.hpp:504
void set_x(T const &v) const
Sets the symbol "x" to a value.
Definition gsFunctionExpr.hpp:492
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
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsFunctionExpr.hpp:740
void set_t(T const &t) const
Sets the symbol "t" to a value.
Definition gsFunctionExpr.hpp:510
void set_y(T const &v) const
Sets the symbol "y" to a value.
Definition gsFunctionExpr.hpp:495
gsFunctionExpr()
Default empty constructor.
Definition gsFunctionExpr.hpp:338
index_t size() const
size
Definition gsFunction.h:295
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
Provides an exprtk adaptor for the Unum Posit arithmetic type.
Provides an exprtk adaptor for the Unum Posit arithmetic type.
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
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
This is the main header file that collects wrappers of Eigen for linear algebra.
Provides declaration of input/output XML utilities struct.
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition gsXml.cpp:32
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition gsXml.cpp:54
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition gsXml.cpp:37
The G+Smo namespace, containing all definitions for the library.
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,...
Definition gsMemory.h:368