41 typename gsExprHelper<T>::Ptr m_exprdata;
44 std::vector<T> m_elWise;
50 typedef typename gsBoundaryConditions<T>::bcRefList bcRefList;
52 typedef std::vector< boundaryInterface > intContainer;
53 typedef std::vector< patchSide > bContainer;
55 typedef typename gsExprHelper<T>::element element;
56 typedef typename gsExprHelper<T>::geometryMap geometryMap;
64 m_options(defaultOptions()) { }
67 : m_exprdata(env), m_value(-1), m_options(defaultOptions())
73 : m_exprdata(o.exprData()), m_options(defaultOptions())
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);
93 T
value()
const {
return m_value; }
96 size_t nValues()
const {
return m_elWise.size(); }
99 const std::vector<T> &
elementwise()
const {
return m_elWise; }
111 { m_exprdata->setMultiBasis(mesh); }
113 const typename gsExprHelper<T>::Ptr exprData()
const {
return m_exprdata; }
117 {
return m_exprdata->getMap(mp); }
121 {
return m_exprdata->getMap(gm); }
125 {
return m_exprdata->getVar(func, dim); }
129 {
return m_exprdata->getVar(func, G); }
138 en.array() = en.array().sqrt();
139 m_value = math::sqrt(m_value);
146 en.array() = en.array().pow(
static_cast<T
>(1)/p);
147 m_value = math::pow(m_value,
static_cast<T
>(1)/p );
155 {
return compute_impl<E,false,plus_op>(expr); }
160 {
return compute_impl<E,true,plus_op>(expr); }
163 T
integral(
const T & val) {
return integral<T>(val); }
164 T
integralElWise(
const T & val) {
return integralElWise<T>(val); }
170 {
return computeBdr_impl<E,plus_op>(expr,
171 m_exprdata->multiBasis().topology().boundaries()); }
176 T
integralBdr(
const expr::_expr<E> & expr,
const bContainer & bdrlist)
177 {
return computeBdr_impl<E,plus_op>(expr,bdrlist); }
183 {
return computeBdrBc_impl<E,plus_op>(BCs,expr); }
189 {
return computeInterface_impl<E,plus_op>(expr,
190 m_exprdata->multiBasis().topology().interfaces()); }
196 {
return computeInterface_impl<E,plus_op>(expr, iFaces); }
201 T
max(
const expr::_expr<E> & expr)
202 {
return compute_impl<E,false,max_op>(expr); }
208 {
return compute_impl<E,true,max_op>(expr); }
214 {
return computeInterface_impl<E,max_op>(expr, m_exprdata->multiBasis().topology().interfaces()); }
219 T
maxInterface(
const expr::_expr<E> & expr,
const intContainer & iFaces)
220 {
return computeInterface_impl<E,max_op>(expr, iFaces); }
226 {
return computeInterface_impl<E,min_op>(expr, m_exprdata->multiBasis().topology().interfaces()); }
231 T
minInterface(
const expr::_expr<E> & expr,
const intContainer & iFaces)
232 {
return computeInterface_impl<E,min_op>(expr, iFaces); }
237 T
min(
const expr::_expr<E> & expr)
238 {
return compute_impl<E,false,min_op>(expr); }
244 {
return compute_impl<E,true,min_op>(expr); }
249 template<
class E>
void
251 template<
class E,
int mode,
short_t d>
252 typename util::enable_if<E::ScalarValued,void>::type
254 eval(
const expr::_expr<E> & expr,
255 gsGridIterator<T,mode,d> & git,
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,
270 typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
276 typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
284 typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
286 evalIfc(
const expr::_expr<E> & testExpr,
const gsVector<T> & pt,
290 typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
291 evalIfc(
const expr::_expr<E> & testExpr,
const gsVector<T> & pt,
298 typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
300 evalBdr(
const expr::_expr<E> & testExpr,
const gsVector<T> & pt,
304 typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
305 evalBdr(
const expr::_expr<E> & testExpr,
const gsVector<T> & pt,
310 template<
class E>
void
315 gsInfo <<
"Result:\n"<<
eval(expr,pt,patchInd) <<
"\n";
318 void info()
const { m_exprdata->print(); }
321 template<
class E>
void interpolate(
const expr::_expr<E> &)
343 geometryMap G, std::string
const & fn)
344 { writeParaview_impl<E,true>(expr,G,fn); }
352 std::string
const & fn)
353 { writeParaview_impl<E,false>(expr,m_exprdata->getMap(),fn); }
357 template<
class E,
bool gmap>
358 void writeParaview_impl(
const expr::_expr<E> & expr,
359 geometryMap G, std::string
const & fn);
363 template<
class E,
bool storeElWise,
class _op>
364 T compute_impl(
const expr::_expr<E> & expr);
366 template<
class E,
class _op>
369 template<
class E,
class _op>
370 T computeBdrBc_impl(
const bcRefList & BCs,
const expr::_expr<E> & expr);
372 template<
class E,
class _op>
373 T computeInterface_impl(
const expr::_expr<E> & expr,
const intContainer & iFaces);
376 void computeGrid_impl(
const expr::_expr<E> & expr,
const index_t patchInd);
380 static inline T init() {
return 0; }
381 static inline void acc(
const T contrib,
const T w, T & res)
382 { res += w * contrib; }
384 static inline void acc_global(
const T contrib, T & res)
386# pragma omp atomic update
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)
397# pragma omp atomic write
398 res = math::min(contrib, res);
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)
409# pragma omp atomic write
410 res = math::max(contrib, res);
417template<
class E,
bool storeElWise,
class _op>
418T gsExprEvaluator<T>::compute_impl(
const expr::_expr<E> & expr)
420 m_value = _op::init();
423 m_elWise.resize(m_exprdata->multiBasis().totalElements());
428 const int tid = omp_get_thread_num();
429 const int nt = omp_get_num_threads();
430 T thValue = _op::init();
432 gsQuadRule<T> QuRule;
433 auto _arg = expr.val();
434 m_exprdata->parse(_arg);
440 typename gsBasis<T>::domainIter domIt;
441 for (
unsigned patchInd=0; patchInd < m_exprdata->multiBasis().nBases(); ++patchInd)
447 domIt = m_exprdata->multiBasis().piece(patchInd).makeDomainIterator();
449 for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
451 for (; domIt->good(); domIt->next() )
455 QuRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(),
456 m_exprdata->points(), m_exprdata->weights());
459 m_exprdata->precompute(patchInd);
463 for (
index_t k = 0; k != m_exprdata->weights().rows(); ++k)
464 _op::acc(_arg.eval(k), m_exprdata->weights()[k], elVal);
465 _op::acc(elVal, (T)1,
473 m_elWise[poffset+domIt->id()] = elVal;
476 poffset += m_exprdata->multiBasis().basis(patchInd).numElements();
479 _op::acc_global(thValue, m_value);
486template<
class E,
class _op>
488 const bContainer & bdrlist)
497 auto _arg = expr.val();
498 m_exprdata->parse(_arg);
503 m_value = _op::init();
505 for (
typename gsBoxTopology::const_biterator bit =
506 bdrlist.begin(); bit != bdrlist.end(); ++bit)
509 QuRule =
gsQuadrature::get(m_exprdata->multiBasis().basis(bit->patch), m_options,bit->direction());
512 typename gsBasis<T>::domainIter domIt =
513 m_exprdata->multiBasis().piece(bit->patch).makeDomainIterator(bit->side());
516 for (; domIt->good(); domIt->next() )
519 QuRule.
mapTo( domIt->lowerCorner(), domIt->upperCorner(),
520 m_exprdata->points(), m_exprdata->weights());
523 m_exprdata->precompute(bit->patch, bit->side() );
527 for (
index_t k = 0; k != m_exprdata->weights().rows(); ++k)
528 _op::acc(_arg.eval(k), m_exprdata->weights()[k], elVal);
530 _op::acc(elVal, 1, m_value);
539template<
class E,
class _op>
541 const expr::_expr<E> & expr)
549 if ( BCs.empty() )
return 0;
550 m_exprdata->setMutSource(*BCs.front().get().function());
552 typename gsQuadRule<T>::uPtr QuRule;
553 auto _arg = expr.val();
554 m_exprdata->parse(_arg);
559 m_value = _op::init();
562 for (
typename bcRefList::const_iterator iit = BCs.begin(); iit!= BCs.end(); ++iit)
567 QuRule =
gsQuadrature::getPtr(m_exprdata->multiBasis().basis(it->patch()), m_options, it->side().direction());
570 m_exprdata->setMutSource(*it->function());
573 typename gsBasis<T>::domainIter domIt =
574 m_exprdata->multiBasis().basis(it->patch()).makeDomainIterator(it->side());
577 for (; domIt->good(); domIt->next() )
580 QuRule->
mapTo( domIt->lowerCorner(), domIt->upperCorner(),
581 m_exprdata->points(), m_exprdata->weights());
583 if (m_exprdata->points().cols()==0)
587 m_exprdata->precompute(it->patch(), it->side() );
591 for (
index_t k = 0; k != m_exprdata->weights().rows(); ++k)
592 _op::acc(_arg.eval(k), m_exprdata->weights()[k], elVal);
594 _op::acc(elVal, 1, m_value);
603template<
class E,
class _op>
604T gsExprEvaluator<T>::computeInterface_impl(
const expr::_expr<E> & expr,
const intContainer & iFaces)
606 auto arg_tpl = expr.val();
607 m_exprdata->parse(arg_tpl);
610 typename gsQuadRule<T>::uPtr QuRule;
613 m_value = _op::init();
615 m_elWise.reserve(m_exprdata->multiBasis().topology().nInterfaces());
618 ifacemap interfaceMap;
619 for (
typename gsBoxTopology::const_iiterator iit =
620 iFaces.begin(); iit != iFaces.end(); ++iit)
622 const boundaryInterface & iFace = *iit;
623 const index_t patch1 = iFace.first().patch;
624 const index_t patch2 = iFace.second().patch;
626 if (iFace.type() == interaction::conforming)
628 m_exprdata->multiBasis().basis(patch1).support(),
629 m_exprdata->multiBasis().basis(patch2).support() );
631 interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
639 m_options, iFace.first().side().direction());
642 typename gsBasis<T>::domainIter domIt =
644 m_exprdata->multiBasis().piece(patch1).makeDomainIterator(iFace.first().side());
648 for (; domIt->good(); domIt->next() )
651 QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
652 m_exprdata->points(), m_exprdata->weights());
653 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
656 m_exprdata->precompute(iFace);
659 for (
index_t k = 0; k != m_exprdata->weights().rows(); ++k)
661 _op::acc(arg_tpl.eval(k), m_exprdata->weights()[k], elVal);
664 _op::acc(elVal, 1, m_value);
666 m_elWise.push_back( elVal );
674template<
class E,
int mode,
short_t d>
675typename util::enable_if<E::ScalarValued,void>::type
677 gsGridIterator<T,mode,d> & git,
683 auto _arg = expr.val();
684 m_exprdata->parse(_arg);
686 m_elWise.reserve(git.numPoints());
688 for( git.reset(); git; ++git )
690 m_exprdata->points() = *git;
691 m_exprdata->precompute(patchInd);
692 m_elWise.push_back( _arg.eval(0) );
698 m_value = m_elWise.back();
702template<
class E,
int mode,
short_t d>
703typename util::enable_if<!E::ScalarValued,void>::type
705 gsGridIterator<T,mode,d> & git,
711 m_exprdata->parse(expr);
713 m_elWise.reserve(git.numPoints());
715 for( git.reset(); git; ++git )
717 m_exprdata->points() = *git;
718 m_exprdata->precompute(patchInd);
721 m_elWise.insert(m_elWise.end(), tmp.data(), tmp.data()+tmp.size());
729typename util::enable_if<E::ScalarValued,gsAsConstMatrix<T> >::type
733 auto _arg = expr.val();
734 m_exprdata->parse(_arg);
736 m_exprdata->points() = pt;
737 m_exprdata->precompute(patchInd);
741 m_value = _arg.eval(0);
742 return gsAsConstMatrix<T>(&m_value,1,1);
747typename util::enable_if<!E::ScalarValued,gsAsConstMatrix<T> >::type
751 m_exprdata->parse(expr);
752 m_exprdata->points() = pt;
753 m_exprdata->precompute(patchInd);
757 gsMatrix<T> tmp = expr.eval(0);
763 m_elWise.resize(r*c);
764 gsAsMatrix<T>(m_elWise, r, c) = tmp;
765 return gsAsConstMatrix<T>(m_elWise, r, c);
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)
829 auto _arg = expr.val();
830 m_exprdata->parse(_arg);
833 const bool flipSide = m_options.
askSwitch(
"flipSide",
false);
834 const boundaryInterface & iFace = flipSide ? ifc.getInverse() : ifc;
836 const index_t patch1 = iFace.first().patch;
837 const index_t patch2 = iFace.second().patch;
839 ifacemap interfaceMap;
840 if (iFace.type() == interaction::conforming)
842 m_exprdata->multiBasis().basis(patch1).support(),
843 m_exprdata->multiBasis().basis(patch2).support() );
845 interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
847 m_exprdata->points() = pt;
848 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
849 m_exprdata->precompute(iFace);
853 m_value = _arg.eval(0);
854 return gsAsConstMatrix<T>(&m_value,1,1);
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)
863 m_exprdata->parse(expr);
865 const bool flipSide = m_options.
askSwitch(
"flipSide",
false);
866 const boundaryInterface & iFace = flipSide ? ifc.getInverse() : ifc;
868 const index_t patch1 = iFace.first().patch;
869 const index_t patch2 = iFace.second().patch;
871 ifacemap interfaceMap;
872 if (iFace.type() == interaction::conforming)
874 m_exprdata->multiBasis().basis(patch1).support(),
875 m_exprdata->multiBasis().basis(patch2).support() );
877 interfaceMap = gsCPPInterface<T>::make(m_exprdata->multiPatch(), m_exprdata->multiBasis(), iFace);
879 m_exprdata->points() = pt;
880 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
882 m_exprdata->precompute(iFace);
886 gsMatrix<T> tmp = expr.eval(0);
892 m_elWise.resize(r*c);
893 gsAsMatrix<T>(m_elWise, r, c) = tmp;
894 return gsAsConstMatrix<T>(m_elWise, r, c);
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)
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);
911 m_exprdata->points() = pt;
912 m_exprdata->precompute(ps.patch, ps.side());
914 m_value = _arg.eval(0);
915 return gsAsConstMatrix<T>(&m_value,1,1);
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)
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());
929 gsMatrix<T> tmp = expr.eval(0);
932 m_elWise.resize(r*c);
933 gsAsMatrix<T>(m_elWise, r, c) = tmp;
934 return gsAsConstMatrix<T>(m_elWise, r, c);
938template<
class E,
bool gmap>
939void gsExprEvaluator<T>::writeParaview_impl(
const expr::_expr<E> & expr,
941 std::string
const & fn)
944 m_exprdata->parse(expr);
947 const index_t n = m_exprdata->multiBasis().nBases();
951 std::stringstream file;
953 file <<
"<?xml version=\"1.0\"?>\n";
954 file <<
"<VTKFile type=\"Collection\" version=\"0.1\">";
955 file <<
"<Collection>\n";
961 std::string fileName;
963 gsMatrix<T> pts, vals, ab;
965 const bool mesh = m_options.
askSwitch(
"plot.elements");
967 for (
index_t i=0; i != n; ++i )
970 unsigned nPts = m_options.
askInt(
"plot.npts", 1000);
972 ab = G.source().piece(i).support();
973 gsGridIterator<T,CUBE> pt(ab, nPts);
975 nPts = pt.numPoints();
976 vals = allValues(m_elWise.size()/nPts, nPts);
981 pts = allValues(m_elWise.size()/nPts, nPts);
984 gsWriteParaviewTPgrid( gmap ? pts : pt.toMatrix(),
986 pt.numPointsCwise(), fileName );
990 GISMO_ASSERT(counter!=-1,
"Error: collection has been already saved." );
991 file <<
"<DataSet part=\""<< counter++ <<
"\" file=\""<<fileName<<
".vts"<<
"\"/>\n";
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);
1001 GISMO_ASSERT(counter!=-1,
"Error: collection has been already saved." );
1002 file <<
"<DataSet part=\""<< counter++ <<
"\" file=\""<<fileName<<
"_mesh.vtp"<<
"\"/>\n";
1009 GISMO_ASSERT(counter!=-1,
"Error: gsParaviewCollection::save() already called." );
1010 file <<
"</Collection>\n";
1011 file <<
"</VTKFile>\n";
1013 std::string mfn = fn +
".pvd";
1015 std::ofstream f( mfn.c_str() );