G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsExprEvaluator.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 // #include<gsIO/gsParaviewCollection.h>
17 #include <fstream>
21 //#include <gsIO/gsWriteParaview.h>
22 
23 namespace gismo
24 {
25 
37 template<class T>
39 {
40 private:
41  typename gsExprHelper<T>::Ptr m_exprdata;
42 
43 private:
44  std::vector<T> m_elWise;
45  T m_value;
46 
47  gsOptionList m_options;
48 
49 public:
50  typedef typename gsBoundaryConditions<T>::bcRefList bcRefList;
51 
52  typedef std::vector< boundaryInterface > intContainer;
53  typedef std::vector< patchSide > bContainer;
54 
55  typedef typename gsExprHelper<T>::element element;
56  typedef typename gsExprHelper<T>::geometryMap geometryMap;
57  typedef typename gsExprHelper<T>::variable variable;
58 
59  typedef typename gsFunction<T>::uPtr ifacemap;
60 
61 public:
62 
63  gsExprEvaluator() : m_exprdata(gsExprHelper<T>::make()),
64  m_options(defaultOptions()) { }
65 
66  gsExprEvaluator(typename gsExprHelper<T>::Ptr env)
67  : m_exprdata(env), m_value(-1), m_options(defaultOptions())
68  { }
69 
70  //gsExprEvaluator(typename gsExprHelper<T> env)
71 
73  : m_exprdata(o.exprData()), m_options(defaultOptions())
74  { }
75 
76  gsOptionList defaultOptions()
77  {
78  gsOptionList opt;
79  opt.addReal("quA", "Number of quadrature points: quA*deg + quB", 1.0 );
80  opt.addInt ("quB", "Number of quadrature points: quA*deg + quB", 1 );
81  opt.addInt ("plot.npts", "Number of sampling points for plotting", 3000 );
82  opt.addSwitch("plot.elements", "Include the element mesh in plot (when applicable)", false);
83  opt.addSwitch("flipSide", "Flip side of interface where evaluation is performed.", false);
84  //opt.addSwitch("plot.cnet", "Include the control net in plot (when applicable)", false);
85  return opt;
86  }
87 
88  gsOptionList & options() {return m_options;}
89 
90 public:
91 
93  T value() const { return m_value; }
94 
96  size_t nValues() const { return m_elWise.size(); }
97 
99  const std::vector<T> & elementwise() const { return m_elWise; }
100 
102  gsAsConstVector<T> allValues() const { return gsAsConstVector<T>(m_elWise); }
103 
106  { return gsAsConstMatrix<T>(m_elWise, nR, nC); }
107 
111  { m_exprdata->setMultiBasis(mesh); }
112 
113  const typename gsExprHelper<T>::Ptr exprData() const { return m_exprdata; }
114 
116  geometryMap getMap(const gsMultiPatch<T> & mp) //conv->tmp->error
117  { return m_exprdata->getMap(mp); }
118 
120  geometryMap getMap(const gsFunctionSet<T> & gm)
121  { return m_exprdata->getMap(gm); }
122 
124  variable getVariable(const gsFunctionSet<T> & func, index_t dim = 1)
125  { return m_exprdata->getVar(func, dim); }
126 
128  expr::gsComposition<T> getVariable(const gsFunctionSet<T> & func, geometryMap G)
129  { return m_exprdata->getVar(func, G); }
130 
132  element getElement() { return m_exprdata->getElement(); }
133 
135  void calcSqrt()
136  {
137  gsAsVector<T> en(m_elWise);
138  en.array() = en.array().sqrt();
139  m_value = math::sqrt(m_value);
140  }
141 
143  void calcRoot(const index_t p)
144  {
145  gsAsVector<T> en(m_elWise);
146  en.array() = en.array().pow(static_cast<T>(1)/p);
147  m_value = math::pow(m_value, static_cast<T>(1)/p );
148  }
149 
150 public:
151 
153  template<class E>
154  T integral(const expr::_expr<E> & expr)
155  { return compute_impl<E,false,plus_op>(expr); }
156 
158  template<class E>
159  T integralElWise(const expr::_expr<E> & expr)
160  { return compute_impl<E,true,plus_op>(expr); }
161 
162  // overloads for scalars
163  T integral(const T & val) { return integral<T>(val); }
164  T integralElWise(const T & val) { return integralElWise<T>(val); }
165 
168  template<class E> // note: integralBdrElWise not offered
169  T integralBdr(const expr::_expr<E> & expr)
170  { return computeBdr_impl<E,plus_op>(expr,
171  m_exprdata->multiBasis().topology().boundaries()); }
172 
175  template<class E> // note: integralBdrElWise not offered
176  T integralBdr(const expr::_expr<E> & expr, const bContainer & bdrlist)
177  { return computeBdr_impl<E,plus_op>(expr,bdrlist); }
178 
181  template<class E> // note: integralBdrElWise not offered
182  T integralBdrBc(const bcRefList & BCs, const expr::_expr<E> & expr)
183  { return computeBdrBc_impl<E,plus_op>(BCs,expr); }
184 
187  template<class E> // note: elementwise integral not offered
188  T integralInterface(const expr::_expr<E> & expr)
189  { return computeInterface_impl<E,plus_op>(expr,
190  m_exprdata->multiBasis().topology().interfaces()); }
191 
194  template<class E> // note: elementwise integral not offered
195  T integralInterface(const expr::_expr<E> & expr, const intContainer & iFaces)
196  { return computeInterface_impl<E,plus_op>(expr, iFaces); }
197 
200  template<class E>
201  T max(const expr::_expr<E> & expr)
202  { return compute_impl<E,false,max_op>(expr); }
203 
206  template<class E>
207  T maxElWise(const expr::_expr<E> & expr)
208  { return compute_impl<E,true,max_op>(expr); }
209 
212  template<class E> // note: elementwise integral not offered
213  T maxInterface(const expr::_expr<E> & expr)
214  { return computeInterface_impl<E,max_op>(expr, m_exprdata->multiBasis().topology().interfaces()); }
215 
218  template<class E> // note: elementwise integral not offered
219  T maxInterface(const expr::_expr<E> & expr, const intContainer & iFaces)
220  { return computeInterface_impl<E,max_op>(expr, iFaces); }
221 
224  template<class E> // note: elementwise integral not offered
225  T minInterface(const expr::_expr<E> & expr)
226  { return computeInterface_impl<E,min_op>(expr, m_exprdata->multiBasis().topology().interfaces()); }
227 
230  template<class E> // note: elementwise integral not offered
231  T minInterface(const expr::_expr<E> & expr, const intContainer & iFaces)
232  { return computeInterface_impl<E,min_op>(expr, iFaces); }
233 
236  template<class E>
237  T min(const expr::_expr<E> & expr)
238  { return compute_impl<E,false,min_op>(expr); }
239 
242  template<class E>
243  T minElWise(const expr::_expr<E> & expr)
244  { return compute_impl<E,true,min_op>(expr); }
245 
248 #ifdef __DOXYGEN__
249  template<class E> void
250 #else
251  template<class E, int mode, short_t d>
252  typename util::enable_if<E::ScalarValued,void>::type
253 #endif
254  eval(const expr::_expr<E> & expr,
255  gsGridIterator<T,mode,d> & git,
256  const index_t patchInd = 0);
257 
258  template<class E, int mode, short_t d>
259  typename util::enable_if<!E::ScalarValued,void>::type
260  eval(const expr::_expr<E> & expr,
261  gsGridIterator<T,mode,d> & git,
262  const index_t patchInd = 0);
263 
266  template<class E>
267 #ifdef __DOXYGEN__
269 #else
270  typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
271 #endif
272  eval(const expr::_expr<E> & testExpr, const gsVector<T> & pt,
273  const index_t patchInd = 0);
274 
275  template<class E>
276  typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
277  eval(const expr::_expr<E> & testExpr, const gsVector<T> & pt,
278  const index_t patchInd = 0);
279 
280  template<class E>
281 #ifdef __DOXYGEN__
283 #else
284  typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
285 #endif
286  evalIfc(const expr::_expr<E> & testExpr, const gsVector<T> & pt,
287  const boundaryInterface & ifc);
288 
289  template<class E>
290  typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
291  evalIfc(const expr::_expr<E> & testExpr, const gsVector<T> & pt,
292  const boundaryInterface & ifc);
293 
296  template<class E> void
297  testEval(const expr::_expr<E> & expr,
298  const gsVector<T> & pt, const index_t patchInd = 0)
299  {
300  expr.print(gsInfo);
301  gsInfo << "Result:\n"<< eval(expr,pt,patchInd) <<"\n";
302  }
303 
304  void info() const { m_exprdata->print(); }
305 
306  // Interpolates the expression \a expr over the isogeometric domain \a G
307  template<class E> void interpolate(const expr::_expr<E> &)
308  {
310  // for all patches
311  // get anchors of patch
312  // evaluate expr
313  // solve system
314  // add to multipatch
315  // return multipatch
316  }
317 
319  //( expression \a expr over the isogeometric domain \a G.
322  template<class E>
323  void writeParaview(const expr::_expr<E> & expr,
324  geometryMap G, std::string const & fn)
325  { writeParaview_impl<E,true>(expr,G,fn); }
326 
328  //( expression \a expr over the parametric domain.
331  template<class E>
332  void writeParaview(const expr::_expr<E> & expr,
333  std::string const & fn)
334  { writeParaview_impl<E,false>(expr,m_exprdata->getMap(),fn); }
335 
336 private:
337 
338  template<class E, bool gmap>
339  void writeParaview_impl(const expr::_expr<E> & expr,
340  geometryMap G, std::string const & fn);
341 
342 
343 
344  template<class E, bool storeElWise, class _op>
345  T compute_impl(const expr::_expr<E> & expr);
346 
347  template<class E, class _op>
348  T computeBdr_impl(const expr::_expr<E> & expr, const bContainer & bdrlist);
349 
350  template<class E, class _op>
351  T computeBdrBc_impl(const bcRefList & BCs, const expr::_expr<E> & expr);
352 
353  template<class E, class _op>
354  T computeInterface_impl(const expr::_expr<E> & expr, const intContainer & iFaces);
355 
356  template<class E>
357  void computeGrid_impl(const expr::_expr<E> & expr, const index_t patchInd);
358 
359  struct plus_op
360  {
361  static inline T init() { return 0; }
362  static inline void acc(const T contrib, const T w, T & res)
363  { res += w * contrib; }
364  };
365  struct min_op
366  {
367  static inline T init() { return math::limits::max(); }
368  static inline void acc (const T contrib, const T, T & res)
369  { res = math::min(contrib, res); } //note: min/max are not atomic
370  };
371  struct max_op
372  {
373  static inline T init() { return math::limits::min(); }
374  static inline void acc (const T contrib, const T, T & res)
375  { res = math::max(contrib, res); }
376  };
377 
378 };
379 
380 template<class T>
381 template<class E, bool storeElWise, class _op>
382 T gsExprEvaluator<T>::compute_impl(const expr::_expr<E> & expr)
383 {
384  m_value = _op::init();
385  m_elWise.clear();
386  if ( storeElWise )
387  m_elWise.resize(m_exprdata->multiBasis().totalElements());
388 
389 #pragma omp parallel
390 {
391 # ifdef _OPENMP
392  const int tid = omp_get_thread_num();
393  const int nt = omp_get_num_threads();
394  index_t patch_cnt = 0;
395 # endif
396 
397  gsQuadRule<T> QuRule; // Quadrature rule
398  gsVector<T> quWeights; // quadrature weights
399 
400  auto _arg = expr.val();
401  m_exprdata->parse(_arg);
402  m_exprdata->activateFlags(SAME_ELEMENT);
403 
404  // Computed value on element
405  T elVal;
406  index_t c = 0;
407  for (unsigned patchInd=0; patchInd < m_exprdata->multiBasis().nBases(); ++patchInd)
408  {
409  // Quadrature rule
410  QuRule = gsQuadrature::get(m_exprdata->multiBasis().basis(patchInd), m_options);
411 
412  // Initialize domain element iterator
413  typename gsBasis<T>::domainIter domIt =
414  m_exprdata->multiBasis().piece(patchInd).makeDomainIterator();
415  m_exprdata->getElement().set(*domIt,quWeights);
416 
417  // Start iteration over elements of patchInd
418 # ifdef _OPENMP
419  if ( storeElWise )
420  {
421  c = patch_cnt + tid;
422  patch_cnt += domIt->numElements();// a bit costy
423  }
424  for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
425 # else
426  for (; domIt->good(); domIt->next() )
427 # endif
428  {
429  // Map the Quadrature rule to the element
430  QuRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(),
431  m_exprdata->points(), quWeights);
432 
433  // Perform required pre-computations on the quadrature nodes
434  m_exprdata->precompute(patchInd);
435 
436  // Compute on element
437  elVal = _op::init();
438  for (index_t k = 0; k != quWeights.rows(); ++k) // loop over quad. nodes
439  _op::acc(_arg.eval(k), quWeights[k], elVal);
440 
441  if ( storeElWise )
442  {
443 # ifdef _OPENMP
444  m_elWise[c] = elVal;
445  c += nt;
446 # else
447  m_elWise[c++] = elVal;
448 # endif
449  }
450 
451 # pragma omp critical (_op_acc)
452  _op::acc(elVal, 1, m_value);
453  }
454  }
455 
456 }//omp parallel
457  return m_value;
458 }
459 
460 template<class T>
461 template<class E, class _op>
462 T gsExprEvaluator<T>::computeBdr_impl(const expr::_expr<E> & expr,
463  const bContainer & bdrlist)
464 {
465  // GISMO_ASSERT( expr.isScalar(),
466  // "Expecting scalar expression instead of "
467  // <<expr.cols()<<" x "<<expr.rows() );
468 
469  //expr.print(gsInfo);
470 
471  gsQuadRule<T> QuRule; // Quadrature rule
472  gsVector<T> quWeights; // quadrature weights
473 
474  auto _arg = expr.val();
475  m_exprdata->parse(_arg);
476  m_exprdata->activateFlags(SAME_ELEMENT);
477 
478  // Computed value
479  T elVal;
480  m_value = _op::init();
481  m_elWise.clear();
482 
483  for (typename gsBoxTopology::const_biterator bit =
484  bdrlist.begin(); bit != bdrlist.end(); ++bit)
485  {
486  // Quadrature rule
487  QuRule = gsQuadrature::get(m_exprdata->multiBasis().basis(bit->patch), m_options,bit->direction());
488 
489  // Initialize domain element iterator
490  typename gsBasis<T>::domainIter domIt =
491  m_exprdata->multiBasis().piece(bit->patch).makeDomainIterator(bit->side());
492  m_exprdata->getElement().set(*domIt,quWeights);
493 
494  // Start iteration over elements
495  for (; domIt->good(); domIt->next() )
496  {
497  // Map the Quadrature rule to the element
498  QuRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(),
499  m_exprdata->points(), quWeights);
500 
501  // Perform required pre-computations on the quadrature nodes
502  m_exprdata->precompute(bit->patch, bit->side() );
503 
504  // Compute on element
505  elVal = _op::init();
506  for (index_t k = 0; k != quWeights.rows(); ++k) // loop over quadrature nodes
507  _op::acc(_arg.eval(k), quWeights[k], elVal);
508 
509  _op::acc(elVal, 1, m_value);
510  //if ( storeElWise ) m_elWise.push_back( elVal );
511  }
512  }
513 
514  return m_value;
515 }
516 
517 template<class T>
518 template<class E, class _op>
519 T gsExprEvaluator<T>::computeBdrBc_impl(const bcRefList & BCs,
520  const expr::_expr<E> & expr)
521 {
522  // GISMO_ASSERT( expr.isScalar(),
523  // "Expecting scalar expression instead of "
524  // <<expr.cols()<<" x "<<expr.rows() );
525 
526  //expr.print(gsInfo);
527 
528  if ( BCs.empty() ) return 0;
529  m_exprdata->setMutSource(*BCs.front().get().function()); //initialize once
530 
531  typename gsQuadRule<T>::uPtr QuRule; // Quadrature rule ---->OUT
532  gsVector<T> quWeights; // quadrature weights
533 
534  auto _arg = expr.val();
535  m_exprdata->parse(_arg);
536  m_exprdata->activateFlags(SAME_ELEMENT);
537 
538  // Computed value
539  T elVal;
540  m_value = _op::init();
541  m_elWise.clear();
542 
543  for (typename bcRefList::const_iterator iit = BCs.begin(); iit!= BCs.end(); ++iit)
544  {
545  const boundary_condition<T> * it = &iit->get();
546 
547  // Quadrature rule
548  QuRule = gsQuadrature::getPtr(m_exprdata->multiBasis().basis(it->patch()), m_options, it->side().direction());
549 
550  // Update boundary function source
551  m_exprdata->setMutSource(*it->function());
552 
553  // Initialize domain element iterator
554  typename gsBasis<T>::domainIter domIt =
555  m_exprdata->multiBasis().basis(it->patch()).makeDomainIterator(it->side());
556  m_exprdata->getElement().set(*domIt,quWeights);
557 
558  // Start iteration over elements
559  for (; domIt->good(); domIt->next() )
560  {
561  // Map the Quadrature rule to the element
562  QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
563  m_exprdata->points(), quWeights);
564 
565  if (m_exprdata->points().cols()==0)
566  continue;
567 
568  // Perform required pre-computations on the quadrature nodes
569  m_exprdata->precompute(it->patch(), it->side() );
570 
571  // Compute on element
572  elVal = _op::init();
573  for (index_t k = 0; k != quWeights.rows(); ++k) // loop over quadrature nodes
574  _op::acc(_arg.eval(k), quWeights[k], elVal);
575 
576  _op::acc(elVal, 1, m_value);
577  //if ( storeElWise ) m_elWise.push_back( elVal );
578  }
579  }
580 
581  return m_value;
582 }
583 
584 template<class T>
585 template<class E, class _op>
586 T gsExprEvaluator<T>::computeInterface_impl(const expr::_expr<E> & expr, const intContainer & iFaces)
587 {
588  auto arg_tpl = expr.val();
589  m_exprdata->parse(arg_tpl);
590  // m_exprdata->activateFlags(SAME_ELEMENT);
591 
592  typename gsQuadRule<T>::uPtr QuRule;
593  gsVector<T> quWeights; // quadrature weights
594 
595  // Computed value
596  T elVal;
597  m_value = _op::init();
598  //if ( storeElWise )
599  m_elWise.reserve(m_exprdata->multiBasis().topology().nInterfaces());
600  m_elWise.clear();
601 
602  ifacemap interfaceMap;
603  for (typename gsBoxTopology::const_iiterator iit =
604  iFaces.begin(); iit != iFaces.end(); ++iit)
605  {
606  const boundaryInterface & iFace = *iit;
607  const index_t patch1 = iFace.first().patch;
608  const index_t patch2 = iFace.second().patch;
609 
610  if (iFace.type() == interaction::conforming)
611  interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
612  m_exprdata->multiBasis().basis(patch1).support(),
613  m_exprdata->multiBasis().basis(patch2).support() );
614  else
615  interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
616 
617  //gsRemapInterface<T> interfaceMap(m_exprdata->multiPatch(),
618  // m_exprdata->multiBasis(),
619  // *iit);//,opt
620 
621  // Quadrature rule
622  QuRule = gsQuadrature::getPtr(m_exprdata->multiBasis().basis(patch1),
623  m_options, iFace.first().side().direction());
624 
625  // Initialize domain element iterator
626  typename gsBasis<T>::domainIter domIt =
627  //interfaceMap.makeDomainIterator();
628  m_exprdata->multiBasis().piece(patch1).makeDomainIterator(iFace.first().side());
629  m_exprdata->getElement().set(*domIt,quWeights);
630 
631  // Start iteration over elements
632  elVal = _op::init();
633  for (; domIt->good(); domIt->next() )
634  {
635  // Map the Quadrature rule to the element
636  QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
637  m_exprdata->points(), quWeights);
638  interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
639 
640  // Perform required pre-computations on the quadrature nodes
641  m_exprdata->precompute(iFace);
642 
643  // Compute on element
644  for (index_t k = 0; k != quWeights.rows(); ++k) // loop over qu-nodes
645  {
646  _op::acc(arg_tpl.eval(k), quWeights[k], elVal);
647  }
648  }
649  _op::acc(elVal, 1, m_value);
650  //if ( storeElWise )
651  m_elWise.push_back( elVal );
652  }
653 
654  return m_value;
655 }
656 
657 
658 template<class T>
659 template<class E, int mode, short_t d>
660 typename util::enable_if<E::ScalarValued,void>::type
661 gsExprEvaluator<T>::eval(const expr::_expr<E> & expr,
662  gsGridIterator<T,mode,d> & git,
663  const index_t patchInd)
664 { // to remove
665  // bug: fails due to gsFeVariable::rows() before evaluation
666  // GISMO_ASSERT( expr.isScalar(), "Expecting scalar");
667 
668  auto _arg = expr.val();
669  m_exprdata->parse(_arg);
670  m_elWise.clear();
671  m_elWise.reserve(git.numPoints());
672 
673  for( git.reset(); git; ++git )
674  {
675  m_exprdata->points() = *git;
676  m_exprdata->precompute(patchInd);
677  m_elWise.push_back( _arg.eval(0) );
678 
679  // equivalent:
680  //m_elWise.push_back( m_exprdata->eval(expr).value() );
681 
682  }
683  m_value = m_elWise.back(); // not used
684 }
685 
686 template<class T>
687 template<class E, int mode, short_t d>
688 typename util::enable_if<!E::ScalarValued,void>::type
689 gsExprEvaluator<T>::eval(const expr::_expr<E> & expr,
690  gsGridIterator<T,mode,d> & git,
691  const index_t patchInd)
692 {
693  // bug: fails due to gsFeVariable::rows() before evaluation
694  // GISMO_ASSERT( expr.isScalar(), "Expecting scalar");
695 
696  m_exprdata->parse(expr);
697  m_elWise.clear();
698  m_elWise.reserve(git.numPoints());
699  gsMatrix<T> tmp;
700  for( git.reset(); git; ++git )
701  {
702  m_exprdata->points() = *git; // ..
703  m_exprdata->precompute(patchInd);
704  // m_exprdata->eval_into(expr, tmp);
705  tmp = expr.eval(0);
706  m_elWise.insert(m_elWise.end(), tmp.data(), tmp.data()+tmp.size());
707  }
708  m_value = 0; // not used
709 }
710 
711 
712 template<class T>
713 template<class E>
714 typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
715 gsExprEvaluator<T>::eval(const expr::_expr<E> & expr, const gsVector<T> & pt,
716  const index_t patchInd)
717 {
718  auto _arg = expr.val();
719  m_exprdata->parse(_arg);
720  m_elWise.clear();
721  m_exprdata->points() = pt;
722  m_exprdata->precompute(patchInd);
723 
724  // expr.printDetail(gsInfo); //
725 
726  m_value = _arg.eval(0);
727  return gsAsConstMatrix<T>(&m_value,1,1);
728 }
729 
730 template<class T>
731 template<class E>
732 typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
733 gsExprEvaluator<T>::eval(const expr::_expr<E> & expr, const gsVector<T> & pt,
734  const index_t patchInd)
735 {
736  m_exprdata->parse(expr);
737  m_exprdata->points() = pt;
738  m_exprdata->precompute(patchInd);
739 
740  // expr.printDetail(gsInfo); //after precompute
741 
742  gsMatrix<T> tmp = expr.eval(0);
743  // const index_t r = expr.rows();
744  // const index_t c = expr.cols();
745  // gsInfo <<"tmp - "<< tmp.dim() <<" rc - "<< r <<", "<<c<<"\n";
746  const index_t r = tmp.rows();
747  const index_t c = tmp.cols();
748  m_elWise.resize(r*c);
749  gsAsMatrix<T>(m_elWise, r, c) = tmp; //expr.eval(0);
750  return gsAsConstMatrix<T>(m_elWise, r, c);
751 }
752 
753 // template<class T>
754 // template<class E, bool gmap>
755 // void gsExprEvaluator<T>::writeParaview_impl(const expr::_expr<E> & expr,
756 // geometryMap G,
757 // std::string const & fn)
758 // {
759 // m_exprdata->parse(expr);
760 
761 // //if false, embed topology ?
762 // const index_t n = m_exprdata->multiBasis().nBases();
763 // gsParaviewCollection collection(fn);
764 // std::string fileName;
765 
766 // gsMatrix<T> pts, vals, ab;
767 
768 // const bool mesh = m_options.askSwitch("plot.elements");
769 
770 // for ( index_t i=0; i != n; ++i )
771 // {
772 // fileName = fn + util::to_string(i);
773 // unsigned nPts = m_options.askInt("plot.npts", 1000);
774 // ab = m_exprdata->multiBasis().piece(i).support();
775 // gsGridIterator<T,CUBE> pt(ab, nPts);
776 // eval(expr, pt, i);
777 // nPts = pt.numPoints();
778 // vals = allValues(m_elWise.size()/nPts, nPts);
779 
780 // if (gmap) // Forward the points ?
781 // {
782 // eval(G, pt, i);
783 // pts = allValues(m_elWise.size()/nPts, nPts);
784 // }
785 
786 // gsWriteParaviewTPgrid( gmap ? pts : pt.toMatrix(), // parameters
787 // vals,
788 // pt.numPointsCwise(), fileName );
789 // collection.addPart(fileName + ".vts");
790 
791 // if ( mesh )
792 // {
793 // fileName+= "_mesh";
794 // gsMesh<T> msh(m_exprdata->multiBasis().basis(i), 2);
795 // static_cast<const gsGeometry<T>&>(G.source().piece(i)).evaluateMesh(msh);
796 // gsWriteParaview(msh, fileName, false);
797 // collection.addPart(fileName+ ".vtp");
798 // }
799 // }
800 // collection.save();
801 // }
802 
803 
804 
805 // This is a copy of the above (commented out ) function, which has parts
806 // of gsParaviewCollection pasted in it. In this way the inclusion of
807 // gsParaviewCollection.h is prevented. This is a temporary modification.
808 template<class T>
809 template<class E>
810 typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
811 gsExprEvaluator<T>::evalIfc(const expr::_expr<E> & expr, const gsVector<T> & pt,
812  const boundaryInterface & ifc)
813 {
814  auto _arg = expr.val();
815  m_exprdata->parse(_arg);
816  m_elWise.clear();
817 
818  const bool flipSide = m_options.askSwitch("flipSide", false);
819  const boundaryInterface & iFace = flipSide ? ifc.getInverse() : ifc;
820 
821  const index_t patch1 = iFace.first().patch;
822  const index_t patch2 = iFace.second().patch;
823 
824  ifacemap interfaceMap;
825  if (iFace.type() == interaction::conforming)
826  interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
827  m_exprdata->multiBasis().basis(patch1).support(),
828  m_exprdata->multiBasis().basis(patch2).support() );
829  else
830  interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
831 
832  m_exprdata->points() = pt;
833  interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
834  m_exprdata->precompute(iFace);
835 
836  // expr.printDetail(gsInfo); //
837 
838  m_value = _arg.eval(0);
839  return gsAsConstMatrix<T>(&m_value,1,1);
840 }
841 
842 template<class T>
843 template<class E>
844 typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
845 gsExprEvaluator<T>::evalIfc(const expr::_expr<E> & expr, const gsVector<T> & pt,
846  const boundaryInterface & ifc)
847 {
848  m_exprdata->parse(expr);
849 
850  const bool flipSide = m_options.askSwitch("flipSide", false);
851  const boundaryInterface & iFace = flipSide ? ifc.getInverse() : ifc;
852 
853  const index_t patch1 = iFace.first().patch;
854  const index_t patch2 = iFace.second().patch;
855 
856  ifacemap interfaceMap;
857  if (iFace.type() == interaction::conforming)
858  interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
859  m_exprdata->multiBasis().basis(patch1).support(),
860  m_exprdata->multiBasis().basis(patch2).support() );
861  else
862  interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
863 
864  m_exprdata->points() = pt;
865  interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
866 
867  m_exprdata->precompute(iFace);
868 
869  // expr.printDetail(gsInfo); //after precompute
870 
871  gsMatrix<T> tmp = expr.eval(0);
872  // const index_t r = expr.rows();
873  // const index_t c = expr.cols();
874  // gsInfo <<"tmp - "<< tmp.dim() <<" rc - "<< r <<", "<<c<<"\n";
875  const index_t r = tmp.rows();
876  const index_t c = tmp.cols();
877  m_elWise.resize(r*c);
878  gsAsMatrix<T>(m_elWise, r, c) = tmp; //expr.eval(0);
879  return gsAsConstMatrix<T>(m_elWise, r, c);
880 }
881 
882 
883 template<class T>
884 template<class E, bool gmap>
885 void gsExprEvaluator<T>::writeParaview_impl(const expr::_expr<E> & expr,
886  geometryMap G,
887  std::string const & fn)
888  {
889  //if gmap is false, embed topology ?
890  m_exprdata->parse(expr);
891 
892  //if false, embed topology ?
893  const index_t n = m_exprdata->multiBasis().nBases();
894 
895  // Snippet from gsParaviewCollection
896  // gsParaviewCollection collection(fn);
897  std::stringstream file;
898  int counter = 0;
899  file <<"<?xml version=\"1.0\"?>\n";
900  file <<"<VTKFile type=\"Collection\" version=\"0.1\">";
901  file <<"<Collection>\n";
902  // End snippet from gsParaviewCollection
903 
904  //const index_t n = G.source().nPieces();
905  //gsParaviewCollection collection(fn);
906 
907  std::string fileName;
908 
909  gsMatrix<T> pts, vals, ab;
910 
911  const bool mesh = m_options.askSwitch("plot.elements");
912 
913  for ( index_t i=0; i != n; ++i )
914  {
915  fileName = fn + util::to_string(i);
916  unsigned nPts = m_options.askInt("plot.npts", 1000);
917  //ab = m_exprdata->multiBasis().piece(i).support();
918  ab = G.source().piece(i).support();
919  gsGridIterator<T,CUBE> pt(ab, nPts);
920  eval(expr, pt, i);
921  nPts = pt.numPoints();
922  vals = allValues(m_elWise.size()/nPts, nPts);
923 
924  if (gmap) // Forward the points ?
925  {
926  eval(G, pt, i);
927  pts = allValues(m_elWise.size()/nPts, nPts);
928  }
929 
930  gsWriteParaviewTPgrid( gmap ? pts : pt.toMatrix(), // parameters
931  vals,
932  pt.numPointsCwise(), fileName );
933 
934  // Snippet from gsParaviewCollection
935  // collection.addPart(fileName+ ".vts");
936  GISMO_ASSERT(counter!=-1, "Error: collection has been already saved." );
937  file << "<DataSet part=\""<< counter++ <<"\" file=\""<<fileName<<".vts"<<"\"/>\n";
938  // End snippet from gsParaviewCollection
939 
940  if ( mesh )
941  {
942  gsMesh<T> msh(m_exprdata->multiBasis().basis(i), 2);
943  static_cast<const gsGeometry<T>&>(G.source().piece(i)).evaluateMesh(msh);
944  gsWriteParaview(msh, fileName + "_mesh", false);
945  // Snippet from gsParaviewCollection
946  // collection.addPart(fileName+ ".vtp");
947  GISMO_ASSERT(counter!=-1, "Error: collection has been already saved." );
948  file << "<DataSet part=\""<< counter++ <<"\" file=\""<<fileName<<"_mesh.vtp"<<"\"/>\n";
949  // End snippet from gsParaviewCollection
950  }
951  }
952 
953  // Snippet from gsParaviewCollection
954  // collection.save();
955  GISMO_ASSERT(counter!=-1, "Error: gsParaviewCollection::save() already called." );
956  file <<"</Collection>\n";
957  file <<"</VTKFile>\n";
958 
959  std::string mfn = fn + ".pvd";
960  gsInfo << mfn << "\n";
961  std::ofstream f( mfn.c_str() );
962  GISMO_ASSERT(f.is_open(), "Error creating "<< mfn );
963  f << file.rdbuf();
964  f.close();
965  file.str("");
966  counter = -1;
967  // End snippet from gsParaviewCollection
968  }
969 
970 } //namespace gismo
T integralBdr(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:169
Provides a mapping between the corresponding sides of two patches sharing an interface.
function_ptr function() const
Returns the function data pointer of the boundary condition.
Definition: gsBoundaryConditions.h:254
T integral(const expr::_expr< E > &expr)
Calculates the integral of the expression expr on the whole integration domain.
Definition: gsExprEvaluator.h:154
Definition: gsExprAssembler.h:30
Class representing a reference quadrature rule.
Definition: gsQuadRule.h:28
#define GISMO_NO_IMPLEMENTATION
Definition: gsDebug.h:129
Definition: gsExpressions.h:96
void setIntegrationElements(const gsMultiBasis< T > &mesh)
Sets the domain of integration.
Definition: gsExprEvaluator.h:110
Provides a mapping between the corresponding sides of two patches sharing an interface, by means of a Closest Point Projection.
std::string to_string(const C &value)
Converts value to string, assuming &quot;operator&lt;&lt;&quot; defined on C.
Definition: gsUtils.h:56
boxSide side() const
Returns the side to which this boundary condition refers to.
Definition: gsBoundaryConditions.h:269
#define index_t
Definition: gsConfig.h:32
static gsQuadRule< T >::uPtr getPtr(const gsBasis< T > &basis, const gsOptionList &options, short_t fixDir=-1)
Constructs a quadrature rule based on input options.
Definition: gsQuadrature.h:61
const std::vector< T > & elementwise() const
Returns an std::vector containing the last computed values per element.
Definition: gsExprEvaluator.h:99
const gsBasis< T > & piece(const index_t k) const
Returns the piece(s) of the function(s) at subdomain k.
Definition: gsBasis.h:106
T maxInterface(const expr::_expr< E > &expr, const intContainer &iFaces)
Definition: gsExprEvaluator.h:219
T computeBdr_impl(const expr::_expr< E > &expr, const bContainer &bdrlist)
Definition: gsExprEvaluator.h:462
memory::unique_ptr< gsFunction > uPtr
Unique pointer for gsFunction.
Definition: gsFunction.h:68
T integralElWise(const expr::_expr< E > &expr)
Calculates the integral of the expression expr on each element.
Definition: gsExprEvaluator.h:159
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
index_t patch() const
Returns the patch to which this boundary condition refers to.
Definition: gsBoundaryConditions.h:266
T integralInterface(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:188
variable getVariable(const gsFunctionSet< T > &func, index_t dim=1)
Registers func as a variable and returns a handle to it.
Definition: gsExprEvaluator.h:124
T maxElWise(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:207
void addInt(const std::string &label, const std::string &desc, const index_t &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:201
static gsQuadRule< T > get(const gsBasis< T > &basis, const gsOptionList &options, short_t fixDir=-1)
Constructs a quadrature rule based on input options.
Definition: gsQuadrature.h:48
Creates a mapped object or data pointer to a vector without copying data.
Definition: gsLinearAlgebra.h:129
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
T minInterface(const expr::_expr< E > &expr, const intContainer &iFaces)
Definition: gsExprEvaluator.h:231
void testEval(const expr::_expr< E > &expr, const gsVector< T > &pt, const index_t patchInd=0)
Definition: gsExprEvaluator.h:297
element getElement()
Returns a handle to an isogeometric element.
Definition: gsExprEvaluator.h:132
T integralInterface(const expr::_expr< E > &expr, const intContainer &iFaces)
Definition: gsExprEvaluator.h:195
expr::gsComposition< T > getVariable(const gsFunctionSet< T > &func, geometryMap G)
Registers func as a variable defined on G and returns a handle to it.
Definition: gsExprEvaluator.h:128
#define gsInfo
Definition: gsDebug.h:43
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition: gsFuncData.h:23
void eval(const expr::_expr< E > &expr, gsGridIterator< T, mode, d > &git, const index_t patchInd=0)
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
Generic evaluator of isogeometric expressions.
Definition: gsExprEvaluator.h:38
T min(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:237
Creates a mapped object or data pointer to a const matrix without copying data.
Definition: gsLinearAlgebra.h:127
T integralBdr(const expr::_expr< E > &expr, const bContainer &bdrlist)
Definition: gsExprEvaluator.h:176
Creates a variety of quadrature rules.
T integralBdrBc(const bcRefList &BCs, const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:182
virtual void mapTo(const gsVector< T > &lower, const gsVector< T > &upper, gsMatrix< T > &nodes, gsVector< T > &weights) const
Maps quadrature rule (i.e., points and weights) from the reference domain to an element.
Definition: gsQuadRule.h:177
gsAsConstMatrix< T > allValues(index_t nR, index_t nC) const
Returns the last computed values per element, resized as a matrix.
Definition: gsExprEvaluator.h:105
Enable optimizations based on the assumption that all evaluation points are in the same bezier domain...
Definition: gsForwardDeclarations.h:89
Class that defines a boundary condition for a side of a patch for some unknown variable of a PDE...
Definition: gsBoundaryConditions.h:106
T minInterface(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:225
T max(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:201
geometryMap getMap(const gsFunctionSet< T > &gm)
Registers g as an isogeometric geometry map and return a handle to it.
Definition: gsExprEvaluator.h:120
void addReal(const std::string &label, const std::string &desc, const Real &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:211
gsAsConstVector< T > allValues() const
Returns a vector containing the last computed values per element.
Definition: gsExprEvaluator.h:102
T maxInterface(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:213
void calcSqrt()
Calculates the square root of the lastly computed quantities (eg. integrals)
Definition: gsExprEvaluator.h:135
Creates a mapped object or data pointer to a const vector without copying data.
Definition: gsLinearAlgebra.h:130
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
size_t nValues() const
The number of lastly computed values.
Definition: gsExprEvaluator.h:96
Class which holds a list of parameters/options, and provides easy access to them. ...
Definition: gsOptionList.h:32
T minElWise(const expr::_expr< E > &expr)
Definition: gsExprEvaluator.h:243
void writeParaview(const expr::_expr< E > &expr, geometryMap G, std::string const &fn)
Creates a paraview file named fn containing valies of the.
Definition: gsExprEvaluator.h:323
void writeParaview(const expr::_expr< E > &expr, std::string const &fn)
Creates a paraview file named fn containing valies of the.
Definition: gsExprEvaluator.h:332
void addSwitch(const std::string &label, const std::string &desc, const bool &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:235
geometryMap getMap(const gsMultiPatch< T > &mp)
Registers mp as an isogeometric geometry map and return a handle to it.
Definition: gsExprEvaluator.h:116
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
Definition: gsExpressions.h:114
T value() const
Returns the last computed value.
Definition: gsExprEvaluator.h:93
void calcRoot(const index_t p)
Calculates the p-th root of the lastly computed quantities (eg. integrals)
Definition: gsExprEvaluator.h:143