130 int i, j, k, n, cnt, gId;
131 int meshVertId, meshEdgeId, meshFaceId;
135 const int nExp = expList->GetExpSize();
136 const int nDirBnd = asmMap->GetNumGlobalDirBndCoeffs();
139 PeriodicMap periodicVerts, periodicEdges, periodicFaces;
140 expList->GetPeriodicEntities(periodicVerts, periodicEdges, periodicFaces);
150 vector<map<int, vector<NekDouble>>> idMats(nStorage);
154 vector<map<int, int>> gidMeshIds(3);
158 vector<map<int, int>> gidDofs(nStorage);
170 for (cnt = n = 0; n < nExp; ++n)
172 exp = expList->GetExp(n);
182 auto tmpMat =
m_linsys.lock()->GetBlock(n);
185 int nBndDofs = exp->NumBndryCoeffs();
186 int nIntDofs = exp->GetNcoeffs() - nBndDofs;
191 exp->GetBoundaryMap(bndMap);
199 for (
int i = 0; i < nBndDofs; ++i)
201 for (
int j = 0; j < nBndDofs; ++j)
203 (*bndryMat)(i, j) = (*tmpMat)(bndMap[i], bndMap[j]);
214 exp->GetInteriorMap(intMap);
216 vector<NekDouble> tmpStore(nIntDofs * nIntDofs);
217 for (
int i = 0; i < nIntDofs; ++i)
219 for (
int j = 0; j < nIntDofs; ++j)
221 tmpStore[j + i * nIntDofs] =
222 (*tmpMat)(intMap[i], intMap[j]);
227 idMats[3][n] = tmpStore;
228 gidDofs[3][n] = nIntDofs;
237 schurMat =
m_linsys.lock()->GetStaticCondBlock(n)->GetBlock(0, 0);
242 for (i = 0; i < exp->GetNverts(); ++i)
244 meshVertId = exp->GetGeom()->GetVid(i);
245 int locId = exp->GetVertexMap(i);
248 gId = asmMap->GetLocalToGlobalMap(cnt + locId) - nDirBnd;
259 NekDouble vertVal = (*schurMat)(locId, locId);
263 auto gIt = idMats[0].find(gId);
265 if (gIt == idMats[0].end())
268 idMats[0][gId] = vector<NekDouble>(1, vertVal);
274 gIt->second[0] += vertVal;
281 auto pIt = periodicVerts.find(meshVertId);
282 if (pIt != periodicVerts.end())
284 for (j = 0; j < pIt->second.size(); ++j)
286 meshVertId =
min(meshVertId, pIt->second[j].id);
292 gidMeshIds[0][gId] = meshVertId;
293 maxVertIds[0] =
max(maxVertIds[0], meshVertId);
299 for (i = 0; i < exp->GetGeom()->GetNumEdges(); ++i)
301 meshEdgeId = exp->GetGeom()->GetEid(i);
309 auto pIt = periodicEdges.find(meshEdgeId);
310 if (pIt != periodicEdges.end())
312 pair<int, StdRegions::Orientation> idOrient =
315 meshEdgeId = idOrient.first;
316 edgeOrient = idOrient.second;
322 if (exp->GetGeom()->GetNumFaces())
325 ->GetEdgeInteriorToElementMap(i, bmap,
sign, edgeOrient);
327 ->GetEdgeInverseBoundaryMap(i);
331 exp->GetTraceInteriorToElementMap(i, bmap,
sign, edgeOrient);
333 ->GetTraceInverseBoundaryMap(i);
337 const int nEdgeCoeffs = bmap.size();
338 if (nEdgeCoeffs == 0)
344 vector<NekDouble> tmpStore(nEdgeCoeffs * nEdgeCoeffs);
346 gId = asmMap->GetLocalToGlobalMap(cnt + bmap[0]);
348 for (j = 0; j < nEdgeCoeffs; ++j)
356 asmMap->GetLocalToGlobalMap(cnt + bmap[j]) - nDirBnd);
368 for (k = 0; k < nEdgeCoeffs; ++k)
370 tmpStore[k + j * nEdgeCoeffs] =
371 sign1 *
sign[k] * (*schurMat)(bmap2[j], bmap2[k]);
380 gidDofs[1][gId] = nEdgeCoeffs;
383 auto gIt = idMats[1].find(gId);
384 if (gIt == idMats[1].end())
386 idMats[1][gId] = tmpStore;
390 ASSERTL1(tmpStore.size() == gIt->second.size(),
391 "Number of modes mismatch");
392 Vmath::Vadd(nEdgeCoeffs * nEdgeCoeffs, &gIt->second[0], 1,
393 &tmpStore[0], 1, &gIt->second[0], 1);
396 gidMeshIds[1][gId] = meshEdgeId;
397 maxVertIds[2] =
max(maxVertIds[2], meshEdgeId);
398 maxVertIds[3] =
max(maxVertIds[3], nEdgeCoeffs);
403 for (i = 0; i < exp->GetGeom()->GetNumFaces(); ++i)
405 meshFaceId = exp->GetGeom()->GetFid(i);
413 auto pIt = periodicFaces.find(meshFaceId);
414 if (pIt != periodicFaces.end())
416 meshFaceId =
min(meshFaceId, pIt->second[0].id);
418 pIt->second[0].orient);
422 exp->GetTraceInteriorToElementMap(i, bmap,
sign, faceOrient);
424 ->GetTraceInverseBoundaryMap(i);
427 const int nFaceCoeffs = bmap.size();
428 if (nFaceCoeffs == 0)
434 vector<NekDouble> tmpStore(nFaceCoeffs * nFaceCoeffs);
436 gId = asmMap->GetLocalToGlobalMap(cnt + bmap[0]);
438 for (j = 0; j < nFaceCoeffs; ++j)
441 asmMap->GetLocalToGlobalMap(cnt + bmap[j]) - nDirBnd);
453 for (k = 0; k < nFaceCoeffs; ++k)
455 tmpStore[k + j * nFaceCoeffs] =
456 sign1 *
sign[k] * (*schurMat)(bmap2[j], bmap2[k]);
465 gidDofs[2][gId] = nFaceCoeffs;
468 auto gIt = idMats[2].find(gId);
469 if (gIt == idMats[2].end())
471 idMats[2][gId] = tmpStore;
475 ASSERTL1(tmpStore.size() == gIt->second.size(),
476 "Number of modes mismatch");
477 Vmath::Vadd(nFaceCoeffs * nFaceCoeffs, &gIt->second[0], 1,
478 &tmpStore[0], 1, &gIt->second[0], 1);
481 gidMeshIds[2][gId] = meshFaceId;
482 maxVertIds[4] =
max(maxVertIds[4], meshFaceId);
483 maxVertIds[5] =
max(maxVertIds[5], nFaceCoeffs);
486 cnt += exp->GetNcoeffs();
492 expList->GetSession()->GetComm()->GetRowComm();
497 vector<NekDouble> storageBuf;
498 vector<long> globalToUniversal;
500 for (i = 0, cnt = 1; i < 3; ++i)
502 const int maxDofs = maxVertIds[2 * i + 1];
507 for (
auto &gIt : idMats[i])
510 storageBuf.insert(storageBuf.end(), gIt.second.begin(),
514 ASSERTL1(gidMeshIds[i].count(gIt.first) > 0,
515 "Unable to find global ID " + std::to_string(gIt.first) +
517 meshVertId = gidMeshIds[i][gIt.first];
519 for (j = 0; j < gIt.second.size(); ++j)
521 globalToUniversal.push_back(cnt +
522 meshVertId * maxDofs * maxDofs + j);
529 cnt += (maxVertIds[2 * i] + 1) * maxDofs * maxDofs;
532 ASSERTL1(storageBuf.size() == globalToUniversal.size(),
533 "Storage buffer and global to universal map size does "
538 &globalToUniversal[0]);
542 Gs::Init(globalToUniversalMap, vComm,
543 expList->GetSession()->DefinesCmdLineArgument(
"verbose"));
549 int nblksSize = 1 + idMats[1].size() + idMats[2].size();
552 nblksSize += idMats[3].size();
557 n_blks[0] = idMats[0].size();
562 for (i = 1; i < nStorage; ++i)
564 for (
auto &gIt : idMats[i])
566 ASSERTL1(gidDofs[i].count(gIt.first) > 0,
567 "Unable to find number of degrees of freedom for "
569 std::to_string(gIt.first));
572 if (gidDofs[i][gIt.first])
574 n_blks[cnt++] = gidDofs[i][gIt.first];
590 for (
auto gIt = idMats[0].begin(); gIt != idMats[0].end(); ++gIt, ++cnt)
592 (*vertMat)(cnt, cnt) = 1.0 / storageData[cnt];
601 for (i = 1; i < nStorage; ++i)
603 for (
auto &gIt : idMats[i])
605 int nDofs = gidDofs[i][gIt.first];
616 for (j = 0; j < nDofs; ++j)
618 for (k = 0; k < nDofs; ++k)
624 (*tmp)(j, k) = gIt.second[k + j * nDofs];
629 (*tmp)(j, k) = storageData[k + j * nDofs + cnt];
634 cnt += nDofs * nDofs;
637 m_blkMat->SetBlock(cnt2, cnt2, tmp);
658 std::shared_ptr<MultiRegions::ExpList> expList =
659 ((
m_linsys.lock())->GetLocMat()).lock();
660 std::shared_ptr<MultiRegions::ExpList> trace = expList->GetTrace();
666 std::dynamic_pointer_cast<AssemblyMapDG>(
m_locToGloMap.lock());
668 int i, j, k, n, cnt, cnt2;
671 int nTrace = expList->GetTrace()->GetExpSize();
672 int nDir = asmMap->GetNumGlobalDirBndCoeffs();
674 for (cnt = n = 0; n < nTrace; ++n)
681 cnt += trace->GetExp(n)->GetNcoeffs();
688 int maxTraceSize = -1;
689 map<int, int> arrayOffsets;
691 for (cnt = 0, n = nDir; n < nTrace; ++n)
693 int nCoeffs = trace->GetExp(n)->GetNcoeffs();
694 int nCoeffs2 = nCoeffs * nCoeffs;
696 arrayOffsets[n] = cnt;
699 if (maxTraceSize < nCoeffs2)
701 maxTraceSize = nCoeffs2;
707 expList->GetSession()->GetComm()->GetRowComm();
714 for (cnt = n = 0; n < expList->GetExpSize(); ++n)
717 locExpansion = expList->GetExp(elmt);
720 asmMap->GetElmtToTrace()[elmt];
723 loc_mat = (
m_linsys.lock())->GetStaticCondBlock(n);
724 bnd_mat = loc_mat->GetBlock(0, 0);
726 int nFacets = locExpansion->GetNtraces();
728 for (cnt2 = i = 0; i < nFacets; ++i)
730 int nCoeffs = elmtToTraceMap[i]->GetNcoeffs();
731 int elmtId = elmtToTraceMap[i]->GetElmtId();
741 NekDouble *off = &tmpStore[arrayOffsets[elmtId]];
743 for (j = 0; j < nCoeffs; ++j)
745 NekDouble sign1 = asmMap->GetLocalToGlobalBndSign(cnt + j);
746 for (k = 0; k < nCoeffs; ++k)
748 NekDouble sign2 = asmMap->GetLocalToGlobalBndSign(cnt + k);
749 off[j * nCoeffs + k] +=
750 (*bnd_mat)(cnt2 + j, cnt2 + k) * sign1 * sign2;
761 for (cnt = 0, n = nDir; n < nTrace; ++n)
764 int nCoeffs = traceExp->GetNcoeffs();
765 int geomId = traceExp->GetGeom()->GetGlobalID();
767 for (i = 0; i < nCoeffs * nCoeffs; ++i)
769 uniIds[cnt++] = geomId * maxTraceSize + i + 1;
776 expList->GetSession()->DefinesCmdLineArgument(
"verbose"));
781 for (n = 0; n < nTrace - nDir; ++n)
783 n_blks[n] = trace->GetExp(n + nDir)->GetNcoeffs();
789 for (n = 0; n < nTrace - nDir; ++n)
791 int nCoeffs = trace->GetExp(n + nDir)->GetNcoeffs();
794 NekDouble *off = &tmpStore[arrayOffsets[n + nDir]];
796 for (i = 0; i < nCoeffs; ++i)
798 for (j = 0; j < nCoeffs; ++j)
800 (*tmp)(i, j) = off[i * nCoeffs + j];