36 #include <boost/core/ignore_unused.hpp> 49 #include <boost/algorithm/string/classification.hpp> 50 #include <boost/algorithm/string/split.hpp> 51 #include <boost/algorithm/string/predicate.hpp> 57 namespace MultiRegions
69 DisContField3D::DisContField3D() :
71 m_bndCondExpansions (),
84 const std::string &variable,
85 const bool SetUpJustDG,
87 ExpList3D (pSession, graph3D, variable, ImpType),
93 if (variable.compare(
"DefaultVar") != 0)
120 for(f = 0; f < locExpList->GetExpSize(); ++f)
123 = (*m_exp)[ElmtID[cnt+f]]->
124 as<LocalRegions::Expansion3D>();
126 = locExpList->GetExp(f)->
127 as<LocalRegions::Expansion2D>();
129 exp3d->SetFaceExp(FaceID[cnt+f],exp2d);
130 exp2d->SetAdjacentElementExp(FaceID[cnt+f],exp3d);
144 const std::string &variable,
145 const bool SetUpJustDG)
175 for(f = 0; f < locExpList->GetExpSize(); ++f)
178 = (*m_exp)[ElmtID[cnt+f]]->
179 as<LocalRegions::Expansion3D>();
181 = locExpList->GetExp(f)->
182 as<LocalRegions::Expansion2D>();
184 exp3d->SetFaceExp(FaceID[cnt+f],exp2d);
185 exp2d->SetAdjacentElementExp(FaceID[cnt+f],exp3d);
220 for(f = 0; f < locExpList->GetExpSize(); ++f)
223 = (*m_exp)[ElmtID[cnt+f]]->
224 as<LocalRegions::Expansion3D>();
226 = locExpList->GetExp(f)->
227 as<LocalRegions::Expansion2D>();
229 exp3d->SetFaceExp(FaceID[cnt+f], exp2d);
230 exp2d->SetAdjacentElementExp(FaceID[cnt+f], exp3d);
236 if (
m_session->DefinesSolverInfo(
"PROJECTION"))
238 std::string ProjectStr =
240 if (ProjectStr ==
"MixedCGDG" ||
241 ProjectStr ==
"Mixed_CG_Discontinuous")
286 "Routine currently only tested for HybridDGHelmholtz");
289 "The local to global map is not set up for the requested " 298 (*m_globalBndMat)[mkey] = glo_matrix;
302 glo_matrix = matrixIter->second;
325 bool UseGenSegExp =
true;
336 if (
m_session->DefinesCmdLineArgument(
"verbose"))
349 for (
int i = 0; i <
m_exp->size(); ++i)
351 for (
int j = 0; j < (*m_exp)[i]->GetNfaces(); ++j)
357 exp3d->SetFaceExp (j, exp2d);
366 for (
int i = 0; i <
m_trace->GetExpSize(); ++i)
371 int offset =
m_trace->GetPhys_Offset(i);
372 int traceGeomId = traceEl->GetGeom2D()->GetGlobalID();
377 if (traceGeomId != min(pIt->second[0].id, traceGeomId))
379 traceEl->GetLeftAdjacentElementExp()->NegateFaceNormal(
380 traceEl->GetLeftAdjacentElementFace());
383 else if (
m_traceMap->GetTraceToUniversalMapUnique(offset) < 0)
385 traceEl->GetLeftAdjacentElementExp()->NegateFaceNormal(
386 traceEl->GetLeftAdjacentElementFace());
401 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
408 std::unordered_map<int,pair<int,int> > perFaceToExpMap;
411 for (
int n = 0; n <
m_exp->size(); ++n)
414 for (
int e = 0; e < exp3d->GetNfaces(); ++e, ++cnt)
417 exp3d->GetGeom3D()->GetFid(e));
421 perFaceToExpMap[it->first] = make_pair(n, e);
429 for (
int i = 0; i <
m_exp->size(); ++i)
431 for (
int j = 0; j < (*m_exp)[i]->GetNfaces(); ++j, ++cnt)
439 for (
int n = 0; n <
m_exp->size(); ++n)
442 for (
int e = 0; e < exp3d->GetNfaces(); ++e, ++cnt)
444 int faceGeomId = exp3d->
GetGeom3D()->GetFid(e);
445 int offset =
m_trace->GetPhys_Offset(
446 elmtToTrace[n][e]->GetElmtId());
454 auto it2 = perFaceToExpMap.find(ent.
id);
456 if (it2 == perFaceToExpMap.end())
458 if (
m_session->GetComm()->GetSize() > 1 &&
465 ASSERTL1(
false,
"Periodic edge not found!");
470 "Periodic face in non-forward space?");
472 int offset2 =
m_trace->GetPhys_Offset(
473 elmtToTrace[it2->second.first][it2->second.second]->
478 int nquad1 = elmtToTrace[n][e]->GetNumPoints(0);
479 int nquad2 = elmtToTrace[n][e]->GetNumPoints(1);
481 vector<int> tmpBwd(nquad1*nquad2);
482 vector<int> tmpFwd(nquad1*nquad2);
489 for (
int i = 0; i < nquad2; ++i)
491 for (
int j = 0; j < nquad1; ++j)
493 tmpBwd[i*nquad1+j] = offset2 + i*nquad1+j;
494 tmpFwd[i*nquad1+j] = offset + j*nquad2+i;
500 for (
int i = 0; i < nquad2; ++i)
502 for (
int j = 0; j < nquad1; ++j)
504 tmpBwd[i*nquad1+j] = offset2 + i*nquad1+j;
505 tmpFwd[i*nquad1+j] = offset + i*nquad1+j;
516 for (
int i = 0; i < nquad2; ++i)
518 for (
int j = 0; j < nquad1/2; ++j)
520 swap(tmpFwd[i*nquad1 + j],
521 tmpFwd[i*nquad1 + nquad1-j-1]);
532 for (
int j = 0; j < nquad1; ++j)
534 for (
int i = 0; i < nquad2/2; ++i)
536 swap(tmpFwd[i*nquad1 + j],
537 tmpFwd[(nquad2-i-1)*nquad1 + j]);
542 for (
int i = 0; i < nquad1*nquad2; ++i)
568 bool returnval =
true;
588 int vSame = returnval ? 1 : 0;
609 const std::string &variable)
626 for (
auto &it : bregions)
629 bconditions, it.first, variable);
632 graph3D, variable, locBCond->GetComm());
635 if(locBCond->GetBoundaryConditionType() !=
642 m_bndConditions[cnt++] = locBCond;
655 const std::string &variable)
665 m_graph->GetCompositeOrdering();
667 m_graph->GetBndRegionOrdering();
683 map<int,RotPeriodicInfo> rotComp;
684 map<int,int> perComps;
685 map<int,vector<int> > allVerts;
686 map<int,SpatialDomains::PointGeomVector> allCoord;
687 map<int,vector<int> > allEdges;
688 map<int,vector<StdRegions::Orientation> > allOrient;
693 int region1ID, region2ID, i, j, k, cnt;
697 for(i = 0; i < (*m_exp).size(); ++i)
699 for(j = 0; j < (*m_exp)[i]->GetNverts(); ++j)
701 int id = (*m_exp)[i]->GetGeom()->GetVid(j);
705 for(j = 0; j < (*m_exp)[i]->GetNedges(); ++j)
707 int id = (*m_exp)[i]->GetGeom()->GetEid(j);
715 for (
auto &it : bregions)
719 bconditions, it.first, variable);
721 if (locBCond->GetBoundaryConditionType()
728 region1ID = it.first;
729 region2ID = std::static_pointer_cast<
731 locBCond)->m_connectedBoundaryRegion;
735 "Boundary region "+boost::lexical_cast<
string>(
736 region1ID)+
" should only contain 1 composite.");
744 if (vComm->GetSize() == 1)
746 cId1 = it.second->begin()->first;
747 cId2 = bregions.find(region2ID)->second->begin()->first;
751 cId1 = bndRegOrder.find(region1ID)->second[0];
752 cId2 = bndRegOrder.find(region2ID)->second[0];
756 if(boost::icontains(locBCond->GetUserDefined(),
"Rotated"))
758 vector<string> tmpstr;
760 boost::split(tmpstr,locBCond->GetUserDefined(),
761 boost::is_any_of(
":"));
763 if(boost::iequals(tmpstr[0],
"Rotated"))
766 "Expected Rotated user defined string to " 767 "contain direction and rotation angle " 768 "and optionally a tolerance, " 769 "i.e. Rotated:dir:PI/2:1e-6");
772 ASSERTL1((tmpstr[1] ==
"x")||(tmpstr[1] ==
"y")
773 ||(tmpstr[1] ==
"z"),
"Rotated Dir is " 774 "not specified as x,y or z");
777 RotInfo.
m_dir = (tmpstr[1] ==
"x")? 0:
778 (tmpstr[1] ==
"y")? 1:2;
784 if(tmpstr.size() == 4)
787 RotInfo.
m_tol = boost::lexical_cast
792 "failed to cast tolerance input " 793 "to a double value in Rotated" 794 "boundary information");
799 RotInfo.
m_tol = 1e-8;
801 rotComp[cId1] = RotInfo;
807 vector<unsigned int> tmpOrder;
815 for (i = 0; i < c->m_geomVec.size(); ++i)
818 std::dynamic_pointer_cast<
820 ASSERTL1(faceGeom,
"Unable to cast to shared ptr");
823 int faceId = c->m_geomVec[i]->GetGlobalID();
824 locFaces.insert(faceId);
828 if (vComm->GetSize() == 1)
830 tmpOrder.push_back(c->m_geomVec[i]->GetGlobalID());
835 vector<int> vertList, edgeList;
837 vector<StdRegions::Orientation> orientVec;
838 for (j = 0; j < faceGeom->GetNumVerts(); ++j)
840 vertList .push_back(faceGeom->GetVid (j));
841 edgeList .push_back(faceGeom->GetEid (j));
842 coordVec .push_back(faceGeom->GetVertex(j));
843 orientVec.push_back(faceGeom->GetEorient(j));
846 allVerts [faceId] = vertList;
847 allEdges [faceId] = edgeList;
848 allCoord [faceId] = coordVec;
849 allOrient[faceId] = orientVec;
854 if (vComm->GetSize() == 1)
856 compOrder[it.second->begin()->first] = tmpOrder;
862 if (perComps.count(cId1) == 0)
864 if (perComps.count(cId2) == 0)
866 perComps[cId1] = cId2;
870 std::stringstream ss;
871 ss <<
"Boundary region " << cId2 <<
" should be " 872 <<
"periodic with " << perComps[cId2] <<
" but " 873 <<
"found " << cId1 <<
" instead!";
874 ASSERTL0(perComps[cId2] == cId1, ss.str());
879 std::stringstream ss;
880 ss <<
"Boundary region " << cId1 <<
" should be " 881 <<
"periodic with " << perComps[cId1] <<
" but " 882 <<
"found " << cId2 <<
" instead!";
883 ASSERTL0(perComps[cId1] == cId1, ss.str());
889 int n = vComm->GetSize();
890 int p = vComm->GetRank();
900 rotcounts[
p] = rotComp.size();
906 for (i = 1; i < n ; ++i)
908 rotoffset[i] = rotoffset[i-1] + rotcounts[i-1];
917 auto rIt = rotComp.begin();
919 for(i = 0; rIt != rotComp.end(); ++rIt)
921 compid [rotoffset[
p] + i ] = rIt->first;
922 rotdir [rotoffset[
p] + i ] = rIt->second.m_dir;
923 rotangle[rotoffset[
p] + i ] = rIt->second.m_angle;
924 rottol [rotoffset[
p] + i++] = rIt->second.m_tol;
933 for(i =0; i < totrot; ++i)
937 rotComp[compid[i]] = rinfo;
942 facecounts[
p] = locFaces.size();
948 for (i = 1; i < n; ++i)
950 faceoffset[i] = faceoffset[i-1] + facecounts[i-1];
964 auto sIt = locFaces.begin();
965 for (i = 0; sIt != locFaces.end(); ++sIt)
967 faceIds [faceoffset[
p] + i ] = *sIt;
968 faceVerts[faceoffset[
p] + i++] = allVerts[*sIt].size();
991 for (i = 0; i < n; ++i)
993 if (facecounts[i] > 0)
996 facecounts[i], faceVerts + faceoffset[i], 1);
1007 for (i = 1; i < n; ++i)
1009 vertoffset[i] = vertoffset[i-1] + procVerts[i-1];
1023 for (cnt = 0, sIt = locFaces.begin();
1024 sIt != locFaces.end(); ++sIt)
1026 for (j = 0; j < allVerts[*sIt].size(); ++j)
1028 int vertId = allVerts[*sIt][j];
1029 vertIds[vertoffset[
p] + cnt ] = vertId;
1030 vertX [vertoffset[
p] + cnt ] = (*allCoord[*sIt][j])(0);
1031 vertY [vertoffset[
p] + cnt ] = (*allCoord[*sIt][j])(1);
1032 vertZ [vertoffset[
p] + cnt ] = (*allCoord[*sIt][j])(2);
1033 edgeIds[vertoffset[
p] + cnt ] = allEdges [*sIt][j];
1034 edgeOrt[vertoffset[
p] + cnt++] = allOrient[*sIt][j];
1049 map<int, vector<int> > vertMap;
1050 map<int, vector<int> > edgeMap;
1051 map<int, SpatialDomains::PointGeomVector> coordMap;
1057 map<int, SpatialDomains::PointGeomSharedPtr> vCoMap;
1058 map<int, pair<int, int> > eIdMap;
1060 for (cnt = i = 0; i < totFaces; ++i)
1062 vector<int> edges(faceVerts[i]);
1063 vector<int> verts(faceVerts[i]);
1069 for (j = 0; j < faceVerts[i]; ++j, ++cnt)
1071 edges[j] = edgeIds[cnt];
1072 verts[j] = vertIds[cnt];
1075 3, verts[j], vertX[cnt], vertY[cnt], vertZ[cnt]);
1076 vCoMap[vertIds[cnt]] = coord[j];
1079 auto testIns = eIdMap.insert(
1082 make_pair(vertIds[tmp+j],
1083 vertIds[tmp+((j+1) % faceVerts[i])])));
1085 if (testIns.second ==
false)
1107 swap(testIns.first->second.first,
1108 testIns.first->second.second);
1112 vertMap [faceIds[i]] = verts;
1113 edgeMap [faceIds[i]] = edges;
1114 coordMap[faceIds[i]] = coord;
1132 map<int, map<StdRegions::Orientation, vector<int> > > vmap;
1133 map<int, map<StdRegions::Orientation, vector<int> > > emap;
1135 map<StdRegions::Orientation, vector<int> > quadVertMap;
1145 map<StdRegions::Orientation, vector<int> > quadEdgeMap;
1155 map<StdRegions::Orientation, vector<int> > triVertMap;
1159 map<StdRegions::Orientation, vector<int> > triEdgeMap;
1163 vmap[3] = triVertMap;
1164 vmap[4] = quadVertMap;
1165 emap[3] = triEdgeMap;
1166 emap[4] = quadEdgeMap;
1168 map<int,int> allCompPairs;
1171 map<int,int> fIdToCompId;
1176 for (
auto &cIt : perComps)
1179 const int id1 = cIt.first;
1180 const int id2 = cIt.second;
1181 std::string id1s = boost::lexical_cast<
string>(id1);
1182 std::string id2s = boost::lexical_cast<
string>(id2);
1184 if (compMap.count(id1) > 0)
1186 c[0] = compMap[id1];
1189 if (compMap.count(id2) > 0)
1191 c[1] = compMap[id2];
1195 "Neither composite not found on this process!");
1200 map<int,int> compPairs;
1204 "Unable to find composite "+id1s+
" in order map.");
1206 "Unable to find composite "+id2s+
" in order map.");
1207 ASSERTL0(compOrder[id1].size() == compOrder[id2].size(),
1208 "Periodic composites "+id1s+
" and "+id2s+
1209 " should have the same number of elements.");
1210 ASSERTL0(compOrder[id1].size() > 0,
1211 "Periodic composites "+id1s+
" and "+id2s+
1215 for (i = 0; i < compOrder[id1].size(); ++i)
1217 int eId1 = compOrder[id1][i];
1218 int eId2 = compOrder[id2][i];
1220 ASSERTL0(compPairs.count(eId1) == 0,
1224 if (compPairs.count(eId2) != 0)
1226 ASSERTL0(compPairs[eId2] == eId1,
"Pairing incorrect");
1228 compPairs[eId1] = eId2;
1231 fIdToCompId[eId1] = id1;
1232 fIdToCompId[eId2] = id2;
1238 for (
auto &pIt : compPairs)
1240 int ids [2] = {pIt.first, pIt.second};
1241 bool local[2] = {locFaces.count(pIt.first) > 0,
1242 locFaces.count(pIt.second) > 0};
1244 ASSERTL0(coordMap.count(ids[0]) > 0 &&
1245 coordMap.count(ids[1]) > 0,
1246 "Unable to find face in coordinate map");
1248 allCompPairs[pIt.first ] = pIt.second;
1249 allCompPairs[pIt.second] = pIt.first;
1254 = { coordMap[ids[0]], coordMap[ids[1]] };
1256 ASSERTL0(tmpVec[0].size() == tmpVec[1].size(),
1257 "Two periodic faces have different number " 1266 bool rotbnd =
false;
1273 if(rotComp.count(fIdToCompId[pIt.first]))
1276 dir = rotComp[fIdToCompId[pIt.first]].m_dir;
1277 angle = rotComp[fIdToCompId[pIt.first]].m_angle;
1278 tol = rotComp[fIdToCompId[pIt.first]].m_tol;
1282 for (i = 0; i < 2; ++i)
1290 int other = (i+1) % 2;
1293 sign = (i == 0)? 1.0:-1.0;
1296 if (tmpVec[0].size() == 3)
1299 tmpVec[i], tmpVec[other],
1300 rotbnd, dir, sign*angle, tol);
1305 tmpVec[i], tmpVec[other],
1306 rotbnd,dir,sign*angle,tol);
1316 int nFaceVerts = vertMap[ids[0]].size();
1319 for (i = 0; i < 2; ++i)
1321 int other = (i+1) % 2;
1324 sign = (i == 0)? 1.0:-1.0;
1327 if (tmpVec[0].size() == 3)
1330 tmpVec[i], tmpVec[other], rotbnd, dir,
1336 tmpVec[i], tmpVec[other], rotbnd, dir,
1340 if (nFaceVerts == 3)
1345 "Unsupported face orientation for face "+
1346 boost::lexical_cast<string>(ids[i]));
1350 vector<int> per1 = vertMap[ids[i]];
1351 vector<int> per2 = vertMap[ids[other]];
1355 map<int, pair<int, bool> > tmpMap;
1359 for (j = 0; j < nFaceVerts; ++j)
1361 int v = vmap[nFaceVerts][o][j];
1362 tmpMap[per1[j]] = make_pair(
1363 per2[v], locVerts.count(per2[v]) > 0);
1367 for (
auto &mIt : tmpMap)
1374 auto perIt = periodicVerts.find(mIt.first);
1376 if (perIt == periodicVerts.end())
1380 periodicVerts[mIt.first].push_back(ent2);
1381 perIt = periodicVerts.find(mIt.first);
1388 for (k = 0; k < perIt->second.size(); ++k)
1390 if (perIt->second[k].id == mIt.second.first)
1396 if (k == perIt->second.size())
1398 perIt->second.push_back(ent2);
1406 for (i = 0; i < 2; ++i)
1408 int other = (i+1) % 2;
1411 sign = (i == 0)? 1.0:-1.0;
1413 if (tmpVec[0].size() == 3)
1416 tmpVec[i], tmpVec[other], rotbnd, dir,
1422 tmpVec[i], tmpVec[other], rotbnd, dir,
1426 vector<int> per1 = edgeMap[ids[i]];
1427 vector<int> per2 = edgeMap[ids[other]];
1429 map<int, pair<int, bool> > tmpMap;
1431 for (j = 0; j < nFaceVerts; ++j)
1433 int e = emap[nFaceVerts][o][j];
1434 tmpMap[per1[j]] = make_pair(
1435 per2[e], locEdges.count(per2[e]) > 0);
1438 for (
auto &mIt : tmpMap)
1445 auto perIt = periodicEdges.find(mIt.first);
1447 if (perIt == periodicEdges.end())
1449 periodicEdges[mIt.first].push_back(ent2);
1450 perIt = periodicEdges.find(mIt.first);
1454 for (k = 0; k < perIt->second.size(); ++k)
1456 if (perIt->second[k].id == mIt.second.first)
1462 if (k == perIt->second.size())
1464 perIt->second.push_back(ent2);
1473 pairSizes[
p] = allCompPairs.size();
1481 for (i = 1; i < n; ++i)
1483 pairOffsets[i] = pairOffsets[i-1] + pairSizes[i-1];
1487 ASSERTL1(allCompPairs.size() == fIdToCompId.size(),
1488 "At this point the size of allCompPairs " 1489 "should have been the same as fIdToCompId");
1494 cnt = pairOffsets[
p];
1496 for (
auto &pIt : allCompPairs)
1498 first [cnt ] = pIt.first;
1499 second[cnt++] = pIt.second;
1505 allCompPairs.clear();
1507 for(cnt = 0; cnt < totPairSizes; ++cnt)
1509 allCompPairs[first[cnt]] = second[cnt];
1519 cnt = pairOffsets[
p];
1521 for (
auto &pIt : fIdToCompId)
1523 first [cnt ] = pIt.first;
1524 second[cnt++] = pIt.second;
1530 fIdToCompId.clear();
1532 for(cnt = 0; cnt < totPairSizes; ++cnt)
1534 fIdToCompId[first[cnt]] = second[cnt];
1539 map<int,int> eIdToCompId;
1545 for (cnt = i = 0; i < totFaces; ++i)
1547 bool rotbnd =
false;
1552 int faceId = faceIds[i];
1554 ASSERTL0(allCompPairs.count(faceId) > 0,
1555 "Unable to find matching periodic face.");
1557 int perFaceId = allCompPairs[faceId];
1560 ASSERTL1(fIdToCompId.count(faceId) > 0,
"Face " +
1561 boost::lexical_cast<
string>(faceId) +
1562 " not found in fIdtoCompId map");
1563 if(rotComp.count(fIdToCompId[faceId]))
1566 dir = rotComp[fIdToCompId[faceId]].m_dir;
1567 angle = rotComp[fIdToCompId[faceId]].m_angle;
1568 tol = rotComp[fIdToCompId[faceId]].m_tol;
1571 for (j = 0; j < faceVerts[i]; ++j, ++cnt)
1573 int vId = vertIds[cnt];
1575 auto perId = periodicVerts.find(vId);
1577 if (perId == periodicVerts.end())
1586 = { coordMap[faceId], coordMap[perFaceId] };
1588 int nFaceVerts = tmpVec[0].size();
1591 tmpVec[0], tmpVec[1], rotbnd, dir, angle, tol):
1593 tmpVec[0], tmpVec[1], rotbnd, dir, angle, tol);
1597 int perVertexId = vertMap[perFaceId][vmap[nFaceVerts][o][j]];
1602 locVerts.count(perVertexId) > 0);
1604 periodicVerts[vId].push_back(ent);
1607 int eId = edgeIds[cnt];
1609 perId = periodicEdges.find(eId);
1614 eIdToCompId[eId] = fIdToCompId[faceId];
1617 if (perId == periodicEdges.end())
1625 = { coordMap[faceId], coordMap[perFaceId] };
1627 int nFaceEdges = tmpVec[0].size();
1630 tmpVec[0], tmpVec[1], rotbnd, dir, angle, tol):
1632 tmpVec[0], tmpVec[1], rotbnd, dir, angle, tol);
1636 int perEdgeId = edgeMap[perFaceId][emap[nFaceEdges][o][j]];
1640 locEdges.count(perEdgeId) > 0);
1642 periodicEdges[eId].push_back(ent);
1649 eIdToCompId[perEdgeId] = fIdToCompId[perFaceId];
1657 for (
auto &perIt : periodicVerts)
1660 for (i = 0; i < perIt.second.size(); ++i)
1663 auto perIt2 = periodicVerts.find(perIt.second[i].id);
1664 ASSERTL0(perIt2 != periodicVerts.end(),
1665 "Couldn't find periodic vertex.");
1670 for (j = 0; j < perIt2->second.size(); ++j)
1672 if (perIt2->second[j].id == perIt.first)
1677 for (k = 0; k < perIt.second.size(); ++k)
1679 if (perIt2->second[j].id == perIt.second[k].id)
1685 if (k == perIt.second.size())
1687 perIt.second.push_back(perIt2->second[j]);
1693 for (
auto &perIt : periodicEdges)
1695 for (i = 0; i < perIt.second.size(); ++i)
1697 auto perIt2 = periodicEdges.find(perIt.second[i].id);
1698 ASSERTL0(perIt2 != periodicEdges.end(),
1699 "Couldn't find periodic edge.");
1701 for (j = 0; j < perIt2->second.size(); ++j)
1703 if (perIt2->second[j].id == perIt.first)
1708 for (k = 0; k < perIt.second.size(); ++k)
1710 if (perIt2->second[j].id == perIt.second[k].id)
1716 if (k == perIt.second.size())
1718 perIt.second.push_back(perIt2->second[j]);
1725 for (
auto &perIt : periodicEdges)
1727 bool rotbnd =
false;
1734 auto eIt = eIdMap.find(perIt.first);
1736 *vCoMap[eIt->second.first],
1737 *vCoMap[eIt->second.second]
1741 if(rotComp.count(eIdToCompId[perIt.first]))
1744 dir = rotComp[eIdToCompId[perIt.first]].m_dir;
1745 angle = rotComp[eIdToCompId[perIt.first]].m_angle;
1746 tol = rotComp[eIdToCompId[perIt.first]].m_tol;
1752 for (i = 0; i < perIt.second.size(); ++i)
1754 eIt = eIdMap.find(perIt.second[i].id);
1757 *vCoMap[eIt->second.first],
1758 *vCoMap[eIt->second.second]
1761 int vMap[2] = {-1,-1};
1767 r.
Rotate(v[0],dir,angle);
1769 if(r.
dist(w[0])< tol)
1775 r.
Rotate(v[1],dir,angle);
1776 if(r.
dist(w[0]) < tol)
1782 ASSERTL0(
false,
"Unable to align rotationally periodic edge vertex");
1788 NekDouble cx = 0.5*(w[0](0)-v[0](0)+w[1](0)-v[1](0));
1789 NekDouble cy = 0.5*(w[0](1)-v[0](1)+w[1](1)-v[1](1));
1790 NekDouble cz = 0.5*(w[0](2)-v[0](2)+w[1](2)-v[1](2));
1792 for (j = 0; j < 2; ++j)
1797 for (k = 0; k < 2; ++k)
1803 if (sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y)+(z1-z)*(z1-z))
1813 ASSERTL0(vMap[0] >= 0 && vMap[1] >= 0,
1814 "Unable to align periodic edge vertex.");
1815 ASSERTL0((vMap[0] == 0 || vMap[0] == 1) &&
1816 (vMap[1] == 0 || vMap[1] == 1) &&
1817 (vMap[0] != vMap[1]),
1818 "Unable to align periodic edge vertex.");
1832 for (
auto &perIt : periodicVerts)
1834 if (locVerts.count(perIt.first) > 0)
1840 for (
auto &perIt : periodicEdges)
1842 if (locEdges.count(perIt.first) > 0)
1853 as<LocalRegions::Expansion2D>();
1855 int offset =
m_trace->GetPhys_Offset(traceEl->GetElmtId());
1858 if (traceEl->GetLeftAdjacentElementFace () == -1 ||
1859 traceEl->GetRightAdjacentElementFace() == -1)
1869 int traceGeomId = traceEl->GetGeom2D()->GetGlobalID();
1874 fwd = traceGeomId == min(traceGeomId,pIt->second[0].id);
1879 GetTraceToUniversalMapUnique(offset) >= 0;
1883 else if (traceEl->GetLeftAdjacentElementFace () != -1 &&
1884 traceEl->GetRightAdjacentElementFace() != -1)
1887 fwd = (traceEl->GetLeftAdjacentElementExp().get() == (*m_exp)[n].get() );
1891 ASSERTL2(
false,
"Unconnected trace element!");
1933 int n, cnt, npts, e;
1945 GetNFwdLocTracePts();
1961 id2 =
m_trace->GetPhys_Offset(
1962 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
1979 id2 =
m_trace->GetPhys_Offset(
1980 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
2000 ASSERTL0(
false,
"Method only set up for Dirichlet, Neumann " 2001 "and Robin conditions.");
2025 "Field is not in physical space.");
2035 Vmath::Zero(outarray.num_elements(), outarray, 1);
2043 m_traceMap->UniversalTraceAssemble(outarray);
2071 m_trace->IProductWRTBase(Fn, Fcoeffs);
2106 m_trace->IProductWRTBase(Fwd,Coeffs);
2108 m_trace->IProductWRTBase(Bwd,Coeffs);
2122 map<int,int> globalIdMap;
2133 globalIdMap[exp3d->GetGeom3D()->GetGlobalID()] = i;
2152 as<LocalRegions::Expansion2D>();
2155 m_graph->GetElementsFromFace(exp2d->GetGeom2D());
2157 tmp->at(0).first->GetGlobalID()];
2158 m_BCtoFaceMap[cnt] = tmp->at(0).second;
2167 std::shared_ptr<ExpList> &result,
2168 const bool DeclareCoeffPhysArrays)
2171 int offsetOld, offsetNew;
2172 std::vector<unsigned int> eIDs;
2178 for (cnt = n = 0; n < i; ++n)
2186 eIDs.push_back(ElmtID[cnt+n]);
2192 (*
this, eIDs, DeclareCoeffPhysArrays);
2195 if (DeclareCoeffPhysArrays)
2198 for (n = 0; n < result->GetExpSize(); ++n)
2200 nq =
GetExp(ElmtID[cnt+n])->GetTotPoints();
2202 offsetNew = result->GetPhys_Offset(n);
2204 tmp2 = result->UpdatePhys()+ offsetNew, 1);
2206 nq =
GetExp(ElmtID[cnt+n])->GetNcoeffs();
2208 offsetNew = result->GetCoeff_Offset(n);
2210 tmp2 = result->UpdateCoeffs()+ offsetNew, 1);
2240 const bool PhysSpaceForcing)
2242 boost::ignore_unused(flags, varfactors, dirForcing);
2244 int i,j,n,cnt,cnt1,nbndry;
2255 if(PhysSpaceForcing)
2268 int GloBndDofs =
m_traceMap->GetNumGlobalBndCoeffs();
2269 int NumDirichlet =
m_traceMap->GetNumLocalDirBndCoeffs();
2287 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2296 for(cnt = cnt1 = n = 0; n < nexp; ++n)
2298 nbndry = (*m_exp)[n]->NumDGBndryCoeffs();
2300 e_ncoeffs = (*m_exp)[n]->GetNcoeffs();
2302 e_l = loc_lambda + cnt1;
2309 Floc =
Transpose(*(HDGLamToU->GetBlock(n,n)))*ElmtFce;
2328 id =
m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(cnt++);
2340 id =
m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(cnt++);
2347 ASSERTL0(
false,
"HDG implementation does not support " 2348 "periodic boundary conditions at present.");
2356 if(GloBndDofs - NumDirichlet > 0)
2373 m_traceMap->GlobalToLocalBnd(BndSol,loc_lambda);
2376 out = (*InvHDGHelm)*F + (*HDGLamToU)*LocLambda;
2393 boost::ignore_unused(coeffstate);
2395 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2400 m_traceMap->GlobalToLocalBnd(inarray, loc_lambda);
2401 LocLambda = (*HDGHelm) * LocLambda;
2402 m_traceMap->AssembleBnd(loc_lambda,outarray);
2421 map<int, RobinBCInfoSharedPtr> returnval;
2436 int npoints = locExpList->GetNpoints();
2442 locExpList->GetCoords(x0, x1, x2);
2445 std::static_pointer_cast<
2450 coeffeqn.
Evaluate(x0, x1, x2, 0.0, coeffphys);
2452 for(e = 0; e < locExpList->GetExpSize(); ++e)
2457 Array_tmp = coeffphys +
2458 locExpList->GetPhys_Offset(e));
2460 elmtid = ElmtID[cnt+e];
2462 if(returnval.count(elmtid) != 0)
2464 rInfo->next = returnval.find(elmtid)->second;
2466 returnval[elmtid] = rInfo;
2498 int i,cnt,f,ncoeff_face;
2503 int nq_elmt, nm_elmt;
2504 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2509 face_lambda = loc_lambda;
2518 nm_elmt = (*m_exp)[i]->GetNcoeffs();
2522 out_tmp = force + nm_elmt;
2525 int num_points0 = (*m_exp)[i]->GetBasis(0)->GetNumPoints();
2526 int num_points1 = (*m_exp)[i]->GetBasis(1)->GetNumPoints();
2527 int num_points2 = (*m_exp)[i]->GetBasis(2)->GetNumPoints();
2528 int num_modes0 = (*m_exp)[i]->GetBasis(0)->GetNumModes();
2529 int num_modes1 = (*m_exp)[i]->GetBasis(1)->GetNumModes();
2530 int num_modes2 = (*m_exp)[i]->GetBasis(2)->GetNumModes();
2535 int nFaces = (*m_exp)[i]->GetNfaces();
2537 for(f = 0; f < nFaces; ++f)
2539 ncoeff_face = elmtToTrace[i][f]->GetNcoeffs();
2541 Vmath::Vcopy(ncoeff_face, face_lambda, 1, faceCoeffs[f], 1);
2542 exp->SetFaceToGeomOrientation(f, faceCoeffs[f]);
2543 face_lambda = face_lambda + ncoeff_face;
2587 ASSERTL0(
false,
"Wrong shape type, HDG postprocessing is not implemented");
2593 (*m_exp)[i]->DGDeriv(
2595 elmtToTrace[i], faceCoeffs, out_tmp);
2596 (*m_exp)[i]->BwdTrans(out_tmp,qrhs);
2597 ppExp->IProductWRTDerivBase(0,qrhs,force);
2601 (*m_exp)[i]->DGDeriv(
2603 elmtToTrace[i], faceCoeffs, out_tmp);
2604 (*m_exp)[i]->BwdTrans(out_tmp,qrhs);
2605 ppExp->IProductWRTDerivBase(1,qrhs,out_tmp);
2610 (*m_exp)[i]->DGDeriv(
2612 elmtToTrace[i], faceCoeffs, out_tmp);
2613 (*m_exp)[i]->BwdTrans(out_tmp,qrhs);
2614 ppExp->IProductWRTDerivBase(2,qrhs,out_tmp);
2618 (*m_exp)[i]->BwdTrans(
2620 force[0] = (*m_exp)[i]->Integral(qrhs);
2634 ppExp->BwdTrans(out.
GetPtr(), work);
2635 (*m_exp)[i]->FwdTrans(work,
2674 const std::string varName,
2678 boost::ignore_unused(x2_in, x3_in);
2685 for (i = 0; i < nbnd; ++i)
2690 npoints = locExpList->GetNpoints();
2697 locExpList->GetCoords(x0, x1, x2);
2706 string exprbcs = bcPtr->m_expr;
2711 valuesFile = locExpList->GetPhys();
2717 DirichletBoundaryCondition >(
2720 condition.
Evaluate(x0, x1, x2, time, valuesExp);
2723 Vmath::Vmul(npoints, valuesExp, 1, valuesFile, 1, locExpList->UpdatePhys(), 1);
2725 locExpList->FwdTrans_BndConstrained(
2726 locExpList->GetPhys(),
2727 locExpList->UpdateCoeffs());
2745 static_pointer_cast<SpatialDomains::
2746 NeumannBoundaryCondition>(
2749 condition.
Evaluate(x0, x1, x2, time,
2750 locExpList->UpdatePhys());
2752 locExpList->IProductWRTBase(locExpList->GetPhys(),
2753 locExpList->UpdateCoeffs());
2771 static_pointer_cast<SpatialDomains::
2772 RobinBoundaryCondition>(
2775 condition.
Evaluate(x0, x1, x2, time,
2776 locExpList->UpdatePhys());
2780 locExpList->IProductWRTBase(locExpList->GetPhys(),
2781 locExpList->UpdateCoeffs());
2791 ASSERTL0(
false,
"This type of BC not implemented yet");
const Array< OneD, const NekDouble > & GetPhys() const
This function returns (a reference to) the array (implemented as m_phys) containing the function ev...
const DNekScalBlkMatSharedPtr & GetBlockMatrix(const GlobalMatrixKey &gkey)
#define ASSERTL0(condition, msg)
virtual void v_Reset()
Reset geometry information, metrics, matrix managers and geometry information.
virtual ~DisContField3D()
Destructor.
std::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
GlobalLinSysSharedPtr GetGlobalBndLinSys(const GlobalLinSysKey &mkey)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
virtual void v_ExtractTracePhys(Array< OneD, NekDouble > &outarray)
Array< OneD, MultiRegions::ExpListSharedPtr > m_bndCondExpansions
An object which contains the discretised boundary conditions.
int id
Geometry ID of entity.
int DefineFunction(const std::string &vlist, const std::string &expr)
Defines a function for the purposes of evaluation.
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
static ExpListSharedPtr NullExpListSharedPtr
std::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
void EvaluateBoundaryConditions(const NekDouble time=0.0, const std::string varName="", const NekDouble=NekConstants::kNekUnsetDouble, const NekDouble=NekConstants::kNekUnsetDouble)
#define sign(a, b)
return the sign(b)*a
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::vector< PointGeomSharedPtr > PointGeomVector
void SetAdjacentElementExp(int face, Expansion3DSharedPtr &f)
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< TetGeom > TetGeomSharedPtr
std::shared_ptr< std::vector< std::pair< GeometrySharedPtr, int > > > GeometryLinkSharedPtr
bool IsLeftAdjacentFace(const int n, const int e)
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
GlobalLinSysMapShPtr m_globalBndMat
NekDouble Evaluate(const int id)
Evaluate a function which depends only on constants and/or parameters.
const BoundaryConditionCollection & GetBoundaryConditions(void) const
const Array< OneD, const NekDouble > & GetCoeffs() const
This function returns (a reference to) the array (implemented as m_coeffs) containing all local expa...
virtual const std::vector< bool > & v_GetLeftAdjacentFaces(void) const
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
std::vector< bool > m_leftAdjacentFaces
std::set< int > m_boundaryFaces
A set storing the global IDs of any boundary faces.
std::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
std::shared_ptr< NeumannBoundaryCondition > NeumannBCShPtr
std::map< int, CompositeSharedPtr > CompositeMap
PeriodicMap m_periodicFaces
A map which identifies pairs of periodic faces.
virtual void v_GetFwdBwdTracePhys(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
This method extracts the "forward" and "backward" trace data from the array field and puts the data i...
std::map< ConstFactorType, NekDouble > ConstFactorMap
void GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
void EvaluateHDGPostProcessing(Array< OneD, NekDouble > &outarray)
Evaluate HDG post-processing to increase polynomial order of solution.
std::shared_ptr< Composite > CompositeSharedPtr
virtual void v_AddFwdBwdTraceIntegral(const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &outarray)
Add trace contributions into elemental coefficient spaces.
void ApplyGeomInfo()
Apply geometry information to each expansion.
std::shared_ptr< ExpList2D > ExpList2DSharedPtr
Shared pointer to an ExpList2D object.
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
int GetExpSize(void)
This function returns the number of elements in the expansion.
virtual void v_EvaluateBoundaryConditions(const NekDouble time=0.0, const std::string varName="", const NekDouble x2_in=NekConstants::kNekUnsetDouble, const NekDouble x3_in=NekConstants::kNekUnsetDouble)
This function evaluates the boundary conditions at a certain time-level.
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
std::shared_ptr< GlobalLinSys > GenGlobalBndLinSys(const GlobalLinSysKey &mkey, const AssemblyMapSharedPtr &locToGloMap)
Generate a GlobalLinSys from information provided by the key "mkey" and the mapping provided in LocTo...
void Rotate(PointGeom &a, int dir, NekDouble angle)
_this = rotation of a by angle 'angle' around axis dir
Gauss Radau pinned at x=-1, .
std::shared_ptr< RobinBoundaryCondition > RobinBCShPtr
NekDouble m_tol
Tolerance to rotation is considered identical.
Principle Orthogonal Functions .
void FindPeriodicFaces(const SpatialDomains::BoundaryConditions &bcs, const std::string &variable)
Determine the periodic faces, edges and vertices for the given graph.
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::shared_ptr< Expansion3D > Expansion3DSharedPtr
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
virtual std::map< int, RobinBCInfoSharedPtr > v_GetRobinBCInfo()
std::vector< int > m_periodicFwdCopy
A vector indicating degress of freedom which need to be copied from forwards to backwards space in ca...
std::vector< int > m_periodicBwdCopy
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
DisContField3D()
Default constructor.
std::map< StdRegions::VarCoeffType, Array< OneD, NekDouble > > VarCoeffMap
int GetNcoeffs(void) const
Returns the total number of local degrees of freedom .
LocTraceToTraceMapSharedPtr m_locTraceToTraceMap
Map of local trace (the points at the face of the element) to the trace space discretisation.
std::map< int, std::vector< unsigned int > > CompositeOrdering
bool m_physState
The state of the array m_phys.
int m_ncoeffs
The total number of local degrees of freedom. m_ncoeffs .
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
bool isLocal
Flag specifying if this entity is local to this partition.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Principle Orthogonal Functions .
StdRegions::Orientation orient
Orientation of entity within higher dimensional entity.
Principle Orthogonal Functions .
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
SpatialDomains::MeshGraphSharedPtr m_graph
Mesh associated with this expansion list.
void GenerateBoundaryConditionExpansion(const SpatialDomains::MeshGraphSharedPtr &graph3D, const SpatialDomains::BoundaryConditions &bcs, const std::string &variable)
virtual void v_GeneralMatrixOp(const GlobalMatrixKey &gkey, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal)
Calculates the result of the multiplication of a global matrix of type specified by mkey with a vecto...
LibUtilities::SessionReaderSharedPtr m_session
Session.
Defines a specification for a set of points.
void Neg(int n, T *x, const int incx)
Negate x = -x.
NekDouble Evaluate() const
void SetUpDG(const std::string="DefaultVar")
Set up all DG member variables and maps.
bool SameTypeOfBoundaryConditions(const DisContField3D &In)
std::map< int, BoundaryConditionMapShPtr > BoundaryConditionCollection
static StdRegions::Orientation GetFaceOrientation(const QuadGeom &face1, const QuadGeom &face2, bool doRot=false, int dir=0, NekDouble angle=0.0, NekDouble tol=1e-8)
Get the orientation of face1.
static StdRegions::Orientation GetFaceOrientation(const TriGeom &face1, const TriGeom &face2, bool doRot, int dir, NekDouble angle, NekDouble tol)
void ExtractFileBCs(const std::string &fileName, LibUtilities::CommSharedPtr comm, const std::string &varName, const std::shared_ptr< ExpList > locExpList)
virtual void v_GetBndElmtExpansion(int i, std::shared_ptr< ExpList > &result, const bool DeclareCoeffPhysArrays)
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
Describe a linear system.
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Describes a matrix with ordering defined by a local to global map.
Interpreter class for the evaluation of mathematical expressions.
std::shared_ptr< Expansion > ExpansionSharedPtr
LibUtilities::CommSharedPtr m_comm
Communicator.
static AssemblyMapSharedPtr NullAssemblyMapSharedPtr
SpatialDomains::Geometry3DSharedPtr GetGeom3D() const
PeriodicMap m_periodicVerts
A map which identifies groups of periodic vertices.
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
virtual void v_GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &FaceID)
Set up a list of elemeent IDs and edge IDs that link to the boundary conditions.
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed t...
std::shared_ptr< HexGeom > HexGeomSharedPtr
virtual void v_Reset()
Reset this field, so that geometry information can be updated.
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal)
std::shared_ptr< DirichletBoundaryCondition > DirichletBCShPtr
Gauss Radau pinned at x=-1, .
Array< OneD, SpatialDomains::BoundaryConditionShPtr > m_bndConditions
An array which contains the information about the boundary condition on the different boundary region...
AssemblyMapDGSharedPtr m_traceMap
Abstraction of a three-dimensional multi-elemental expansion which is merely a collection of local ex...
static SpatialDomains::BoundaryConditionShPtr GetBoundaryCondition(const SpatialDomains::BoundaryConditionCollection &collection, unsigned int index, const std::string &variable)
int m_dir
Axis of rotation. 0 = 'x', 1 = 'y', 2 = 'z'.
Array< OneD, int > m_BCtoElmMap
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
NekDouble dist(PointGeom &a)
return distance between this and input a
NekDouble m_angle
Angle of rotation in radians.
Array< OneD, int > m_BCtoFaceMap
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
std::shared_ptr< PrismGeom > PrismGeomSharedPtr
std::map< int, std::vector< unsigned int > > BndRegionOrdering
int GetCoeff_Offset(int n) const
Get the start offset position for a global list of m_coeffs correspoinding to element n...
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
void Zero(int n, T *x, const int incx)
Zero vector.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
int GetPhys_Offset(int n) const
Get the start offset position for a global list of m_phys correspoinding to element n...
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Describes the specification for a Basis.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
const BoundaryRegionCollection & GetBoundaryRegions(void) const
Array< OneD, DataType > & GetPtr()
1D Gauss-Lobatto-Legendre quadrature points
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.
virtual void v_AddTraceIntegral(const Array< OneD, const NekDouble > &Fn, Array< OneD, NekDouble > &outarray)
Add trace contributions into elemental coefficient spaces.
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
PeriodicMap m_periodicEdges
A map which identifies groups of periodic edges.
std::map< StdRegions::ConstFactorType, Array< OneD, NekDouble > > VarFactorsMap
virtual void v_HelmSolve(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const FlagList &flags, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const MultiRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing)