25 template <
typename Derived>
26 void secDerToHessian(
const gsEigen::DenseBase<Derived> & secDers,
28 gsMatrix<typename Derived::Scalar> & hessian)
30 const index_t sz = dim*(dim+1)/2;
31 const gsAsConstMatrix<typename Derived::Scalar>
32 ders(secDers.derived().data(), sz, secDers.size() / sz );
33 hessian.resize(dim*dim, ders.cols() );
38 hessian = secDers.transpose();
41 hessian.row(0)=ders.row(0);
43 hessian.row(2)=ders.row(2);
44 hessian.row(3)=ders.row(1);
47 hessian.row(0)=ders.row(0);
49 hessian.row(1)=ders.row(3);
51 hessian.row(2)=ders.row(4);
52 hessian.row(4)=ders.row(1);
54 hessian.row(5)=ders.row(5);
55 hessian.row(8)=ders.row(2);
66 fs(&_fs), dim(
give(_dim)), id(
give(_id)) { }
77 return static_cast<size_t>(fs->size()*dim)==mapper.
mapSize();
108 template <
class E>
struct is_arithmetic{
enum{value=0};};
109 template <>
struct is_arithmetic<real_t>{
enum{value=1};};
110 template <typename E, bool = is_arithmetic<E>::value >
111 class _expr {
using E::GISMO_ERROR_expr;};
113 template<
class T>
class gsFeSpace;
115 template<
class T>
class gsFeSolution;
116 template<
class E>
class symm_expr;
117 template<
class E>
class symmetrize_expr;
118 template<
class E>
class normalized_expr;
119 template<
class E>
class trace_expr;
121 template<
class E>
class adjugate_expr;
122 template<
class E>
class norm_expr;
123 template<
class E>
class sqNorm_expr;
124 template<
class E>
class det_expr;
125 template<
class E>
class value_expr;
127 template<
class E>
class max_expr;
128 template<
class E>
class rowsum_expr;
129 template<
class E>
class colsum_expr;
130 template<
class E>
class col_expr;
131 template<
class T>
class meas_expr;
132 template<
class E>
class inv_expr;
133 template<
class E,
bool cw = false>
class tr_expr;
134 template<
class E>
class cb_expr;
135 template<
class E>
class abs_expr;
141 template<
class T>
class cdiam_expr;
142 template<
class E>
class temp_expr;
143 template<
class E1,
class E2,
bool = E1::ColBlocks && !E1::ScalarValued && !E2::ScalarValued>
class mult_expr
144 {
using E1::GISMO_ERROR_mult_expr_has_invalid_template_arguments;};
148 pow(_expr<E>
const& u, real_t q) {
return pow_expr<E>(u,q); }
153 template <
typename E>
struct expr_traits
157 typedef real_t Scalar;
158 typedef const E Nested_t;
161 # define Temporary_t typename util::conditional<ScalarValued,Scalar, \
162 typename gsMatrix<Scalar>::Base >::type
163 #if __cplusplus >= 201402L || _MSVC_LANG >= 201402L // c++14
164 # define MatExprType auto
165 # define AutoReturn_t auto
167 #else // 199711L, 201103L
168 # define MatExprType typename gsMatrix<real_t>::constRef
169 # define AutoReturn_t typename util::conditional<ScalarValued,real_t,MatExprType>::type
175 template <
typename E>
176 class _expr<E, false>
180 _expr(
const _expr&) { }
190 typedef typename expr_traits<E>::Nested_t Nested_t;
191 typedef typename expr_traits<E>::Scalar Scalar;
197 static_cast<E const&
>(*this).print(os);
216 std::ostream & printDetail(std::ostream &os)
const
218 os << (isVectorTr() ?
"VectorTr " :
219 (isVector() ?
"Vector " :
220 (isMatrix() ?
"Matrix " :
222 <<
"expression of size "<< rows()
223 <<
" x "<<cols()<<
"\n";
230 {
return static_cast<E const&
>(*this).eval(k); }
233 tr_expr<E>
tr()
const
234 {
return tr_expr<E,false>(
static_cast<E const&
>(*this)); }
238 {
return tr_expr<E,true>(
static_cast<E const&
>(*this)); }
241 cb_expr<E>
cb()
const
242 {
return cb_expr<E>(
static_cast<E const&
>(*this)); }
246 {
return sign_expr<E>(
static_cast<E const&
>(*this), tolerance); }
250 {
return exp_expr<E>(
static_cast<E const&
>(*this)); }
259 mult_expr<real_t, ppart_expr<mult_expr<double,E,false>> ,
false>
260 npart()
const {
return -1* ( -(*this) ).ppart() ; }
264 {
return temp_expr<E>(
static_cast<E const&
>(*this)); }
267 inv_expr<E>
const inv()
const
268 {
return inv_expr<E>(
static_cast<E const&
>(*this)); }
272 {
return trace_expr<E>(
static_cast<E const&
>(*this)); }
275 adjugate_expr<E>
adj()
const
276 {
return adjugate_expr<E>(
static_cast<E const&
>(*this)); }
280 {
return norm_expr<E>(
static_cast<E const&
>(*this)); }
284 {
return normalized_expr<E>(
static_cast<E const&
>(*this)); }
288 {
return det_expr<E>(
static_cast<E const&
>(*this)); }
292 {
return sqNorm_expr<E>(
static_cast<E const&
>(*this)); }
295 mult_expr<E,E,0> (sqr)()
const {
return (*
this)*(*this); }
297 symm_expr<E> symm()
const
298 {
return symm_expr<E>(
static_cast<E const&
>(*this)); }
300 symmetrize_expr<E> symmetrize()
const
301 {
return symmetrize_expr<E>(
static_cast<E const&
>(*this)); }
306 {
return value_expr<E>(
static_cast<E const&
>(*this)); }
314 {
return max_expr<E>(
static_cast<E const&
>(*this)); }
318 {
return rowsum_expr<E>(
static_cast<E const&
>(*this)); }
322 {
return colsum_expr<E>(
static_cast<E const&
>(*this)); }
324 col_expr<E> operator[](
const index_t i)
const
325 {
return col_expr<E>(
static_cast<E const&
>(*this),i); }
329 {
return static_cast<E const&
>(*this).rows(); }
333 {
return static_cast<E const&
>(*this).cols(); }
336 {
return static_cast<E const&
>(*this).cardinality_impl(); }
338 static index_t cardinality_impl() {
return 1; }
345 static bool isVectorTr() {
return 2==E::Space; }
346 static bool isMatrix () {
return 3==E::Space; }
351 {
static_cast<E const&
>(*this).parse(evList); }
353 template<
class op>
void apply(op & _op)
const
354 {
static_cast<E const&
>(*this).apply(_op); }
361 return static_cast<E const&
>(*this).rowVar();
369 return static_cast<E const&
>(*this).colVar();
374 operator E&() {
return static_cast< E&
>(*this); }
375 operator E
const&()
const {
return static_cast<const E&
>(*this); }
377 E
const & derived()
const {
return static_cast<const E&
>(*this); }
381 template <
typename E>
382 std::ostream &operator<<(std::ostream &os, const _expr<E> & b)
383 {b.print(os);
return os; }
399 class gsNullExpr :
public _expr<gsNullExpr<T> >
403 operator const gsFeSpace<T> & ()
const
405 static gsFeSpace<T> vv(-1);
413 void parse(gsExprHelper<T> &)
const { }
415 const gsFeSpace<T> & rowVar()
const {
GISMO_ERROR(
"gsNullExpr"); }
416 const gsFeSpace<T> & colVar()
const {
GISMO_ERROR(
"gsNullExpr"); }
418 void print(std::ostream &os)
const { os <<
"NullExpr"; }
420 static const gsNullExpr &
get()
431 class symbol_expr :
public _expr<E>
434 typedef typename expr_traits<E>::Scalar Scalar;
438 const gsFunctionSet<Scalar> * m_fs;
439 const gsFuncData<Scalar> * m_fd;
446 bool isAcross()
const {
return m_isAcross; }
450 E ac(this->derived());
452 ac.m_isAcross =
true;
458 E ac(this->derived());
460 ac.m_isAcross =
false;
465 const gsFunctionSet<Scalar> & source()
const {
return *m_fs;}
468 const gsFuncData<Scalar> & data()
const
470 GISMO_ASSERT(NULL!=m_fd,
"FuncData member not registered "<<
this<<
"/"<< m_fs);
475 void parse(gsExprHelper<Scalar> & evList)
const
481 index_t cardinality_impl()
const
483 GISMO_ASSERT(this->data().actives.rows()!=0,
"Cardinality depends on the NEED_ACTIVE flag");
484 return m_d * this->data().actives.rows();
488 void setSource(
const gsFunctionSet<Scalar> & fs) { m_fs = &fs;}
491 void setData(
const gsFuncData<Scalar> & val) { m_fd = &val;}
492 void setDim(
index_t _d) { m_d = _d; }
493 void clear() { m_fs = NULL; }
496 explicit symbol_expr(
index_t _d)
497 : m_fs(NULL), m_fd(NULL), m_d(_d), m_isAcross(false) { }
500 bool isValid()
const {
return NULL!=m_fd && NULL!=m_fs; }
509 {
return m_fd->values[0].col(k).blockDiag(m_d); }
512 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
513 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
517 GISMO_ASSERT(NULL!=m_fs,
"FeVariable: Function source not registered");
518 return m_fs->targetDim();
521 index_t cols()
const {
return m_d; }
523 void print(std::ostream &os)
const { os <<
"u"; }
528 index_t dim()
const {
return m_d;}
532 index_t targetDim()
const {
return m_fs->targetDim(); }
535 index_t parDim()
const {
return m_fs->domainDim(); }
539 GISMO_ASSERT(0!=m_fd->values[0].size(),
"Probable error.");
540 return m_fd->values[0].rows();
548 class col_expr :
public _expr<col_expr<E> >
550 typename E::Nested_t _c;
553 typedef typename E::Scalar Scalar;
554 typedef const col_expr<E> Nested_t;
556 enum { Space = E::Space, ScalarValued = 0, ColBlocks = 0 };
558 col_expr(
const E & c,
const index_t i) : _c(c), _i(i) { }
565 index_t rows()
const {
return _c.rows(); }
566 index_t cols()
const {
return 1; }
567 void parse(gsExprHelper<Scalar> & evList)
const { _c.parse(evList); }
569 const gsFeSpace<Scalar> & rowVar()
const {
return _c.rowVar(); }
570 const gsFeSpace<Scalar> & colVar()
const {
return _c.colVar(); }
572 void print(std::ostream &os)
const { os<<_c<<
"["<<_i<<
"]"; }
579 class _expr<T, true> :
public _expr<_expr<T> >
584 typedef const _expr<T> Nested_t;
586 explicit _expr(Scalar c) : _c(
give(c)) { }
589 enum {Space = 0, ScalarValued = 1, ColBlocks= 0};
591 inline Scalar eval(
const index_t )
const {
return _c; }
593 inline _expr val()
const {
return *
this; }
594 index_t rows()
const {
return 0; }
595 index_t cols()
const {
return 0; }
596 void parse(gsExprHelper<Scalar> &)
const { }
598 const gsFeSpace<T> & rowVar()
const {
return gsNullExpr<T>::get(); }
599 const gsFeSpace<T> & colVar()
const {
return gsNullExpr<T>::get(); }
601 void print(std::ostream &os)
const { os<<_c; }
608 class gsGeometryMap :
public _expr<gsGeometryMap<T> >
610 const gsFunctionSet<T> * m_fs;
611 const gsMapData<T> * m_fd;
617 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
619 bool isAcross()
const {
return m_isAcross; }
621 gsGeometryMap right()
const
625 ac.m_isAcross =
true;
629 gsGeometryMap left()
const
633 ac.m_isAcross =
false;
638 const gsFunctionSet<T> & source()
const {
return *m_fs;}
641 const gsMapData<T> & data()
const
643 GISMO_ASSERT(NULL!=m_fd,
"gsGeometryMap: invalid data "<< m_fs <<
","<<m_fd);
647 index_t targetDim()
const {
return m_fs->targetDim();}
648 index_t domainDim()
const {
return m_fs->domainDim();}
651 void copyCoefs(
const gsGeometryMap<T> & other)
const
653 GISMO_ASSERT(
dynamic_cast<const gsMultiPatch<T>*
>( this->m_fs ),
"error");
654 const gsMultiPatch<T> & thisMP =
static_cast<const gsMultiPatch<T>&
>(*this->m_fs );
655 GISMO_ASSERT(
dynamic_cast<const gsMultiPatch<T>*
>( other.m_fs ),
"error");
656 const gsMultiPatch<T> & otherMP =
static_cast<const gsMultiPatch<T>&
>(*other.m_fs );
657 GISMO_ASSERT( (thisMP.domainDim()==otherMP.domainDim())&&
658 (thisMP.geoDim()==otherMP.geoDim())&&
659 (thisMP.coefsSize() == otherMP.coefsSize())&&
660 (thisMP.nPatches()==otherMP.nPatches()),
661 "The geometryMaps are not compatible!");
664 for (
index_t p=0; p < thisMP.nPatches(); p++ )
667 thisMP.patch(p).coefs() = otherMP.patch(p).coefs();
672 void deformBy(
const gsFeSolution<T> & displacement)
const
674 const index_t dim = m_fs->domainDim();
676 const gsMultiBasis<T> & mb =
static_cast<const gsMultiBasis<T>&
>(displacement.space().source());
677 const gsMultiPatch<T> & mp =
static_cast<const gsMultiPatch<T>&
>(*this->m_fs );
678 GISMO_ASSERT(
dynamic_cast<const gsMultiBasis<T>*
>(&displacement.space().source()),
"error");
679 GISMO_ASSERT(
dynamic_cast<const gsMultiPatch<T>*
>( this->m_fs),
"error");
682 for (
size_t p=0; p < mp.nPatches(); p++ )
685 gsMatrix<T> &result = mp.patch(p).coefs();
688 const index_t sz = mb[p].size();
691 for (
index_t c = 0; c!=dim; c++)
694 for (
index_t i = 0; i < sz; ++i)
696 const int ii = displacement.mapper().index(i, p, c);
697 if ( displacement.mapper().is_free_index(ii) )
699 result(i,c) += displacement.coefs().at(ii);
703 result(i,c) += displacement.fixedPart().at( displacement.mapper().global_to_bindex(ii));
715 void print(std::ostream &os)
const { os <<
"G"; }
717 auto eval(
const index_t k)
const -> decltype(m_fd->values[0].col(k))
718 {
return m_fd->values[0].col(k); }
722 gsGeometryMap() : m_fs(NULL), m_fd(NULL), m_isAcross(false) { }
724 void setSource(
const gsFunctionSet<Scalar> & fs) { m_fs = &fs;}
725 void setData(
const gsMapData<Scalar> & val) { m_fd = &val;}
729 index_t rows()
const {
return m_fs->targetDim(); }
730 index_t cols()
const {
return 1; }
732 const gsFeSpace<T> & rowVar()
const {
return gsNullExpr<T>::get(); }
733 const gsFeSpace<T> & colVar()
const {
return gsNullExpr<T>::get(); }
735 void parse(gsExprHelper<Scalar> & evList)
const
743 template <
typename T>
struct expr_traits<gsGeometryMap<T> >
746 typedef const gsGeometryMap<T> Nested_t;
753 class meas_expr :
public _expr<meas_expr<T> >
755 typename gsGeometryMap<T>::Nested_t _G;
758 enum {Space = 0, ScalarValued = 1, ColBlocks = 0};
762 meas_expr(
const gsGeometryMap<T> & G) : _G(G) { }
766 return _G.data().measures.at(k);
769 index_t rows()
const {
return 0; }
770 index_t cols()
const {
return 0; }
771 void parse(gsExprHelper<Scalar> & evList)
const
777 const gsFeSpace<T> & rowVar()
const {
return gsNullExpr<T>::get(); }
778 const gsFeSpace<T> & colVar()
const {
return gsNullExpr<T>::get(); }
780 void print(std::ostream &os)
const { os <<
"meas("; _G.print(os); os <<
")"; }
790 friend class cdiam_expr<T>;
792 const gsDomainIterator<T> * m_di;
794 const gsVector<T> * m_weights;
797 gsFeElement(
const gsFeElement &);
801 gsFeElement() : m_di(NULL), m_weights(nullptr) { }
803 void set(
const gsDomainIterator<T> & di,
const gsVector<T> & weights)
804 { m_di = &di, m_weights = &weights; }
806 bool isValid()
const {
return nullptr!=m_weights; }
808 const gsVector<T> & weights()
const {
return *m_weights;}
811 integral_expr<E> integral(
const _expr<E>& ff)
const
812 {
return integral_expr<E>(*
this,ff); }
814 typedef integral_expr<T> AreaRetType;
815 AreaRetType area()
const
816 {
return integral(_expr<T,true>(1)); }
818 typedef integral_expr<meas_expr<T> > PHAreaRetType;
820 PHAreaRetType area(
const gsGeometryMap<Scalar> & _G)
const
821 {
return integral(meas_expr<T>(_G)); }
823 typedef pow_expr<integral_expr<T> > DiamRetType;
825 DiamRetType diam() const
826 {
return pow(integral(_expr<T,true>(1)),(T)(1)/(T)(2)); }
828 typedef pow_expr<integral_expr<meas_expr<T> > > PHDiamRetType;
830 PHDiamRetType diam(
const gsGeometryMap<Scalar> & _G)
const
831 {
return pow(integral(meas_expr<T>(_G)),(T)(1)/(T)(2)); }
837 void print(std::ostream &os)
const { os <<
"e"; }
839 void parse(gsExprHelper<T> & evList)
const
851 class integral_expr :
public _expr<integral_expr<E> >
855 typedef real_t Scalar;
856 mutable Scalar m_val;
858 const gsFeElement<Scalar> &
_e;
859 typename _expr<E>::Nested_t _ff;
861 enum {Space= 0, ScalarValued= 1, ColBlocks = 0};
863 integral_expr(
const gsFeElement<Scalar> & el,
const _expr<E> & u)
864 : m_val(-1),
_e(el), _ff(u) { }
866 const Scalar & eval(
const index_t k)
const
868 GISMO_ENSURE(
_e.isValid(),
"Element is valid within integrals only.");
871 const Scalar * w =
_e.weights().data();
872 m_val = (*w) * _ff.val().eval(0);
873 for (
index_t j = 1; j !=
_e.weights().rows(); ++j)
874 m_val += (*(++w)) * _ff.val().eval(j);
879 inline const integral_expr<E> & val()
const {
return *
this; }
880 inline index_t rows()
const {
return 0; }
881 inline index_t cols()
const {
return 0; }
882 void parse(gsExprHelper<Scalar> & evList)
const
887 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get(); }
888 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get(); }
890 void print(std::ostream &os)
const
924 template <
typename T>
925 struct expr_traits<gsFeVariable<T> >
928 typedef const gsFeVariable<T> Nested_t;
936 class gsFeVariable :
public symbol_expr< gsFeVariable<T> >
939 typedef symbol_expr< gsFeVariable<T> > Base;
941 explicit gsFeVariable(
index_t _d = 1) : Base(_d) { }
943 enum {Space = 0, ScalarValued = 0, ColBlocks = 0};
947 class gsComposition :
public symbol_expr< gsComposition<T> >
950 typedef symbol_expr< gsComposition<T> > Base;
951 typename gsGeometryMap<T>::Nested_t _G;
953 explicit gsComposition(
const gsGeometryMap<T> & G,
index_t _d = 1)
954 : Base(_d), _G(G) { }
956 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
958 typename gsMatrix<T>::constColumn
959 eval(
const index_t k)
const {
return this->m_fd->values[0].col(k); }
961 const gsGeometryMap<T> & inner()
const {
return _G;};
963 void parse(gsExprHelper<T> & evList)
const
981 class gsFeSpace :
public symbol_expr< gsFeSpace<T> >
983 friend class gsNullExpr<T>;
986 typedef symbol_expr< gsFeSpace<T> > Base;
989 gsFeSpaceData<T> * m_sd;
992 enum{Space = 1, ScalarValued=0, ColBlocks=0};
994 typedef const gsFeSpace Nested_t;
998 const gsFeSpace<T> & rowVar()
const {
return *
this;}
1000 gsDofMapper & mapper()
1002 GISMO_ASSERT(NULL!=m_sd,
"Space/mapper not properly initialized.");
1003 return m_sd->mapper;
1006 const gsDofMapper & mapper()
const
1007 {
return const_cast<gsFeSpace*
>(
this)->mapper();}
1009 inline const gsMatrix<T> & fixedPart()
const {
return m_sd->fixedDofs;}
1010 gsMatrix<T> & fixedPart() {
return m_sd->fixedDofs;}
1012 index_t id()
const {
return (m_sd ? m_sd->id : -101); }
1013 void setSpaceData(gsFeSpaceData<T>& sd) {m_sd = &sd;}
1015 index_t interfaceCont()
const {
return m_sd->cont;}
1018 GISMO_ASSERT(_r>-2 && _r<1,
"Invalid or not implemented (r="<<_r<<
").");
1019 return m_sd->cont = _r;
1022 gsFeSolution<T>
function(
const gsMatrix<T>& solVector)
const
1023 {
return gsFeSolution<T>(*this); }
1025 void getCoeffs(
const gsMatrix<T>& solVector, gsMatrix<T> & result,
1028 const index_t dim = this->dim();
1030 const gsMultiBasis<T> & mb =
static_cast<const gsMultiBasis<T>&
>(this->source());
1031 GISMO_ASSERT(
dynamic_cast<const gsMultiBasis<T>*
>(&this->source()),
"error");
1034 const index_t sz = mb[p].size();
1035 result.resize(sz, dim!=1 ? dim : solVector.cols());
1037 for (
index_t c = 0; c!=dim; c++)
1040 for (
index_t i = 0; i < sz; ++i)
1042 const int ii = m_sd->mapper.index(i, p, c);
1043 if ( m_sd->mapper.is_free_index(ii) )
1044 for(
index_t s = 0; s != solVector.cols(); ++s )
1045 result(i,c+s) = solVector(ii,s);
1047 result(i,c) = m_sd->fixedDofs.at( m_sd->mapper.global_to_bindex(ii) );
1055 void setupMapper(gsDofMapper dofsMapper)
const
1057 GISMO_ASSERT( dofsMapper.isFinalized(),
"The provided dof-mapper is not finalized.");
1058 GISMO_ASSERT( dofsMapper.mapSize()==
static_cast<size_t>(this->source().size()*dofsMapper.numComponents()),
"The dof-mapper is not consistent: mapSize()="<<dofsMapper.mapSize()<<
"!="<<
static_cast<size_t>(this->source().size())<<
"=this->source().size()");
1059 m_sd->mapper =
give(dofsMapper);
1062 void setup(
const index_t _icont = -1)
const
1064 this->setInterfaceCont(_icont);
1065 m_sd->mapper = gsDofMapper();
1067 if (
const gsMultiBasis<T> * mb =
1068 dynamic_cast<const gsMultiBasis<T>*
>(&this->source()) )
1070 m_sd->mapper = gsDofMapper(*mb, this->dim() );
1072 if ( 0==this->interfaceCont() )
1074 for ( gsBoxTopology::const_iiterator it = mb->topology().iBegin();
1075 it != mb->topology().iEnd(); ++it )
1077 mb->matchInterface(*it, m_sd->mapper);
1082 if (
const gsMappedBasis<2,T> * mb =
1083 dynamic_cast<const gsMappedBasis<2,T>*
>(&this->source()) )
1085 m_sd->mapper.setIdentity(mb->nPatches(), mb->size() , this->dim());
1088 m_sd->mapper.finalize();
1091 void setup(
const gsBoundaryConditions<T> & bc,
const index_t dir_values,
1092 const index_t _icont = -1)
const
1094 this->setInterfaceCont(_icont);
1095 m_sd->mapper = gsDofMapper();
1096 const index_t dim = this->dim();
1097 const gsMultiBasis<T> *mb =
dynamic_cast<const gsMultiBasis<T> *
>(&this->source());
1100 m_sd->mapper = gsDofMapper(*mb, this->dim());
1102 if (0 == this->interfaceCont())
1104 for (gsBoxTopology::const_iiterator it = mb->topology().iBegin();
1105 it != mb->topology().iEnd(); ++it) {
1106 mb->matchInterface(*it, m_sd->mapper);
1111 gsMatrix<index_t> bnd;
1112 for (
typename gsBoundaryConditions<T>::const_iterator
1113 it = bc.begin(
"Dirichlet"); it != bc.end(
"Dirichlet"); ++it)
1115 const index_t cc = it->unkComponent();
1116 GISMO_ASSERT(static_cast<size_t>(it->ps.patch) < this->mapper().numPatches(),
1117 "Problem: a boundary condition is set on a patch id which does not exist.");
1119 bnd = mb->basis(it->ps.patch).boundary(it->ps.side());
1120 m_sd->mapper.markBoundary(it->ps.patch, bnd, cc);
1123 gsMatrix<index_t> bnd1;
1124 for (
typename gsBoundaryConditions<T>::const_iterator
1125 it = bc.begin(
"Clamped"); it != bc.end(
"Clamped"); ++it)
1127 const index_t cc = it->unkComponent();
1129 GISMO_ASSERT(static_cast<size_t>(it->ps.patch) < this->mapper().numPatches(),
1130 "Problem: a boundary condition is set on a patch id which does not exist.");
1132 bnd = mb->basis(it->ps.patch).boundaryOffset(it->ps.side(), 0);
1133 bnd1 = mb->basis(it->ps.patch).boundaryOffset(it->ps.side(), 1);
1135 if (!it->ps.parameter())
1137 for (
index_t c = 0; c!=dim; c++)
1139 if (c==cc || cc==-1 )
1140 for (
index_t k = 0; k < bnd.size(); ++k)
1141 m_sd->mapper.matchDof(it->ps.patch, (bnd)(k, 0),
1142 it->ps.patch, (bnd1)(k, 0), c);
1148 for (
typename gsBoundaryConditions<T>::const_iterator
1149 it = bc.begin(
"Collapsed"); it != bc.end(
"Collapsed"); ++it)
1151 const index_t cc = it->unkComponent();
1153 GISMO_ASSERT(static_cast<size_t>(it->ps.patch) < this->mapper().numPatches(),
1154 "Problem: a boundary condition is set on a patch id which does not exist.");
1156 bnd = mb->basis(it->ps.patch).boundary(it->ps.side());
1159 for (
index_t c = 0; c!=dim; c++)
1161 if (c==cc || cc==-1)
1162 for (
index_t k = 0; k < bnd.size() - 1; ++k)
1163 m_sd->mapper.matchDof(it->ps.patch, (bnd)(0, 0),
1164 it->ps.patch, (bnd)(k + 1, 0), c);
1169 for (
typename gsBoundaryConditions<T>::const_cpliterator
1170 it = bc.coupledBegin(); it != bc.coupledEnd(); ++it)
1172 const index_t cc = it->component;
1175 "Problem: a boundary condition is set on a patch id which does not exist.");
1177 "Problem: a boundary condition is set on a patch id which does not exist.");
1180 bnd = mb->basis(it->ifc.first().patch).boundary(it->ifc.first().side());
1181 bnd1 = mb->basis(it->ifc.second().patch).boundary(it->ifc.second().side());
1184 for (
index_t c = 0; c!=dim; c++)
1186 if (c==cc || cc==-1)
1188 for (
index_t k = 0; k < bnd.size() - 1; ++k)
1189 m_sd->mapper.matchDof(it->ifc.first() .patch, (bnd)(0, 0),
1190 it->ifc.first() .patch, (bnd)(k + 1, 0), c);
1191 for (
index_t k = 0; k < bnd1.size(); ++k)
1192 m_sd->mapper.matchDof(it->ifc.first() .patch, (bnd)(0, 0),
1193 it->ifc.second().patch, (bnd1)(k, 0), c);
1199 for (
typename gsBoundaryConditions<T>::const_citerator
1200 it = bc.cornerBegin(); it != bc.cornerEnd(); ++it)
1202 for (
index_t r = 0; r!=this->dim(); ++r)
1204 if (it->component!=-1 && r!=it->component)
continue;
1207 GISMO_ASSERT(static_cast<size_t>(it->patch) < mb->nBases(),
1208 "Problem: a corner boundary condition is set on a patch id which does not exist.");
1209 m_sd->mapper.eliminateDof(mb->basis(it->patch).functionAtCorner(it->corner),
1210 it->patch, it->component);
1214 }
else if (
const gsBasis<T> *b =
1215 dynamic_cast<const gsBasis<T> *
>(&this->source()))
1217 m_sd->mapper = gsDofMapper(*b, this->dim() );
1218 gsMatrix<index_t> bnd;
1219 for (
typename gsBoundaryConditions<T>::const_iterator
1220 it = bc.begin(
"Dirichlet"); it != bc.end(
"Dirichlet"); ++it) {
1222 "Problem: a boundary condition is set on a patch id which does not exist.");
1224 bnd = b->boundary(it->ps.side());
1225 m_sd->mapper.markBoundary(0, bnd, it->unkComponent());
1228 for (
typename gsBoundaryConditions<T>::const_iterator
1229 it = bc.begin(
"Clamped"); it != bc.end(
"Clamped"); ++it) {
1231 "Problem: a boundary condition is set on a patch id which does not exist.");
1233 bnd = b->boundary(it->ps.side());
1238 m_sd->mapper = gsDofMapper(*b);
1239 for (
typename gsBoundaryConditions<T>::const_iterator
1240 it = bc.begin(
"Collapsed"); it != bc.end(
"Collapsed"); ++it) {
1242 "Problem: a boundary condition is set on a patch id which does not exist.");
1244 bnd = b->boundary(it->ps.side());
1248 }
else if (
const gsMappedBasis<2, T> *mapb =
1249 dynamic_cast<const gsMappedBasis<2, T> *
>(&this->source()))
1251 m_sd->mapper.setIdentity(mapb->nPatches(), mapb->size(), this->dim());
1253 if (0 == this->interfaceCont())
1255 gsMatrix<index_t> int1, int2;
1256 for (gsBoxTopology::const_iiterator it = mapb->getTopol().iBegin();
1257 it != mapb->getTopol().iEnd(); ++it) {
1258 int1 = mapb->basis(it->first().patch).boundaryOffset(it->first().side(), 0);
1259 int2 = mapb->basis(it->second().patch).boundaryOffset(it->second().side(), 0);
1261 m_sd->mapper.matchDofs(it->first().patch, int1, it->second().patch, int2);
1264 if (1 == this->interfaceCont())
1266 GISMO_ERROR(
"Boundary offset function is not implemented for gsMappedBasis in general.");
1269 gsMatrix<index_t> bnd;
1270 for (
typename gsBoundaryConditions<T>::const_iterator
1271 it = bc.begin(
"Dirichlet"); it != bc.end(
"Dirichlet"); ++it) {
1272 const index_t cc = it->unkComponent();
1273 GISMO_ASSERT(static_cast<size_t>(it->ps.patch) < this->mapper().numPatches(),
1274 "Problem: a boundary condition is set on a patch id which does not exist.");
1276 bnd = mapb->basis(it->ps.patch).boundary(it->ps.side());
1277 m_sd->mapper.markBoundary(it->ps.patch, bnd, cc);
1281 gsMatrix<index_t> bnd1;
1282 for (
typename gsBoundaryConditions<T>::const_iterator
1283 it = bc.begin(
"Clamped"); it != bc.end(
"Clamped"); ++it) {
1284 const index_t cc = it->unkComponent();
1286 GISMO_ASSERT(static_cast<size_t>(it->ps.patch) < this->mapper().numPatches(),
1287 "Problem: a boundary condition is set on a patch id which does not exist.");
1289 bnd = mapb->basis(it->ps.patch).boundaryOffset(it->ps.side(), 0);
1290 bnd1 = mapb->basis(it->ps.patch).boundaryOffset(it->ps.side(), 1);
1295 if (!it->ps.parameter())
1297 for (
index_t c = 0; c!=dim; c++)
1299 if (c==cc || cc==-1 )
1300 for (
index_t k = 0; k < bnd.size() - 1; ++k)
1301 m_sd->mapper.matchDof( it->ps.patch, (bnd)(k, 0),
1302 it->ps.patch, (bnd1)(k, 0), c);
1305 gsWarn <<
"Unable to apply clamped condition.\n";
1309 for (
typename gsBoundaryConditions<T>::const_iterator
1310 it = bc.begin(
"Collapsed"); it != bc.end(
"Collapsed"); ++it) {
1311 const index_t cc = it->unkComponent();
1313 GISMO_ASSERT(static_cast<size_t>(it->ps.patch) < this->mapper().numPatches(),
1314 "Problem: a boundary condition is set on a patch id which does not exist.");
1316 bnd = mapb->basis(it->ps.patch).boundary(it->ps.side());
1322 for (
index_t c = 0; c!=dim; c++)
1324 if (c==cc || cc==-1)
1325 for (
index_t k = 0; k < bnd.size() - 1; ++k)
1326 m_sd->mapper.matchDof(it->ps.patch, (bnd)(0, 0),
1327 it->ps.patch, (bnd)(k + 1, 0), c);
1333 for (
typename gsBoundaryConditions<T>::const_citerator
1334 it = bc.cornerBegin(); it != bc.cornerEnd(); ++it)
1338 "Problem: a corner boundary condition is set on a patch id which does not exist.");
1339 m_sd->mapper.eliminateDof(mapb->basis(it->patch).functionAtCorner(it->corner), it->patch, it->component);
1343 GISMO_ASSERT(0 == bc.size(),
"Problem: BCs are ignored.");
1344 m_sd->mapper.setIdentity(this->source().nPieces(), this->source().size());
1347 m_sd->mapper.finalize();
1350 gsDirichletValues(bc, dir_values, *
this);
1353 void print(std::ostream &os)
const { os <<
"u"; }
1357 friend class symbol_expr<gsFeSpace>;
1358 explicit gsFeSpace(
index_t _d = 1) : Base(_d), m_sd(nullptr) { }
1361 template<
class T>
inline bool
1362 operator== (
const gsFeSpace<T> & a,
const gsFeSpace<T> & b)
1363 {
return a.id()== b.id() && a.isAcross()==b.isAcross(); }
1373 class gsFeSolution :
public _expr<gsFeSolution<T> >
1376 const gsFeSpace<T> _u;
1382 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
1384 bool isAcross()
const {
return m_isAcross; }
1386 gsFeSolution right()
const
1388 gsFeSolution ac(*
this);
1389 ac.m_isAcross =
true;
1393 gsFeSolution left()
const {
return gsFeSolution(*
this); }
1395 explicit gsFeSolution(
const gsFeSpace<T> & u) : _u(u), _Sv(NULL) { }
1397 gsFeSolution(
const gsFeSpace<T> & u, gsMatrix<T> & Sv) : _u(u), _Sv(&Sv) { }
1399 const gsFeSpace<T> & space()
const {
return _u;};
1401 mutable gsMatrix<T> res;
1402 const gsMatrix<T> & eval(
index_t k)
const
1404 bool singleActives = (1 == _u.data().actives.cols());
1406 res.setZero(_u.dim(), 1);
1407 const gsDofMapper & map = _u.mapper();
1408 GISMO_ASSERT(_Sv->size()==map.freeSize(),
"The solution vector has wrong dimensions: "<<_Sv->size()<<
" != "<<map.freeSize());
1410 for (
index_t c = 0; c!=_u.dim(); c++)
1412 for (
index_t i = 0; i!=_u.data().actives.rows(); ++i)
1414 const index_t ii = map.index(_u.data().actives(i, singleActives ? 0 : k), _u.data().patchId, c);
1415 if ( map.is_free_index(ii) )
1416 res.at(c) += _Sv->at(ii) * _u.data().values[0](i,k);
1418 res.at(c) += _u.data().values[0](i,k) *
1419 _u.fixedPart().at( map.global_to_bindex(ii) );
1429 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
1430 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
1431 index_t rows()
const {
return _u.dim(); }
1433 static index_t cols() {
return 1; }
1435 void parse(gsExprHelper<Scalar> & evList)
const
1441 void print(std::ostream &os)
const { os <<
"s"; }
1444 index_t dim()
const {
return _u.dim();}
1447 {
return _u.source().domainDim(); }
1450 const gsDofMapper & mapper()
const {
return _u.mapper();}
1452 inline const gsMatrix<T> & fixedPart()
const {
return _u.fixedPart();}
1453 gsMatrix<T> & fixedPart() {
return _u.fixedPart();}
1456 const gsFuncData<T> & data()
const {
return _u.data();}
1458 void setSolutionVector(gsMatrix<T>& solVector)
1459 { _Sv = & solVector; }
1466 void setComponent(
index_t component, real_t value,
index_t patch=-1)
1468 gsMatrix<T> & solVector = *_Sv;
1469 const gsDofMapper & mapper = _u.mapper();
1474 patchEnd = _u.mapper().numPatches();
1478 patchEnd = patch + 1;
1481 for (
index_t p=patchStart; p!=patchEnd; ++p)
1483 for (
size_t i = 0; i != mapper.patchSize(p, component); ++i)
1485 const index_t ii = mapper.index(i, p, component);
1486 if ( mapper.is_free_index(ii) )
1487 solVector.at(ii) = value;
1492 const gsMatrix<T> & coefs()
const {
return *_Sv; }
1503 GISMO_ASSERT(j<_Sv->size(),
"Solution vector is not initialized/allocated, sz="<<_Sv->size() );
1511 void extract(gsMatrix<T> & result,
const index_t p = 0)
const
1512 { _u.getCoeffs(*_Sv, result, p); }
1516 void extractFull(gsMatrix<T> & result)
const
1520 const size_t totalSz = _u.mapper().mapSize();
1521 result.resize(totalSz, 1);
1522 for (
size_t p=0; p!=_u.mapper().numPatches(); ++p)
1524 offset = _u.mapper().offset(p);
1527 for (
index_t c = 0; c!=dim; c++)
1529 const index_t sz = _u.mapper().patchSize(p,c);
1532 for (
index_t i = 0; i < sz; ++i)
1535 const int ii = _u.mapper().index(i, p, c);
1537 if ( _u.mapper().is_free_index(ii) )
1539 result(i+offset,0) = _Sv->at(ii);
1542 result(i+offset,0) = _u.fixedPart().at( _u.mapper().global_to_bindex(ii) );
1550 void extract(gsMultiPatch<T> & result)
const
1554 if(
const gsMultiBasis<T>* basis =
dynamic_cast<const gsMultiBasis<T>*
>(&_u.source()) )
1555 for (
size_t i = 0; i != basis->nBases(); ++i)
1557 memory::unique_ptr<gsGeometry<T> > p(this->extractPiece(i));
1558 result.addPatch(*p);
1563 void extract(gsMappedSpline<2,T> & result)
const
1565 if(
const gsMappedBasis<2,T>* basis =
dynamic_cast<const gsMappedBasis<2,T>*
>(&_u.source()) )
1568 this->extractFull(coefs);
1569 coefs.resize(coefs.rows()/_u.dim(),_u.dim());
1570 result.init(*basis,coefs);
1575 memory::unique_ptr<gsGeometry<T> > extractPiece(
const index_t p)
const
1577 if (
const gsBasis<T> * b =
dynamic_cast<const gsBasis<T>*
>(&_u.source().piece(p)) )
1581 return b->makeGeometry(
give(cf));
1587 void insert(
const gsGeometry<T> & g,
const index_t p = 0)
const
1589 const gsMatrix<T> & cf = g.coefs();
1590 gsMatrix<T> & sol = *_Sv;
1592 const gsDofMapper & mapper = _u.mapper();
1593 for (
index_t c = 0; c!=_u.dim(); c++)
1595 for (
index_t i = 0; i != cf.rows(); ++i)
1597 const index_t ii = mapper.index(i, p, c);
1598 if ( mapper.is_free_index(ii) )
1599 sol.at(ii) = cf(i, c);
1614 template<
class E,
bool cw>
1615 class tr_expr :
public _expr<tr_expr<E,cw> >
1617 typename E::Nested_t _u;
1621 typedef typename E::Scalar Scalar;
1623 tr_expr(_expr<E>
const& u)
1627 enum {ColBlocks = E::ColBlocks, ScalarValued=E::ScalarValued};
1628 enum {Space = cw?E::Space:(E::Space==1?2:(E::Space==2?1:E::Space))};
1630 mutable Temporary_t res;
1631 const Temporary_t & eval(
const index_t k)
const
1634 res = _u.eval(k).blockTranspose( _u.cardinality() );
1636 res = _u.eval(k).transpose();
1640 index_t rows()
const {
return _u.cols(); }
1642 index_t cols()
const {
return _u.rows(); }
1644 void parse(gsExprHelper<Scalar> & evList)
const
1645 { _u.parse(evList); }
1647 const gsFeSpace<Scalar> & rowVar()
const {
return cw?_u.rowVar():_u.colVar(); }
1648 const gsFeSpace<Scalar> & colVar()
const {
return cw?_u.colVar():_u.rowVar(); }
1650 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1652 void print(std::ostream &os)
const { os<<
"("; _u.print(os); os <<
")\u1D40"; }
1669 class cb_expr :
public _expr<cb_expr<E> >
1671 typename E::Nested_t _u;
1675 typedef typename E::Scalar Scalar;
1677 cb_expr(_expr<E>
const& u)
1681 enum {ColBlocks = 1, ScalarValued=E::ScalarValued};
1682 enum {Space = E::Space};
1684 mutable gsMatrix<Scalar> ev, res;
1686 const gsMatrix<Scalar> & eval(
const index_t k)
const
1699 GISMO_ASSERT(res.rows() % _u.rows() == 0 && res.cols() % _u.cols() == 0,
"Result is not a multiple of the space dimensions?");
1702 if ( (cardinality = res.rows() / _u.rows()) >= 1 && res.cols() / _u.cols() == 1 )
1704 res.resize(_u.rows(), cardinality * _u.cols());
1705 for (
index_t r = 0; r!=cardinality; r++)
1706 res.block(0 , r * _u.cols(), _u.rows(), _u.cols()) = ev.block( r * _u.rows(), 0, _u.rows(), _u.cols() );
1708 else if ( (cardinality = res.rows() / _u.rows()) == 1 && res.cols() / _u.cols() >= 1 )
1710 res.resize(_u.rows(), cardinality * _u.cols());
1711 for (
index_t r = 0; r!=cardinality; r++)
1712 res.block(0 , r * _u.cols(), _u.rows(), _u.cols()) = ev.block( 0, r * _u.cols(), _u.rows(), _u.cols() );
1718 index_t rows()
const {
return _u.rows(); }
1720 index_t cols()
const {
return _u.cols(); }
1722 void parse(gsExprHelper<Scalar> & evList)
const
1723 { _u.parse(evList); }
1725 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
1726 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
1728 index_t cardinality_impl()
const
1732 if ( res.rows() / _u.rows() >= 1 && res.cols() / _u.cols() == 1 )
1733 cardinality = res.rows() / _u.rows();
1734 else if ( res.rows() / _u.rows() == 1 && res.cols() / _u.cols() >= 1 )
1735 cardinality = res.cols() / _u.cols();
1737 GISMO_ERROR(
"Cardinality for cb_expr cannot be determined.");
1742 void print(std::ostream &os)
const { os<<
"{"; _u.print(os); os <<
"}"; }
1750 class temp_expr :
public _expr<temp_expr<E> >
1752 typename E::Nested_t _u;
1753 typedef typename E::Scalar Scalar;
1754 mutable gsMatrix<Scalar> tmp;
1757 temp_expr(_expr<E>
const& u)
1761 enum {Space = E::Space, ScalarValued = E::ScalarValued,
1762 ColBlocks = E::ColBlocks};
1766 const gsMatrix<Scalar> & eval(
const index_t k)
const
1772 index_t rows()
const {
return _u.rows(); }
1773 index_t cols()
const {
return _u.cols(); }
1774 void parse(gsExprHelper<Scalar> & evList)
const { _u.parse(evList); }
1775 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
1776 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
1778 void print(std::ostream &os)
const { _u.print(os); }
1785 class trace_expr :
public _expr<trace_expr<E> >
1788 typedef typename E::Scalar Scalar;
1789 enum {ScalarValued = 0, Space = E::Space, ColBlocks= 0};
1792 typename E::Nested_t _u;
1793 mutable gsMatrix<Scalar> res;
1796 trace_expr(_expr<E>
const& u) : _u(u)
1803 const gsMatrix<Scalar> & eval(
const index_t k)
const
1805 auto tmp = _u.eval(k);
1807 const index_t r = _u.cardinality();
1813 for (
index_t i = 0; i!=r; ++i)
1814 res.at(i) = tmp.middleCols(i*cb,cb).trace();
1821 index_t rows()
const {
return _u.cols() / _u.rows(); }
1822 index_t cols()
const {
return 1; }
1824 index_t cardinality_impl()
const {
return _u.cardinality(); }
1826 void parse(gsExprHelper<Scalar> & evList)
const
1827 { _u.parse(evList); }
1829 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
1830 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
1832 void print(std::ostream &os)
const { os <<
"trace("; _u.print(os); os<<
")"; }
1839 class adjugate_expr :
public _expr<adjugate_expr<E> >
1842 typedef typename E::Scalar Scalar;
1843 enum {ScalarValued = 0, ColBlocks = E::ColBlocks};
1844 enum {Space = E::Space};
1846 typename E::Nested_t _u;
1847 mutable gsMatrix<Scalar> res;
1850 adjugate_expr(_expr<E>
const& u) : _u(u)
1857 const gsMatrix<Scalar> & eval(
const index_t k)
const
1859 auto tmp = _u.eval(k);
1861 const index_t r = _u.cols() / cb;
1862 res.resize(_u.rows(),_u.cols());
1863 for (
index_t i = 0; i!=r; ++i){
1864 res.middleCols(i*cb,cb) = tmp.middleCols(i*cb,cb).adjugate();
1872 index_t rows()
const {
return _u.rows(); }
1873 index_t cols()
const {
return _u.cols(); }
1875 void parse(gsExprHelper<Scalar> & evList)
const
1876 { _u.parse(evList); }
1878 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
1879 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
1881 void print(std::ostream &os)
const { os <<
"adj("; _u.print(os); os<<
")"; }
1885 class reshape_expr :
public _expr<reshape_expr<E> >
1888 typedef typename E::Scalar Scalar;
1889 enum {ScalarValued = 0, ColBlocks = E::ColBlocks};
1890 enum {Space = E::Space};
1892 typename E::Nested_t _u;
1894 mutable gsMatrix<Scalar> tmp;
1899 reshape_expr(_expr<E>
const& u,
index_t n,
index_t m) : _u(u), _n(n), _m(m)
1904 const gsAsConstMatrix<Scalar> eval(
const index_t k)
const
1907 GISMO_ASSERT( _u.rows()*_u.cols() == _n*_m,
"Wrong dimension "
1908 << _u.rows() <<
" x "<<_u.cols() <<
"!=" << _n <<
" * "<< _m );
1910 return gsAsConstMatrix<Scalar>(tmp.data(),_n,_m);
1913 index_t rows()
const {
return _n; }
1914 index_t cols()
const {
return _m; }
1916 void parse(gsExprHelper<Scalar> & evList)
const
1917 { _u.parse(evList); }
1919 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
1920 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
1922 void print(std::ostream &os)
const { os <<
"reshape("; _u.print(os); os<<
","<<_n<<
","<<_m<<
")"; }
1926 template <
typename E> EIGEN_STRONG_INLINE
1928 {
return reshape_expr<E>(u, n, m); }
1931 class replicate_expr :
public _expr<replicate_expr<E> >
1934 typedef typename E::Scalar Scalar;
1935 enum {ScalarValued = 0, Space = E::Space, ColBlocks= E::ColBlocks};
1937 typename E::Nested_t _u;
1939 mutable gsMatrix<Scalar> tmp;
1944 replicate_expr(_expr<E>
const& u,
index_t n,
index_t m) : _u(u), _n(n), _m(m)
1948 auto eval(
const index_t k)
const -> decltype(tmp.replicate(_n,_m))
1951 return tmp.replicate(_n,_m);
1954 index_t rows()
const {
return _n*_u.rows(); }
1955 index_t cols()
const {
return _m*_u.cols(); }
1957 void parse(gsExprHelper<Scalar> & evList)
const
1958 { _u.parse(evList); }
1960 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
1961 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
1962 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1964 void print(std::ostream &os)
const { os <<
"replicate("; _u.print(os); os<<
","<<_n<<
","<<_m<<
")"; }
1968 template <
typename E> EIGEN_STRONG_INLINE
1970 {
return replicate_expr<E>(u, n, m); }
1983 typedef typename E::Scalar Scalar;
1984 enum {ScalarValued = 0, Space = E::Space, ColBlocks= 0};
1986 typename E::Nested_t _u;
1999 const index_t numActives = _u.cardinality();
2001 for (
index_t i = 0; i<numActives; ++i)
2003 tmp(0,2*i+1) += tmp(1,2*i);
2004 std::swap(tmp(1,2*i), tmp(1,2*i+1));
2007 tmp.resize(4,numActives);
2008 tmp.conservativeResize(3,numActives);
2011 tmp.transposeInPlace();
2013 tmp.transposeInPlace();
2018 index_t rows()
const {
return 1; }
2019 index_t cols()
const {
return 3; }
2022 { _u.parse(evList); }
2026 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
2028 void print(std::ostream &os)
const { os <<
"flat("; _u.print(os); os<<
")"; }
2032 template <
typename E> EIGEN_STRONG_INLINE
2041 class diag_expr :
public _expr<diag_expr<E> >
2044 typedef typename E::Scalar Scalar;
2045 enum {Space=0, ColBlocks=E::ColBlocks, ScalarValued = 0};
2047 typename E::Nested_t _u;
2048 mutable gsMatrix<Scalar> res;
2051 diag_expr(_expr<E>
const& u) : _u(u)
2053 GISMO_ASSERT(0== _u.cols()%_u.rows(),
"Expecting square-block expression, got "
2054 << _u.rows() <<
" x "<< _u.cols() );
2057 const gsMatrix<Scalar> & eval(
const index_t k)
const
2062 const index_t r = _u.cols() / cb;
2064 for (
index_t i = 0; i!=r; ++i)
2065 res.row(i) = tmp.middleCols(i*cb,cb).diagonal();
2069 index_t rows()
const {
return _u.cols() / _u.rows(); }
2070 index_t cols()
const {
return _u.rows(); }
2072 void parse(gsExprHelper<Scalar> & evList)
const
2073 { _u.parse(evList); }
2075 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2076 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
2079 void print(std::ostream &os)
const { os <<
"diag("; _u.print(os); os<<
")"; }
2083 template <
typename E> EIGEN_STRONG_INLINE
2085 {
return diag_expr<E>(u); }
2087 #define GISMO_EXPR_VECTOR_EXPRESSION(name, mname, isSv) \
2088 template<class E> class name##_##expr : public _expr<name##_##expr<E> > { \
2089 typename E::Nested_t _u; \
2091 typedef typename E::Scalar Scalar; \
2092 enum {Space= E::Space, ScalarValued= isSv, ColBlocks= E::ColBlocks}; \
2093 name##_##expr(_expr<E> const& u) : _u(u) { } \
2094 mutable Temporary_t tmp; \
2095 const Temporary_t & eval(const index_t k) const { \
2096 tmp = _u.eval(k).mname(); return tmp; } \
2097 index_t rows() const { return isSv ? 0 : _u.rows(); } \
2098 index_t cols() const { return isSv ? 0 : _u.cols(); } \
2099 void parse(gsExprHelper<Scalar> & evList) const { _u.parse(evList); } \
2100 const gsFeSpace<Scalar> & rowVar() const {return gsNullExpr<Scalar>::get();} \
2101 const gsFeSpace<Scalar> & colVar() const {return gsNullExpr<Scalar>::get();} \
2102 void print(std::ostream &os) const \
2103 { os << #name <<"("; _u.print(os); os <<")"; } \
2124 #undef GISMO_EXPR_VECTOR_EXPRESSION
2130 class asdiag_expr :
public _expr<asdiag_expr<E> >
2133 typedef typename E::Scalar Scalar;
2135 typename E::Nested_t _u;
2139 enum{Space = E::Space, ScalarValued= 0, ColBlocks= E::ColBlocks};
2141 asdiag_expr(_expr<E>
const& u) : _u(u) { }
2145 const gsMatrix<Scalar> & eval(
const index_t k)
const
2147 auto m = _u.eval(k);
2151 for (
index_t i = 0; i!=c; ++i)
2152 res.middleCols(i*r,r) = m.col(i).asDiagonal();
2156 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2157 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
2159 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
2161 index_t rows()
const {
return _u.rows(); }
2162 index_t cols()
const {
return _u.rows() * _u.cols(); }
2163 void parse(gsExprHelper<Scalar> & evList)
const
2164 { _u.parse(evList); }
2166 void print(std::ostream &os)
const { os <<
"diag("; _u.print(os); os <<
")";}
2171 class max_expr :
public _expr<max_expr<E> >
2174 typedef typename E::Scalar Scalar;
2175 enum {ScalarValued = 0, Space = E::Space, ColBlocks = 1};
2177 typename E::Nested_t _u;
2178 mutable gsMatrix<Scalar> tmp;
2179 mutable gsMatrix<Scalar> res;
2183 max_expr(_expr<E>
const& u) : _u(u)
2188 const gsMatrix<Scalar> & eval(
const index_t k)
const {
return eval_impl(_u,k); }
2190 index_t rows()
const {
return 1; }
2191 index_t cols()
const {
return 1; }
2192 void setFlag()
const { _u.setFlag(); }
2194 void parse(gsExprHelper<Scalar> & evList)
const
2195 { _u.parse(evList); }
2197 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2198 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
2199 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
2201 void print(std::ostream &os)
const { os <<
"max("; _u.print(os); os<<
")"; }
2203 template<
class U>
inline
2204 typename util::enable_if< util::is_same<U,gsFeSpace<Scalar> >::value,
const gsMatrix<Scalar> & >::type
2205 eval_impl(
const U & u,
const index_t k)
const
2209 res.resize(1,u.cardinality());
2211 for (
index_t c=0; c!=_u.cardinality(); c++)
2212 res(0,c) = tmp.block(0,c*u.cols(),u.rows(),u.cols()).maxCoeff();
2214 for (
index_t c=0; c!=_u.rows(); c++)
2215 res(0,c) = tmp.block(c*u.rows(),0,u.rows(),u.cols()).maxCoeff();
2220 template<
class U>
inline
2221 typename util::enable_if< !util::is_same<U,gsFeSpace<Scalar> >::value,
const gsMatrix<Scalar> & >::type
2222 eval_impl(
const U & u,
const index_t k)
const
2224 res = u.eval(k).colwise().maxCoeff();
2230 class rowsum_expr :
public _expr<rowsum_expr<E> >
2233 typedef typename E::Scalar Scalar;
2234 enum {ScalarValued = 0, Space = E::Space, ColBlocks = E::ColBlocks};
2236 typename E::Nested_t _u;
2237 mutable gsMatrix<Scalar> tmp;
2241 rowsum_expr(_expr<E>
const& u) : _u(u)
2246 const gsMatrix<Scalar> & eval(
const index_t k)
const
2248 tmp = _u.eval(k).rowwise().sum();
2252 index_t rows()
const {
return _u.rows(); }
2253 index_t cols()
const {
return 1; }
2254 void setFlag()
const { _u.setFlag(); }
2256 void parse(gsExprHelper<Scalar> & evList)
const
2257 { _u.parse(evList); }
2259 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2260 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
2261 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
2263 void print(std::ostream &os)
const { os <<
"rowsum("; _u.print(os); os<<
")"; }
2267 class colsum_expr :
public _expr<colsum_expr<E> >
2270 typedef typename E::Scalar Scalar;
2271 enum {ScalarValued = 0, Space = E::Space, ColBlocks = E::ColBlocks};
2273 typename E::Nested_t _u;
2274 mutable gsMatrix<Scalar> tmp;
2278 colsum_expr(_expr<E>
const& u) : _u(u)
2283 const gsMatrix<Scalar> & eval(
const index_t k)
const
2285 tmp = _u.eval(k).colwise().sum();
2289 index_t rows()
const {
return _u.rows(); }
2290 index_t cols()
const {
return 1; }
2291 void setFlag()
const { _u.setFlag(); }
2293 void parse(gsExprHelper<Scalar> & evList)
const
2294 { _u.parse(evList); }
2296 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2297 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
2298 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
2300 void print(std::ostream &os)
const { os <<
"colsum("; _u.print(os); os<<
")"; }
2309 typedef real_t Scalar;
2310 enum {Space = 0, ScalarValued = 0, ColBlocks = 0};
2324 index_t rows()
const {
return _dim; }
2325 index_t cols()
const {
return _dim; }
2331 void print(std::ostream &os)
const { os <<
"id("<<_dim <<
")";}
2340 typedef real_t Scalar;
2341 enum {Space = 0, ScalarValued = 0, ColBlocks = 0};
2355 index_t rows()
const {
return _mat.rows(); }
2356 index_t cols()
const {
return _mat.cols(); }
2362 void print(std::ostream &os)
const { os <<
"constMat";}
2369 class sign_expr :
public _expr<sign_expr<E> >
2371 typename E::Nested_t _u;
2372 typename E::Scalar _tol;
2374 typedef typename E::Scalar Scalar;
2375 enum {ScalarValued = 1, Space = E::Space, ColBlocks= 0};
2377 sign_expr(_expr<E>
const& u, Scalar tolerance = 0.0) : _u(u),_tol(tolerance){
2378 GISMO_ASSERT( _tol >= 0,
"Tolerance for sign_expr should be a positive number.");
2381 Scalar eval(
const index_t k)
const
2383 const Scalar v = _u.val().eval(k);
2384 return ( v>_tol ? 1 : ( v<-_tol ? -1 : 0 ) );
2387 static index_t rows() {
return 0; }
2388 static index_t cols() {
return 0; }
2390 void parse(gsExprHelper<Scalar> & el)
const
2393 static bool isScalar() {
return true; }
2395 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
2396 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
2398 void print(std::ostream &os)
const { os<<
"sgn("; _u.print(os); os <<
")"; }
2405 class exp_expr :
public _expr<exp_expr<E> >
2407 typename E::Nested_t _u;
2409 typedef typename E::Scalar Scalar;
2410 enum {ScalarValued = 1, Space = E::Space, ColBlocks= 0};
2412 exp_expr(_expr<E>
const& u) : _u(u) { }
2414 Scalar eval(
const index_t k)
const
2416 const Scalar v = _u.val().eval(k);
2417 return math::exp(v);
2420 static index_t rows() {
return 0; }
2421 static index_t cols() {
return 0; }
2423 void parse(gsExprHelper<Scalar> & el)
const
2426 static bool isScalar() {
return true; }
2428 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
2429 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
2431 void print(std::ostream &os)
const { os<<
"exp("; _u.print(os); os <<
")"; }
2438 class ppart_expr :
public _expr<ppart_expr<E> >
2441 typedef typename E::Scalar Scalar;
2442 enum {ScalarValued = E::ScalarValued, Space = E::Space, ColBlocks= E::ColBlocks};
2444 typename E::Nested_t _u;
2445 mutable gsMatrix<Scalar> res;
2448 ppart_expr(_expr<E>
const& u) : _u(u) { }
2450 const gsMatrix<Scalar> & eval(
index_t k)
const
2452 res = _u.eval(k).cwiseMax(0.0);
2457 index_t rows()
const {
return _u.rows(); }
2458 index_t cols()
const {
return _u.cols(); }
2460 void parse(gsExprHelper<Scalar> & el)
const
2463 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar();}
2464 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar();}
2466 void print(std::ostream &os)
const { os<<
"posPart("; _u.print(os); os <<
")"; }
2473 class ppartval_expr :
public _expr<ppartval_expr<E> >
2475 typename E::Nested_t _u;
2477 typedef typename E::Scalar Scalar;
2478 enum {ScalarValued = 1, Space = 0, ColBlocks= 0};
2482 ppartval_expr(_expr<E>
const& u) : _u(u) { }
2484 Scalar & eval(
index_t k)
const
2486 res = std::max(0.0,_u.eval(k));
2490 index_t rows()
const {
return 0; }
2491 index_t cols()
const {
return 0; }
2493 void parse(gsExprHelper<Scalar> & evList)
const
2494 { _u.parse(evList); }
2496 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
2497 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
2499 void print(std::ostream &os)
const { os<<
"posPart("; _u.print(os); os <<
")"; }
2506 class pow_expr :
public _expr<pow_expr<E> >
2508 typename E::Nested_t _u;
2511 typedef typename E::Scalar Scalar;
2512 enum {ScalarValued = 1, Space = E::Space, ColBlocks= E::ColBlocks};
2516 pow_expr(_expr<E>
const& u, Scalar q) : _u(u), _q(q) { }
2518 Scalar eval(
const index_t k)
const
2520 const Scalar v = _u.val().eval(k);
2521 return math::pow(v,_q);
2524 static index_t rows() {
return 0; }
2525 static index_t cols() {
return 0; }
2527 void parse(gsExprHelper<Scalar> & el)
const
2530 static bool isScalar() {
return true; }
2532 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
2533 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
2535 void print(std::ostream &os)
const { os<<
"pow("; _u.print(os); os <<
")"; }
2543 template <
typename E1,
typename E2>
2547 typedef typename E1::Scalar Scalar;
2548 enum {ScalarValued = 0, ColBlocks = 1};
2549 enum {Space = E2::Space};
2552 typename E1::Nested_t _u;
2553 typename E2::Nested_t _v;
2564 const index_t N = _v.cols() / (r*r);
2566 const auto uEv = _u.eval(k);
2567 const auto vEv = _v.eval(k);
2569 res.resize(r, N*r*r);
2571 for (
index_t s = 0; s!=r; ++s)
2572 for (
index_t i = 0; i!=N; ++i)
2574 res.middleCols((s*N + i)*r,r).noalias() =
2575 uEv.col(s) * vEv.middleCols((s*N + i)*r,r).row(s);
2582 index_t rows()
const {
return _u.cols(); }
2583 index_t cols()
const {
return _v.cols(); }
2586 { _u.parse(evList); _v.parse(evList); }
2591 void print(std::ostream &os)
const { os <<
"matrix_by_space("; _u.print(os); os<<
")"; }
2599 template <
typename E1,
typename E2>
2603 typedef typename E1::Scalar Scalar;
2604 enum {ScalarValued = 0, ColBlocks = 1};
2605 enum {Space = E2::Space};
2608 typename E1::Nested_t _u;
2609 typename E2::Nested_t _v;
2620 const index_t N = _v.cols() / (r*r);
2622 const auto uEv = _u.eval(k);
2623 const auto vEv = _v.eval(k);
2625 res.resize(r, N*r*r);
2626 for (
index_t s = 0; s!=r; ++s)
2627 for (
index_t i = 0; i!=N; ++i)
2629 res.middleCols((s*N + i)*r,r).noalias() =
2630 uEv.transpose()*vEv.middleCols((s*N + i)*r,r).transpose();
2636 index_t rows()
const {
return _u.cols(); }
2637 index_t cols()
const {
return _v.cols(); }
2640 { _u.parse(evList); _v.parse(evList); }
2645 void print(std::ostream &os)
const { os <<
"matrix_by_space_tr("; _u.print(os); os<<
")"; }
2652 class value_expr :
public _expr<value_expr<E> >
2654 typename E::Nested_t _u;
2657 typedef typename E::Scalar Scalar;
2658 value_expr(_expr<E>
const& u) : _u(u)
2665 enum {Space= 0, ScalarValued= 1, ColBlocks= 0};
2667 Scalar eval(
const index_t k)
const {
return eval_impl(_u,k); }
2670 inline value_expr<E> val()
const {
return *
this; }
2671 index_t rows()
const {
return 0; }
2672 index_t cols()
const {
return 0; }
2673 void parse(gsExprHelper<Scalar> & evList)
const
2674 { _u.parse(evList); }
2676 static bool isScalar() {
return true; }
2678 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
2679 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
2681 void print(std::ostream &os)
const { _u.print(os); }
2686 template<
class U>
static inline
2687 typename util::enable_if<U::ScalarValued,Scalar>::type
2688 eval_impl(
const U & u,
const index_t k) {
return u.eval(k); }
2690 template<
class U>
static inline
2691 typename util::enable_if<!U::ScalarValued,Scalar>::type
2692 eval_impl(
const U & u,
const index_t k) {
return u.eval(k).value(); }
2696 class abs_expr :
public _expr<abs_expr<E> >
2698 typename E::Nested_t _u;
2701 typedef typename E::Scalar Scalar;
2702 explicit abs_expr(_expr<E>
const& u) : _u(u) { }
2705 enum {Space= 0, ScalarValued= 1, ColBlocks= 0};
2707 Scalar eval(
const index_t k)
const {
return abs_expr::eval_impl(_u,k); }
2709 index_t rows()
const {
return _u.rows(); }
2710 index_t cols()
const {
return _u.cols(); }
2711 void parse(gsExprHelper<Scalar> & evList)
const
2712 { _u.parse(evList); }
2714 static bool isScalar() {
return true; }
2716 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get();}
2717 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get();}
2719 void print(std::ostream &os)
const { _u.print(os); }
2724 template<
class U>
static inline
2725 typename util::enable_if<U::ScalarValued,Scalar>::type
2727 template<
class U>
static inline
2728 typename util::enable_if<!U::ScalarValued,gsMatrix<Scalar> >::type
2729 eval_impl(
const U & u,
const index_t k) {
return u.eval(k).cwiseAbs(); }
2738 class grad_expr :
public _expr<grad_expr<E> >
2740 typename E::Nested_t _u;
2742 enum {Space = E::Space, ScalarValued= 0, ColBlocks= 0};
2744 typedef typename E::Scalar Scalar;
2745 mutable gsMatrix<Scalar> tmp;
2747 grad_expr(
const E & u) : _u(u)
2748 {
GISMO_ASSERT(1==u.dim(),
"grad(.) requires 1D variable, use jac(.) instead.");}
2750 const gsMatrix<Scalar> & eval(
const index_t k)
const
2755 tmp = _u.data().values[1].reshapeCol(k, cols(), cardinality_impl()).transpose();
2759 index_t rows()
const {
return 1 ; }
2761 index_t cols()
const {
return _u.source().domainDim(); }
2763 index_t cardinality_impl()
const
2764 {
return _u.data().values[1].rows() / cols(); }
2766 void parse(gsExprHelper<Scalar> & evList)
const
2769 _u.data().flags |= NEED_GRAD;
2772 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2773 const gsFeSpace<Scalar> & colVar()
const
2774 {
return gsNullExpr<Scalar>::get();}
2776 void print(std::ostream &os)
const { os <<
"\u2207("; _u.print(os); os <<
")"; }
2779 template<
class U>
static inline
2780 typename util::enable_if<util::is_same<U,gsComposition<Scalar> >::value,
2781 const gsMatrix<Scalar> &>::type
2782 eval_impl(
const U & u,
const index_t k)
2796 class grad_expr<gsFeSolution<T> > :
public _expr<grad_expr<gsFeSolution<T> > >
2799 const gsFeSolution<T> _u;
2803 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
2805 explicit grad_expr(
const gsFeSolution<T> & u) : _u(u) { }
2807 mutable gsMatrix<T> res;
2808 const gsMatrix<T> & eval(
index_t k)
const
2810 GISMO_ASSERT(1==_u.data().actives.cols(),
"Single actives expected");
2812 res.setZero(_u.dim(), _u.parDim());
2813 const gsDofMapper & map = _u.mapper();
2814 for (
index_t c = 0; c!= _u.dim(); c++)
2816 for (
index_t i = 0; i!=_u.data().actives.size(); ++i)
2818 const index_t ii = map.index(_u.data().actives.at(i), _u.data().patchId,c);
2819 if ( map.is_free_index(ii) )
2821 res.row(c) += _u.coefs().at(ii) *
2822 _u.data().values[1].col(k).segment(i*_u.parDim(), _u.parDim()).transpose();
2827 _u.fixedPart().at( map.global_to_bindex(ii) ) *
2828 _u.data().values[1].col(k).segment(i*_u.parDim(), _u.parDim()).transpose();
2835 index_t rows()
const {
return _u.dim();}
2836 index_t cols()
const {
return _u.parDim(); }
2838 const gsFeSpace<Scalar> & rowVar()
const
2839 {
return gsNullExpr<Scalar>::get();}
2840 const gsFeSpace<Scalar> & colVar()
const
2841 {
return gsNullExpr<Scalar>::get();}
2843 void parse(gsExprHelper<Scalar> & evList)
const
2846 evList.add(_u.space());
2850 void print(std::ostream &os)
const { os <<
"\u2207(s)"; }
2860 class dJacdc_expr :
public _expr<dJacdc_expr<E> >
2862 typename E::Nested_t _u;
2864 enum{ Space = E::Space, ScalarValued = 0, ColBlocks = (1==E::Space?1:0)};
2866 typedef typename E::Scalar Scalar;
2868 mutable gsMatrix<Scalar> res;
2871 dJacdc_expr(
const E & u,
index_t c) : _u(u), _c(c)
2872 {
GISMO_ASSERT(1==u.dim(),
"grad(.) requires 1D variable, use jac(.) instead.");}
2874 const gsMatrix<Scalar> & eval(
const index_t k)
const
2876 index_t dd = _u.source().domainDim();
2878 res.setZero(dd, dd*n);
2880 gsMatrix<Scalar>
grad = _u.data().values[1].reshapeCol(k, dd, n);
2881 for(
index_t i = 0; i < n; i++){
2882 res.row(_c).segment(i*dd,dd) = grad.col(i);
2887 index_t rows()
const {
return _u.source().domainDim(); }
2889 index_t cols()
const {
return _u.source().domainDim()*_u.rows(); }
2891 void parse(gsExprHelper<Scalar> & evList)
const
2894 _u.data().flags |= NEED_GRAD;
2897 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
2898 const gsFeSpace<Scalar> & colVar()
const
2899 {
return gsNullExpr<Scalar>::get();}
2901 void print(std::ostream &os)
const { os <<
"dJacdc("; _u.print(os); os <<
")"; }
2909 class nabla_expr :
public _expr<nabla_expr<T> >
2911 typename gsFeVariable<T>::Nested_t u;
2922 nabla_expr(
const gsFeVariable<T> & _u) : u(_u)
2928 mutable gsMatrix<Scalar> res;
2930 const gsMatrix<Scalar> & eval(
const index_t k)
const
2934 res.setZero(rows(), d);
2936 for (
index_t i = 0; i!=d; ++i)
2937 res.col(i).segment(i*n,n) = u.data().values[1].reshapeCol(k, d, n).row(i);
2941 index_t rows()
const {
return u.rows(); }
2942 index_t cols()
const {
return u.cols(); }
2944 void parse(gsExprHelper<Scalar> & evList)
const
2947 u.data().flags |= NEED_GRAD;
2950 const gsFeSpace<T> & rowVar()
const {
return u.rowVar(); }
2951 const gsFeSpace<T> & colVar()
const
2952 {
return gsNullExpr<Scalar>::get();}
2954 void print(std::ostream &os)
const { os <<
"nabla("; u.print(os); os <<
")"; }
2964 class nabla2_expr :
public _expr<nabla2_expr<T> >
2966 typename gsFeVariable<T>::Nested_t u;
2977 nabla2_expr(
const gsFeVariable<T> & _u)
2984 return u.data().values[2]
2985 .reShapeCol(k, u.data().values[2].rows()/u.cSize(), u.cSize() )
2986 .topRows(u.parDim()).transpose();
2989 index_t rows()
const {
return u.rows(); }
2990 index_t cols()
const {
return u.parDim(); }
2992 void parse(gsExprHelper<Scalar> & evList)
const
2998 const gsFeSpace<T> & rowVar()
const {
return u.rowVar(); }
2999 const gsFeSpace<T> & colVar()
const
3000 {
return gsNullExpr<T>::get();}
3015 typename gsGeometryMap<T>::Nested_t _G;
3019 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
3021 explicit onormal_expr(
const gsGeometryMap<T> & G) : _G(G) { }
3023 auto eval(
const index_t k)
const -> decltype(_G.data().outNormals.col(k))
3024 {
return _G.data().outNormals.col(k); }
3026 index_t rows()
const {
return _G.source().targetDim(); }
3027 index_t cols()
const {
return 1; }
3029 const gsFeSpace<T> & rowVar()
const {
return gsNullExpr<T>::get();}
3030 const gsFeSpace<T> & colVar()
const {
return gsNullExpr<T>::get();}
3038 void print(std::ostream &os)
const { os <<
"nv("; _G.print(os); os <<
")"; }
3048 typename gsGeometryMap<T>::Nested_t _G;
3052 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
3056 GISMO_ENSURE( _G.source().domainDim()+1 == _G.source().targetDim(),
"Surface normal requires codimension 1");
3059 auto eval(
const index_t k)
const -> decltype(_G.data().normals.col(k))
3060 {
return _G.data().normals.col(k); }
3062 index_t rows()
const {
return _G.source().targetDim(); }
3063 index_t cols()
const {
return 1; }
3065 const gsFeSpace<T> & rowVar()
const {
return gsNullExpr<T>::get();}
3066 const gsFeSpace<T> & colVar()
const {
return gsNullExpr<T>::get();}
3074 void print(std::ostream &os)
const { os <<
"sn("; _G.print(os); os <<
")"; }
3084 typename gsGeometryMap<T>::Nested_t _G;
3088 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
3095 if (_G.targetDim()==2)
3097 res = _G.data().outNormals.col(k);
3098 std::swap( res(0,0), res(1,0) );
3102 else if (_G.targetDim()==3)
3105 res.col3d(0) = _G.data().normals.col3d(k)
3106 .cross( _G.data().outNormals.col3d(k) );
3110 GISMO_ERROR(
"Function not implemented for dimension"<<_G.targetDim());
3114 index_t rows()
const {
return _G.source().targetDim(); }
3115 index_t cols()
const {
return 1; }
3127 void print(std::ostream &os)
const { os <<
"tv("; _G.print(os); os <<
")"; }
3136 typename E::Nested_t _u;
3139 typedef typename E::Scalar Scalar;
3140 enum {Space = E::Space, ScalarValued= 0, ColBlocks= 0};
3144 auto eval(
const index_t k)
const -> decltype(_u.data().laplacians.col(k))
3147 return _u.data().laplacians.col(k);
3153 index_t rows()
const {
return _u.data().laplacians.rows(); }
3154 index_t cols()
const {
return 1; }
3156 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
3167 void print(std::ostream &os)
const { os <<
"\u2206("; _u.print(os); os <<
")"; }
3174 class lapl_expr<gsFeSolution<T> > :
public _expr<lapl_expr<gsFeSolution<T> > >
3177 const gsFeSolution<T> _u;
3181 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
3183 lapl_expr(
const gsFeSolution<T> & u) : _u(u) { }
3185 mutable gsMatrix<T> res;
3186 const gsMatrix<T> & eval(
const index_t k)
const
3188 GISMO_ASSERT(1==_u.data().actives.cols(),
"Single actives expected");
3190 res.setZero(_u.dim(), 1);
3191 const gsDofMapper & map = _u.mapper();
3193 index_t numActs = _u.data().values[0].rows();
3194 index_t numDers = _u.parDim() * (_u.parDim() + 1) / 2;
3197 for (
index_t c = 0; c!= _u.dim(); c++)
3198 for (
index_t i = 0; i!=numActs; ++i)
3200 const index_t ii = map.index(_u.data().actives.at(i), _u.data().patchId,c);
3201 deriv2 = _u.data().values[2].block(i*numDers,k,_u.parDim(),1);
3202 if ( map.is_free_index(ii) )
3203 res.at(c) += _u.coefs().at(ii) * deriv2.sum();
3205 res.at(c) +=_u.fixedPart().at( map.global_to_bindex(ii) ) * deriv2.sum();
3210 index_t rows()
const {
return _u.dim(); }
3211 index_t cols()
const {
return 1; }
3213 void parse(gsExprHelper<Scalar> & evList)
const
3215 evList.add(_u.space());
3219 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<T>::get();}
3220 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<T>::get();}
3222 void print(std::ostream &os)
const { os <<
"\u2206(s)"; }
3229 class fform2nd_expr :
public _expr<fform2nd_expr<T> >
3231 typename gsGeometryMap<T>::Nested_t _G;
3234 enum {Space = 0, ScalarValued = 0, ColBlocks = 0};
3236 fform2nd_expr(
const gsGeometryMap<T> & G) : _G(G) { }
3238 const gsAsConstMatrix<Scalar> eval(
const index_t k)
const
3240 return gsAsConstMatrix<Scalar>(_G.data().fundForms.col(k).data(),rows(),cols());
3243 index_t rows()
const {
return _G.source().domainDim() ; }
3244 index_t cols()
const {
return _G.source().domainDim() ; }
3246 void parse(gsExprHelper<Scalar> & evList)
const
3252 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<T>::get();}
3253 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<T>::get();}
3255 void print(std::ostream &os)
const { os <<
"fform2nd("; _G.print(os); os <<
")"; }
3263 class jacInv_expr :
public _expr<jacInv_expr<T> >
3265 typename gsGeometryMap<T>::Nested_t _G;
3268 enum {Space = 0, ScalarValued = 0, ColBlocks = 0};
3270 jacInv_expr(
const gsGeometryMap<T> & G) : _G(G)
3276 MatExprType eval(
const index_t k)
const {
return _G.data().jacInvTr.reshapeCol(k,cols(),rows()).transpose(); }
3278 index_t rows()
const {
return _G.source().domainDim(); }
3279 index_t cols()
const {
return _G.source().targetDim(); }
3281 void parse(gsExprHelper<Scalar> & evList)
const
3287 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<T>::get();}
3288 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<T>::get();}
3293 void print(std::ostream &os)
const { os <<
"jacInv("; _G.print(os); os <<
")"; }
3300 class jac_expr :
public _expr<jac_expr<E> >
3302 typename E::Nested_t _u;
3304 enum {ColBlocks = (1==E::Space?1:0) };
3305 enum {Space = E::Space, ScalarValued= 0 };
3307 typedef typename E::Scalar Scalar;
3309 mutable gsMatrix<Scalar> res;
3311 jac_expr(
const E & _u_)
3319 res = _u.data().values[1].col(k).transpose().blockDiag(_u.dim());
3323 res = _u.data().values[1]
3324 .reshapeCol(k, _u.parDim(), _u.targetDim()).transpose()
3325 .blockDiag(_u.dim());
3330 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
3332 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get(); }
3334 index_t rows()
const {
return rows_impl(_u); }
3335 index_t cols()
const {
return cols_impl(_u); }
3340 index_t cardinality_impl()
const
3342 return _u.dim() * _u.data().actives.rows();
3345 void parse(gsExprHelper<Scalar> & evList)
const
3352 void print(std::ostream &os)
const { os <<
"\u2207("; _u.print(os);os <<
")"; }
3360 template<
class U>
inline
3361 typename util::enable_if<!(util::is_same<U,gsFeSpace<Scalar> >::value),
index_t >::type
3362 rows_impl(
const U & u)
const
3364 return u.source().targetDim();
3367 template<
class U>
inline
3368 typename util::enable_if< (util::is_same<U,gsFeSpace<Scalar> >::value),
index_t >::type
3369 rows_impl(
const U & u)
const
3374 template<
class U>
inline
3375 typename util::enable_if<!(util::is_same<U,gsFeSpace<Scalar> >::value),
index_t >::type
3376 cols_impl(
const U & u)
const
3378 return u.source().domainDim();
3381 template<
class U>
inline
3382 typename util::enable_if< (util::is_same<U,gsFeSpace<Scalar> >::value),
index_t >::type
3383 cols_impl(
const U & u)
const
3385 return u.source().domainDim();
3392 template<
class U>
inline
3393 typename util::enable_if<!(util::is_same<U,gsFeSpace<Scalar> >::value),
const gsFeSpace<Scalar> & >::type
3396 return gsNullExpr<Scalar>::get();
3399 template<
class U>
inline
3400 typename util::enable_if<(util::is_same<U,gsFeSpace<Scalar> >::value),
const gsFeSpace<Scalar> & >::type
3411 class jac_expr<gsGeometryMap<T> > :
public _expr<jac_expr<gsGeometryMap<T> > >
3413 typename gsGeometryMap<T>::Nested_t _G;
3417 enum {Space = 0, ScalarValued= 0, ColBlocks= 0};
3419 jac_expr(
const gsGeometryMap<T> & G) : _G(G) { }
3423 return _G.data().values[1]
3424 .reshapeCol(k, _G.data().dim.first, _G.data().dim.second).transpose();
3427 index_t rows()
const {
return _G.source().targetDim(); }
3429 index_t cols()
const {
return _G.source().domainDim(); }
3431 static const gsFeSpace<Scalar> & rowVar() {
return gsNullExpr<Scalar>::get(); }
3432 static const gsFeSpace<Scalar> & colVar() {
return gsNullExpr<Scalar>::get(); }
3434 void parse(gsExprHelper<Scalar> & evList)
const
3440 meas_expr<T> absDet()
const
3442 GISMO_ASSERT(rows() == cols(),
"The Jacobian matrix is not square");
3443 return meas_expr<T>(_G);
3446 jacInv_expr<T> inv()
const
3448 GISMO_ASSERT(rows() == cols(),
"The Jacobian matrix is not square");
3449 return jacInv_expr<T>(_G);
3453 jacInv_expr<T> ginv()
const {
return jacInv_expr<T>(_G); }
3455 void print(std::ostream &os)
const { os <<
"\u2207("; _G.print(os); os <<
")"; }
3459 class hess_expr :
public _expr<hess_expr<E> >
3462 typedef typename E::Scalar Scalar;
3464 typename E::Nested_t _u;
3465 mutable gsMatrix<Scalar> res;
3467 enum {ScalarValued = 0, ColBlocks = (1==E::Space?1:0) };
3468 enum {Space = E::Space };
3471 hess_expr(
const E & u) : _u(u)
3477 const gsMatrix<Scalar> & eval(
const index_t k)
const
3479 const gsFuncData<Scalar> & dd = _u.data();
3480 const index_t sz = cardinality_impl();
3481 res.resize(dd.dim.first, sz*dd.dim.first);
3482 secDerToHessian(dd.values[2].col(k), dd.dim.first, res);
3483 res.resize(dd.dim.first, res.cols()*dd.dim.first);
3489 index_t rows()
const {
return _u.data().dim.first; }
3495 index_t cardinality_impl()
const
3497 return 2*_u.data().values[2].rows()/
3498 (_u.data().dim.first*(1+_u.data().dim.first));
3502 void parse(gsExprHelper<Scalar> & evList)
const
3505 _u.data().flags |= NEED_2ND_DER;
3508 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
3509 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get(); }
3511 void print(std::ostream &os)
const
3513 { os <<
"\u210D(U)"; }
3517 class hess_expr<gsFeSolution<T> > :
public _expr<hess_expr<gsFeSolution<T> > >
3520 const gsFeSolution<T> _u;
3524 enum{Space = 0, ScalarValued = 0, ColBlocks = 0 };
3526 hess_expr(
const gsFeSolution<T> & u) : _u(u) { }
3528 mutable gsMatrix<T> res;
3529 const gsMatrix<T> & eval(
const index_t k)
const
3531 GISMO_ASSERT(1==_u.data().actives.cols(),
"Single actives expected. Actives: \n"<<_u.data().actives);
3533 const gsDofMapper & map = _u.mapper();
3535 const index_t numActs = _u.data().values[0].rows();
3536 const index_t pdim = _u.parDim();
3537 index_t numDers = pdim*(pdim+1)/2;
3543 res.setZero(numDers,1);
3544 for (
index_t i = 0; i!=numActs; ++i)
3546 const index_t ii = map.index(_u.data().actives.at(i), _u.data().patchId,0);
3547 deriv2 = _u.data().values[2].block(i*numDers,k,numDers,1);
3548 if ( map.is_free_index(ii) )
3549 res += _u.coefs().at(ii) * deriv2;
3551 res +=_u.fixedPart().at( map.global_to_bindex(ii) ) * deriv2;
3553 secDerToHessian(res, pdim, deriv2);
3555 res.resize(pdim,pdim);
3560 res.setZero(rows(), numDers);
3561 for (
index_t c = 0; c != _u.dim(); c++)
3562 for (
index_t i = 0; i != numActs; ++i) {
3563 const index_t ii = map.index(_u.data().actives.at(i), _u.data().patchId, c);
3564 deriv2 = _u.space().data().values[2].block(i * numDers, k, numDers,
3566 if (map.is_free_index(ii))
3567 res.row(c) += _u.coefs().at(ii) * deriv2;
3569 res.row(c) += _u.fixedPart().at(map.global_to_bindex(ii)) * deriv2;
3588 return _u.parDim() * (_u.parDim() + 1) / 2;
3591 const gsFeSpace<Scalar> & rowVar()
const {
return gsNullExpr<Scalar>::get(); }
3592 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get(); }
3594 void parse(gsExprHelper<Scalar> & evList)
const
3597 evList.add(_u.space());
3601 void print(std::ostream &os)
const { os <<
"\u210D(s)"; }
3610 class dJacG_expr :
public _expr<dJacG_expr<T> >
3612 typename gsGeometryMap<T>::Nested_t _G;
3614 mutable gsMatrix<T> res;
3618 dJacG_expr(
const gsGeometryMap<T> & G) : _G(G) { }
3622 const index_t sz = _G.data().values[0].rows();
3623 const index_t s = _G.data().derivSize();
3625 res.resize(_G.data().dim.second, sz*_G.data().dim.first);
3630 index_t rows()
const {
return _G.source().targetDim(); }
3631 index_t cols()
const {
return _G.source().domainDim(); }
3633 void parse(gsExprHelper<Scalar> & evList)
const
3636 _G.data().flags |= NEED_2ND_DER;
3645 class curl_expr :
public _expr<curl_expr<T> >
3650 typename gsFeVariable<T>::Nested_t _u;
3651 mutable gsMatrix<Scalar> res;
3653 enum{ Space = 1, ScalarValued= 0, ColBlocks= 0};
3655 curl_expr(
const gsFeVariable<T> & u) : _u(u)
3656 {
GISMO_ASSERT(3==u.dim(),
"curl(.) requires 3D variable."); }
3658 const gsMatrix<T> & eval(
const index_t k)
const
3660 res.setZero( rows(), _u.dim());
3661 const index_t na = _u.data().values[0].rows();
3662 gsAsConstMatrix<T, Dynamic, Dynamic> pd =
3663 _u.data().values[1].reshapeCol(k, cols(), na);
3665 res.col(0).segment(na ,na) = -pd.row(2);
3666 res.col(0).segment(2*na,na) = pd.row(1);
3667 res.col(1).segment(0 ,na) = pd.row(2);
3668 res.col(1).segment(2*na,na) = -pd.row(0);
3669 res.col(2).segment(0 ,na) = -pd.row(1);
3670 res.col(2).segment(na ,na) = pd.row(0);
3674 index_t rows()
const {
return _u.dim() * _u.data().values[0].rows(); }
3675 index_t cols()
const {
return _u.data().dim.first; }
3677 void parse(gsExprHelper<Scalar> & evList)
const
3680 _u.data().flags |= NEED_GRAD;
3683 const gsFeSpace<T> & rowVar()
const {
return _u.rowVar(); }
3684 const gsFeSpace<T> & colVar()
const {
return gsNullExpr<T>::get();}
3686 void print(std::ostream &os)
const { os <<
"curl("; _u.print(os); os <<
")"; }
3699 template <
typename E1,
typename E2>
3700 class mult_expr<E1,E2,false> :
public _expr<mult_expr<E1, E2, false> >
3702 typename E1::Nested_t _u;
3703 typename E2::Nested_t _v;
3706 enum {ScalarValued = E1::ScalarValued && E2::ScalarValued,
3707 ColBlocks = E2::ColBlocks};
3708 enum {Space = (int)E1::Space + (
int)E2::Space };
3710 typedef typename E1::Scalar Scalar;
3712 mult_expr(_expr<E1>
const& u,
3716 mutable Temporary_t tmp;
3717 const Temporary_t & eval(
const index_t k)
const
3719 GISMO_ASSERT(0==_u.cols()*_v.rows() || _u.cols() == _v.rows(),
3720 "Wrong dimensions "<<_u.cols()<<
"!="<<_v.rows()<<
" in * operation:\n"
3721 << _u <<
" times \n" << _v );
3724 tmp = _u.eval(k) * _v.eval(k);
3728 index_t rows()
const {
return E1::ScalarValued ? _v.rows() : _u.rows(); }
3729 index_t cols()
const {
return E2::ScalarValued ? _u.cols() : _v.cols(); }
3730 void parse(gsExprHelper<Scalar> & evList)
const
3731 { _u.parse(evList); _v.parse(evList); }
3734 index_t cardinality_impl()
const
3735 {
return 0==E1::Space ? _v.cardinality(): _u.cardinality(); }
3737 const gsFeSpace<Scalar> & rowVar()
const
3738 {
return 0==E1::Space ? _v.rowVar() : _u.rowVar(); }
3739 const gsFeSpace<Scalar> & colVar()
const
3740 {
return 0==E2::Space ? _u.colVar() : _v.colVar(); }
3742 void print(std::ostream &os)
const { _u.print(os); os<<
"*"; _v.print(os); }
3759 template <
typename E1,
typename E2>
3760 class mult_expr<E1, E2, true> :
public _expr<mult_expr<E1, E2, true> >
3763 typedef typename E2::Scalar Scalar;
3765 typename E1::Nested_t _u;
3766 typename E2::Nested_t _v;
3768 mutable gsMatrix<Scalar> res;
3770 enum {ScalarValued = 0, ColBlocks = E1::ColBlocks};
3771 enum {Space = (int)E1::Space + (
int)E2::Space };
3773 mult_expr(_expr<E1>
const& u,
3780 const gsMatrix<Scalar> & eval(
const index_t k)
const
3784 const index_t nb = _u.cardinality();
3785 const auto tmpA = _u.eval(k);
3786 const auto tmpB = _v.eval(k);
3791 if ( 1 == _v.cardinality() )
3793 res.resize(ur, vc*nb);
3794 GISMO_ASSERT(tmpA.cols()==uc*nb,
"Dimension error.. "<< tmpA.cols()<<
"!="<<uc*nb );
3797 for (
index_t i = 0; i!=nb; ++i)
3798 res.middleCols(i*vc,vc).noalias()
3799 = tmpA.middleCols(i*uc,uc) * tmpB;
3806 const index_t nbv = _v.cardinality();
3807 res.resize(ur*nb, vc*nbv);
3808 for (
index_t i = 0; i!=nb; ++i)
3809 for (
index_t j = 0; j!=nbv; ++j)
3811 res.block(i*ur,j*vc,ur,vc).noalias() =
3812 tmpA.middleCols(i*uc,uc) * tmpB.middleCols(j*vc,vc);
3827 void parse(gsExprHelper<Scalar> & evList)
const
3828 { _u.parse(evList); _v.parse(evList); }
3831 index_t cardinality_impl()
const {
return _u.cardinality(); }
3833 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
3834 const gsFeSpace<Scalar> & colVar()
const
3836 if ( 1 == _v.cardinality() )
3842 void print(std::ostream &os)
const
3843 { os <<
"("; _u.print(os);os <<
"*";_v.print(os);os <<
")"; }
3851 template <
typename E2>
3852 class mult_expr<typename E2::Scalar, E2, false>
3853 :
public _expr<mult_expr<typename E2::Scalar, E2, false> >
3857 typedef typename E2::Scalar Scalar;
3860 typename E2::Nested_t _v;
3864 enum {ScalarValued = E2::ScalarValued, ColBlocks = E2::ColBlocks};
3865 enum {Space = E2::Space};
3867 mult_expr(Scalar
const & c, _expr<E2>
const& v)
3870 EIGEN_STRONG_INLINE AutoReturn_t eval(
const index_t k)
const
3872 return ( _c * _v.eval(k) );
3876 index_t rows()
const {
return _v.rows(); }
3877 index_t cols()
const {
return _v.cols(); }
3879 void parse(gsExprHelper<Scalar> & evList)
const
3880 { _v.parse(evList); }
3882 index_t cardinality_impl()
const
3883 {
return _v.cardinality(); }
3885 const gsFeSpace<Scalar> & rowVar()
const {
return _v.rowVar(); }
3886 const gsFeSpace<Scalar> & colVar()
const {
return _v.colVar(); }
3888 void print(std::ostream &os)
const { os << _c <<
"*";_v.print(os); }
3892 template <
typename E1,
typename E2>
3893 class collapse_expr :
public _expr<collapse_expr<E1, E2> >
3895 typename E1::Nested_t _u;
3896 typename E2::Nested_t _v;
3899 enum {ScalarValued = 0, ColBlocks = 0};
3900 enum { Space = (int)E1::Space + (
int)E2::Space };
3902 typedef typename E1::Scalar Scalar;
3904 mutable gsMatrix<Scalar> res;
3906 collapse_expr(_expr<E1>
const& u,
3911 const gsMatrix<Scalar> &
3915 const auto tmpA = _u.eval(k);
3916 const auto tmpB = _v.eval(k);
3922 for (
index_t i = 0; i!=nb; ++i)
3924 res.row(i).transpose().noalias() = tmpA.middleCols(i*ur,ur) * tmpB;
3927 else if (E2::ColBlocks)
3931 for (
index_t i = 0; i!=nb; ++i)
3933 res.row(i).noalias() = tmpA * tmpB.middleCols(i*ur,ur);
3940 index_t rows()
const {
return E1::ColBlocks ? _u.cols() / _v.rows() : _v.cols() / _u.cols() ; }
3941 index_t cols()
const {
return E1::ColBlocks ? _v.rows() : _u.cols(); }
3943 void parse(gsExprHelper<Scalar> & evList)
const
3944 { _u.parse(evList); _v.parse(evList); }
3946 const gsFeSpace<Scalar> & rowVar()
const
3947 {
return E1::ColBlocks ? _u.rowVar() : _v.rowVar(); }
3948 const gsFeSpace<Scalar> & colVar()
const
3953 void print(std::ostream &os)
const { _u.print(os); os<<
"~"; _v.print(os); }
3957 template <
typename E1,
typename E2>
3959 collapse_expr<E1,E2> collapse( _expr<E1>
const& u, _expr<E2>
const& v)
3960 {
return collapse_expr<E1, E2>(u, v); }
3973 template <
typename E1,
typename E2,
bool = E2::ColBlocks>
3974 class frprod_expr :
public _expr<frprod_expr<E1, E2> >
3977 typedef typename E1::Scalar Scalar;
3978 enum {ScalarValued = 0, ColBlocks=E2::ColBlocks};
3979 enum { Space = (int)E1::Space + (
int)E2::Space };
3987 typename E1::Nested_t _u;
3988 typename E2::Nested_t _v;
3990 mutable gsMatrix<Scalar> res;
3994 frprod_expr(_expr<E1>
const& u, _expr<E2>
const& v)
4004 const gsMatrix<Scalar> & eval(
const index_t k)
const
4008 const index_t nb = _u.cardinality();
4009 auto A = _u.eval(k);
4010 auto B = _v.eval(k);
4012 for (
index_t i = 0; i!=nb; ++i)
4013 for (
index_t j = 0; j!=nb; ++j)
4015 (A.middleCols(i*rb,rb).array() * B.middleCols(j*rb,rb).array()).sum();
4019 index_t rows()
const {
return _u.cols() / _u.rows(); }
4020 index_t cols()
const {
return _u.cols() / _u.rows(); }
4022 void parse(gsExprHelper<Scalar> & evList)
const
4023 { _u.parse(evList); _v.parse(evList); }
4025 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4026 const gsFeSpace<Scalar> & colVar()
const {
return _v.colVar(); }
4028 void print(std::ostream &os)
const
4029 { os <<
"("; _u.print(os); os<<
" % "; _v.print(os); os<<
")";}
4039 template <
typename E1,
typename E2>
4040 class frprod_expr<E1,E2,false> :
public _expr<frprod_expr<E1, E2,false> >
4043 typedef typename E1::Scalar Scalar;
4044 enum {ScalarValued = 0, Space = E1::Space, ColBlocks= E1::ColBlocks};
4047 typename E1::Nested_t _u;
4048 typename E2::Nested_t _v;
4050 mutable gsMatrix<Scalar> res;
4054 frprod_expr(_expr<E1>
const& u, _expr<E2>
const& v)
4064 const gsMatrix<Scalar> & eval(
const index_t k)
const
4067 auto A = _u.eval(k);
4068 auto B = _v.eval(k);
4070 const index_t nb = _u.cardinality();
4072 for (
index_t i = 0; i!=nb; ++i)
4074 (A.middleCols(i*rb,rb).array() * B.array()).sum();
4078 index_t rows()
const {
return _u.cols() / _u.rows(); }
4079 index_t cols()
const {
return 1; }
4081 void parse(gsExprHelper<Scalar> & evList)
const
4082 { _u.parse(evList); _v.parse(evList); }
4085 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4086 const gsFeSpace<Scalar> & colVar()
const {
return _v.rowVar(); }
4088 void print(std::ostream &os)
const
4089 { os <<
"("; _u.print(os); os<<
" % "; _v.print(os); os<<
")";}
4095 template <
typename E1,
typename E2>
4096 class divide_expr :
public _expr<divide_expr<E1,E2> >
4098 typename E1::Nested_t _u;
4099 typename E2::Nested_t _v;
4102 typedef typename E1::Scalar Scalar;
4105 enum {ScalarValued = E1::ScalarValued, ColBlocks= E2::ColBlocks};
4106 enum {Space = E1::Space};
4108 divide_expr(_expr<E1>
const& u, _expr<E2>
const& v)
4111 GISMO_STATIC_ASSERT(E2::ScalarValued,
"The denominator needs to be scalar valued.");
4114 AutoReturn_t eval(
const index_t k)
const
4115 {
return ( _u.eval(k) / _v.eval(k) ); }
4117 index_t rows()
const {
return _u.rows(); }
4118 index_t cols()
const {
return _u.cols(); }
4120 void parse(gsExprHelper<Scalar> & evList)
const
4121 { _u.parse(evList); _v.parse(evList); }
4124 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4125 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
4127 void print(std::ostream &os)
const
4128 { os <<
"("; _u.print(os);os <<
" / ";_v.print(os);os <<
")"; }
4134 template <
typename E1>
4135 class divide_expr<E1,typename E1::Scalar>
4136 :
public _expr<divide_expr<E1,typename E1::Scalar> >
4139 typedef typename E1::Scalar Scalar;
4142 typename E1::Nested_t _u;
4146 enum {Space= E1::Space, ScalarValued = E1::ScalarValued, ColBlocks= E1::ColBlocks};
4148 divide_expr(_expr<E1>
const& u, Scalar
const c)
4151 AutoReturn_t eval(
const index_t k)
const
4152 {
return ( _u.eval(k) / _c ); }
4154 index_t rows()
const {
return _u.rows(); }
4155 index_t cols()
const {
return _u.cols(); }
4157 void parse(gsExprHelper<Scalar> & evList)
const
4158 { _u.parse(evList); }
4161 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4162 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
4164 void print(std::ostream &os)
const
4165 { os <<
"("; _u.print(os);os <<
"/"<< _c <<
")"; }
4172 template <
typename E2>
4173 class divide_expr<typename E2::Scalar,E2>
4174 :
public _expr<divide_expr<typename E2::Scalar,E2> >
4177 typedef typename E2::Scalar Scalar;
4181 typename E2::Nested_t _u;
4183 enum {Space= 0, ScalarValued = 1, ColBlocks= 0};
4185 divide_expr(Scalar
const c, _expr<E2>
const& u)
4187 { GISMO_STATIC_ASSERT(E2::ScalarValued,
"The denominator needs to be scalar valued."); }
4189 Scalar eval(
const index_t k)
const
4190 {
return ( _c / _u.val().eval(k) ); }
4192 index_t rows()
const {
return 0; }
4193 index_t cols()
const {
return 0; }
4195 void parse(gsExprHelper<Scalar> & evList)
const
4196 { _u.parse(evList); }
4199 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4200 const gsFeSpace<Scalar> & colVar()
const {
return _u.colVar(); }
4202 void print(std::ostream &os)
const
4203 { os <<
"("<< _c <<
"/";_u.print(os);os <<
")";}
4209 template <
typename E1,
typename E2>
4210 class add_expr :
public _expr<add_expr<E1, E2> >
4212 typename E1::Nested_t _u;
4213 typename E2::Nested_t _v;
4216 enum {ScalarValued = E1::ScalarValued && E2::ScalarValued,
4217 ColBlocks = E1::ColBlocks || E2::ColBlocks };
4218 enum {Space = E1::Space};
4220 typedef typename E1::Scalar Scalar;
4222 add_expr(_expr<E1>
const& u, _expr<E2>
const& v)
4226 _u.rowVar()==_v.rowVar() && _u.colVar()==_v.colVar(),
4227 "Error: adding apples and oranges (use comma instead),"
4228 " namely:\n" << _u <<
"\n"<<_v<<
4229 " \nvars:\n" << _u.rowVar().id()<<
"!="<<_v.rowVar().id() <<
", "<< _u.colVar().id()<<
"!="<<_v.colVar().id()<<
4230 " \nspaces:\n" << (int)E1::Space<<
"!="<< (
int)E2::Space
4234 mutable Temporary_t res;
4235 const Temporary_t & eval(
const index_t k)
const
4238 "Wrong dimensions "<<_u.rows()<<
"!="<<_v.rows()<<
" in + operation:\n"
4239 << _u <<
" plus \n" << _v );
4241 "Wrong dimensions "<<_u.cols()<<
"!="<<_v.cols()<<
" in + operation:\n"
4242 << _u <<
" plus \n" << _v );
4243 res = _u.eval(k) + _v.eval(k);
4247 index_t rows()
const {
return _u.rows(); }
4248 index_t cols()
const {
return _u.cols(); }
4250 void parse(gsExprHelper<Scalar> & evList)
const
4251 { _u.parse(evList); _v.parse(evList); }
4254 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
4256 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4257 const gsFeSpace<Scalar> & colVar()
const {
return _v.colVar(); }
4259 void print(std::ostream &os)
const
4260 { os <<
"("; _u.print(os);os <<
" + ";_v.print(os);os <<
")"; }
4276 template <
typename E1,
typename E2>
4277 class summ_expr :
public _expr<summ_expr<E1,E2> >
4280 typedef typename E1::Scalar Scalar;
4282 enum {Space = E1::Space, ScalarValued= 0, ColBlocks= E2::ColBlocks};
4284 summ_expr(E1
const& u, E2
const& M) : _u(u), _M(M) { }
4286 const gsMatrix<Scalar> & eval(
const index_t k)
const
4288 auto sl = _u.eval(k);
4290 auto ml = _M.eval(k);
4292 const index_t mb = _M.cardinality();
4294 GISMO_ASSERT(_M.cols()==_M.rows(),
"Matrix must be square: "<< _M.rows()<<
" x "<< _M.cols() <<
" expr: "<< _M );
4295 GISMO_ASSERT(mb==_u.cols(),
"cardinality must match vector, but card(M)="<<_M.cardinality()<<
" and cols(u)="<<_u.cols());
4297 res.setZero(mr, sr * mr);
4298 for (
index_t i = 0; i!=sr; ++i)
4299 for (
index_t t = 0; t!=mb; ++t)
4300 res.middleCols(i*mr,mr) += sl(i,t) * ml.middleCols(t*mr,mr);
4304 index_t rows()
const {
return _M.rows(); }
4305 index_t cols()
const {
return _M.rows(); }
4307 void parse(gsExprHelper<Scalar> & evList)
const
4308 { _u.parse(evList); _M.parse(evList); }
4310 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4311 const gsFeSpace<Scalar> & colVar()
const {
return gsNullExpr<Scalar>::get(); }
4313 index_t cardinality_impl()
const
4316 void print(std::ostream &os)
const
4317 { os <<
"sum("; _M.print(os); os<<
","; _u.print(os); os<<
")"; }
4320 typename E1::Nested_t _u;
4321 typename E2::Nested_t _M;
4323 mutable gsMatrix<Scalar> res;
4330 template <
typename E1,
typename E2>
4331 class sub_expr :
public _expr<sub_expr<E1, E2> >
4333 typename E1::Nested_t _u;
4334 typename E2::Nested_t _v;
4337 enum {ScalarValued = E1::ScalarValued && E2::ScalarValued,
4338 ColBlocks = E1::ColBlocks || E2::ColBlocks };
4339 enum {Space = E1::Space};
4341 typedef typename E1::Scalar Scalar;
4343 sub_expr(_expr<E1>
const& u, _expr<E2>
const& v)
4347 _u.rowVar()==_v.rowVar() && _u.colVar()==_v.colVar(),
4348 "Error: substracting apples from oranges (use comma instead),"
4349 " namely:\n" << _u <<
"\n"<<_v);
4352 mutable Temporary_t res;
4353 const Temporary_t & eval(
const index_t k)
const
4360 "Wrong dimensions "<<_u.rows()<<
"!="<<_v.rows()<<
" in - operation:\n" << _u <<
" minus \n" << _v );
4362 "Wrong dimensions "<<_u.cols()<<
"!="<<_v.cols()<<
" in - operation:\n" << _u <<
" minus \n" << _v );
4364 "Cardinality "<< _u.cardinality()<<
" != "<< _v.cardinality());
4367 res = _u.eval(k) - _v.eval(k);
4371 index_t rows()
const {
return _u.rows(); }
4372 index_t cols()
const {
return _u.cols(); }
4374 void parse(gsExprHelper<Scalar> & evList)
const
4375 { _u.parse(evList); _v.parse(evList); }
4377 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4378 const gsFeSpace<Scalar> & colVar()
const {
return _v.colVar(); }
4380 index_t cardinality_impl()
const
4383 "Cardinality "<< _u.cardinality()<<
" != "<< _v.cardinality());
4384 return _u.cardinality();
4387 void print(std::ostream &os)
const
4388 { os <<
"("; _u.print(os); os<<
" - ";_v.print(os); os <<
")";}
4394 template <
typename E>
4395 class symm_expr :
public _expr<symm_expr<E> >
4397 typename E::Nested_t _u;
4399 mutable gsMatrix<typename E::Scalar> tmp;
4401 typedef typename E::Scalar Scalar;
4403 enum { Space = (0==E::Space ? 0 : E::Space), ScalarValued= E::ScalarValued, ColBlocks= E::ColBlocks };
4405 symm_expr(_expr<E>
const& u)
4413 return tmp * tmp.transpose();
4416 index_t rows()
const {
return _u.rows(); }
4417 index_t cols()
const {
return _u.rows(); }
4419 void parse(gsExprHelper<Scalar> & evList)
const
4420 { _u.parse(evList); }
4422 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4423 const gsFeSpace<Scalar> & colVar()
const {
return _u.rowVar(); }
4425 void print(std::ostream &os)
const { os <<
"symm("; _u.print(os); os <<
")"; }
4428 template <
typename E>
4429 class symmetrize_expr :
public _expr<symmetrize_expr<E> >
4431 typename E::Nested_t _u;
4433 mutable gsMatrix<typename E::Scalar> tmp;
4435 enum { Space = (0==E::Space ? 0 : 3), ScalarValued=E::ScalarValued, ColBlocks= E::ColBlocks };
4436 typedef typename E::Scalar Scalar;
4438 symmetrize_expr(_expr<E>
const& u)
4446 return tmp + tmp.transpose();
4449 index_t rows()
const {
return _u.rows(); }
4450 index_t cols()
const {
return _u.rows(); }
4452 void parse(gsExprHelper<Scalar> & evList)
const
4453 { _u.parse(evList); }
4455 const gsFeSpace<Scalar> & rowVar()
const {
return _u.rowVar(); }
4456 const gsFeSpace<Scalar> & colVar()
const {
return _u.rowVar(); }
4457 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
4459 void print(std::ostream &os)
const { os <<
"symmetrize("; _u.print(os); os <<
")"; }
4474 EIGEN_STRONG_INLINE constMat_expr ones(
const index_t dim) {
4477 return constMat_expr(ones);
4480 EIGEN_STRONG_INLINE constMat_expr mat(
const gsMatrix<real_t> mat) {
return constMat_expr(mat); }
4487 template<
class E> EIGEN_STRONG_INLINE
4488 abs_expr<E>
abs(
const E & u) {
return abs_expr<E>(u); }
4491 template<
class E> EIGEN_STRONG_INLINE
4492 grad_expr<E>
grad(
const E & u) {
return grad_expr<E>(u); }
4495 template<
class E> EIGEN_STRONG_INLINE
4499 template<
class T> EIGEN_STRONG_INLINE
4503 template<
class T> EIGEN_STRONG_INLINE
4507 template<
class T> EIGEN_STRONG_INLINE
4510 template<
class T> EIGEN_STRONG_INLINE
4511 normal_expr<T> sn(
const gsGeometryMap<T> & u) {
return normal_expr<T>(u); }
4514 template<
class T> EIGEN_STRONG_INLINE
4517 template<
class E> EIGEN_STRONG_INLINE
4518 lapl_expr<E> lapl(
const symbol_expr<E> & u) {
return lapl_expr<E>(u); }
4520 template<
class T> EIGEN_STRONG_INLINE
4521 lapl_expr<gsFeSolution<T> > lapl(
const gsFeSolution<T> & u)
4522 {
return lapl_expr<gsFeSolution<T> >(u); }
4525 template<
class T> EIGEN_STRONG_INLINE fform2nd_expr<T>
fform2nd(
const gsGeometryMap<T> & G)
4526 {
return fform2nd_expr<T>(G); }
4529 template<
class E> EIGEN_STRONG_INLINE
4530 jac_expr<E>
jac(
const symbol_expr<E> & u) {
return jac_expr<E>(u); }
4533 template<
class T> EIGEN_STRONG_INLINE
4534 jac_expr<gsGeometryMap<T> >
jac(
const gsGeometryMap<T> & G) {
return jac_expr<gsGeometryMap<T> >(G);}
4537 template<
class T> EIGEN_STRONG_INLINE
4538 grad_expr<gsFeSolution<T> >
jac(
const gsFeSolution<T> & s) {
return grad_expr<gsFeSolution<T> >(s);}
4540 template<
class E> EIGEN_STRONG_INLINE
4541 hess_expr<E> hess(
const symbol_expr<E> & u) {
return hess_expr<E>(u); }
4544 template<
class T> EIGEN_STRONG_INLINE
4545 hess_expr<gsGeometryMap<T> > hess(
const gsGeometryMap<T> & u) {
return hess_expr<gsGeometryMap<T> >(u); }
4548 template<
class T> EIGEN_STRONG_INLINE
4549 hess_expr<gsFeSolution<T> > hess(
const gsFeSolution<T> & u) {
return hess_expr<gsFeSolution<T> >(u); }
4552 template<
class T> EIGEN_STRONG_INLINE
4553 dJacG_expr<T>
dJac(
const gsGeometryMap<T> & G) {
return dJacG_expr<T>(G); }
4556 template<
class T> EIGEN_STRONG_INLINE
4557 meas_expr<T>
meas(
const gsGeometryMap<T> & G) {
return meas_expr<T>(G); }
4560 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4561 mult_expr<E1,E2>
const operator*(_expr<E1>
const& u, _expr<E2>
const& v)
4562 {
return mult_expr<E1, E2>(u, v); }
4564 template <
typename E2> EIGEN_STRONG_INLINE
4565 mult_expr<typename E2::Scalar,E2,false>
const
4566 operator*(
typename E2::Scalar
const& u, _expr<E2>
const& v)
4567 {
return mult_expr<typename E2::Scalar, E2, false>(u, v); }
4569 template <
typename E1> EIGEN_STRONG_INLINE
4570 mult_expr<typename E1::Scalar,E1,false>
const
4571 operator*(_expr<E1>
const& v,
typename E1::Scalar
const& u)
4572 {
return mult_expr<typename E1::Scalar,E1, false>(u, v); }
4574 template <
typename E1> EIGEN_STRONG_INLINE
4575 mult_expr<typename E1::Scalar,E1,false>
const
4576 operator-(_expr<E1>
const& u)
4577 {
return mult_expr<typename E1::Scalar,E1, false>(-1, u); }
4579 template <
typename E> mult_expr<constMat_expr, E>
const
4580 operator*( gsMatrix<typename E::Scalar>
const& u, _expr<E>
const& v)
4581 {
return mult_expr<constMat_expr, E>(mat(u), v); }
4583 template <
typename E> mult_expr<E, constMat_expr>
const
4584 operator*(_expr<E>
const& u, gsMatrix<typename E::Scalar>
const& v)
4585 {
return mult_expr<E, constMat_expr>(u, mat(v) ); }
4588 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4589 frprod_expr<E1,E2>
const operator%(_expr<E1>
const& u, _expr<E2>
const& v)
4590 {
return frprod_expr<E1, E2>(u, v); }
4593 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4594 divide_expr<E1,E2>
const operator/(_expr<E1>
const& u, _expr<E2>
const& v)
4595 {
return divide_expr<E1,E2>(u, v); }
4597 template <
typename E> EIGEN_STRONG_INLINE
4598 divide_expr<E,typename E::Scalar>
const
4599 operator/(_expr<E>
const& u,
const typename E::Scalar v)
4600 {
return divide_expr<E,typename E::Scalar>(u, v); }
4602 template <
typename E> EIGEN_STRONG_INLINE
4603 divide_expr<typename E::Scalar,E>
const
4604 operator/(
const typename E::Scalar u, _expr<E>
const& v)
4605 {
return divide_expr<typename E::Scalar,E>(u, v); }
4608 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4609 add_expr<E1,E2>
const operator+(_expr<E1>
const& u, _expr<E2>
const& v)
4610 {
return add_expr<E1, E2>(u, v); }
4613 template <
typename E> EIGEN_STRONG_INLINE
4614 add_expr< E, _expr<typename E::Scalar, true> >
4616 {
return add_expr<E,_expr<typename E::Scalar>>(u, _expr<typename E::Scalar,true>(v)); }
4619 template <
typename E> EIGEN_STRONG_INLINE
4620 add_expr< E, _expr<typename E::Scalar, true> >
4622 {
return add_expr<E,_expr<typename E::Scalar>>(u, _expr<typename E::Scalar,true>(v)); }
4625 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4626 summ_expr<E1,E2>
const summ(E1
const & u, E2
const& M)
4627 {
return summ_expr<E1,E2>(u, M); }
4631 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4637 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4642 template <
typename E1,
typename E2> EIGEN_STRONG_INLINE
4643 sub_expr<E1,E2>
const operator-(_expr<E1>
const& u, _expr<E2>
const& v)
4644 {
return sub_expr<E1, E2>(u, v); }
4646 template <
typename E2> EIGEN_STRONG_INLINE
4647 sub_expr<_expr<typename E2::Scalar>,E2>
const
4648 operator-(
typename E2::Scalar
const& s, _expr<E2>
const& v)
4651 return sub_expr<_expr<typename E2::Scalar>, E2>(_expr<typename E2::Scalar>(s), v);
4657 #define GISMO_SHORTCUT_VAR_EXPRESSION(name,impl) template<class E> EIGEN_STRONG_INLINE \
4658 auto name(const E & u) -> decltype(impl) { return impl; }
4659 #define GISMO_SHORTCUT_MAP_EXPRESSION(name,impl) template<class T> EIGEN_STRONG_INLINE \
4660 auto name(const gsGeometryMap<T> & G) -> decltype(impl) { return impl; }
4661 #define GISMO_SHORTCUT_PHY_EXPRESSION(name,impl) template<class E> EIGEN_STRONG_INLINE \
4662 auto name(const E & u, const gsGeometryMap<typename E::Scalar> & G) -> decltype(impl) { return impl; }
4665 GISMO_SHORTCUT_VAR_EXPRESSION( div,
jac(u).trace() )
4666 GISMO_SHORTCUT_PHY_EXPRESSION( idiv, ijac(u,G).trace() )
4669 GISMO_SHORTCUT_MAP_EXPRESSION(unv,
nv(G).normalized() )
4671 GISMO_SHORTCUT_MAP_EXPRESSION(usn, sn(G).normalized() )
4673 GISMO_SHORTCUT_PHY_EXPRESSION(igrad, grad(u)*
jac(G).ginv() )
4674 GISMO_SHORTCUT_VAR_EXPRESSION(igrad, grad(u) )
4676 GISMO_SHORTCUT_PHY_EXPRESSION( ijac,
jac(u) *
jac(G).ginv())
4679 GISMO_SHORTCUT_PHY_EXPRESSION(ihess,
4680 jac(G).ginv().tr()*( hess(u) -
summ(igrad(u,G),hess(G)) ) *
jac(G).ginv() )
4681 GISMO_SHORTCUT_VAR_EXPRESSION(ihess, hess(u) )
4683 GISMO_SHORTCUT_PHY_EXPRESSION(ilapl, ihess(u,G).trace() )
4684 GISMO_SHORTCUT_VAR_EXPRESSION(ilapl, hess(u).trace() )
4686 GISMO_SHORTCUT_VAR_EXPRESSION(fform,
jac(u).tr()*
jac(u) )
4687 GISMO_SHORTCUT_VAR_EXPRESSION(shapeop, fform(u).inv() *
fform2nd(u) )
4689 #undef GISMO_SHORTCUT_PHY_EXPRESSION
4690 #undef GISMO_SHORTCUT_VAR_EXPRESSION
4691 #undef GISMO_SHORTCUT_MAP_EXPRESSION
EIGEN_STRONG_INLINE matrix_by_space_expr< E1, E2 > const matrix_by_space(E1 const &u, E2 const &v)
Definition: gsExpressions.h:4632
asdiag_expr< E > asDiag() const
Returns a diagonal matrix expression of the vector expression.
Definition: gsExpressions.h:309
#define MatExprType
[Include namespace]
Definition: gsThinShellUtils.h:32
mult_expr< real_t, ppart_expr< mult_expr< double, E, false > >, false > npart() const
Returns the expression's negative part.
Definition: gsExpressions.h:260
Definition: gsExpressions.h:120
Definition: gsExpressions.h:96
Definition: gsExpressions.h:137
size_t mapSize() const
Returns the total number of patch-local degrees of freedom that are being mapped. ...
Definition: gsDofMapper.h:473
Gradient of the object.
Definition: gsForwardDeclarations.h:73
EIGEN_STRONG_INLINE diag_expr< E > const diagonal(E const &u)
Get diagonal elements of matrix as a vector.
Definition: gsExpressions.h:2084
Matrix< Scalar, Dynamic, Dynamic > cramerInverse() const
Inversion for small matrices using Cramer's Rule.
Definition: gsMatrixAddons.h:55
Definition: gsExpressions.h:3046
normalized_expr< E > normalized() const
Returns the vector normalized to unit length.
Definition: gsExpressions.h:283
The functions compute Dirichlet degrees of freedom using various methods.
EIGEN_STRONG_INLINE matrix_by_space_expr_tr< E1, E2 > const matrix_by_space_tr(E1 const &u, E2 const &v)
Definition: gsExpressions.h:4638
sqNorm_expr< E > sqNorm() const
Returns the squared Euclidean norm of the expression.
Definition: gsExpressions.h:291
index_t rows() const
Returns the row-size of the expression.
Definition: gsExpressions.h:328
Definition: gsExpressions.h:2306
ppart_expr< E > ppart() const
Returns the expression's positive part.
Definition: gsExpressions.h:253
const gsFeSpace< Scalar > & rowVar() const
Definition: gsExpressions.h:358
Outward normal on the boundary.
Definition: gsForwardDeclarations.h:86
EIGEN_STRONG_INLINE tangent_expr< T > tv(const gsGeometryMap< T > &u)
The tangent boundary vector of a geometry map in 2D.
Definition: gsExpressions.h:4515
norm_expr< E > norm() const
Returns the Euclidean norm of the expression.
Definition: gsExpressions.h:279
adjugate_expr< E > adj() const
Returns the adjugate of the expression (for matrix-valued expressions)
Definition: gsExpressions.h:275
Definition: gsExpressions.h:3013
S give(S &x)
Definition: gsMemory.h:266
EIGEN_STRONG_INLINE dJacG_expr< T > dJac(const gsGeometryMap< T > &G)
The partial derivatives of the Jacobian matrix of a geometry map.
Definition: gsExpressions.h:4553
Second derivatives.
Definition: gsForwardDeclarations.h:80
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
const gsFeElement< Scalar > & _e
Reference to the element.
Definition: gsExpressions.h:858
EIGEN_STRONG_INLINE fform2nd_expr< T > fform2nd(const gsGeometryMap< T > &G)
The second fundamental form of G.
Definition: gsExpressions.h:4525
EIGEN_STRONG_INLINE frprod_expr< E1, E2 > const operator%(_expr< E1 > const &u, _expr< E2 > const &v)
Frobenious product (also known as double dot product) operator for expressions.
Definition: gsExpressions.h:4589
det_expr< E > det() const
Returns the determinant of the expression.
Definition: gsExpressions.h:287
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
EIGEN_STRONG_INLINE summ_expr< E1, E2 > const summ(E1 const &u, E2 const &M)
Matrix-summation operator for expressions.
Definition: gsExpressions.h:4626
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
Definition: gsExpressions.h:3134
Struct containing information for matrix assembly.
Definition: gsExpressions.h:63
colsum_expr< E > colSum() const
Returns the colSum of a matrix.
Definition: gsExpressions.h:321
Laplacian.
Definition: gsForwardDeclarations.h:83
const gsFeSpace< Scalar > & colVar() const
Definition: gsExpressions.h:366
void finalize()
Must be called after all boundaries and interfaces have been marked to set up the dof numbering...
Definition: gsDofMapper.cpp:240
value_expr< E > val() const
Definition: gsExpressions.h:305
temp_expr< E > temp() const
Returns an evaluation of the (sub-)expression in temporary memory.
Definition: gsExpressions.h:263
exp_expr< E > exp() const
Returns exp(expression)
Definition: gsExpressions.h:249
#define gsWarn
Definition: gsDebug.h:50
Definition: gsExpressions.h:2337
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
Normal vector of the object.
Definition: gsForwardDeclarations.h:85
inv_expr< E > const inv() const
Returns the inverse of the expression (for matrix-valued expressions)
Definition: gsExpressions.h:267
Provides declaration of Basis abstract interface.
EIGEN_STRONG_INLINE mult_expr< E1, E2 > const operator*(_expr< E1 > const &u, _expr< E2 > const &v)
Multiplication operator for expressions.
Definition: gsExpressions.h:4561
EIGEN_STRONG_INLINE onormal_expr< T > nv(const gsGeometryMap< T > &u)
The (outer pointing) boundary normal of a geometry map.
Definition: gsExpressions.h:4508
Definition: gsExpressions.h:139
Definition: gsExpressions.h:140
cb_expr< E > cb() const
Returns the puts the expression to colBlocks.
Definition: gsExpressions.h:241
tr_expr< E > tr() const
Returns the transpose of the expression.
Definition: gsExpressions.h:233
void print(std::ostream &os) const
Prints the expression as a string to os.
Definition: gsExpressions.h:194
MatExprType eval(const index_t k) const
Evaluates the expression at evaluation point indexed by k.
Definition: gsExpressions.h:229
Active function ids.
Definition: gsForwardDeclarations.h:84
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition: gsFuncData.h:23
EIGEN_STRONG_INLINE nabla_expr< T > nabla(const gsFeVariable< T > &u)
The nabla ( ) of a finite element variable.
Definition: gsExpressions.h:4504
Definition: gsExpressions.h:138
Second fundamental form.
Definition: gsForwardDeclarations.h:87
Definition: gsExpressions.h:126
The density of the measure pull back.
Definition: gsForwardDeclarations.h:76
trace_expr< E > trace() const
Returns the trace of the expression (for matrix-valued expressions)
Definition: gsExpressions.h:271
tr_expr< E, true > cwisetr() const
Returns the coordinate-wise transpose of the expression.
Definition: gsExpressions.h:237
EIGEN_STRONG_INLINE curl_expr< T > curl(const gsFeVariable< T > &u)
The curl of a finite element variable.
Definition: gsExpressions.h:4500
Definition: gsExpressions.h:2600
size_t numPatches() const
Returns the number of patches present underneath the mapper.
Definition: gsDofMapper.h:469
EIGEN_STRONG_INLINE reshape_expr< E > const reshape(E const &u, index_t n, index_t m)
Reshape an expression.
Definition: gsExpressions.h:1927
EIGEN_STRONG_INLINE dJacdc_expr< E > dJacdc(const E &u, index_t c)
The derivative of the jacobian of a geometry map with respect to a coordinate.
Definition: gsExpressions.h:4496
nabla2_expr< T > nabla2(const gsFeVariable< T > &u)
The nabla2 ( ) of a finite element variable.
Definition: gsExpressions.h:3005
Definition: gsExpressions.h:136
EIGEN_STRONG_INLINE flat_expr< E > const flat(E const &u)
Make a matrix 2x2 expression "flat".
Definition: gsExpressions.h:2033
Value of the object.
Definition: gsForwardDeclarations.h:72
EIGEN_STRONG_INLINE grad_expr< E > grad(const E &u)
The gradient of a variable.
Definition: gsExpressions.h:4492
index_t cols() const
Returns the column-size of the expression.
Definition: gsExpressions.h:332
EIGEN_STRONG_INLINE idMat_expr id(const index_t dim)
The identity matrix of dimension dim.
Definition: gsExpressions.h:4472
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
EIGEN_STRONG_INLINE meas_expr< T > meas(const gsGeometryMap< T > &G)
The measure of a geometry map.
Definition: gsExpressions.h:4557
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4488
EIGEN_STRONG_INLINE divide_expr< E1, E2 > const operator/(_expr< E1 > const &u, _expr< E2 > const &v)
Scalar division operator for expressions.
Definition: gsExpressions.h:4594
Gradient transformation matrix.
Definition: gsForwardDeclarations.h:77
static bool isVector()
rowSpan && !colSpan
Definition: gsExpressions.h:344
max_expr< E > max() const
Returns the rowSum of a matrix.
Definition: gsExpressions.h:313
GISMO_EXPR_VECTOR_EXPRESSION(norm, norm, 1)
Eucledian Norm.
void parse(gsExprHelper< Scalar > &evList) const
Parse the expression and discover the list of evaluation sources, also sets the required evaluation f...
Definition: gsExpressions.h:350
This object is a cache for computed values from an evaluator.
EIGEN_STRONG_INLINE add_expr< E1, E2 > const operator+(_expr< E1 > const &u, _expr< E2 > const &v)
Addition operator for expressions.
Definition: gsExpressions.h:4609
rowsum_expr< E > rowSum() const
Returns the rowSum of a matrix.
Definition: gsExpressions.h:317
Definition: gsExpressions.h:1980
EIGEN_STRONG_INLINE replicate_expr< E > const replicate(E const &u, index_t n, index_t m=1)
Replicate an expression.
Definition: gsExpressions.h:1969
Definition: gsExpressions.h:114
Defines expression precomputed_expr.
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
sign_expr< E > sgn(Scalar tolerance=0) const
Returns the sign of the expression.
Definition: gsExpressions.h:245
Definition: gsExpressions.h:3082
bool isScalar() const
Returns true iff the expression is scalar-valued.
Definition: gsExpressions.h:342
Definition: gsExpressions.h:2544
EIGEN_STRONG_INLINE jac_expr< E > jac(const symbol_expr< E > &u)
The Jacobian matrix of a FE variable.
Definition: gsExpressions.h:4530