33 typename gsExprHelper<T>::Ptr m_exprdata;
41 std::list<gsFeSpaceData<T> > m_sdata;
42 std::vector<gsFeSpaceData<T>*> m_vrow;
43 std::vector<gsFeSpaceData<T>*> m_vcol;
45 typedef typename gsExprHelper<T>::nullExpr nullExpr;
53 typedef typename gsBoundaryConditions<T>::bcRefList bcRefList;
54 typedef gsBoxTopology::bContainer bContainer;
55 typedef gsBoxTopology::ifContainer ifContainer;
57 typedef typename gsExprHelper<T>::element
element;
61 typedef typename expr::gsFeSolution<T>
solution;
67 m_exprdata->cleanUp();
75 m_vrow(_rBlocks,nullptr), m_vcol(_cBlocks,nullptr)
88 "gsExprAssembler::numDofs() says: initSystem() has not been called.");
89 return m_vcol.back()->mapper.firstIndex() +
90 m_vcol.back()->mapper.freeSize();
97 "initSystem() has not been called.");
98 return m_vrow.back()->mapper.firstIndex() +
99 m_vrow.back()->mapper.freeSize();
107 for (
size_t i = 0; i!=m_vrow.size(); ++i)
108 nb += m_vrow[i]->dim;
137 { m_exprdata->setMultiBasis(mesh); }
146 return (
nullptr == m_gmap ? m_exprdata->multiPatch() : *m_gmap);
149 #if EIGEN_HAS_RVALUE_REFERENCES
156 {
return m_exprdata->multiBasis(); }
158 const typename gsExprHelper<T>::Ptr exprData()
const {
return m_exprdata; }
162 {
return m_exprdata->getMap(g); }
171 "Given ID "<<
id<<
" exceeds "<<m_vcol.size()-1 );
173 if (m_vcol[
id]==
nullptr)
175 m_sdata.emplace_back(mp,dim,
id);
176 m_vcol[
id] = &m_sdata.back();
177 if ((
size_t)
id<m_vrow.size() &&
nullptr==m_vrow[
id]) m_vrow[
id]=m_vcol[
id];
181 m_vcol[
id]->fs = ∓
182 m_vcol[
id]->dim = dim;
186 u.setSpaceData(*m_vcol[
id]);
196 "Given ID "<<
id<<
" exceeds "<<m_vrow.size()-1 );
198 if ( (m_vrow[
id]==
nullptr) ||
199 ((size_t)
id<m_vcol.size() && m_vrow[
id]==m_vcol[
id]) )
201 m_sdata.emplace_back(mp,dim,
id);
202 m_vrow[
id] = &m_sdata.back();
206 m_vrow[
id]->fs = ∓
207 m_vrow[
id]->dim = dim;
211 s.setSpaceData(m_sdata.back());
228 {
return getTestSpace( mp,(-1 == dim ? u.dim() : dim), u.id() ); }
236 getSpace(*m_vcol[
id]->fs,m_vcol[
id]->dim);
237 s.setSpaceData(*m_vcol[
id]);
250 getSpace(*m_vrow[
id]->fs,m_vrow[
id]->dim);
251 s.setSpaceData(*m_vrow[
id]);
261 {
return m_exprdata->getVar(func, 1); }
266 {
return m_exprdata->getVar(func,G); }
277 variable getBdrFunction()
const {
return m_exprdata->getMutVar(); }
279 expr::gsComposition<T> getBdrFunction(
geometryMap & G)
const
280 {
return m_exprdata->getMutVar(G); }
282 element getElement()
const {
return m_exprdata->getElement(); }
285 void setFixedDofVector(gsMatrix<T> & dof,
short_t unk = 0);
287 void setFixedDofs(
const gsMatrix<T> & coefMatrix,
short_t unk = 0,
size_t patch = 0);
304 void clearRhs() { m_rhs.setZero(); }
314 if (m_matrix.nonZeros() && save_sparsety_pattern)
316 std::fill(m_matrix.valuePtr(),
317 m_matrix.valuePtr() + m_matrix.nonZeros(), 0.);
323 if (0 == m_matrix.rows() || 0 == m_matrix.cols())
324 gsWarn <<
" No internal DOFs, zero sized system.\n";
327 const T bdA = m_options.
getReal(
"bdA");
329 const T bdO = m_options.
getReal(
"bdO");
331 const short_t dim = m_exprdata->multiBasis().domainDim();
332 for (
short_t i = 0; i != dim; ++i)
333 nz *= bdA * static_cast<T>(
334 m_exprdata->multiBasis().maxDegree(i)) +
338 cast<T, index_t>(nz * (1.0 + bdO)));
356 "initSystem() has not been called.");
358 _blockDims(rowSizes, colSizes);
359 return m_matrix.
blockView(rowSizes,colSizes);
368 "initSystem() has not been called.");
370 _blockDims(rowSizes, colSizes);
371 return m_matrix.
blockView(rowSizes,colSizes);
381 template<
class... expr>
void assemble(
const expr &... args);
386 template<
class... expr>
void assembleBdr(
const bcRefList & BCs, expr&... args);
388 template<
class... expr>
void assembleBdr(
const bContainer & bnd, expr&... args);
390 template<
class... expr>
void assembleIfc(
const ifContainer & iFaces, expr... args);
401 template<
class expr>
void assembleJacobianIfc(
const ifContainer & iFaces,
409 if (1==m_vcol.size() && 1==m_vrow.size())
420 rowSizes.resize(m_vrow.size());
421 for (
index_t r = 0; r != rowSizes.size(); ++r)
422 rowSizes[r] = m_vrow[r]->dim() * m_vrow[r]->mapper.freeSize();
423 colSizes.resize(m_vcol.size());
424 for (
index_t c = 0; c != colSizes.size(); ++c)
425 colSizes[c] = m_vcol[c]->dim() * m_vcol[c]->mapper.freeSize();
436 template <
typename E>
void operator() (
const gismo::expr::_expr<E> & v)
444 const gismo::expr::_expr<E> & ee)
446 auto u = ee.rowVar();
447 auto v = ee.colVar();
449 const bool m = E::isMatrix();
451 GISMO_ASSERT(v.isValid(),
"The row space is not valid");
452 GISMO_ASSERT(!m || u.isValid(),
"The column space is not valid");
453 GISMO_ASSERT(m || (ea.numDofs()==ee.rhs().size()),
"The right-hand side vector is not initialized");
460 gsSparseMatrix<T> & m_matrix;
462 const gsVector<T> & m_quWeights;
464 gsMatrix<T> localMat;
467 _eval(gsSparseMatrix<T> & _matrix,
469 const gsVector<> & _quWeights)
470 : m_matrix(_matrix), m_rhs(_rhs),
471 m_quWeights(_quWeights), m_elim(true)
474 void setElim(
bool elim) {m_elim = elim;}
476 template <
typename E>
void operator() (
const gismo::expr::_expr<E> & ee)
479 quadrature(ee,localMat);
483 if (m_elim) push<true,true>(ee.rowVar(), ee.colVar());
484 else push<true,false>(ee.rowVar(), ee.colVar());
485 else if (E::isVector())
486 if (m_elim) push<false,true>(ee.rowVar(), ee.colVar());
487 else push<false,false>(ee.rowVar(), ee.colVar());
490 GISMO_ERROR(
"Something went terribly wrong at this point");
496 template <
typename E>
497 inline void quadrature(
const gismo::expr::_expr<E> & ee,
501 const T * w = m_quWeights.data();
502 lm.noalias() = (*w) * ee.eval(0);
503 for (
index_t k = 1; k != m_quWeights.rows(); ++k)
504 lm.noalias() += (*(++w)) * ee.eval(k);
507 template <
typename E>
void diff(
const gismo::expr::_expr<E> & ee,
510 GISMO_ASSERT(E::isVector(),
"Expecting a vector expression.");
511 static const T delta = 0.00001;
513 const index_t sz = u.space().cardinality();
514 localMat.setZero(sz, sz);
516 for (
index_t c=0; c!= u.dim(); c++)
518 const index_t rls = c * u.data().actives.rows();
519 for (
index_t j = 0; j != sz/u.dim(); j++ )
521 const index_t jj = u.mapper().index(u.data().actives.at(j),
522 u.space().data().patchId, c);
523 if (u.mapper().is_free_index(jj) )
528 u.perturbLocal( delta , jj, u.space().data().patchId);
530 localMat.col(rls+j) += 8 * aux;
531 u.perturbLocal( delta , jj, u.space().data().patchId);
533 localMat.col(rls+j) -= aux;
534 u.perturbLocal(-3*delta, jj, u.space().data().patchId);
536 localMat.col(rls+j) -= 8 * aux;
537 u.perturbLocal( -delta , jj, u.space().data().patchId);
539 localMat.col(rls+j) += aux;
540 localMat.col(rls+j) /= 12*delta;
542 u.perturbLocal(2*delta, jj, u.space().data().patchId);
548 push<true,false>(ee.rowVar(), ee.rowVar());
551 void operator() (
const expr::_expr<expr::gsNullExpr<T> > &) {}
553 template<
bool isMatrix,
bool elim = true>
554 void push(
const expr::gsFeSpace<T> & v,
555 const expr::gsFeSpace<T> & u)
557 GISMO_ASSERT(v.isValid(),
"The row space is not valid");
558 GISMO_ASSERT(!isMatrix || u.isValid(),
"The column space is not valid");
565 const gsDofMapper & rowMap = v.mapper();
566 const gsDofMapper & colMap = (isMatrix ? u.mapper() : rowMap);
567 gsMatrix<index_t> & rowInd0 =
const_cast<gsMatrix<index_t>&
>(v.data().actives);
568 gsMatrix<index_t> & colInd0 = (isMatrix ?
const_cast<gsMatrix<index_t>&
>(u.data().actives) : rowInd0);
569 const gsMatrix<T> & fixedDofs = (isMatrix ? u.fixedPart() : gsMatrix<T>());
573 GISMO_ASSERT( rowInd0.rows()*rd==localMat.rows() && colInd0.rows()*cd==localMat.cols(),
574 "Invalid local matrix (expected "<<rowInd0.rows()*rd <<
"x"<< colInd0.rows()*cd <<
"), got\n" << localMat );
577 "Invalid values for fixed part");
583 for (
index_t r = 0; r != rd; ++r)
585 const index_t rls = r * rowInd0.rows();
586 for (
index_t i = 0; i != rowInd0.rows(); ++i)
588 const index_t ii = rowMap.index(rowInd0.at(i),v.data().patchId,r);
589 if ( rowMap.is_free_index(ii) )
593 for (
index_t c = 0; c != cd; ++c)
595 const index_t cls = c * colInd0.rows();
597 for (
index_t j = 0; j != colInd0.rows(); ++j)
599 if ( 0 == localMat(rls+i,cls+j) )
continue;
601 const index_t jj = colMap.index(colInd0.at(j),u.data().patchId,c);
602 if ( colMap.is_free_index(jj) )
607 # pragma omp critical (acc_m_matrix)
608 m_matrix.coeffRef(ii, jj) += localMat(rls+i,cls+j);
614 # pragma omp critical (acc_m_rhs)
615 m_rhs.at(ii) -= localMat(rls+i,cls+j) *
616 fixedDofs.at(colMap.global_to_bindex(jj));
624 # pragma omp critical (acc_m_rhs)
625 m_rhs.row(ii) += localMat.row(rls+i);
640 opt.
addInt(
"DirichletValues" ,
"Method for computation of Dirichlet DoF values [100..103]", 101);
641 opt.
addInt(
"DirichletStrategy",
"Method for enforcement of Dirichlet BCs [11..14]", 11);
642 opt.
addReal(
"quA",
"Number of quadrature points: quA*deg + quB; For patchRule: Regularity of the target space", 1.0 );
643 opt.
addInt (
"quB",
"Number of quadrature points: quA*deg + quB; For patchRule: Degree of the target space", 1 );
644 opt.
addReal(
"bdA",
"Estimated nonzeros per column of the matrix: bdA*deg + bdB", 2.0 );
645 opt.
addInt (
"bdB",
"Estimated nonzeros per column of the matrix: bdA*deg + bdB", 1 );
646 opt.
addReal(
"bdO",
"Overhead of sparse mem. allocation: (1+bdO)(bdA*deg + bdB) [0..1]", 0.333);
647 opt.
addInt (
"quRule",
"Quadrature rule used (1) Gauss-Legendre; (2) Gauss-Lobatto; (3) Patch-Rule",1);
648 opt.
addSwitch(
"overInt",
"Apply over-integration on boundary elements or not?",
false);
649 opt.
addSwitch(
"flipSide",
"Flip side of interface where integration is performed.",
false);
650 opt.
addSwitch(
"movingInterface",
"Used in interface assembly when interface is not stationary.",
false);
668 fixedDofs.swap(vals);
671 GISMO_ENSURE( fixedDofs.size() == m_vcol[unk]->mapper.boundarySize(),
672 "The Dirichlet DoFs were not provided correctly.");
676 void gsExprAssembler<T>::setFixedDofs(
const gsMatrix<T> & coefMatrix,
short_t unk,
size_t patch)
678 GISMO_ASSERT( m_options.getInt(
"DirichletValues") == dirichlet::user,
"Incorrect options");
680 expr::gsFeSpace<T> & u = *m_vcol[unk];
682 const gsMultiBasis<T> & mbasis = *
dynamic_cast<const gsMultiBasis<T>*
>(m_vcol[unk]->fs);
684 const gsDofMapper & mapper = m_vcol[unk]->mapper;
691 gsMatrix<T> & fixedDofs = m_vcol[unk]->fixedDofs;
692 GISMO_ASSERT(fixedDofs.size() == m_vcol[unk]->mapper.boundarySize(),
693 "Fixed DoFs were not initialized.");
696 typedef typename gsBoundaryConditions<T>::bcRefList bcRefList;
697 for (
typename bcRefList::const_iterator it = u.bc().dirichletBegin();
698 it != u.bc().dirichletEnd() ; ++it )
700 const index_t com = it->unkComponent();
705 const gsMatrix<index_t> boundary =
706 mbasis[k].boundary(it->side());
710 for (
index_t i=0; i!= boundary.size(); ++i)
714 const index_t ii = mapper.bindex( boundary.at(i) , k, com );
716 fixedDofs.at(ii) = coefMatrix(boundary.at(i), com);
725 if (!m_vcol.front()->valid()) m_vcol.front()->init();
726 if (!m_vrow.front()->valid()) m_vrow.front()->init();
727 for (
size_t i = 1; i!=m_vcol.size(); ++i)
729 if (!m_vcol.front()->valid()) m_vcol.front()->init();
730 m_vcol[i]->mapper.setShift(m_vcol[i-1]->mapper.firstIndex() +
731 m_vcol[i-1]->dim*m_vcol[i-1]->mapper.freeSize() );
733 if ( m_vcol[i] != m_vrow[i] )
735 if (!m_vrow.front()->valid()) m_vrow.front()->init();
736 m_vrow[i]->mapper.setShift(m_vrow[i-1]->mapper.firstIndex() +
737 m_vrow[i-1]->dim*m_vrow[i-1]->mapper.freeSize() );
742 template<
size_t I,
class op,
typename... Ts>
743 void op_tuple_impl (op & _op,
const std::tuple<Ts...> &tuple)
745 _op(std::get<I>(tuple));
746 if (I + 1 <
sizeof... (Ts))
747 op_tuple_impl<(I+1 <
sizeof... (Ts) ? I+1 : I)> (_op, tuple);
750 template<
class op,
typename... Ts>
751 void op_tuple (op & _op,
const std::tuple<Ts...> &tuple)
752 { op_tuple_impl<0>(_op,tuple); }
755 template<
class... expr>
758 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized, matrix().cols() = "<<matrix().cols()<<
"!="<<numDofs()<<
" = numDofs()");
761 #pragma omp parallel shared(failed)
764 const int tid = omp_get_thread_num();
765 const int nt = omp_get_num_threads();
767 auto arg_tpl = std::make_tuple(args...);
769 m_exprdata->parse(arg_tpl);
773 typename gsQuadRule<T>::uPtr QuRule;
776 _eval ee(m_matrix, m_rhs, quWeights);
777 const index_t elim = m_options.getInt(
"DirichletStrategy");
778 ee.setElim(dirichlet::elimination==elim);
782 for (
unsigned patchInd = 0; patchInd < m_exprdata->multiBasis().nBases() && (!failed); ++patchInd)
787 typename gsBasis<T>::domainIter domIt =
788 m_exprdata->multiBasis().basis(patchInd).makeDomainIterator();
789 m_exprdata->getElement().set(*domIt,quWeights);
793 for ( domIt->next(tid); domIt->good() && (!failed); domIt->next(nt) )
795 for (; domIt->good(); domIt->next() )
799 QuRule->
mapTo( domIt->lowerCorner(), domIt->upperCorner(),
800 m_exprdata->points(), quWeights);
802 if (m_exprdata->points().cols()==0)
810 m_exprdata->precompute(patchInd);
816 #pragma omp atomic write
821 m_exprdata->precompute(patchInd);
826 op_tuple(ee, arg_tpl);
831 GISMO_ENSURE(!failed,
"Assembly failed due to an error");
832 m_matrix.makeCompressed();
836 template<
class... expr>
839 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized");
841 if ( BCs.empty() || 0==numDofs() )
return;
842 m_exprdata->setMutSource(*BCs.front().get().function());
850 auto arg_tpl = std::make_tuple(args...);
851 m_exprdata->parse(arg_tpl);
854 typename gsQuadRule<T>::uPtr QuRule;
857 _eval ee(m_matrix, m_rhs, quWeights);
860 for (
typename bcRefList::const_iterator iit = BCs.begin(); iit!= BCs.end(); ++iit)
867 m_exprdata->setMutSource(*it->
function());
869 typename gsBasis<T>::domainIter domIt =
870 m_exprdata->multiBasis().basis(it->
patch()).
871 makeDomainIterator(it->
side());
872 m_exprdata->getElement().set(*domIt,quWeights);
875 for (; domIt->good(); domIt->next() )
878 QuRule->
mapTo( domIt->lowerCorner(), domIt->upperCorner(),
879 m_exprdata->points(), quWeights);
881 if (m_exprdata->points().cols()==0)
885 m_exprdata->precompute(it->
patch(), it->
side());
888 op_tuple(ee, arg_tpl);
894 m_matrix.makeCompressed();
899 template<
class... expr>
902 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized");
904 if ( bnd.size()==0 || 0==numDofs() )
return;
906 auto arg_tpl = std::make_tuple(args...);
907 m_exprdata->parse(arg_tpl);
909 typename gsQuadRule<T>::uPtr QuRule;
912 _eval ee(m_matrix, m_rhs, quWeights);
916 for (gsBoxTopology::const_biterator it = bnd.begin();
917 it != bnd.end(); ++it )
920 m_options, it->side().direction());
922 typename gsBasis<T>::domainIter domIt =
923 m_exprdata->multiBasis().basis(it->patch).
924 makeDomainIterator(it->side());
925 m_exprdata->getElement().set(*domIt,quWeights);
928 for (; domIt->good(); domIt->next() )
931 QuRule->
mapTo( domIt->lowerCorner(), domIt->upperCorner(),
932 m_exprdata->points(), quWeights);
934 if (m_exprdata->points().cols()==0)
938 m_exprdata->precompute(it->patch, it->side());
941 op_tuple(ee, arg_tpl);
947 m_matrix.makeCompressed();
950 template<
class T>
template<
class... expr>
951 void gsExprAssembler<T>::assembleIfc(
const ifContainer & iFaces, expr... args)
953 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized");
957 typedef typename gsFunction<T>::uPtr ifacemap;
959 auto arg_tpl = std::make_tuple(args...);
961 m_exprdata->parse(arg_tpl);
964 typename gsQuadRule<T>::uPtr QuRule;
965 gsVector<T> quWeights;
966 _eval ee(m_matrix, m_rhs, quWeights);
968 const bool flipSide = m_options.askSwitch(
"flipSide",
false);
970 ifacemap interfaceMap;
972 for (gsBoxTopology::const_iiterator it = iFaces.begin();
973 it != iFaces.end(); ++it )
977 const boundaryInterface & iFace = flipSide ? it->getInverse() : *it;
978 const index_t patch1 = iFace.first() .patch;
979 const index_t patch2 = iFace.second().patch;
981 if (iFace.type() == interaction::conforming)
982 interfaceMap = gsAffineFunction<T>::make( iFace.dirMap(), iFace.dirOrientation(),
983 m_exprdata->multiBasis().basis(patch1).support(),
984 m_exprdata->multiBasis().basis(patch2).support() );
986 interfaceMap = gsCPPInterface<T>::make(getGeometryMap(), m_exprdata->multiBasis(), iFace);
989 m_options, iFace.first().side().direction());
991 typename gsBasis<T>::domainIter domIt =
992 m_exprdata->multiBasis().basis(patch1)
993 .makeDomainIterator(iFace.first().side());
994 m_exprdata->getElement().set(*domIt, quWeights);
997 for (; domIt->good(); domIt->next() )
1000 QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
1001 m_exprdata->points(), quWeights);
1002 interfaceMap->eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
1004 if (m_exprdata->points().cols()==0)
1008 m_exprdata->precompute(iFace);
1015 op_tuple(ee, arg_tpl);
1020 m_matrix.makeCompressed();
1023 template<
class T>
template<
class expr>
1026 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized");
1027 GISMO_ASSERT(expr::isVector(),
"Expecting a vector expression.");
1032 #pragma omp parallel
1035 const int tid = omp_get_thread_num();
1036 const int nt = omp_get_num_threads();
1039 m_exprdata->parse(residual, u);
1043 typename gsQuadRule<T>::uPtr QuRule;
1047 _eval ee(m_matrix, m_rhs, quWeights);
1051 for (
unsigned patchInd = 0; patchInd < m_exprdata->multiBasis().nBases(); ++patchInd)
1056 typename gsBasis<T>::domainIter domIt =
1057 m_exprdata->multiBasis().basis(patchInd).makeDomainIterator();
1058 m_exprdata->getElement().set(*domIt,quWeights);
1062 for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
1064 for (; domIt->good(); domIt->next() )
1068 QuRule->
mapTo( domIt->lowerCorner(), domIt->upperCorner(),
1069 m_exprdata->points(), quWeights);
1071 if (m_exprdata->points().cols()==0)
1075 m_exprdata->precompute(patchInd);
1077 # pragma omp critical (assemble_fdiffs)
1080 ee.diff(residual, u);
1086 m_matrix.makeCompressed();
1090 template<
class T>
template<
class expr>
1092 const expr residual, solution u)
1094 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized");
1095 GISMO_ASSERT(expr::isVector(),
"Expecting a vector expression.");
1099 m_exprdata->parse(residual, u);
1103 typename gsQuadRule<T>::uPtr QuRule;
1106 _eval ee(m_matrix, m_rhs, quWeights);
1107 const bool flipSide = m_options.askSwitch(
"flipSide",
false);
1108 const bool movingInterface = m_options.askSwitch(
"movingInterface",
false);
1110 for (gsBoxTopology::const_iiterator it = iFaces.begin();
1111 it != iFaces.end(); ++it )
1120 m_exprdata->multiBasis(), iFace);
1125 typename gsBasis<T>::domainIter domIt =
1126 m_exprdata->multiBasis().basis(patch1)
1127 .makeDomainIterator(iFace.
first().side());
1128 m_exprdata->getElement().set(*domIt, quWeights);
1131 for (; domIt->good(); domIt->next() )
1134 QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
1135 m_exprdata->points(), quWeights);
1136 interfaceMap.
eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
1138 if (m_exprdata->points().cols()==0)
1142 m_exprdata->precompute(iFace);
1145 if (!movingInterface)
1147 ee.diff(residual, u);
1151 GISMO_ASSERT(expr::isVector(),
"Expecting a vector expression.");
1152 static const T delta = 0.00001;
1154 const index_t sz = residual.eval(0).rows();
1155 ee.localMat.setZero(sz, sz);
1157 auto & rowVar = residual.rowVar();
1159 for (
index_t c=0; c!= u.dim(); c++)
1161 const index_t rls = c * rowVar.data().actives.rows();
1162 for (
index_t j = 0; j != sz/u.dim(); j++ )
1164 const index_t jj = u.mapper().index(rowVar.data().actives(j),
1165 rowVar.data().patchId, c);
1166 if (rowVar.mapper().is_free_index(jj) )
1169 u.perturbLocal( delta , jj, rowVar.data().patchId);
1170 interfaceMap.updateBdr();
1171 interfaceMap.eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
1172 m_exprdata->precompute(iFace);
1173 ee.quadrature(residual, ee.aux);
1174 ee.localMat.col(rls+j) += 8 * ee.aux;
1177 u.perturbLocal( delta , jj, rowVar.data().patchId);
1178 interfaceMap.updateBdr();
1179 interfaceMap.eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
1180 m_exprdata->precompute(iFace);
1181 ee.quadrature(residual, ee.aux);
1182 ee.localMat.col(rls+j) -= ee.aux;
1184 u.perturbLocal(-3*delta, jj, rowVar.data().patchId);
1185 interfaceMap.updateBdr();
1186 interfaceMap.eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
1187 m_exprdata->precompute(iFace);
1188 ee.quadrature(residual, ee.aux);
1189 ee.localMat.col(rls+j) -= 8 * ee.aux;
1191 u.perturbLocal( -delta , jj, rowVar.data().patchId);
1192 interfaceMap.updateBdr();
1193 interfaceMap.eval_into(m_exprdata->points(), m_exprdata->pointsIfc());
1194 m_exprdata->precompute(iFace);
1195 ee.quadrature(residual, ee.aux);
1196 ee.localMat.col(rls+j) += ee.aux;
1198 ee.localMat.col(rls+j) /= 12*delta;
1200 u.perturbLocal(2*delta, jj, rowVar.data().patchId);
1201 interfaceMap.updateBdr();
1207 ee.template push<true,false>(residual.rowVar(), residual.rowVar());
1212 m_matrix.makeCompressed();
1216 void gsExprAssembler<T>::quPointsWeights(std::vector<gsMatrix<T> >& cPoints, std::vector<gsVector<T> > & cWeights)
1218 GISMO_ASSERT(matrix().cols()==numDofs(),
"System not initialized, matrix().cols() = "<<matrix().cols()<<
"!="<<numDofs()<<
" = numDofs()");
1220 #pragma omp parallel
1223 const int tid = omp_get_thread_num();
1224 const int nt = omp_get_num_threads();
1227 typename gsQuadRule<T>::uPtr QuRule;
1229 gsVector<T> quWeights;
1230 _eval ee(m_matrix, m_rhs, quWeights);
1231 const index_t elim = m_options.getInt(
"DirichletStrategy");
1232 ee.setElim(dirichlet::elimination==elim);
1234 cPoints.resize( m_exprdata->multiBasis().nBases() );
1235 cWeights.resize( m_exprdata->multiBasis().nBases() );
1240 for (
unsigned patchInd = 0; patchInd < m_exprdata->multiBasis().nBases(); ++patchInd)
1242 auto & bb = m_exprdata->multiBasis().basis(patchInd);
1245 const index_t numNodes = QuRule->numNodes();
1247 const index_t sz = bb.numElements() * numNodes;
1248 cPoints[patchInd].resize(bb.domainDim(), sz );
1249 cWeights[patchInd].resize( sz );
1252 typename gsBasis<T>::domainIter domIt = bb.makeDomainIterator();
1253 m_exprdata->getElement().set(*domIt,quWeights);
1257 for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
1259 for (; domIt->good(); domIt->next() )
1263 QuRule->mapTo( domIt->lowerCorner(), domIt->upperCorner(),
1264 m_exprdata->points(), quWeights);
1266 cWeights[patchInd].segment(count, numNodes) = quWeights;
1267 cPoints[patchInd].middleCols(count, numNodes) = m_exprdata->points();
1273 m_matrix.makeCompressed();
function_ptr function() const
Returns the function data pointer of the boundary condition.
Definition: gsBoundaryConditions.h:254
void initVector(const index_t numRhs=1)
Initializes the right-hand side vector only.
Definition: gsExprAssembler.h:344
void assembleJacobian(const expr residual, solution &u)
Assembles the Jacobian matrix of the expression args with.
Definition: gsExprAssembler.h:1024
Definition: gsExprAssembler.h:30
BlockView blockView(const gsVector< index_t > &rowSizes, const gsVector< index_t > &colSizes)
Return a block view of the matrix with rowSizes and colSizes.
Definition: gsSparseMatrix.h:298
void resetDimensions()
Reset the dimensions of all involved spaces. Called internally by the init* functions.
Definition: gsExprAssembler.h:723
index_t boundarySize() const
Returns the number of eliminated dofs.
Definition: gsDofMapper.h:457
gsExprHelper< T >::variable variable
Variable type.
Definition: gsExprAssembler.h:59
Definition: gsExpressions.h:96
void initMatrix()
Initializes the sparse matrix only.
Definition: gsExprAssembler.h:298
gsExprHelper< T >::geometryMap geometryMap
Geometry map type.
Definition: gsExprAssembler.h:58
void clearMatrix(const bool &save_sparsety_pattern=true)
Re-Init Matrix (set zero by default)
Definition: gsExprAssembler.h:312
Provides a mapping between the corresponding sides of two patches sharing an interface, by means of a Closest Point Projection.
#define short_t
Definition: gsConfig.h:35
space getTestSpace(const gsFunctionSet< T > &mp, index_t dim=1, index_t id=0)
Definition: gsExprAssembler.h:192
Provides a mapping between the corresponding sides of two patches sharing an interface, by means of a closest point projection.
Definition: gsCPPInterface.h:32
boxSide side() const
Returns the side to which this boundary condition refers to.
Definition: gsBoundaryConditions.h:269
void matrix_into(gsSparseMatrix< T > &out)
Writes the resulting matrix in out. The internal matrix is moved.
Definition: gsExprAssembler.h:119
space testSpace(const index_t id)
Definition: gsExprAssembler.h:246
S give(S &x)
Definition: gsMemory.h:266
void assemble(const expr &...args)
Adds the expressions args to the system matrix/rhs The arguments are considered as integrals over the...
Definition: gsExprAssembler.h:756
#define index_t
Definition: gsConfig.h:32
Generic expressions helper.
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
static gsQuadRule< T >::uPtr getPtr(const gsBasis< T > &basis, const gsOptionList &options, short_t fixDir=-1)
Constructs a quadrature rule based on input options.
Definition: gsQuadrature.h:61
space trialSpace(space &v) const
Return the trial space of a pre-existing test space v.
Definition: gsExprAssembler.h:242
index_t numDofs() const
Returns the number of degrees of freedom (after initialization)
Definition: gsExprAssembler.h:85
const index_t & getInt(const std::string &label) const
Reads value for option label from options.
Definition: gsOptionList.cpp:37
space trialSpace(const index_t id) const
Definition: gsExprAssembler.h:232
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
index_t numBlocks() const
Definition: gsExprAssembler.h:104
index_t coupledSize() const
Returns the number of coupled (not eliminated) dofs.
Definition: gsDofMapper.cpp:601
space getTestSpace(space u, const gsFunctionSet< T > &mp, index_t dim=-1)
Registers mp as an isogeometric test space corresponding to trial space u and return a handle to it...
Definition: gsExprAssembler.h:227
index_t patch() const
Returns the patch to which this boundary condition refers to.
Definition: gsBoundaryConditions.h:266
virtual short_t targetDim() const
Dimension of the target space.
Definition: gsFunctionSet.h:560
const gsMatrix< T > & rhs() const
Returns the right-hand side vector(s)
Definition: gsExprAssembler.h:129
void addInt(const std::string &label, const std::string &desc, const index_t &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:201
const gsSparseMatrix< T > & matrix() const
Returns the left-hand global matrix.
Definition: gsExprAssembler.h:116
index_t numTestDofs() const
Returns the number of test functions (after initialization)
Definition: gsExprAssembler.h:94
#define gsWarn
Definition: gsDebug.h:50
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
expr::gsComposition< T > getCoeff(const gsFunctionSet< T > &func, geometryMap &G)
Definition: gsExprAssembler.h:265
#define gsInfo
Definition: gsDebug.h:43
Definition: gsDirichletValues.h:23
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition: gsFuncData.h:23
matConstBlockView matrixBlockView() const
Definition: gsExprAssembler.h:365
geometryMap getMap(const gsFunctionSet< T > &g)
Registers g as an isogeometric geometry map and return a handle to it.
Definition: gsExprAssembler.h:161
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
space getSpace(const gsFunctionSet< T > &mp, index_t dim=1, index_t id=0)
Definition: gsExprAssembler.h:166
Creates a variety of quadrature rules.
void setOptions(gsOptionList opt)
Set the assembler options.
Definition: gsExprAssembler.h:375
void setGeometryMap(const gsMultiPatch< T > &gMap)
Set the geometrymap ( used for interface assembly)
Definition: gsExprAssembler.h:141
virtual void mapTo(const gsVector< T > &lower, const gsVector< T > &upper, gsMatrix< T > &nodes, gsVector< T > &weights) const
Maps quadrature rule (i.e., points and weights) from the reference domain to an element.
Definition: gsQuadRule.h:177
Enable optimizations based on the assumption that all evaluation points are in the same bezier domain...
Definition: gsForwardDeclarations.h:89
Class that defines a boundary condition for a side of a patch for some unknown variable of a PDE...
Definition: gsBoundaryConditions.h:106
void addReal(const std::string &label, const std::string &desc, const Real &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:211
Provides functions to generate structured point data.
EIGEN_STRONG_INLINE idMat_expr id(const index_t dim)
The identity matrix of dimension dim.
Definition: gsExpressions.h:4470
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
matBlockView matrixBlockView()
Definition: gsExprAssembler.h:353
static gsOptionList defaultOptions()
Returns the list of default options for assembly.
Definition: gsExprAssembler.h:637
gsExprHelper< T >::element element
Current element.
Definition: gsExprAssembler.h:57
gsOptionList & options()
Returns a reference to the options structure.
Definition: gsExprAssembler.h:113
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
gsExprHelper< T >::space space
Space type.
Definition: gsExprAssembler.h:60
Class which holds a list of parameters/options, and provides easy access to them. ...
Definition: gsOptionList.h:32
index_t freeSize() const
Returns the number of free (not eliminated) dofs.
Definition: gsDofMapper.h:436
const gsMultiBasis< T > & integrationElements() const
Returns the domain of integration.
Definition: gsExprAssembler.h:155
void setIntegrationElements(const gsMultiBasis< T > &mesh)
Sets the domain of integration.
Definition: gsExprAssembler.h:136
void addSwitch(const std::string &label, const std::string &desc, const bool &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:235
gsExprAssembler(index_t _rBlocks=1, index_t _cBlocks=1)
Definition: gsExprAssembler.h:73
expr::gsFeSolution< T > solution
Solution type.
Definition: gsExprAssembler.h:61
solution getSolution(const expr::gsFeSpace< T > &s, gsMatrix< T > &cf) const
Registers a representation of a solution variable from space s, based on the vector cf...
Definition: gsExprAssembler.h:274
void initSystem(const index_t numRhs=1)
Initializes the sparse system (sparse matrix and rhs)
Definition: gsExprAssembler.h:290
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
variable getCoeff(const gsFunctionSet< T > &func)
Definition: gsExprAssembler.h:260
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates the interface map.
Definition: gsCPPInterface.hpp:62
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
Definition: gsExpressions.h:114
void assembleBdr(const bcRefList &BCs, expr &...args)
Adds the expressions args to the system matrix/rhs The arguments are considered as integrals over the...
Definition: gsExprAssembler.h:837
Real getReal(const std::string &label) const
Reads value for option label from options.
Definition: gsOptionList.cpp:44
space testSpace(space u) const
Return the test space of a pre-existing trial space u.
Definition: gsExprAssembler.h:256
void rhs_into(gsMatrix< T > &out)
Writes the resulting vector in out. The internal data is moved.
Definition: gsExprAssembler.h:132
patchSide & first()
first, returns the first patchSide of this interface
Definition: gsBoundary.h:776