46 namespace MultiRegions
76 const boost::weak_ptr<ExpList> &pExpList,
77 const boost::shared_ptr<AssemblyMap> &pLocToGloMap)
79 m_locToGloMap (pLocToGloMap)
105 const Array<OneD, const NekDouble> &in,
106 Array<OneD, NekDouble> &out,
108 const Array<OneD, const NekDouble> &dirForcing)
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()
122 Array<OneD, NekDouble> F =
m_wsp + 2*nLocBndDofs;
123 Array<OneD, NekDouble> tmp;
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;
164 else if((!dirForcCalculated) && (atLastLevel))
168 pLocToGloMap->GlobalToLocalBnd(V_GlobBnd,V_LocBnd);
169 V_LocBnd = SchurCompl*V_LocBnd;
174 V_LocBnd = BinvD*F_Int;
177 pLocToGloMap->AssembleBnd(V_LocBnd,V_GlobHomBndTmp,
179 F_HomBnd = F_HomBnd - V_GlobHomBndTmp;
190 int lcLevel = pLocToGloMap->GetLowestStaticCondLevel();
191 if(atLastLevel && scLevel < lcLevel)
196 Array<OneD, NekDouble> tmp(nGlobBndDofs);
197 for (
int i = scLevel; i < lcLevel; ++i)
200 pLocToGloMap->UniversalAssembleBnd(tmp);
202 tmp.get()+nDirBndDofs, 1,
203 V_GlobHomBndTmp.GetPtr().get(), 1);
204 F_HomBnd = F_HomBnd - V_GlobHomBndTmp;
211 Array<OneD, NekDouble> pert(nGlobBndDofs,0.0);
216 nGlobBndDofs, F, pert, pLocToGloMap, nDirBndDofs);
223 &pert[nDirBndDofs],1,&out[nDirBndDofs],1);
229 pLocToGloMap->GetNextLevelLocalToGlobalMap());
238 if(nGlobHomBndDofs || nDirBndDofs)
242 if(dirForcCalculated && nDirBndDofs)
244 pLocToGloMap->GlobalToLocalBnd(V_GlobHomBnd,V_LocBnd,
249 pLocToGloMap->GlobalToLocalBnd(V_GlobBnd,V_LocBnd);
251 F_Int = F_Int - C*V_LocBnd;
267 const boost::shared_ptr<AssemblyMap>& pLocToGloMap)
271 m_wsp = Array<OneD, NekDouble>(2*nLocalBnd + nGlobal);
273 if (pLocToGloMap->AtLastLevel())
280 pLocToGloMap->GetNextLevelLocalToGlobalMap());
297 const boost::shared_ptr<AssemblyMap>& pLocToGloMap)
300 int n_exp =
m_expList.lock()->GetNumElmts();
302 const Array<OneD,const unsigned int>& nbdry_size
303 = pLocToGloMap->GetNumLocalBndCoeffsPerPatch();
304 const Array<OneD,const unsigned int>& nint_size
305 = pLocToGloMap->GetNumLocalIntCoeffsPerPatch();
318 for(n = 0; n < n_exp; ++n)
334 m_schurCompl->SetBlock(n, n, t = loc_schur->GetBlock(0,0));
335 m_BinvD ->SetBlock(n, n, t = loc_schur->GetBlock(0,1));
336 m_C ->SetBlock(n, n, t = loc_schur->GetBlock(1,0));
337 m_invD ->SetBlock(n, n, t = loc_schur->GetBlock(1,1));
359 const Array<OneD,const unsigned int>& nBndDofsPerPatch
360 = pLocToGloMap->GetNumLocalBndCoeffsPerPatch();
361 const Array<OneD,const unsigned int>& nIntDofsPerPatch
362 = pLocToGloMap->GetNumLocalIntCoeffsPerPatch();
380 int nPatches = pLocToGloMap->GetNumPatches();
381 int nEntriesA = 0;
int nEntriesB = 0;
382 int nEntriesC = 0;
int nEntriesD = 0;
384 for(i = 0; i < nPatches; i++)
386 nEntriesA += nBndDofsPerPatch[i]*nBndDofsPerPatch[i];
387 nEntriesB += nBndDofsPerPatch[i]*nIntDofsPerPatch[i];
388 nEntriesC += nIntDofsPerPatch[i]*nBndDofsPerPatch[i];
389 nEntriesD += nIntDofsPerPatch[i]*nIntDofsPerPatch[i];
394 Array<OneD, DNekMatSharedPtr> substructuredMat[4]
395 = {Array<OneD, DNekMatSharedPtr>(nPatches),
396 Array<OneD, DNekMatSharedPtr>(nPatches),
397 Array<OneD, DNekMatSharedPtr>(nPatches),
398 Array<OneD, DNekMatSharedPtr>(nPatches)};
403 Array<OneD, NekDouble> storageA(nEntriesA,0.0);
404 Array<OneD, NekDouble> storageB(nEntriesB,0.0);
405 Array<OneD, NekDouble> storageC(nEntriesC,0.0);
406 Array<OneD, NekDouble> storageD(nEntriesD,0.0);
408 Array<OneD, NekDouble> tmparray;
415 for(i = 0; i < nPatches; i++)
418 tmparray = storageA+cntA;
424 tmparray = storageB+cntB;
430 tmparray = storageC+cntC;
436 tmparray = storageD+cntD;
442 cntA += nBndDofsPerPatch[i] * nBndDofsPerPatch[i];
443 cntB += nBndDofsPerPatch[i] * nIntDofsPerPatch[i];
444 cntC += nIntDofsPerPatch[i] * nBndDofsPerPatch[i];
445 cntD += nIntDofsPerPatch[i] * nIntDofsPerPatch[i];
452 int schurComplSubMatnRows;
453 Array<OneD, const int> patchId, dofId;
454 Array<OneD, const unsigned int> isBndDof;
455 Array<OneD, const NekDouble>
sign;
458 for(n = cnt = 0; n < SchurCompl->GetNumberOfBlockRows(); ++n)
460 schurComplSubMat = SchurCompl->GetBlock(n,n);
461 schurComplSubMatnRows = schurComplSubMat->GetRows();
463 scale = SchurCompl->GetBlock(n,n)->Scale();
464 Array<OneD, NekDouble> schurSubMat
465 = SchurCompl->GetBlock(n,n)->GetOwnedMatrix()->GetPtr();
467 patchId = pLocToGloMap->GetPatchMapFromPrevLevel()
468 ->GetPatchId() + cnt;
469 dofId = pLocToGloMap->GetPatchMapFromPrevLevel()
471 isBndDof = pLocToGloMap->GetPatchMapFromPrevLevel()
473 sign = pLocToGloMap->GetPatchMapFromPrevLevel()
477 for(i = 0; i < schurComplSubMatnRows; ++i)
479 int pId = patchId[i];
480 Array<OneD, NekDouble> subMat0
481 = substructuredMat[0][pId]->GetPtr();
482 Array<OneD, NekDouble> subMat1
483 = substructuredMat[1][patchId[i]]->GetPtr();
484 Array<OneD, NekDouble> subMat2
485 = substructuredMat[2][patchId[i]]->GetPtr();
486 Array<OneD, NekDouble> subMat3
487 = substructuredMat[3][patchId[i]]->GetPtr();
488 int subMat0rows = substructuredMat[0][pId]->GetRows();
489 int subMat1rows = substructuredMat[1][pId]->GetRows();
490 int subMat2rows = substructuredMat[2][pId]->GetRows();
491 int subMat3rows = substructuredMat[3][pId]->GetRows();
495 for(j = 0; j < schurComplSubMatnRows; ++j)
498 "These values should be equal");
502 subMat0[dofId[i]+dofId[j]*subMat0rows] +=
505 i+j*schurComplSubMatnRows]);
509 subMat1[dofId[i]+dofId[j]*subMat1rows] +=
512 i+j*schurComplSubMatnRows]);
518 for(j = 0; j < schurComplSubMatnRows; ++j)
521 "These values should be equal");
525 subMat2[dofId[i]+dofId[j]*subMat2rows] +=
528 i+j*schurComplSubMatnRows]);
532 subMat3[dofId[i]+dofId[j]*subMat3rows] +=
535 i+j*schurComplSubMatnRows]);
540 cnt += schurComplSubMatnRows;
545 for(i = 0; i < nPatches; i++)
547 if(nIntDofsPerPatch[i])
549 Array<OneD, NekDouble> subMat0
550 = substructuredMat[0][i]->GetPtr();
551 Array<OneD, NekDouble> subMat1
552 = substructuredMat[1][i]->GetPtr();
553 Array<OneD, NekDouble> subMat2
554 = substructuredMat[2][i]->GetPtr();
555 int subMat0rows = substructuredMat[0][i]->GetRows();
556 int subMat1rows = substructuredMat[1][i]->GetRows();
557 int subMat2rows = substructuredMat[2][i]->GetRows();
558 int subMat2cols = substructuredMat[2][i]->GetColumns();
561 substructuredMat[3][i]->Invert();
563 (*substructuredMat[1][i]) = (*substructuredMat[1][i])*
564 (*substructuredMat[3][i]);
569 Blas::Dgemm(
'N',
'N', subMat1rows, subMat2cols,
570 subMat2rows, -1.0, &subMat1[0], subMat1rows,
571 &subMat2[0], subMat2rows, 1.0, &subMat0[0],
579 const Array<OneD,const unsigned int>& nbdry_size
580 = pLocToGloMap->GetNumLocalBndCoeffsPerPatch();
581 const Array<OneD,const unsigned int>& nint_size
582 = pLocToGloMap->GetNumLocalIntCoeffsPerPatch();
595 for(i = 0; i < nPatches; i++)
597 for(j = 0; j < 4; j++)
601 blkMatrices[j]->SetBlock(i,i,tmpscalmat);
614 blkMatrices[2], blkMatrices[3], pLocToGloMap);