36 GISMO_ASSERT( dofMapperGlobal.componentsSize() == 1,
"gsIetiMapper::init: "
37 "Got only 1 multi basis, so a gsDofMapper with only 1 component is expected." );
39 "Number of patches does not agree." );
42 m_multiBasis = &multiBasis;
43 m_dofMapperGlobal =
give(dofMapperGlobal);
44 m_dofMapperLocal.clear();
45 m_dofMapperLocal.resize(nPatches);
47 m_fixedPart.resize(nPatches);
48 m_jumpMatrices.clear();
50 m_primalConstraints.clear();
51 m_primalConstraints.resize(nPatches);
52 m_primalDofIndices.clear();
53 m_primalDofIndices.resize(nPatches);
56 for (
index_t k=0; k<nPatches; ++k)
58 const index_t nDofs = m_dofMapperGlobal.patchSize(k);
59 GISMO_ASSERT( nDofs==m_multiBasis->piece(k).size(),
"gsIetiMapper::init: "
60 "The mapper for patch "<<k<<
" has not as many dofs as the corresponding basis." );
62 m_dofMapperLocal[k].setIdentity(1,nDofs);
67 const index_t idx = m_dofMapperGlobal.index(i,k);
68 if (m_dofMapperGlobal.is_boundary_index(idx))
69 m_dofMapperLocal[k].eliminateDof(i,0);
71 m_dofMapperLocal[k].finalize();
73 const index_t szFixedPart = m_dofMapperLocal[k].boundarySize();
74 m_fixedPart[k].setZero(szFixedPart,1);
77 const index_t idx = m_dofMapperGlobal.index(i,k);
78 if (m_dofMapperGlobal.is_boundary_index(idx))
80 const index_t globalBoundaryIdx = m_dofMapperGlobal.bindex(i,k);
81 const index_t localBoundaryIdx = m_dofMapperLocal[k].bindex(i,0);
82 m_fixedPart[k](localBoundaryIdx,0) = fixedPart(globalBoundaryIdx,0);
93 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
95 const index_t nPatches = m_dofMapperGlobal.numPatches();
97 "gsIetiMapper::constructGlobalSolutionFromLocalSolutions; The number of local contributions does "
98 "not argee with the number of patches." );
101 result.setZero( m_dofMapperGlobal.freeSize(), localContribs[0].cols() );
103 for (
index_t k=0; k<nPatches; ++k)
105 const index_t sz=m_dofMapperLocal[k].size();
108 if (m_dofMapperLocal[k].is_free(i,0) && m_dofMapperGlobal.is_free(i,k))
109 result.row(m_dofMapperGlobal.index(i,k)) = localContribs[k].row(m_dofMapperLocal[k].index(i,0));
120 bool operator<(
const dof_helper& other)
const
121 {
return globalIndex < other.globalIndex; }
128 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
129 GISMO_ASSERT( !(m_status&4),
"gsIetiMapper::cornersAsPrimals: This function has already been called." );
132 const index_t nPatches = m_dofMapperLocal.size();
135 std::vector<dof_helper> corners;
136 const index_t dim = m_multiBasis->dim();
137 corners.reserve((1<<dim)*nPatches);
139 for (
index_t k=0; k<nPatches; ++k)
143 const index_t idx = (*m_multiBasis)[k].functionAtCorner(it);
145 dh.globalIndex = m_dofMapperGlobal.index( idx, k );
147 dh.localIndex = m_dofMapperLocal[k].index( idx, 0 );
148 if (m_dofMapperGlobal.is_free_index(dh.globalIndex))
149 corners.push_back(dh);
154 std::sort(corners.begin(), corners.end());
158 const index_t sz = corners.size();
161 if (lastIndex!=corners[i].globalIndex)
163 lastIndex = corners[i].globalIndex;
164 if (i+1<sz&&corners[i+1].globalIndex==corners[i].globalIndex)
169 const index_t cornerIndex = m_nPrimalDofs - 1;
170 const index_t patch = corners[i].patch;
171 const index_t localIndex = corners[i].localIndex;
173 SparseVector constr(m_dofMapperLocal[patch].freeSize());
174 constr[localIndex] = 1;
176 m_primalConstraints[patch].push_back(
give(constr));
177 m_primalDofIndices[patch].push_back(cornerIndex);
194 *(basis.componentBasis_withIndices(bc, indices,
false))
201 const index_t sz = moments.size();
202 GISMO_ASSERT( sz == indices.size(),
"Internal error." );
208 constraint[idx] = moments(i,0);
212 return constraint / sum;
220 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
221 GISMO_ASSERT( d>0,
"gsIetiMapper::interfaceAveragesAsPrimals cannot handle corners." );
222 GISMO_ASSERT( d<=m_multiBasis->dim(),
"gsIetiMapper::interfaceAveragesAsPrimals: "
223 "Interfaces cannot have larger dimension than considered object." );
225 "gsIetiMapper::interfaceAveragesAsPrimals: The given geometry does not fit.");
227 "gsIetiMapper::interfaceAveragesAsPrimals: The given geometry does not fit.");
229 const unsigned flag = 1<<(2+d);
230 GISMO_ASSERT( !(m_status&flag),
"gsIetiMapper::interfaceAveragesAsPrimals: This function has "
231 " already been called for d="<<d );
234 std::vector< std::vector<patchComponent> > components = geo.
allComponents();
235 const index_t nComponents = components.size();
236 for (
index_t n=0; n<nComponents; ++n)
238 const index_t sz = components[n].size();
239 if ( components[n][0].dim() == d && ( sz > 1 || m_multiBasis->dim() == d ))
244 const index_t k = components[n][i].patch();
251 if ( constr.nonZeros() > 0 )
253 m_primalConstraints[k].push_back(
give(constr));
254 m_primalDofIndices[k].push_back(m_nPrimalDofs);
258 GISMO_ASSERT( used==0 || used == sz,
"Internal error." );
269 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
271 const index_t sz = data.size();
274 const index_t patch = data[i].first;
275 m_primalConstraints[patch].push_back(
give(data[i].second));
276 m_primalDofIndices[patch].push_back(m_nPrimalDofs);
284 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
286 std::vector<index_t> result;
287 const index_t patchSize = m_dofMapperGlobal.patchSize(patch);
288 const index_t dim = m_multiBasis->dim();
289 result.reserve(2*dim*std::pow(patchSize,(1.0-dim)/dim));
290 for (
index_t i=0; i<patchSize; ++i)
291 if ( m_dofMapperGlobal.is_coupled(i,patch) )
292 result.push_back(m_dofMapperLocal[patch].index(i,0));
299 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
301 GISMO_ASSERT( !(m_status&2),
"gsIetiMapper::computeJumpMatrices: This function has already been called." );
304 const index_t nPatches = m_dofMapperGlobal.numPatches();
305 const index_t coupledSize = m_dofMapperGlobal.coupledSize();
308 std::vector< std::vector< std::pair<index_t,index_t> > > coupling;
309 coupling.resize(coupledSize);
311 for (
index_t k=0; k<nPatches; ++k)
313 const index_t patchSize = m_dofMapperGlobal.patchSize(k);
314 for (
index_t i=0; i<patchSize; ++i)
316 const index_t globalIndex = m_dofMapperGlobal.index(i,k);
317 if ( m_dofMapperGlobal.is_coupled_index(globalIndex) )
319 const index_t coupledIndex = m_dofMapperGlobal.cindex(i,k);
320 const index_t localIndex = m_dofMapperLocal[k].index(i,0);
321 coupling[coupledIndex].push_back(
322 std::pair<index_t,index_t>(k,localIndex)
331 const index_t dim = m_multiBasis->dim();
332 for (
index_t k=0; k<nPatches; ++k)
336 const index_t idx = (*m_multiBasis)[k].functionAtCorner(it);
337 const index_t globalIndex = m_dofMapperGlobal.index(idx,k);
338 if ( m_dofMapperGlobal.is_coupled_index(globalIndex) )
340 const index_t coupledIndex = m_dofMapperGlobal.cindex(idx,k);
341 coupling[coupledIndex].clear();
349 for (
index_t i=0; i<coupledSize; ++i)
351 const index_t n = coupling[i].size();
352 GISMO_ASSERT( n>1 || excludeCorners,
"gsIetiMapper::computeJumpMatrices:"
353 "Found a coupled dof that is not coupled to any other dof." );
355 numLagrangeMult += (n * (n-1))/2;
357 numLagrangeMult += n-1;
361 std::vector< gsSparseEntries<T> > jumpMatrices_se(nPatches);
362 for (
index_t i=0; i<nPatches; ++i)
364 const index_t dim = m_multiBasis->dim();
365 jumpMatrices_se[i].reserve(std::pow(m_dofMapperLocal[i].freeSize(),(1.0-dim)/dim));
369 for (
index_t i=0; i<coupledSize; ++i)
371 const index_t n = coupling[i].size();
372 const index_t maxIndex = fullyRedundant ? (n-1) : 1;
373 for (
index_t j1=0; j1<maxIndex; ++j1)
375 const index_t patch1 = coupling[i][j1].first;
376 const index_t localMappedIndex1 = coupling[i][j1].second;
377 for (
index_t j2=j1+1; j2<n; ++j2)
379 const index_t patch2 = coupling[i][j2].first;
380 const index_t localMappedIndex2 = coupling[i][j2].second;
381 jumpMatrices_se[patch1].add(multiplier,localMappedIndex1,(T)1);
382 jumpMatrices_se[patch2].add(multiplier,localMappedIndex2,(T)-1);
387 GISMO_ASSERT( multiplier == numLagrangeMult,
"gsIetiMapper::computeJumpMatrices: Internal error: "
388 << multiplier <<
"!=" << numLagrangeMult );
390 m_jumpMatrices.clear();
391 for (
index_t i=0; i<nPatches; ++i)
393 m_jumpMatrices.push_back(
JumpMatrix(numLagrangeMult, m_dofMapperLocal[i].freeSize()));
394 m_jumpMatrices[i].setFrom(jumpMatrices_se[i]);
402 GISMO_ASSERT(localSolution.cols() == m_fixedPart[k].cols(),
"gsIetiMapper::incorporateFixedPart: Dimension missmatch.");
403 const std::size_t sz = m_dofMapperLocal[k].totalSize();
404 Matrix coeffs(sz, localSolution.cols());
405 for (std::size_t i = 0; i < sz; ++i)
407 if ( m_dofMapperLocal[k].is_free(i, 0) )
408 coeffs.row(i) = localSolution.row( m_dofMapperLocal[k].index(i, 0) );
410 coeffs.row(i) = m_fixedPart[k].row( m_dofMapperLocal[k].bindex(i, 0) );
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
std::vector< std::vector< patchComponent > > allComponents(bool combineCorners=false) const
Returns all components representing the topology.
Definition gsBoxTopology.cpp:294
Class defining a globally constant function.
Definition gsConstantFunction.h:34
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
size_t numPatches() const
Returns the number of patches present underneath the mapper.
Definition gsDofMapper.h:469
bool is_free_index(index_t gl) const
Returns true if global dof gl is not eliminated.
Definition gsDofMapper.h:376
index_t freeSize() const
Returns the number of free (not eliminated) dofs.
Definition gsDofMapper.h:436
index_t index(index_t i, index_t k=0, index_t c=0) const
Returns the global dof index associated to local dof i of patch k.
Definition gsDofMapper.h:325
Assembles mass and stiffness matrices and right-hand sides on a given domain.
Definition gsGenericAssembler.h:33
const gsMatrix< T > & assembleMoments(const gsFunction< T > &func, index_t patchIndex=-1, bool refresh=true)
Moments assembly routine.
Definition gsGenericAssembler.hpp:93
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
short_t targetDim() const
Dimension of the ambient physical space (overriding gsFunction::targetDim())
Definition gsGeometry.h:286
gsGeometry::uPtr component(boxComponent const &bc) const
Get parametrization of box component bc as a new gsGeometry uPtr.
Definition gsGeometry.hpp:240
Matrix incorporateFixedPart(index_t k, const gsMatrix< T > &localSolution) const
Incorporates fixedPart (eg. from eliminated Dirichlet dofs) to given patch-local solution.
Definition gsIetiMapper.hpp:400
static gsSparseVector< T > assembleAverage(const gsGeometry< T > &geo, const gsBasis< T > &basis, const gsDofMapper &dm, boxComponent bc)
Assembles for interfaceAveragesAsPrimals.
Definition gsIetiMapper.hpp:183
void computeJumpMatrices(bool fullyRedundant, bool excludeCorners)
This function computes the jump matrices.
Definition gsIetiMapper.hpp:297
void interfaceAveragesAsPrimals(const gsMultiPatch< T > &geo, short_t d)
Set up interface averages as primal dofs.
Definition gsIetiMapper.hpp:218
void cornersAsPrimals()
Set up the corners as primal dofs.
Definition gsIetiMapper.hpp:126
void init(const gsMultiBasis< T > &multiBasis, gsDofMapper dofMapperGlobal, const Matrix &fixedPart)
Init the ieti mapper after default construction.
Definition gsIetiMapper.hpp:30
Matrix constructGlobalSolutionFromLocalSolutions(const std::vector< Matrix > &localContribs)
Construct the global solution from a vector of patch-local ones.
Definition gsIetiMapper.hpp:91
void customPrimalConstraints(std::vector< std::pair< index_t, SparseVector > > data)
With this function, the caller can register more primal constraints.
Definition gsIetiMapper.hpp:267
std::vector< index_t > skeletonDofs(index_t patch) const
Returns a list of dofs that are (on the coarse level) coupled.
Definition gsIetiMapper.hpp:282
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
size_t nBases() const
Number of patch-wise bases.
Definition gsMultiBasis.h:264
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
short_t parDim() const
Dimension of the parameter domain (must match for all patches).
Definition gsMultiPatch.h:249
size_t nPatches() const
Number of patches.
Definition gsMultiPatch.h:274
Sparse vector class, based on gsEigen::SparseVector.
Definition gsSparseVector.h:35
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
Provides declaration of ConstantFunction class.
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides an assembler for common IGA matrices.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266
Struct which represents a certain component (interior, face, egde, corner).
Definition gsBoundary.h:445
Struct which represents a certain corner of a hyper-cube.
Definition gsBoundary.h:292
static boxCorner getEnd(short_t dim)
helper for iterating on corners of an n-dimensional box
Definition gsBoundary.h:372
static boxCorner getFirst(short_t)
helper for iterating on corners of an n-dimensional box
Definition gsBoundary.h:356