46 namespace MultiRegions
74 GlobalLinSysStaticCond::GlobalLinSysStaticCond(
76 const std::weak_ptr<ExpList> &pExpList,
77 const std::shared_ptr<AssemblyMap> &pLocToGloMap)
79 m_locToGloMap (pLocToGloMap)
110 bool dirForcCalculated = (bool) dirForcing.num_elements();
111 bool atLastLevel = pLocToGloMap->AtLastLevel();
112 int scLevel = pLocToGloMap->GetStaticCondLevel();
114 int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
115 int nGlobBndDofs = pLocToGloMap->GetNumGlobalBndCoeffs();
116 int nDirBndDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
117 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
118 int nLocBndDofs = pLocToGloMap->GetNumLocalBndCoeffs();
119 int nIntDofs = pLocToGloMap->GetNumGlobalCoeffs()
124 if(nDirBndDofs && dirForcCalculated)
126 Vmath::Vsub(nGlobDofs,in.get(),1,dirForcing.get(),1,F.get(),1);
154 if( nIntDofs && ((!dirForcCalculated) && (atLastLevel)) )
160 pLocToGloMap->GlobalToLocalBnd(V_GlobBnd,V_LocBnd);
161 V_LocBnd = BinvD*F_Int + SchurCompl*V_LocBnd;
163 else if((!dirForcCalculated) && (atLastLevel))
167 pLocToGloMap->GlobalToLocalBnd(V_GlobBnd,V_LocBnd);
168 V_LocBnd = SchurCompl*V_LocBnd;
176 pLocToGloMap->AssembleBnd(V_LocBnd,V_GlobHomBndTmp,
178 Subtract(F_HomBnd, F_HomBnd, V_GlobHomBndTmp);
189 int lcLevel = pLocToGloMap->GetLowestStaticCondLevel();
190 if(atLastLevel && scLevel < lcLevel)
196 for (
int i = scLevel; i < lcLevel; ++i)
199 pLocToGloMap->UniversalAssembleBnd(tmp);
201 tmp.get()+nDirBndDofs, 1,
202 V_GlobHomBndTmp.
GetPtr().get(), 1);
203 Subtract( F_HomBnd, F_HomBnd, V_GlobHomBndTmp);
214 nGlobBndDofs, F, pert, pLocToGloMap, nDirBndDofs);
221 &pert[nDirBndDofs],1,&out[nDirBndDofs],1);
227 pLocToGloMap->GetNextLevelLocalToGlobalMap());
236 if(nGlobHomBndDofs || nDirBndDofs)
240 if(dirForcCalculated && nDirBndDofs)
242 pLocToGloMap->GlobalToLocalBnd(V_GlobHomBnd,V_LocBnd,
247 pLocToGloMap->GlobalToLocalBnd(V_GlobBnd,V_LocBnd);
249 F_Int = F_Int - C*V_LocBnd;
264 const std::shared_ptr<AssemblyMap>& pLocToGloMap)
266 int nLocalBnd =
m_locToGloMap.lock()->GetNumLocalBndCoeffs();
268 int nGlobBndDofs = pLocToGloMap->GetNumGlobalBndCoeffs();
269 int nDirBndDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
270 int nGlobHomBndDofs = nGlobBndDofs - nDirBndDofs;
272 (2*nLocalBnd + nGlobal + nGlobHomBndDofs, 0.0);
274 if (pLocToGloMap->AtLastLevel())
281 pLocToGloMap->GetNextLevelLocalToGlobalMap());
298 const std::shared_ptr<AssemblyMap>& pLocToGloMap)
301 int n_exp =
m_expList.lock()->GetNumElmts();
304 = pLocToGloMap->GetNumLocalBndCoeffsPerPatch();
306 = pLocToGloMap->GetNumLocalIntCoeffsPerPatch();
319 for(n = 0; n < n_exp; ++n)
333 m_schurCompl->SetBlock(n, n, t = loc_schur->GetBlock(0,0));
334 m_BinvD ->SetBlock(n, n, t = loc_schur->GetBlock(0,1));
335 m_C ->SetBlock(n, n, t = loc_schur->GetBlock(1,0));
336 m_invD ->SetBlock(n, n, t = loc_schur->GetBlock(1,1));
359 = pLocToGloMap->GetNumLocalBndCoeffsPerPatch();
361 = pLocToGloMap->GetNumLocalIntCoeffsPerPatch();
379 int nPatches = pLocToGloMap->GetNumPatches();
380 int nEntriesA = 0;
int nEntriesB = 0;
381 int nEntriesC = 0;
int nEntriesD = 0;
383 for(i = 0; i < nPatches; i++)
385 nEntriesA += nBndDofsPerPatch[i]*nBndDofsPerPatch[i];
386 nEntriesB += nBndDofsPerPatch[i]*nIntDofsPerPatch[i];
387 nEntriesC += nIntDofsPerPatch[i]*nBndDofsPerPatch[i];
388 nEntriesD += nIntDofsPerPatch[i]*nIntDofsPerPatch[i];
423 for(i = 0; i < nPatches; i++)
426 tmparray = storageA+cntA;
432 tmparray = storageB+cntB;
438 tmparray = storageC+cntC;
444 tmparray = storageD+cntD;
451 cntA += nBndDofsPerPatch[i] * nBndDofsPerPatch[i];
452 cntB += nBndDofsPerPatch[i] * nIntDofsPerPatch[i];
453 cntC += nIntDofsPerPatch[i] * nBndDofsPerPatch[i];
454 cntD += nIntDofsPerPatch[i] * nIntDofsPerPatch[i];
461 int schurComplSubMatnRows;
466 for(n = cnt = 0; n < SchurCompl->GetNumberOfBlockRows(); ++n)
468 schurComplSubMat = SchurCompl->GetBlock(n,n);
469 schurComplSubMatnRows = schurComplSubMat->GetRows();
471 patchId = pLocToGloMap->GetPatchMapFromPrevLevel()
472 ->GetPatchId() + cnt;
473 dofId = pLocToGloMap->GetPatchMapFromPrevLevel()
475 isBndDof = pLocToGloMap->GetPatchMapFromPrevLevel()
477 sign = pLocToGloMap->GetPatchMapFromPrevLevel()
481 for(i = 0; i < schurComplSubMatnRows; ++i)
483 int pId = patchId[i];
485 = substructuredMat[0][pId]->GetPtr();
487 = substructuredMat[1][patchId[i]]->GetPtr();
489 = substructuredMat[2][patchId[i]]->GetPtr();
491 = substructuredMat[3][patchId[i]];
492 int subMat0rows = substructuredMat[0][pId]->GetRows();
493 int subMat1rows = substructuredMat[1][pId]->GetRows();
494 int subMat2rows = substructuredMat[2][pId]->GetRows();
498 for(j = 0; j < schurComplSubMatnRows; ++j)
501 "These values should be equal");
505 subMat0[dofId[i]+dofId[j]*subMat0rows] +=
507 (*schurComplSubMat)(i,j);
511 subMat1[dofId[i]+dofId[j]*subMat1rows] +=
513 (*schurComplSubMat)(i,j);
519 for(j = 0; j < schurComplSubMatnRows; ++j)
522 "These values should be equal");
526 subMat2[dofId[i]+dofId[j]*subMat2rows] +=
528 (*schurComplSubMat)(i,j);
534 if (dofId[i] <= dofId[j])
536 (*subMat3)(dofId[i],dofId[j]) +=
538 (*schurComplSubMat)(i,j);
543 (*subMat3)(dofId[i],dofId[j]) +=
545 (*schurComplSubMat)(i,j);
551 cnt += schurComplSubMatnRows;
556 for(i = 0; i < nPatches; i++)
558 if(nIntDofsPerPatch[i])
561 = substructuredMat[0][i]->GetPtr();
563 = substructuredMat[1][i]->GetPtr();
565 = substructuredMat[2][i]->GetPtr();
566 int subMat0rows = substructuredMat[0][i]->GetRows();
567 int subMat1rows = substructuredMat[1][i]->GetRows();
568 int subMat2rows = substructuredMat[2][i]->GetRows();
569 int subMat2cols = substructuredMat[2][i]->GetColumns();
572 substructuredMat[3][i]->Invert();
574 (*substructuredMat[1][i]) = (*substructuredMat[1][i])*
575 (*substructuredMat[3][i]);
581 subMat2rows, -1.0, &subMat1[0], subMat1rows,
582 &subMat2[0], subMat2rows, 1.0, &subMat0[0],
591 = pLocToGloMap->GetNumLocalBndCoeffsPerPatch();
593 = pLocToGloMap->GetNumLocalIntCoeffsPerPatch();
606 for(i = 0; i < nPatches; i++)
608 for(j = 0; j < 4; j++)
612 blkMatrices[j]->SetBlock(i,i,tmpscalmat);
625 blkMatrices[2], blkMatrices[3], pLocToGloMap);
Array< OneD, NekDouble > m_wsp
Workspace array for matrix multiplication.
#define ASSERTL0(condition, msg)
virtual GlobalLinSysStaticCondSharedPtr v_Recurse(const GlobalLinSysKey &mkey, const std::weak_ptr< ExpList > &pExpList, const DNekScalBlkMatSharedPtr pSchurCompl, const DNekScalBlkMatSharedPtr pBinvD, const DNekScalBlkMatSharedPtr pC, const DNekScalBlkMatSharedPtr pInvD, const std::shared_ptr< AssemblyMap > &locToGloMap)=0
virtual void v_Solve(const Array< OneD, const NekDouble > &in, Array< OneD, NekDouble > &out, const AssemblyMapSharedPtr &locToGloMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)
Solve the linear system for given input and output vectors using a specified local to global map...
void DiagonalBlockFullScalMatrixMultiply(NekVector< double > &result, const NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > &lhs, const NekVector< double > &rhs)
#define sign(a, b)
return the sign(b)*a
std::weak_ptr< AssemblyMap > m_locToGloMap
Local to global map.
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
virtual void v_InitObject()
DNekScalBlkMatSharedPtr m_schurCompl
Block Schur complement matrix.
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
GlobalLinSysStaticCondSharedPtr m_recursiveSchurCompl
Schur complement for Direct Static Condensation.
DNekScalBlkMatSharedPtr m_C
Block matrix.
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
void SolveLinearSystem(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir=0)
Solve the linear system for given input and output vectors.
void SetupTopLevel(const std::shared_ptr< AssemblyMap > &locToGloMap)
Set up the storage for the Schur complement or the top level of the multi-level Schur complement...
std::shared_ptr< DNekMat > DNekMatSharedPtr
virtual DNekScalBlkMatSharedPtr v_GetStaticCondBlock(unsigned int n)
Retrieves a the static condensation block matrices from n-th expansion using the matrix key provided ...
DNekScalBlkMatSharedPtr m_invD
Block matrix.
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where A[m x n], B[n x k], C[m x k].
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
virtual DNekScalMatSharedPtr v_GetBlock(unsigned int n)
Retrieves the block matrix from n-th expansion using the matrix key provided by the m_linSysKey...
virtual DNekScalBlkMatSharedPtr v_PreSolve(int scLevel, NekVector< NekDouble > &F_GlobBnd)
void ConstructNextLevelCondensedSystem(const std::shared_ptr< AssemblyMap > &locToGloMap)
virtual void v_AssembleSchurComplement(std::shared_ptr< AssemblyMap > pLoctoGloMap)
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Describe a linear system.
virtual void v_Initialise(const std::shared_ptr< AssemblyMap > &locToGloMap)
Initialise this object.
PointerWrapper
Specifies if the pointer passed to a NekMatrix or NekVector is copied into an internal representation...
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
virtual void v_BasisFwdTransform(Array< OneD, NekDouble > &pInOut, int offset)
virtual void v_BasisBwdTransform(Array< OneD, NekDouble > &pInOut)
virtual int v_GetNumBlocks()
Get the number of blocks in this system.
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
virtual ~GlobalLinSysStaticCond()
void Initialise(const std::shared_ptr< AssemblyMap > &pLocToGloMap)
RhsMatrixType void Subtract(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
DNekScalBlkMatSharedPtr m_BinvD
Block matrix.
Array< OneD, DataType > & GetPtr()
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.