G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
23namespace gismo
24{
25
37template<class T>
39{
40private:
41 typename gsExprHelper<T>::Ptr m_exprdata;
42
43private:
44 std::vector<T> m_elWise;
45 T m_value;
46
47 gsOptionList m_options;
48
49public:
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
61public:
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
90public:
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
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
150public:
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
294 template<class E>
295#ifdef __DOXYGEN__
297#else
298 typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
299#endif
300 evalBdr(const expr::_expr<E> & testExpr, const gsVector<T> & pt,
301 const patchSide & ps);
302
303 template<class E>
304 typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
305 evalBdr(const expr::_expr<E> & testExpr, const gsVector<T> & pt,
306 const patchSide & ps);
307
310 template<class E> void
311 testEval(const expr::_expr<E> & expr,
312 const gsVector<T> & pt, const index_t patchInd = 0)
313 {
314 expr.print(gsInfo);
315 gsInfo << "Result:\n"<< eval(expr,pt,patchInd) <<"\n";
316 }
317
318 void info() const { m_exprdata->print(); }
319
320 // Interpolates the expression \a expr over the isogeometric domain \a G
321 template<class E> void interpolate(const expr::_expr<E> &)
322 {
324 // for all patches
325 // get anchors of patch
326 // evaluate expr
327 // solve system
328 // add to multipatch
329 // return multipatch
330 }
331
333 //( expression \a expr over the isogeometric domain \a G.
336 // template<class E>
337 // void writeParaview(const expr::_expr<E> & expr, const gsMatrix<T> & uv,
338 // geometryMap G, std::string const & fn)
339 // { writeParaview_impl<E,true>(expr,uv,G,fn); }
340
341 template<class E>
342 void writeParaview(const expr::_expr<E> & expr,
343 geometryMap G, std::string const & fn)
344 { writeParaview_impl<E,true>(expr,G,fn); }
345
347 //( expression \a expr over the parametric domain.
350 template<class E>
351 void writeParaview(const expr::_expr<E> & expr,
352 std::string const & fn)
353 { writeParaview_impl<E,false>(expr,m_exprdata->getMap(),fn); }
354
355private:
356
357 template<class E, bool gmap>
358 void writeParaview_impl(const expr::_expr<E> & expr,
359 geometryMap G, std::string const & fn);
360
361
362
363 template<class E, bool storeElWise, class _op>
364 T compute_impl(const expr::_expr<E> & expr);
365
366 template<class E, class _op>
367 T computeBdr_impl(const expr::_expr<E> & expr, const bContainer & bdrlist);
368
369 template<class E, class _op>
370 T computeBdrBc_impl(const bcRefList & BCs, const expr::_expr<E> & expr);
371
372 template<class E, class _op>
373 T computeInterface_impl(const expr::_expr<E> & expr, const intContainer & iFaces);
374
375 template<class E>
376 void computeGrid_impl(const expr::_expr<E> & expr, const index_t patchInd);
377
378 struct plus_op
379 {
380 static inline T init() { return 0; }
381 static inline void acc(const T contrib, const T w, T & res)
382 { res += w * contrib; }
383
384 static inline void acc_global(const T contrib, T & res)
385 {
386# pragma omp atomic update
387 res += contrib;
388 }
389 };
390 struct min_op
391 {
392 static inline T init() { return math::limits::max(); }
393 static inline void acc (const T contrib, const T, T & res)
394 {res = math::min(contrib, res); }
395 static inline void acc_global(const T contrib, T & res)
396 {
397# pragma omp atomic write
398 res = math::min(contrib, res);
399 }
400
401 };
402 struct max_op
403 {
404 static inline T init() { return math::limits::min(); }
405 static inline void acc (const T contrib, const T, T & res)
406 { res = math::max(contrib, res); }
407 static inline void acc_global(const T contrib, T & res)
408 {
409# pragma omp atomic write
410 res = math::max(contrib, res);
411 }
412 };
413
414};
415
416template<class T>
417template<class E, bool storeElWise, class _op>
418T gsExprEvaluator<T>::compute_impl(const expr::_expr<E> & expr)
419{
420 m_value = _op::init();
421 m_elWise.clear();
422 if ( storeElWise )
423 m_elWise.resize(m_exprdata->multiBasis().totalElements());
424
425#pragma omp parallel
426{
427#ifdef _OPENMP
428 const int tid = omp_get_thread_num();
429 const int nt = omp_get_num_threads();
430 T thValue = _op::init();
431#endif
432 gsQuadRule<T> QuRule; // Quadrature rule
433 auto _arg = expr.val();
434 m_exprdata->parse(_arg);
435 m_exprdata->activateFlags(SAME_ELEMENT);
436
437 // Computed value on element
438 T elVal;
439 index_t poffset = 0;
440 typename gsBasis<T>::domainIter domIt;
441 for (unsigned patchInd=0; patchInd < m_exprdata->multiBasis().nBases(); ++patchInd)
442 {
443 // Quadrature rule
444 QuRule = gsQuadrature::get(m_exprdata->multiBasis().basis(patchInd), m_options);
445
446 // Initialize domain element iterator
447 domIt = m_exprdata->multiBasis().piece(patchInd).makeDomainIterator();
448#ifdef _OPENMP
449 for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
450#else
451 for (; domIt->good(); domIt->next() )
452#endif
453 {
454 // Map the Quadrature rule to the element
455 QuRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(),
456 m_exprdata->points(), m_exprdata->weights());
457
458 // Perform required pre-computations on the quadrature nodes
459 m_exprdata->precompute(patchInd);
460
461 // Compute on element
462 elVal = _op::init();
463 for (index_t k = 0; k != m_exprdata->weights().rows(); ++k) // loop over quad. nodes
464 _op::acc(_arg.eval(k), m_exprdata->weights()[k], elVal);
465 _op::acc(elVal, (T)1,
466#ifdef _OPENMP
467 thValue);
468#else
469 m_value);
470#endif
471 if ( storeElWise )
472 {
473 m_elWise[poffset+domIt->id()] = elVal;
474 }
475 }
476 poffset += m_exprdata->multiBasis().basis(patchInd).numElements();
477 }
478#ifdef _OPENMP
479 _op::acc_global(thValue, m_value);
480#endif
481}//omp parallel
482 return m_value;
483}
484
485template<class T>
486template<class E, class _op>
487T gsExprEvaluator<T>::computeBdr_impl(const expr::_expr<E> & expr,
488 const bContainer & bdrlist)
489{
490 // GISMO_ASSERT( expr.isScalar(),
491 // "Expecting scalar expression instead of "
492 // <<expr.cols()<<" x "<<expr.rows() );
493
494 //expr.print(gsInfo);
495
496 gsQuadRule<T> QuRule; // Quadrature rule
497 auto _arg = expr.val();
498 m_exprdata->parse(_arg);
499 m_exprdata->activateFlags(SAME_ELEMENT);
500
501 // Computed value
502 T elVal;
503 m_value = _op::init();
504 m_elWise.clear();
505 for (typename gsBoxTopology::const_biterator bit =
506 bdrlist.begin(); bit != bdrlist.end(); ++bit)
507 {
508 // Quadrature rule
509 QuRule = gsQuadrature::get(m_exprdata->multiBasis().basis(bit->patch), m_options,bit->direction());
510
511 // Initialize domain element iterator
512 typename gsBasis<T>::domainIter domIt =
513 m_exprdata->multiBasis().piece(bit->patch).makeDomainIterator(bit->side());
514
515 // Start iteration over elements
516 for (; domIt->good(); domIt->next() )
517 {
518 // Map the Quadrature rule to the element
519 QuRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(),
520 m_exprdata->points(), m_exprdata->weights());
521
522 // Perform required pre-computations on the quadrature nodes
523 m_exprdata->precompute(bit->patch, bit->side() );
524
525 // Compute on element
526 elVal = _op::init();
527 for (index_t k = 0; k != m_exprdata->weights().rows(); ++k) // loop over quadrature nodes
528 _op::acc(_arg.eval(k), m_exprdata->weights()[k], elVal);
529
530 _op::acc(elVal, 1, m_value);
531 //if ( storeElWise ) m_elWise.push_back( elVal );
532 }
533 }
534
535 return m_value;
536}
537
538template<class T>
539template<class E, class _op>
540T gsExprEvaluator<T>::computeBdrBc_impl(const bcRefList & BCs,
541 const expr::_expr<E> & expr)
542{
543 // GISMO_ASSERT( expr.isScalar(),
544 // "Expecting scalar expression instead of "
545 // <<expr.cols()<<" x "<<expr.rows() );
546
547 //expr.print(gsInfo);
548
549 if ( BCs.empty() ) return 0;
550 m_exprdata->setMutSource(*BCs.front().get().function()); //initialize once
551
552 typename gsQuadRule<T>::uPtr QuRule; // Quadrature rule ---->OUT
553 auto _arg = expr.val();
554 m_exprdata->parse(_arg);
555 m_exprdata->activateFlags(SAME_ELEMENT);
556
557 // Computed value
558 T elVal;
559 m_value = _op::init();
560 m_elWise.clear();
561
562 for (typename bcRefList::const_iterator iit = BCs.begin(); iit!= BCs.end(); ++iit)
563 {
564 const boundary_condition<T> * it = &iit->get();
565
566 // Quadrature rule
567 QuRule = gsQuadrature::getPtr(m_exprdata->multiBasis().basis(it->patch()), m_options, it->side().direction());
568
569 // Update boundary function source
570 m_exprdata->setMutSource(*it->function());
571
572 // Initialize domain element iterator
573 typename gsBasis<T>::domainIter domIt =
574 m_exprdata->multiBasis().basis(it->patch()).makeDomainIterator(it->side());
575
576 // Start iteration over elements
577 for (; domIt->good(); domIt->next() )
578 {
579 // Map the Quadrature rule to the element
580 QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
581 m_exprdata->points(), m_exprdata->weights());
582
583 if (m_exprdata->points().cols()==0)
584 continue;
585
586 // Perform required pre-computations on the quadrature nodes
587 m_exprdata->precompute(it->patch(), it->side() );
588
589 // Compute on element
590 elVal = _op::init();
591 for (index_t k = 0; k != m_exprdata->weights().rows(); ++k) // loop over quadrature nodes
592 _op::acc(_arg.eval(k), m_exprdata->weights()[k], elVal);
593
594 _op::acc(elVal, 1, m_value);
595 //if ( storeElWise ) m_elWise.push_back( elVal );
596 }
597 }
598
599 return m_value;
600}
601
602template<class T>
603template<class E, class _op>
604T gsExprEvaluator<T>::computeInterface_impl(const expr::_expr<E> & expr, const intContainer & iFaces)
605{
606 auto arg_tpl = expr.val();
607 m_exprdata->parse(arg_tpl);
608 // m_exprdata->activateFlags(SAME_ELEMENT);
609
610 typename gsQuadRule<T>::uPtr QuRule;
611 // Computed value
612 T elVal;
613 m_value = _op::init();
614 //if ( storeElWise )
615 m_elWise.reserve(m_exprdata->multiBasis().topology().nInterfaces());
616 m_elWise.clear();
617
618 ifacemap interfaceMap;
619 for (typename gsBoxTopology::const_iiterator iit =
620 iFaces.begin(); iit != iFaces.end(); ++iit)
621 {
622 const boundaryInterface & iFace = *iit;
623 const index_t patch1 = iFace.first().patch;
624 const index_t patch2 = iFace.second().patch;
625
626 if (iFace.type() == interaction::conforming)
627 interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
628 m_exprdata->multiBasis().basis(patch1).support(),
629 m_exprdata->multiBasis().basis(patch2).support() );
630 else
631 interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
632
633 //gsRemapInterface<T> interfaceMap(m_exprdata->multiPatch(),
634 // m_exprdata->multiBasis(),
635 // *iit);//,opt
636
637 // Quadrature rule
638 QuRule = gsQuadrature::getPtr(m_exprdata->multiBasis().basis(patch1),
639 m_options, iFace.first().side().direction());
640
641 // Initialize domain element iterator
642 typename gsBasis<T>::domainIter domIt =
643 //interfaceMap.makeDomainIterator();
644 m_exprdata->multiBasis().piece(patch1).makeDomainIterator(iFace.first().side());
645
646 // Start iteration over elements
647 elVal = _op::init();
648 for (; domIt->good(); domIt->next() )
649 {
650 // Map the Quadrature rule to the element
651 QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
652 m_exprdata->points(), m_exprdata->weights());
653 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
654
655 // Perform required pre-computations on the quadrature nodes
656 m_exprdata->precompute(iFace);
657
658 // Compute on element
659 for (index_t k = 0; k != m_exprdata->weights().rows(); ++k) // loop over qu-nodes
660 {
661 _op::acc(arg_tpl.eval(k), m_exprdata->weights()[k], elVal);
662 }
663 }
664 _op::acc(elVal, 1, m_value);
665 //if ( storeElWise )
666 m_elWise.push_back( elVal );
667 }
668
669 return m_value;
670}
671
672
673template<class T>
674template<class E, int mode, short_t d>
675typename util::enable_if<E::ScalarValued,void>::type
676gsExprEvaluator<T>::eval(const expr::_expr<E> & expr,
677 gsGridIterator<T,mode,d> & git,
678 const index_t patchInd)
679{ // to remove
680 // bug: fails due to gsFeVariable::rows() before evaluation
681 // GISMO_ASSERT( expr.isScalar(), "Expecting scalar");
682
683 auto _arg = expr.val();
684 m_exprdata->parse(_arg);
685 m_elWise.clear();
686 m_elWise.reserve(git.numPoints());
687
688 for( git.reset(); git; ++git )
689 {
690 m_exprdata->points() = *git;
691 m_exprdata->precompute(patchInd);
692 m_elWise.push_back( _arg.eval(0) );
693
694 // equivalent:
695 //m_elWise.push_back( m_exprdata->eval(expr).value() );
696
697 }
698 m_value = m_elWise.back(); // not used
699}
700
701template<class T>
702template<class E, int mode, short_t d>
703typename util::enable_if<!E::ScalarValued,void>::type
704gsExprEvaluator<T>::eval(const expr::_expr<E> & expr,
705 gsGridIterator<T,mode,d> & git,
706 const index_t patchInd)
707{
708 // bug: fails due to gsFeVariable::rows() before evaluation
709 // GISMO_ASSERT( expr.isScalar(), "Expecting scalar");
710
711 m_exprdata->parse(expr);
712 m_elWise.clear();
713 m_elWise.reserve(git.numPoints());
714 gsMatrix<T> tmp;
715 for( git.reset(); git; ++git )
716 {
717 m_exprdata->points() = *git; // ..
718 m_exprdata->precompute(patchInd);
719 // m_exprdata->eval_into(expr, tmp);
720 tmp = expr.eval(0);
721 m_elWise.insert(m_elWise.end(), tmp.data(), tmp.data()+tmp.size());
722 }
723 m_value = 0; // not used
724}
725
726
727template<class T>
728template<class E>
729typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
730gsExprEvaluator<T>::eval(const expr::_expr<E> & expr, const gsVector<T> & pt,
731 const index_t patchInd)
732{
733 auto _arg = expr.val();
734 m_exprdata->parse(_arg);
735 m_elWise.clear();
736 m_exprdata->points() = pt;
737 m_exprdata->precompute(patchInd);
738
739 // expr.printDetail(gsInfo); //
740
741 m_value = _arg.eval(0);
742 return gsAsConstMatrix<T>(&m_value,1,1);
743}
744
745template<class T>
746template<class E>
747typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
748gsExprEvaluator<T>::eval(const expr::_expr<E> & expr, const gsVector<T> & pt,
749 const index_t patchInd)
750{
751 m_exprdata->parse(expr);
752 m_exprdata->points() = pt;
753 m_exprdata->precompute(patchInd);
754
755 // expr.printDetail(gsInfo); //after precompute
756
757 gsMatrix<T> tmp = expr.eval(0);
758 // const index_t r = expr.rows();
759 // const index_t c = expr.cols();
760 // gsInfo <<"tmp - "<< tmp.dim() <<" rc - "<< r <<", "<<c<<"\n";
761 const index_t r = tmp.rows();
762 const index_t c = tmp.cols();
763 m_elWise.resize(r*c);
764 gsAsMatrix<T>(m_elWise, r, c) = tmp; //expr.eval(0);
765 return gsAsConstMatrix<T>(m_elWise, r, c);
766}
767
768// template<class T>
769// template<class E, bool gmap>
770// void gsExprEvaluator<T>::writeParaview_impl(const expr::_expr<E> & expr,
771// geometryMap G,
772// std::string const & fn)
773// {
774// m_exprdata->parse(expr);
775
776// //if false, embed topology ?
777// const index_t n = m_exprdata->multiBasis().nBases();
778// gsParaviewCollection collection(fn);
779// std::string fileName;
780
781// gsMatrix<T> pts, vals, ab;
782
783// const bool mesh = m_options.askSwitch("plot.elements");
784
785// for ( index_t i=0; i != n; ++i )
786// {
787// fileName = fn + util::to_string(i);
788// unsigned nPts = m_options.askInt("plot.npts", 1000);
789// ab = m_exprdata->multiBasis().piece(i).support();
790// gsGridIterator<T,CUBE> pt(ab, nPts);
791// eval(expr, pt, i);
792// nPts = pt.numPoints();
793// vals = allValues(m_elWise.size()/nPts, nPts);
794
795// if (gmap) // Forward the points ?
796// {
797// eval(G, pt, i);
798// pts = allValues(m_elWise.size()/nPts, nPts);
799// }
800
801// gsWriteParaviewTPgrid( gmap ? pts : pt.toMatrix(), // parameters
802// vals,
803// pt.numPointsCwise(), fileName );
804// collection.addPart(fileName + ".vts");
805
806// if ( mesh )
807// {
808// fileName+= "_mesh";
809// gsMesh<T> msh(m_exprdata->multiBasis().basis(i), 2);
810// static_cast<const gsGeometry<T>&>(G.source().piece(i)).evaluateMesh(msh);
811// gsWriteParaview(msh, fileName, false);
812// collection.addPart(fileName+ ".vtp");
813// }
814// }
815// collection.save();
816// }
817
818
819
820// This is a copy of the above (commented out ) function, which has parts
821// of gsParaviewCollection pasted in it. In this way the inclusion of
822// gsParaviewCollection.h is prevented. This is a temporary modification.
823template<class T>
824template<class E>
825typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
826gsExprEvaluator<T>::evalIfc(const expr::_expr<E> & expr, const gsVector<T> & pt,
827 const boundaryInterface & ifc)
828{
829 auto _arg = expr.val();
830 m_exprdata->parse(_arg);
831 m_elWise.clear();
832
833 const bool flipSide = m_options.askSwitch("flipSide", false);
834 const boundaryInterface & iFace = flipSide ? ifc.getInverse() : ifc;
835
836 const index_t patch1 = iFace.first().patch;
837 const index_t patch2 = iFace.second().patch;
838
839 ifacemap interfaceMap;
840 if (iFace.type() == interaction::conforming)
841 interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
842 m_exprdata->multiBasis().basis(patch1).support(),
843 m_exprdata->multiBasis().basis(patch2).support() );
844 else
845 interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
846
847 m_exprdata->points() = pt;
848 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
849 m_exprdata->precompute(iFace);
850
851 // expr.printDetail(gsInfo); //
852
853 m_value = _arg.eval(0);
854 return gsAsConstMatrix<T>(&m_value,1,1);
855}
856
857template<class T>
858template<class E>
859typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
860gsExprEvaluator<T>::evalIfc(const expr::_expr<E> & expr, const gsVector<T> & pt,
861 const boundaryInterface & ifc)
862{
863 m_exprdata->parse(expr);
864
865 const bool flipSide = m_options.askSwitch("flipSide", false);
866 const boundaryInterface & iFace = flipSide ? ifc.getInverse() : ifc;
867
868 const index_t patch1 = iFace.first().patch;
869 const index_t patch2 = iFace.second().patch;
870
871 ifacemap interfaceMap;
872 if (iFace.type() == interaction::conforming)
873 interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
874 m_exprdata->multiBasis().basis(patch1).support(),
875 m_exprdata->multiBasis().basis(patch2).support() );
876 else
877 interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
878
879 m_exprdata->points() = pt;
880 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
881
882 m_exprdata->precompute(iFace);
883
884 // expr.printDetail(gsInfo); //after precompute
885
886 gsMatrix<T> tmp = expr.eval(0);
887 // const index_t r = expr.rows();
888 // const index_t c = expr.cols();
889 // gsInfo <<"tmp - "<< tmp.dim() <<" rc - "<< r <<", "<<c<<"\n";
890 const index_t r = tmp.rows();
891 const index_t c = tmp.cols();
892 m_elWise.resize(r*c);
893 gsAsMatrix<T>(m_elWise, r, c) = tmp; //expr.eval(0);
894 return gsAsConstMatrix<T>(m_elWise, r, c);
895}
896
897// This is a copy of the above (commented out ) function, which has parts
898// of gsParaviewCollection pasted in it. In this way the inclusion of
899// gsParaviewCollection.h is prevented. This is a temporary modification.
900template<class T>
901template<class E>
902typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
903gsExprEvaluator<T>::evalBdr(const expr::_expr<E> & expr, const gsVector<T> & pt,
904 const patchSide & ps)
905{
906 GISMO_ASSERT(pt(ps.side().direction())==ps.side().parameter(),"Point "<<pt.transpose()<<" is not on boundary "<<ps.side());
907 auto _arg = expr.val();
908 m_exprdata->parse(_arg);
909 m_elWise.clear();
910
911 m_exprdata->points() = pt;
912 m_exprdata->precompute(ps.patch, ps.side());
913
914 m_value = _arg.eval(0);
915 return gsAsConstMatrix<T>(&m_value,1,1);
916}
917
918template<class T>
919template<class E>
920typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
921gsExprEvaluator<T>::evalBdr(const expr::_expr<E> & expr, const gsVector<T> & pt,
922 const patchSide & ps)
923{
924 GISMO_ASSERT(pt(ps.side().direction())==ps.side().parameter(),"Point "<<pt.transpose()<<" is not on boundary "<<ps.side());
925 m_exprdata->parse(expr);
926 m_exprdata->points() = pt;
927 m_exprdata->precompute(ps.patch, ps.side());
928
929 gsMatrix<T> tmp = expr.eval(0);
930 const index_t r = tmp.rows();
931 const index_t c = tmp.cols();
932 m_elWise.resize(r*c);
933 gsAsMatrix<T>(m_elWise, r, c) = tmp; //expr.eval(0);
934 return gsAsConstMatrix<T>(m_elWise, r, c);
935}
936
937template<class T>
938template<class E, bool gmap>
939void gsExprEvaluator<T>::writeParaview_impl(const expr::_expr<E> & expr,
940 geometryMap G,
941 std::string const & fn)
942 {
943 //if gmap is false, embed topology ?
944 m_exprdata->parse(expr);
945
946 //if false, embed topology ?
947 const index_t n = m_exprdata->multiBasis().nBases();
948
949 // Snippet from gsParaviewCollection
950 // gsParaviewCollection collection(fn);
951 std::stringstream file;
952 int counter = 0;
953 file <<"<?xml version=\"1.0\"?>\n";
954 file <<"<VTKFile type=\"Collection\" version=\"0.1\">";
955 file <<"<Collection>\n";
956 // End snippet from gsParaviewCollection
957
958 //const index_t n = G.source().nPieces();
959 //gsParaviewCollection collection(fn);
960
961 std::string fileName;
962
963 gsMatrix<T> pts, vals, ab;
964
965 const bool mesh = m_options.askSwitch("plot.elements");
966
967 for ( index_t i=0; i != n; ++i )
968 {
969 fileName = fn + util::to_string(i);
970 unsigned nPts = m_options.askInt("plot.npts", 1000);
971 //ab = m_exprdata->multiBasis().piece(i).support();
972 ab = G.source().piece(i).support();
973 gsGridIterator<T,CUBE> pt(ab, nPts);
974 eval(expr, pt, i);
975 nPts = pt.numPoints();
976 vals = allValues(m_elWise.size()/nPts, nPts);
977
978 if (gmap) // Forward the points ?
979 {
980 eval(G, pt, i);
981 pts = allValues(m_elWise.size()/nPts, nPts);
982 }
983
984 gsWriteParaviewTPgrid( gmap ? pts : pt.toMatrix(), // parameters
985 vals,
986 pt.numPointsCwise(), fileName );
987
988 // Snippet from gsParaviewCollection
989 // collection.addPart(fileName+ ".vts");
990 GISMO_ASSERT(counter!=-1, "Error: collection has been already saved." );
991 file << "<DataSet part=\""<< counter++ <<"\" file=\""<<fileName<<".vts"<<"\"/>\n";
992 // End snippet from gsParaviewCollection
993
994 if ( mesh )
995 {
996 gsMesh<T> msh(m_exprdata->multiBasis().basis(i), 2);
997 static_cast<const gsGeometry<T>&>(G.source().piece(i)).evaluateMesh(msh);
998 gsWriteParaview(msh, fileName + "_mesh", false);
999 // Snippet from gsParaviewCollection
1000 // collection.addPart(fileName+ ".vtp");
1001 GISMO_ASSERT(counter!=-1, "Error: collection has been already saved." );
1002 file << "<DataSet part=\""<< counter++ <<"\" file=\""<<fileName<<"_mesh.vtp"<<"\"/>\n";
1003 // End snippet from gsParaviewCollection
1004 }
1005 }
1006
1007 // Snippet from gsParaviewCollection
1008 // collection.save();
1009 GISMO_ASSERT(counter!=-1, "Error: gsParaviewCollection::save() already called." );
1010 file <<"</Collection>\n";
1011 file <<"</VTKFile>\n";
1012
1013 std::string mfn = fn + ".pvd";
1014 // gsInfo << mfn << "\n";
1015 std::ofstream f( mfn.c_str() );
1016 GISMO_ASSERT(f.is_open(), "Error creating "<< mfn );
1017 f << file.rdbuf();
1018 f.close();
1019 file.str("");
1020 counter = -1;
1021 // End snippet from gsParaviewCollection
1022 }
1023
1024} //namespace gismo
Definition gsExpressions.h:928
static uPtr make(const gsMatrix< T > mat, const gsVector< T > trans)
Affine maps are the composition of a linear map with a translation this constructor takes the two com...
Definition gsAffineFunction.h:75
Creates a mapped object or data pointer to a const matrix without copying data.
Definition gsAsMatrix.h:141
Creates a mapped object or data pointer to a const vector without copying data.
Definition gsAsMatrix.h:285
Creates a mapped object or data pointer to a vector without copying data.
Definition gsAsMatrix.h:239
Definition gsExprAssembler.h:33
Generic evaluator of isogeometric expressions.
Definition gsExprEvaluator.h:39
void testEval(const expr::_expr< E > &expr, const gsVector< T > &pt, const index_t patchInd=0)
Definition gsExprEvaluator.h:311
T integralInterface(const expr::_expr< E > &expr, const intContainer &iFaces)
Definition gsExprEvaluator.h:195
void calcSqrt()
Calculates the square root of the lastly computed quantities (eg. integrals)
Definition gsExprEvaluator.h:135
T minInterface(const expr::_expr< E > &expr, const intContainer &iFaces)
Definition gsExprEvaluator.h:231
void setIntegrationElements(const gsMultiBasis< T > &mesh)
Sets the domain of integration.
Definition gsExprEvaluator.h:110
T max(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:201
T integralBdr(const expr::_expr< E > &expr, const bContainer &bdrlist)
Definition gsExprEvaluator.h:176
gsAsConstVector< T > allValues() const
Returns a vector containing the last computed values per element.
Definition gsExprEvaluator.h:102
T integral(const expr::_expr< E > &expr)
Calculates the integral of the expression expr on the whole integration domain.
Definition gsExprEvaluator.h:154
const std::vector< T > & elementwise() const
Returns an std::vector containing the last computed values per element.
Definition gsExprEvaluator.h:99
void eval(const expr::_expr< E > &expr, gsGridIterator< T, mode, d > &git, const index_t patchInd=0)
T integralInterface(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:188
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:342
size_t nValues() const
The number of lastly computed values.
Definition gsExprEvaluator.h:96
T integralElWise(const expr::_expr< E > &expr)
Calculates the integral of the expression expr on each element.
Definition gsExprEvaluator.h:159
T minElWise(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:243
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
T maxInterface(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:213
T computeBdr_impl(const expr::_expr< E > &expr, const bContainer &bdrlist)
Definition gsExprEvaluator.h:487
T integralBdrBc(const bcRefList &BCs, const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:182
geometryMap getMap(const gsFunctionSet< T > &gm)
Registers g as an isogeometric geometry map and return a handle to it.
Definition gsExprEvaluator.h:120
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
T value() const
Returns the last computed value.
Definition gsExprEvaluator.h:93
T min(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:237
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 integralBdr(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:169
geometryMap getMap(const gsMultiPatch< T > &mp)
Registers mp as an isogeometric geometry map and return a handle to it.
Definition gsExprEvaluator.h:116
void writeParaview(const expr::_expr< E > &expr, std::string const &fn)
Creates a paraview file named fn containing valies of the.
Definition gsExprEvaluator.h:351
T maxElWise(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:207
void calcRoot(const index_t p)
Calculates the p-th root of the lastly computed quantities (eg. integrals)
Definition gsExprEvaluator.h:143
T maxInterface(const expr::_expr< E > &expr, const intContainer &iFaces)
Definition gsExprEvaluator.h:219
gsAsConstMatrix< T > eval(const expr::_expr< E > &testExpr, const gsVector< T > &pt, const index_t patchInd=0)
T minInterface(const expr::_expr< E > &expr)
Definition gsExprEvaluator.h:225
element getElement()
Returns a handle to an isogeometric element.
Definition gsExprEvaluator.h:132
Definition gsExprHelper.h:27
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition gsFunctionSet.h:219
memory::unique_ptr< gsFunction > uPtr
Unique pointer for gsFunction.
Definition gsFunction.h:68
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
Class which holds a list of parameters/options, and provides easy access to them.
Definition gsOptionList.h:33
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
bool askSwitch(const std::string &label, const bool &value=false) const
Reads value for option label from options.
Definition gsOptionList.cpp:128
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
index_t askInt(const std::string &label, const index_t &value=0) const
Reads value for option label from options.
Definition gsOptionList.cpp:117
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
Class representing a reference quadrature rule.
Definition gsQuadRule.h:29
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
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
std::string to_string(const C &value)
Converts value to string, assuming "operator<<" defined on C.
Definition gsUtils.h:56
Provides a mapping between the corresponding sides of two patches sharing an interface,...
#define index_t
Definition gsConfig.h:32
#define GISMO_NO_IMPLEMENTATION
Definition gsDebug.h:129
#define gsInfo
Definition gsDebug.h:43
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Creates a variety of quadrature rules.
Provides a mapping between the corresponding sides of two patches sharing an interface.
The G+Smo namespace, containing all definitions for the library.
@ SAME_ELEMENT
Enable optimizations based on the assumption that all evaluation points are in the same bezier domain...
Definition gsForwardDeclarations.h:89
Struct which represents an interface between two patches.
Definition gsBoundary.h:650
Class that defines a boundary condition for a side of a patch for some unknown variable of a PDE.
Definition gsBoundaryConditions.h:107
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:51
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:64
Struct which represents a certain side of a patch.
Definition gsBoundary.h:232