21 : m_localMatrix(nPrimalDofs,nPrimalDofs), m_eliminatePointwiseConstraints(false)
28 const std::vector<SparseVector>& primalConstraints,
29 bool eliminatePointwiseConstraints,
37 const index_t localDofs = localMatrix.rows();
38 const index_t nrPrimalConstraints = primalConstraints.size();
42 std::vector<bool> eliminatedDof(localDofs,
false);
43 std::vector<bool> eliminatedConstaint(nrPrimalConstraints,
false);
47 seModifiedLocalMatrix.reserve( localMatrix.nonZeros() + nrPrimalConstraints * localDofs );
49 if (eliminatePointwiseConstraints)
51 for (
index_t i=0; i!=nrPrimalConstraints; ++i)
53 if (primalConstraints[i].nonZeros() == 1)
55 typename SparseVector::InnerIterator it(primalConstraints[i]);
57 eliminatedDof[it.row()] =
true;
58 eliminatedConstaint[i] =
true;
60 seModifiedLocalMatrix.add(it.row(),it.row(),(T)1);
67 for (
index_t i=0; i!=localDofs; ++i)
68 for (
typename SparseMatrix::InnerIterator it(localMatrix,i); it; ++it)
69 if ( !eliminatedDof[it.row()] && !eliminatedDof[it.col()] )
70 seModifiedLocalMatrix.add(it.row(), it.col(), it.value());
73 for (
index_t i=0, j=0; i!=nrPrimalConstraints; ++i)
75 if ( !eliminatedConstaint[i] )
77 for (
typename SparseVector::InnerIterator it(primalConstraints[i]); it; ++it)
79 if ( !eliminatedDof[it.row()] )
81 seModifiedLocalMatrix.add(it.row(), localDofs+j, it.value());
82 seModifiedLocalMatrix.add(localDofs+j, it.row(), it.value());
89 modifiedLocalMatrix.clear();
90 modifiedLocalMatrix.resize(localDofs+nrPrimalConstraints-nElimDofs, localDofs+nrPrimalConstraints-nElimDofs);
91 modifiedLocalMatrix.setFrom(seModifiedLocalMatrix);
92 modifiedLocalMatrix.makeCompressed();
97 localEmbedding.clear();
98 localEmbedding.resize(localDofs+nrPrimalConstraints-nElimDofs,localDofs);
99 embeddingForBasis.clear();
100 embeddingForBasis.resize(localDofs+nrPrimalConstraints-nElimDofs,localDofs);
102 seLocalEmbedding.reserve(localDofs-nElimDofs);
103 seEmbeddingForBasis.reserve(localDofs);
104 for (
index_t i=0; i!=localDofs; ++i)
106 if ( !eliminatedDof[i] )
107 seLocalEmbedding.add(i,i,(T)1);
108 seEmbeddingForBasis.add(i,i,(T)1);
110 localEmbedding.setFrom(seLocalEmbedding);
111 localEmbedding.makeCompressed();
112 embeddingForBasis.setFrom(seEmbeddingForBasis);
113 embeddingForBasis.makeCompressed();
117 rhsForBasis.setZero(localDofs+nrPrimalConstraints-nElimDofs,nrPrimalConstraints);
118 for (
index_t i=0, j=0; i!=nrPrimalConstraints; ++i)
120 if ( eliminatedConstaint[i] )
122 typename SparseVector::InnerIterator it(primalConstraints[i]);
124 for (
typename SparseMatrix::InnerIterator it2(localMatrix, idx); it2; ++it2)
126 if ( !eliminatedDof[it2.row()] )
127 rhsForBasis(it2.row(),i) = - it2.value();
129 rhsForBasis(idx,i) = (T)1;
133 rhsForBasis(localDofs+j,i) = (T)1;
142 OpPtr localSaddlePointSolver,
144 const Matrix& rhsForBasis,
145 const std::vector<index_t>& primalDofIndices,
149 const index_t nrPrimalConstraints = primalDofIndices.size();
150 const index_t localDofs = embeddingForBasis.cols();
152 GISMO_ASSERT( nrPrimalConstraints<=nPrimalDofs,
"gsPrimalSystem::primalBasis: "
153 "There are more local constraints that there are constraints in total. "
154 "Forgot to call gsPrimalSystem::init()?" );
158 if (nPrimalDofs==0||rhsForBasis.cols()==0)
return result;
161 localSaddlePointSolver->apply(rhsForBasis, tmp);
162 Matrix basis = embeddingForBasis.transpose() * tmp;
165 se_result.reserve(localDofs*nrPrimalConstraints);
166 for (
index_t i=0; i<localDofs; ++i)
167 for (
index_t j=0; j<nrPrimalConstraints; ++j)
169 GISMO_ASSERT( primalDofIndices[j]>=0 && primalDofIndices[j]<nPrimalDofs,
170 "gsPrimalSystem::primalBasis: Invalid index.");
171 se_result.add(i,primalDofIndices[j],basis(i,j));
174 result.setFrom(se_result);
187 if (m_jumpMatrix.rows()==0&&m_jumpMatrix.cols()==0)
188 m_jumpMatrix.resize(jumpMatrix.rows(),nPrimalDofs());
190 GISMO_ASSERT( primalBasis.cols() == m_jumpMatrix.cols(),
191 "gsPrimalSystem::incorporate: The given problem size does not match the stored primal problem size. "
192 "Forgot to call gsPrimalSystem::init()?" );
194 m_localMatrix += primalBasis.transpose() * localMatrix * primalBasis;
195 m_localRhs += primalBasis.transpose() * localRhs;
196 m_jumpMatrix +=
JumpMatrix(jumpMatrix * primalBasis);
197 m_primalBases.push_back(
give(primalBasis));
198 m_embeddings.push_back(
give(embedding));
203 const std::vector<SparseVector>& primalConstraints,
204 const std::vector<index_t>& primalDofIndices,
210 SparseMatrix modifiedLocalMatrix, localEmbedding, embeddingForBasis;
213 incorporateConstraints(primalConstraints,eliminatePointwiseConstraints(),
215 modifiedLocalMatrix,localEmbedding,embeddingForBasis,rhsForBasis);
218 jumpMatrix, localMatrix, localRhs,
220 makeSparseLUSolver(modifiedLocalMatrix),
221 embeddingForBasis, rhsForBasis, primalDofIndices, nPrimalDofs()
225 localMatrix =
give(modifiedLocalMatrix);
226 localRhs = localEmbedding * localRhs;
227 jumpMatrix = jumpMatrix * localEmbedding.transpose();
231 std::vector<typename gsPrimalSystem<T>::Matrix>
234 const index_t sz = this->m_primalBases.size();
237 if (static_cast<index_t>(sol.size())==sz && this->m_jumpMatrix.cols()==0)
240 GISMO_ASSERT(static_cast<index_t>(sol.size())==sz+1,
"gsPrimalSystem::distributePrimalSolution "
241 "expects that there is one more subdomain that patches.");
245 GISMO_ASSERT( sol[i].rows() >= this->m_primalBases[i].rows()
246 && this->m_primalBases[i].cols() == sol.back().rows()
247 && sol.back().cols() == sol[i].cols(),
248 "gsPrimalSystem::distributePrimalSolution: Dimensions do not agree: "
249 << sol[i].rows() <<
">=" << this->m_primalBases[i].rows() <<
"&&"
250 << this->m_primalBases[i].cols() <<
"==" << sol.back().rows() <<
"&&"
251 << sol.back().cols() <<
"==" << sol[i].cols() <<
" ( i=" << i <<
"). "
252 <<
"This method assumes the primal subspace to be the last one." );
257 m_embeddings[i]->apply(sol[i],tmp);
261 sol[i].conservativeResize( this->m_primalBases[i].rows(), gsEigen::NoChange );
262 sol[i] += this->m_primalBases[i] * sol.back();
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix...
Definition: gsSparseMatrix.h:33
memory::shared_ptr< Op > OpPtr
Shared pointer to linear operator.
Definition: gsPrimalSystem.h:90
void addContribution(const JumpMatrix &jumpMatrix, const SparseMatrix &localMatrix, const Matrix &localRhs, SparseMatrix primalBasis, OpPtr embedding=OpPtr())
Adds contributions for a patch to the data hold in the class.
Definition: gsPrimalSystem.hpp:179
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void handleConstraints(const std::vector< SparseVector > &primalConstraints, const std::vector< index_t > &primalDofIndices, JumpMatrix &jumpMatrix, SparseMatrix &localMatrix, Matrix &localRhs)
Convenience function for handling the primal constraints.
Definition: gsPrimalSystem.hpp:202
static gsSparseMatrix< T > primalBasis(OpPtr localSaddlePointSolver, const SparseMatrix &embeddingForBasis, const Matrix &rhsForBasis, const std::vector< index_t > &primalDofIndices, index_t nPrimalDofs)
Returns the matrix representation of the energy minimizing primal basis.
Definition: gsPrimalSystem.hpp:141
static void incorporateConstraints(const std::vector< SparseVector > &primalConstraints, bool eliminatePointwiseConstraints, const SparseMatrix &localMatrix, SparseMatrix &modifiedLocalMatrix, SparseMatrix &localEmbedding, SparseMatrix &embeddingForBasis, Matrix &rhsForBasis)
Incorporates the given constraints in the local system.
Definition: gsPrimalSystem.hpp:27
gsPrimalSystem(index_t nPrimalDofs)
Constructor.
Definition: gsPrimalSystem.hpp:20
Matrix m_localRhs
The right-hand side for the primal problem.
Definition: gsPrimalSystem.h:292
std::vector< Matrix > distributePrimalSolution(std::vector< Matrix > sol)
Distributes the given solution for K+1 subdomains to the K patches.
Definition: gsPrimalSystem.hpp:232