35 GISMO_ASSERT( dofMapperGlobal.componentsSize() == 1,
"gsIetiMapper::init: "
36 "Got only 1 multi basis, so a gsDofMapper with only 1 component is expected." );
38 "Number of patches does not agree." );
41 m_multiBasis = &multiBasis;
42 m_dofMapperGlobal =
give(dofMapperGlobal);
43 m_dofMapperLocal.clear();
44 m_dofMapperLocal.resize(nPatches);
46 m_fixedPart.resize(nPatches);
47 m_jumpMatrices.clear();
49 m_primalConstraints.clear();
50 m_primalConstraints.resize(nPatches);
51 m_primalDofIndices.clear();
52 m_primalDofIndices.resize(nPatches);
55 for (
index_t k=0; k<nPatches; ++k)
57 const index_t nDofs = m_dofMapperGlobal.patchSize(k);
58 GISMO_ASSERT( nDofs==m_multiBasis->piece(k).size(),
"gsIetiMapper::init: "
59 "The mapper for patch "<<k<<
" has not as many dofs as the corresponding basis." );
61 m_dofMapperLocal[k].setIdentity(1,nDofs);
66 const index_t idx = m_dofMapperGlobal.index(i,k);
67 if (m_dofMapperGlobal.is_boundary_index(idx))
68 m_dofMapperLocal[k].eliminateDof(i,0);
70 m_dofMapperLocal[k].finalize();
72 const index_t szFixedPart = m_dofMapperLocal[k].boundarySize();
73 m_fixedPart[k].setZero(szFixedPart,1);
76 const index_t idx = m_dofMapperGlobal.index(i,k);
77 if (m_dofMapperGlobal.is_boundary_index(idx))
79 const index_t globalBoundaryIdx = m_dofMapperGlobal.bindex(i,k);
80 const index_t localBoundaryIdx = m_dofMapperLocal[k].bindex(i,0);
81 m_fixedPart[k](localBoundaryIdx,0) = fixedPart(globalBoundaryIdx,0);
92 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
94 const index_t nPatches = m_dofMapperGlobal.numPatches();
95 GISMO_ASSERT( nPatches == static_cast<index_t>(localContribs.size()),
96 "gsIetiMapper::constructGlobalSolutionFromLocalSolutions; The number of local contributions does "
97 "not argee with the number of patches." );
100 result.setZero( m_dofMapperGlobal.freeSize(), localContribs[0].cols() );
102 for (
index_t k=0; k<nPatches; ++k)
104 const index_t sz=m_dofMapperLocal[k].size();
107 if (m_dofMapperLocal[k].is_free(i,0) && m_dofMapperGlobal.is_free(i,k))
108 result.row(m_dofMapperGlobal.index(i,k)) = localContribs[k].row(m_dofMapperLocal[k].index(i,0));
119 bool operator<(
const dof_helper& other)
const
120 {
return globalIndex < other.globalIndex; }
127 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
128 GISMO_ASSERT( !(m_status&4),
"gsIetiMapper::cornersAsPrimals: This function has already been called." );
131 const index_t nPatches = m_dofMapperLocal.size();
134 std::vector<dof_helper> corners;
135 const index_t dim = m_multiBasis->dim();
136 corners.reserve((1<<dim)*nPatches);
138 for (
index_t k=0; k<nPatches; ++k)
142 const index_t idx = (*m_multiBasis)[k].functionAtCorner(it);
144 dh.globalIndex = m_dofMapperGlobal.index( idx, k );
146 dh.localIndex = m_dofMapperLocal[k].index( idx, 0 );
147 if (m_dofMapperGlobal.is_free_index(dh.globalIndex))
148 corners.push_back(dh);
153 std::sort(corners.begin(), corners.end());
157 const index_t sz = corners.size();
160 if (lastIndex!=corners[i].globalIndex)
162 lastIndex = corners[i].globalIndex;
163 if (i+1<sz&&corners[i+1].globalIndex==corners[i].globalIndex)
168 const index_t cornerIndex = m_nPrimalDofs - 1;
169 const index_t patch = corners[i].patch;
170 const index_t localIndex = corners[i].localIndex;
172 SparseVector constr(m_dofMapperLocal[patch].freeSize());
173 constr[localIndex] = 1;
175 m_primalConstraints[patch].push_back(
give(constr));
176 m_primalDofIndices[patch].push_back(cornerIndex);
200 const index_t sz = moments.size();
201 GISMO_ASSERT( sz == indices.size(),
"Internal error." );
207 constraint[idx] = moments(i,0);
211 return constraint / sum;
219 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
220 GISMO_ASSERT( d>0,
"gsIetiMapper::interfaceAveragesAsPrimals cannot handle corners." );
221 GISMO_ASSERT( d<=m_multiBasis->dim(),
"gsIetiMapper::interfaceAveragesAsPrimals: "
222 "Interfaces cannot have larger dimension than considered object." );
224 "gsIetiMapper::interfaceAveragesAsPrimals: The given geometry does not fit.");
226 "gsIetiMapper::interfaceAveragesAsPrimals: The given geometry does not fit.");
228 const unsigned flag = 1<<(2+d);
229 GISMO_ASSERT( !(m_status&flag),
"gsIetiMapper::interfaceAveragesAsPrimals: This function has "
230 " already been called for d="<<d );
233 std::vector< std::vector<patchComponent> > components = geo.
allComponents();
234 const index_t nComponents = components.size();
235 for (
index_t n=0; n<nComponents; ++n)
237 const index_t sz = components[n].size();
238 if ( components[n][0].dim() == d && ( sz > 1 || m_multiBasis->dim() == d ))
243 const index_t k = components[n][i].patch();
250 if ( constr.nonZeros() > 0 )
252 m_primalConstraints[k].push_back(
give(constr));
253 m_primalDofIndices[k].push_back(m_nPrimalDofs);
257 GISMO_ASSERT( used==0 || used == sz,
"Internal error." );
268 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
270 const index_t sz = data.size();
273 const index_t patch = data[i].first;
274 m_primalConstraints[patch].push_back(
give(data[i].second));
275 m_primalDofIndices[patch].push_back(m_nPrimalDofs);
283 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
285 std::vector<index_t> result;
286 const index_t patchSize = m_dofMapperGlobal.patchSize(patch);
287 const index_t dim = m_multiBasis->dim();
288 result.reserve(2*dim*std::pow(patchSize,(1.0-dim)/dim));
289 for (
index_t i=0; i<patchSize; ++i)
290 if ( m_dofMapperGlobal.is_coupled(i,patch) )
291 result.push_back(m_dofMapperLocal[patch].index(i,0));
298 GISMO_ASSERT( m_status&1,
"gsIetiMapper: The class has not been initialized." );
300 GISMO_ASSERT( !(m_status&2),
"gsIetiMapper::computeJumpMatrices: This function has already been called." );
303 const index_t nPatches = m_dofMapperGlobal.numPatches();
304 const index_t coupledSize = m_dofMapperGlobal.coupledSize();
307 std::vector< std::vector< std::pair<index_t,index_t> > > coupling;
308 coupling.resize(coupledSize);
310 for (
index_t k=0; k<nPatches; ++k)
312 const index_t patchSize = m_dofMapperGlobal.patchSize(k);
313 for (
index_t i=0; i<patchSize; ++i)
315 const index_t globalIndex = m_dofMapperGlobal.index(i,k);
316 if ( m_dofMapperGlobal.is_coupled_index(globalIndex) )
318 const index_t coupledIndex = m_dofMapperGlobal.cindex(i,k);
319 const index_t localIndex = m_dofMapperLocal[k].index(i,0);
320 coupling[coupledIndex].push_back(
321 std::pair<index_t,index_t>(k,localIndex)
330 const index_t dim = m_multiBasis->dim();
331 for (
index_t k=0; k<nPatches; ++k)
335 const index_t idx = (*m_multiBasis)[k].functionAtCorner(it);
336 const index_t globalIndex = m_dofMapperGlobal.index(idx,k);
337 if ( m_dofMapperGlobal.is_coupled_index(globalIndex) )
339 const index_t coupledIndex = m_dofMapperGlobal.cindex(idx,k);
340 coupling[coupledIndex].clear();
348 for (
index_t i=0; i<coupledSize; ++i)
350 const index_t n = coupling[i].size();
351 GISMO_ASSERT( n>1 || excludeCorners,
"gsIetiMapper::computeJumpMatrices:"
352 "Found a coupled dof that is not coupled to any other dof." );
354 numLagrangeMult += (n * (n-1))/2;
356 numLagrangeMult += n-1;
360 std::vector< gsSparseEntries<T> > jumpMatrices_se(nPatches);
361 for (
index_t i=0; i<nPatches; ++i)
363 const index_t dim = m_multiBasis->dim();
364 jumpMatrices_se[i].reserve(std::pow(m_dofMapperLocal[i].freeSize(),(1.0-dim)/dim));
368 for (
index_t i=0; i<coupledSize; ++i)
370 const index_t n = coupling[i].size();
371 const index_t maxIndex = fullyRedundant ? (n-1) : 1;
372 for (
index_t j1=0; j1<maxIndex; ++j1)
374 const index_t patch1 = coupling[i][j1].first;
375 const index_t localMappedIndex1 = coupling[i][j1].second;
376 for (
index_t j2=j1+1; j2<n; ++j2)
378 const index_t patch2 = coupling[i][j2].first;
379 const index_t localMappedIndex2 = coupling[i][j2].second;
380 jumpMatrices_se[patch1].add(multiplier,localMappedIndex1,(T)1);
381 jumpMatrices_se[patch2].add(multiplier,localMappedIndex2,(T)-1);
386 GISMO_ASSERT( multiplier == numLagrangeMult,
"gsIetiMapper::computeJumpMatrices: Internal error: "
387 << multiplier <<
"!=" << numLagrangeMult );
389 m_jumpMatrices.clear();
390 for (
index_t i=0; i<nPatches; ++i)
392 m_jumpMatrices.push_back(
JumpMatrix(numLagrangeMult, m_dofMapperLocal[i].freeSize()));
393 m_jumpMatrices[i].setFrom(jumpMatrices_se[i]);
401 GISMO_ASSERT(localSolution.cols() == m_fixedPart[k].cols(),
"gsIetiMapper::incorporateFixedPart: Dimension missmatch.");
402 const std::size_t sz = m_dofMapperLocal[k].totalSize();
403 Matrix coeffs(sz, localSolution.cols());
404 for (std::size_t i = 0; i < sz; ++i)
406 if ( m_dofMapperLocal[k].is_free(i, 0) )
407 coeffs.row(i) = localSolution.row( m_dofMapperLocal[k].index(i, 0) );
409 coeffs.row(i) = m_fixedPart[k].row( m_dofMapperLocal[k].bindex(i, 0) );
void cornersAsPrimals()
Set up the corners as primal dofs.
Definition: gsIetiMapper.hpp:125
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
#define short_t
Definition: gsConfig.h:35
short_t parDim() const
Dimension of the parameter domain (must match for all patches).
Definition: gsMultiPatch.h:183
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
void init(const gsMultiBasis< T > &multiBasis, gsDofMapper dofMapperGlobal, const Matrix &fixedPart)
Init the ieti mapper after default construction.
Definition: gsIetiMapper.hpp:29
const gsMatrix< T > & assembleMoments(const gsFunction< T > &func, index_t patchIndex=-1, bool refresh=true)
Moments assembly routine.
Definition: gsGenericAssembler.hpp:93
virtual uPtr componentBasis_withIndices(boxComponent b, gsMatrix< index_t > &indices, bool noBoundary=true) const
Returns the basis that corresponds to the component.
Definition: gsBasis.hpp:360
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void computeJumpMatrices(bool fullyRedundant, bool excludeCorners)
This function computes the jump matrices.
Definition: gsIetiMapper.hpp:296
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
void customPrimalConstraints(std::vector< std::pair< index_t, SparseVector > > data)
With this function, the caller can register more primal constraints.
Definition: gsIetiMapper.hpp:266
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
bool is_free_index(index_t gl) const
Returns true if global dof gl is not eliminated.
Definition: gsDofMapper.h:376
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
size_t nPatches() const
Number of patches.
Definition: gsMultiPatch.h:208
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
size_t numPatches() const
Returns the number of patches present underneath the mapper.
Definition: gsDofMapper.h:469
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:399
Assembles mass and stiffness matrices and right-hand sides on a given domain.
Definition: gsGenericAssembler.h:32
void interfaceAveragesAsPrimals(const gsMultiPatch< T > &geo, short_t d)
Set up interface averages as primal dofs.
Definition: gsIetiMapper.hpp:217
Matrix constructGlobalSolutionFromLocalSolutions(const std::vector< Matrix > &localContribs)
Construct the global solution from a vector of patch-local ones.
Definition: gsIetiMapper.hpp:90
size_t nBases() const
Number of patch-wise bases.
Definition: gsMultiBasis.h:264
std::vector< std::vector< patchComponent > > allComponents(bool combineCorners=false) const
Returns all components representing the topology.
Definition: gsBoxTopology.cpp:294
std::vector< index_t > skeletonDofs(index_t patch) const
Returns a list of dofs that are (on the coarse level) coupled.
Definition: gsIetiMapper.hpp:281
static boxCorner getFirst(short_t)
helper for iterating on corners of an n-dimensional box
Definition: gsBoundary.h:356
gsGeometry::uPtr component(boxComponent const &bc) const
Get parametrization of box component bc as a new gsGeometry uPtr.
Definition: gsGeometry.hpp:240
short_t targetDim() const
Dimension of the ambient physical space (overriding gsFunction::targetDim())
Definition: gsGeometry.h:286
index_t freeSize() const
Returns the number of free (not eliminated) dofs.
Definition: gsDofMapper.h:436
static gsSparseVector< T > assembleAverage(const gsGeometry< T > &geo, const gsBasis< T > &basis, const gsDofMapper &dm, boxComponent bc)
Assembles for interfaceAveragesAsPrimals.
Definition: gsIetiMapper.hpp:182
Sparse vector class, based on gsEigen::SparseVector.
Definition: gsSparseVector.h:34
static boxCorner getEnd(short_t dim)
helper for iterating on corners of an n-dimensional box
Definition: gsBoundary.h:372
Provides an assembler for common IGA matrices.
Struct which represents a certain corner of a hyper-cube.
Definition: gsBoundary.h:291
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
Class defining a globally constant function.
Definition: gsConstantFunction.h:33
Struct which represents a certain component (interior, face, egde, corner).
Definition: gsBoundary.h:445