45 #include <boost/assign/std/vector.hpp>
47 using namespace boost::assign;
51 namespace MultiRegions
63 DisContField3D::DisContField3D() :
65 m_bndCondExpansions (),
78 const std::string &variable,
79 const bool SetUpJustDG)
81 m_bndCondExpansions(),
85 if(variable.compare(
"DefaultVar") != 0)
104 Array<OneD, int> ElmtID, FaceID;
112 for(f = 0; f < locExpList->GetExpSize(); ++f)
115 = (*m_exp)[ElmtID[cnt+f]]->
116 as<LocalRegions::Expansion3D>();
118 = locExpList->GetExp(f)->
119 as<LocalRegions::Expansion2D>();
121 exp3d->SetFaceExp(FaceID[cnt+f],exp2d);
122 exp2d->SetAdjacentElementExp(FaceID[cnt+f],exp3d);
136 const std::string &variable,
137 const bool SetUpJustDG)
159 Array<OneD, int> ElmtID,FaceID;
167 for(f = 0; f < locExpList->GetExpSize(); ++f)
170 = (*m_exp)[ElmtID[cnt+f]]->
171 as<LocalRegions::Expansion3D>();
173 = locExpList->GetExp(f)->
174 as<LocalRegions::Expansion2D>();
176 exp3d->SetFaceExp(FaceID[cnt+f],exp2d);
177 exp2d->SetAdjacentElementExp(FaceID[cnt+f],exp3d);
208 Array<OneD, int> ElmtID,FaceID;
216 for(f = 0; f < locExpList->GetExpSize(); ++f)
219 = (*m_exp)[ElmtID[cnt+f]]->
220 as<LocalRegions::Expansion3D>();
222 = locExpList->GetExp(f)->
223 as<LocalRegions::Expansion2D>();
225 exp3d->SetFaceExp(FaceID[cnt+f],exp2d);
226 exp2d->SetAdjacentElementExp(FaceID[cnt+f],exp3d);
232 if(
m_session->DefinesSolverInfo(
"PROJECTION"))
234 std::string ProjectStr =
236 if (ProjectStr ==
"MixedCGDG" ||
237 ProjectStr ==
"Mixed_CG_Discontinuous")
259 m_bndCondExpansions (In.m_bndCondExpansions),
260 m_bndConditions (In.m_bndConditions),
261 m_globalBndMat (In.m_globalBndMat),
262 m_trace (In.m_trace),
263 m_traceMap (In.m_traceMap),
264 m_periodicVerts (In.m_periodicVerts),
265 m_periodicEdges (In.m_periodicEdges),
266 m_periodicFaces (In.m_periodicFaces)
281 "Routine currently only tested for HybridDGHelmholtz");
284 "The local to global map is not set up for the requested "
293 (*m_globalBndMat)[mkey] = glo_matrix;
297 glo_matrix = matrixIter->second;
324 bool UseGenSegExp =
true;
334 Array<OneD, Array<OneD, StdRegions::StdExpansionSharedPtr> >
342 for (
int i = 0; i <
m_exp->size(); ++i)
344 for (
int j = 0; j < (*m_exp)[i]->GetNfaces(); ++j)
350 exp3d->SetFaceExp (j, exp2d);
359 for (
int i = 0; i <
m_trace->GetExpSize(); ++i)
364 int offset =
m_trace->GetPhys_Offset(i);
365 int traceGeomId = traceEl->GetGeom2D()->GetGlobalID();
371 if (traceGeomId != min(pIt->second[0].id, traceGeomId))
373 traceEl->GetLeftAdjacentElementExp()->NegateFaceNormal(
374 traceEl->GetLeftAdjacentElementFace());
377 else if (
m_traceMap->GetTraceToUniversalMapUnique(offset) < 0)
379 traceEl->GetLeftAdjacentElementExp()->NegateFaceNormal(
380 traceEl->GetLeftAdjacentElementFace());
395 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
402 boost::unordered_map<int,pair<int,int> > perFaceToExpMap;
403 boost::unordered_map<int,pair<int,int> >
::iterator it2;
406 for (
int n = 0; n <
m_exp->size(); ++n)
409 for (
int e = 0; e < exp3d->GetNfaces(); ++e, ++cnt)
412 exp3d->GetGeom3D()->GetFid(e));
416 perFaceToExpMap[it->first] = make_pair(n, e);
424 for (
int i = 0; i <
m_exp->size(); ++i)
426 for (
int j = 0; j < (*m_exp)[i]->GetNfaces(); ++j, ++cnt)
434 for (
int n = 0; n <
m_exp->size(); ++n)
437 for (
int e = 0; e < exp3d->GetNfaces(); ++e, ++cnt)
439 int faceGeomId = exp3d->
GetGeom3D()->GetFid(e);
440 int offset =
m_trace->GetPhys_Offset(
441 elmtToTrace[n][e]->GetElmtId());
449 it2 = perFaceToExpMap.find(ent.
id);
451 if (it2 == perFaceToExpMap.end())
453 if (
m_session->GetComm()->GetSize() > 1 &&
460 ASSERTL1(
false,
"Periodic edge not found!");
465 "Periodic face in non-forward space?");
467 int offset2 =
m_trace->GetPhys_Offset(
468 elmtToTrace[it2->second.first][it2->second.second]->
473 int nquad1 = elmtToTrace[n][e]->GetNumPoints(0);
474 int nquad2 = elmtToTrace[n][e]->GetNumPoints(1);
476 vector<int> tmpBwd(nquad1*nquad2);
477 vector<int> tmpFwd(nquad1*nquad2);
484 for (
int i = 0; i < nquad2; ++i)
486 for (
int j = 0; j < nquad1; ++j)
488 tmpBwd[i*nquad1+j] = offset2 + i*nquad1+j;
489 tmpFwd[i*nquad1+j] = offset + j*nquad2+i;
495 for (
int i = 0; i < nquad2; ++i)
497 for (
int j = 0; j < nquad1; ++j)
499 tmpBwd[i*nquad1+j] = offset2 + i*nquad1+j;
500 tmpFwd[i*nquad1+j] = offset + i*nquad1+j;
511 for (
int i = 0; i < nquad2; ++i)
513 for (
int j = 0; j < nquad1/2; ++j)
515 swap(tmpFwd[i*nquad1 + j],
516 tmpFwd[i*nquad1 + nquad1-j-1]);
527 for (
int j = 0; j < nquad1; ++j)
529 for (
int i = 0; i < nquad2/2; ++i)
531 swap(tmpFwd[i*nquad1 + j],
532 tmpFwd[(nquad2-i-1)*nquad1 + j]);
537 for (
int i = 0; i < nquad1*nquad2; ++i)
558 bool returnval =
true;
578 int vSame = returnval ? 1 : 0;
599 const std::string &variable)
609 SpatialDomains::BoundaryRegionCollection::const_iterator it;
612 for (it = bregions.begin(); it != bregions.end(); ++it)
616 if (boundaryCondition->GetBoundaryConditionType() !=
624 m_bndConditions = Array<OneD,SpatialDomains::BoundaryConditionShPtr>(cnt);
629 for (it = bregions.begin(); it != bregions.end(); ++it)
632 bconditions, it->first, variable);
634 if(locBCond->GetBoundaryConditionType()
642 if(locBCond->GetBoundaryConditionType() !=
649 m_bndConditions[cnt++] = locBCond;
663 const std::string &variable)
670 = boost::dynamic_pointer_cast<
672 SpatialDomains::BoundaryRegionCollection::const_iterator it;
695 map<int,int> perComps;
696 map<int,vector<int> > allVerts;
697 map<int,SpatialDomains::PointGeomVector> allCoord;
698 map<int,vector<int> > allEdges;
699 map<int,vector<StdRegions::Orientation> > allOrient;
704 int region1ID, region2ID, i, j, k, cnt;
708 for(i = 0; i < (*m_exp).size(); ++i)
710 for(j = 0; j < (*m_exp)[i]->GetNverts(); ++j)
712 int id = (*m_exp)[i]->GetGeom()->GetVid(j);
716 for(j = 0; j < (*m_exp)[i]->GetNedges(); ++j)
718 int id = (*m_exp)[i]->GetGeom()->GetEid(j);
726 for (it = bregions.begin(); it != bregions.end(); ++it)
729 bconditions, it->first, variable);
731 if (locBCond->GetBoundaryConditionType()
738 region1ID = it->first;
739 region2ID = boost::static_pointer_cast<
741 locBCond)->m_connectedBoundaryRegion;
745 "Boundary region "+boost::lexical_cast<
string>(
746 region1ID)+
" should only contain 1 composite.");
754 if (vComm->GetSize() == 1)
756 cId1 = it->second->begin()->first;
757 cId2 = bregions.find(region2ID)->second->begin()->first;
761 cId1 = bndRegOrder.find(region1ID)->second[0];
762 cId2 = bndRegOrder.find(region2ID)->second[0];
766 vector<unsigned int> tmpOrder;
772 for (i = 0; i < c->size(); ++i)
775 boost::dynamic_pointer_cast<
777 ASSERTL1(faceGeom,
"Unable to cast to shared ptr");
780 int faceId = (*c)[i]->GetGlobalID();
781 locFaces.insert(faceId);
785 if (vComm->GetSize() == 1)
787 tmpOrder.push_back((*c)[i]->GetGlobalID());
792 vector<int> vertList, edgeList;
794 vector<StdRegions::Orientation> orientVec;
795 for (j = 0; j < faceGeom->GetNumVerts(); ++j)
797 vertList .push_back(faceGeom->GetVid (j));
798 edgeList .push_back(faceGeom->GetEid (j));
799 coordVec .push_back(faceGeom->GetVertex(j));
800 orientVec.push_back(faceGeom->GetEorient(j));
803 allVerts [faceId] = vertList;
804 allEdges [faceId] = edgeList;
805 allCoord [faceId] = coordVec;
806 allOrient[faceId] = orientVec;
811 if (vComm->GetSize() == 1)
813 compOrder[it->second->begin()->first] = tmpOrder;
819 if (perComps.count(cId1) == 0)
821 if (perComps.count(cId2) == 0)
823 perComps[cId1] = cId2;
827 std::stringstream ss;
828 ss <<
"Boundary region " << cId2 <<
" should be "
829 <<
"periodic with " << perComps[cId2] <<
" but "
830 <<
"found " << cId1 <<
" instead!";
831 ASSERTL0(perComps[cId2] == cId1, ss.str());
836 std::stringstream ss;
837 ss <<
"Boundary region " << cId1 <<
" should be "
838 <<
"periodic with " << perComps[cId1] <<
" but "
839 <<
"found " << cId2 <<
" instead!";
840 ASSERTL0(perComps[cId1] == cId1, ss.str());
846 int n = vComm->GetSize();
847 int p = vComm->GetRank();
849 Array<OneD, int> facecounts(n,0);
850 Array<OneD, int> vertcounts(n,0);
851 Array<OneD, int> faceoffset(n,0);
852 Array<OneD, int> vertoffset(n,0);
855 facecounts[p] = locFaces.size();
861 for (i = 1; i < n; ++i)
863 faceoffset[i] = faceoffset[i-1] + facecounts[i-1];
871 Array<OneD, int> faceIds (totFaces, 0);
872 Array<OneD, int> faceVerts(totFaces, 0);
878 for (i = 0, sIt = locFaces.begin(); sIt != locFaces.end(); ++sIt)
880 faceIds [faceoffset[p] + i ] = *sIt;
881 faceVerts[faceoffset[p] + i++] = allVerts[*sIt].size();
889 Array<OneD, int> procVerts(n,0);
904 for (i = 0; i < n; ++i)
906 if (facecounts[i] > 0)
909 facecounts[i], faceVerts + faceoffset[i], 1);
920 for (i = 1; i < n; ++i)
922 vertoffset[i] = vertoffset[i-1] + procVerts[i-1];
929 Array<OneD, int> vertIds(nTotVerts, 0);
930 Array<OneD, int> edgeIds(nTotVerts, 0);
931 Array<OneD, int> edgeOrt(nTotVerts, 0);
932 Array<OneD, NekDouble> vertX (nTotVerts, 0.0);
933 Array<OneD, NekDouble> vertY (nTotVerts, 0.0);
934 Array<OneD, NekDouble> vertZ (nTotVerts, 0.0);
936 for (cnt = 0, sIt = locFaces.begin();
937 sIt != locFaces.end(); ++sIt)
939 for (j = 0; j < allVerts[*sIt].size(); ++j)
941 int vertId = allVerts[*sIt][j];
942 vertIds[vertoffset[p] + cnt ] = vertId;
943 vertX [vertoffset[p] + cnt ] = (*allCoord[*sIt][j])(0);
944 vertY [vertoffset[p] + cnt ] = (*allCoord[*sIt][j])(1);
945 vertZ [vertoffset[p] + cnt ] = (*allCoord[*sIt][j])(2);
946 edgeIds[vertoffset[p] + cnt ] = allEdges [*sIt][j];
947 edgeOrt[vertoffset[p] + cnt++] = allOrient[*sIt][j];
962 map<int, vector<int> > vertMap;
963 map<int, vector<int> > edgeMap;
964 map<int, SpatialDomains::PointGeomVector> coordMap;
970 map<int, SpatialDomains::PointGeomSharedPtr> vCoMap;
971 map<int, pair<int, int> > eIdMap;
973 for (cnt = i = 0; i < totFaces; ++i)
975 vector<int> edges(faceVerts[i]);
976 vector<int> verts(faceVerts[i]);
982 for (j = 0; j < faceVerts[i]; ++j, ++cnt)
984 edges[j] = edgeIds[cnt];
985 verts[j] = vertIds[cnt];
988 3, verts[j], vertX[cnt], vertY[cnt], vertZ[cnt]);
989 vCoMap[vertIds[cnt]] = coord[j];
992 pair<map<int, pair<int, int> >
::iterator,
bool> testIns =
993 eIdMap.insert(make_pair(
995 make_pair(vertIds[tmp+j],
996 vertIds[tmp+((j+1) % faceVerts[i])])));
998 if (testIns.second ==
false)
1010 swap(testIns.first->second.first,
1011 testIns.first->second.second);
1015 vertMap [faceIds[i]] = verts;
1016 edgeMap [faceIds[i]] = edges;
1017 coordMap[faceIds[i]] = coord;
1024 map<int,int>::const_iterator oIt;
1038 map<int, map<StdRegions::Orientation, vector<int> > > vmap;
1039 map<int, map<StdRegions::Orientation, vector<int> > > emap;
1041 map<StdRegions::Orientation, vector<int> > quadVertMap;
1051 map<StdRegions::Orientation, vector<int> > quadEdgeMap;
1061 map<StdRegions::Orientation, vector<int> > triVertMap;
1065 map<StdRegions::Orientation, vector<int> > triEdgeMap;
1069 vmap[3] = triVertMap;
1070 vmap[4] = quadVertMap;
1071 emap[3] = triEdgeMap;
1072 emap[4] = quadEdgeMap;
1074 map<int,int> allCompPairs;
1079 for (cIt = perComps.begin(); cIt != perComps.end(); ++cIt)
1082 const int id1 = cIt->first;
1083 const int id2 = cIt->second;
1084 std::string id1s = boost::lexical_cast<
string>(id1);
1085 std::string id2s = boost::lexical_cast<
string>(id2);
1087 if (compMap.count(id1) > 0)
1089 c[0] = compMap[id1];
1092 if (compMap.count(id2) > 0)
1094 c[1] = compMap[id2];
1098 "Neither composite not found on this process!");
1103 map<int,int> compPairs;
1106 "Unable to find composite "+id1s+
" in order map.");
1108 "Unable to find composite "+id2s+
" in order map.");
1109 ASSERTL0(compOrder[id1].size() == compOrder[id2].size(),
1110 "Periodic composites "+id1s+
" and "+id2s+
1111 " should have the same number of elements.");
1112 ASSERTL0(compOrder[id1].size() > 0,
1113 "Periodic composites "+id1s+
" and "+id2s+
1117 for (i = 0; i < compOrder[id1].size(); ++i)
1119 int eId1 = compOrder[id1][i];
1120 int eId2 = compOrder[id2][i];
1122 ASSERTL0(compPairs.count(eId1) == 0,
1126 if (compPairs.count(eId2) != 0)
1128 ASSERTL0(compPairs[eId2] == eId1,
"Pairing incorrect");
1130 compPairs[eId1] = eId2;
1136 for (pIt = compPairs.begin(); pIt != compPairs.end(); ++pIt)
1138 int ids [2] = {pIt->first, pIt->second};
1139 bool local[2] = {locFaces.count(pIt->first) > 0,
1140 locFaces.count(pIt->second) > 0};
1142 ASSERTL0(coordMap.count(ids[0]) > 0 &&
1143 coordMap.count(ids[1]) > 0,
1144 "Unable to find face in coordinate map");
1146 allCompPairs[pIt->first ] = pIt->second;
1147 allCompPairs[pIt->second] = pIt->first;
1152 = { coordMap[ids[0]], coordMap[ids[1]] };
1154 ASSERTL0(tmpVec[0].size() == tmpVec[1].size(),
1155 "Two periodic faces have different number "
1166 for (i = 0; i < 2; ++i)
1174 int other = (i+1) % 2;
1177 if (tmpVec[0].size() == 3)
1180 tmpVec[i], tmpVec[other]);
1185 tmpVec[i], tmpVec[other]);
1195 int nFaceVerts = vertMap[ids[0]].size();
1198 for (i = 0; i < 2; ++i)
1200 int other = (i+1) % 2;
1203 if (tmpVec[0].size() == 3)
1206 tmpVec[i], tmpVec[other]);
1211 tmpVec[i], tmpVec[other]);
1214 if (nFaceVerts == 3)
1219 "Unsupported face orientation for face "+
1220 boost::lexical_cast<string>(ids[i]));
1224 vector<int> per1 = vertMap[ids[i]];
1225 vector<int> per2 = vertMap[ids[other]];
1229 map<int, pair<int, bool> > tmpMap;
1234 for (j = 0; j < nFaceVerts; ++j)
1236 int v = vmap[nFaceVerts][o][j];
1237 tmpMap[per1[j]] = make_pair(
1238 per2[v], locVerts.count(per2[v]) > 0);
1242 for (mIt = tmpMap.begin(); mIt != tmpMap.end(); ++mIt)
1246 mIt->second.second);
1252 if (perIt == periodicVerts.end())
1256 periodicVerts[mIt->first].push_back(ent2);
1257 perIt = periodicVerts.find(mIt->first);
1264 for (k = 0; k < perIt->second.size(); ++k)
1266 if (perIt->second[k].id == mIt->second.first)
1272 if (k == perIt->second.size())
1274 perIt->second.push_back(ent2);
1282 for (i = 0; i < 2; ++i)
1284 int other = (i+1) % 2;
1286 if (tmpVec[0].size() == 3)
1289 tmpVec[i], tmpVec[other]);
1294 tmpVec[i], tmpVec[other]);
1297 vector<int> per1 = edgeMap[ids[i]];
1298 vector<int> per2 = edgeMap[ids[other]];
1300 map<int, pair<int, bool> > tmpMap;
1303 for (j = 0; j < nFaceVerts; ++j)
1305 int e = emap[nFaceVerts][o][j];
1306 tmpMap[per1[j]] = make_pair(
1307 per2[e], locEdges.count(per2[e]) > 0);
1310 for (mIt = tmpMap.begin(); mIt != tmpMap.end(); ++mIt)
1316 mIt->second.second);
1320 if (perIt == periodicEdges.end())
1322 periodicEdges[mIt->first].push_back(ent2);
1323 perIt = periodicEdges.find(mIt->first);
1327 for (k = 0; k < perIt->second.size(); ++k)
1329 if (perIt->second[k].id == mIt->second.first)
1335 if (k == perIt->second.size())
1337 perIt->second.push_back(ent2);
1345 Array<OneD, int> pairSizes(n, 0);
1346 pairSizes[p] = allCompPairs.size();
1351 Array<OneD, int> pairOffsets(n, 0);
1354 for (i = 1; i < n; ++i)
1356 pairOffsets[i] = pairOffsets[i-1] + pairSizes[i-1];
1359 Array<OneD, int> first (totPairSizes, 0);
1360 Array<OneD, int> second(totPairSizes, 0);
1362 cnt = pairOffsets[p];
1364 for (pIt = allCompPairs.begin(); pIt != allCompPairs.end(); ++pIt)
1366 first [cnt ] = pIt->first;
1367 second[cnt++] = pIt->second;
1373 allCompPairs.clear();
1375 for(cnt = 0; cnt < totPairSizes; ++cnt)
1377 allCompPairs[first[cnt]] = second[cnt];
1384 for (cnt = i = 0; i < totFaces; ++i)
1386 int faceId = faceIds[i];
1388 ASSERTL0(allCompPairs.count(faceId) > 0,
1389 "Unable to find matching periodic face.");
1391 int perFaceId = allCompPairs[faceId];
1393 for (j = 0; j < faceVerts[i]; ++j, ++cnt)
1395 int vId = vertIds[cnt];
1399 if (perId == periodicVerts.end())
1407 = { coordMap[faceId], coordMap[perFaceId] };
1409 int nFaceVerts = tmpVec[0].size();
1412 tmpVec[0], tmpVec[1]) :
1414 tmpVec[0], tmpVec[1]);
1418 int perVertexId = vertMap[perFaceId][vmap[nFaceVerts][o][j]];
1423 locVerts.count(perVertexId) > 0);
1425 periodicVerts[vId].push_back(ent);
1428 int eId = edgeIds[cnt];
1430 perId = periodicEdges.find(eId);
1432 if (perId == periodicEdges.end())
1440 = { coordMap[faceId], coordMap[perFaceId] };
1442 int nFaceEdges = tmpVec[0].size();
1445 tmpVec[0], tmpVec[1]) :
1447 tmpVec[0], tmpVec[1]);
1451 int perEdgeId = edgeMap[perFaceId][emap[nFaceEdges][o][j]];
1456 locEdges.count(perEdgeId) > 0);
1458 periodicEdges[eId].push_back(ent);
1466 for (perIt = periodicVerts.begin();
1467 perIt != periodicVerts.end(); ++perIt)
1470 for (i = 0; i < perIt->second.size(); ++i)
1473 perIt2 = periodicVerts.find(perIt->second[i].id);
1474 ASSERTL0(perIt2 != periodicVerts.end(),
1475 "Couldn't find periodic vertex.");
1480 for (j = 0; j < perIt2->second.size(); ++j)
1482 if (perIt2->second[j].id == perIt->first)
1487 for (k = 0; k < perIt->second.size(); ++k)
1489 if (perIt2->second[j].id == perIt->second[k].id)
1495 if (k == perIt->second.size())
1497 perIt->second.push_back(perIt2->second[j]);
1503 for (perIt = periodicEdges.begin();
1504 perIt != periodicEdges.end(); ++perIt)
1506 for (i = 0; i < perIt->second.size(); ++i)
1508 perIt2 = periodicEdges.find(perIt->second[i].id);
1509 ASSERTL0(perIt2 != periodicEdges.end(),
1510 "Couldn't find periodic edge.");
1512 for (j = 0; j < perIt2->second.size(); ++j)
1514 if (perIt2->second[j].id == perIt->first)
1519 for (k = 0; k < perIt->second.size(); ++k)
1521 if (perIt2->second[j].id == perIt->second[k].id)
1527 if (k == perIt->second.size())
1529 perIt->second.push_back(perIt2->second[j]);
1536 for (perIt = periodicEdges.begin();
1537 perIt != periodicEdges.end(); perIt++)
1541 = eIdMap.find(perIt->first);
1543 *vCoMap[eIt->second.first],
1544 *vCoMap[eIt->second.second]
1550 for (i = 0; i < perIt->second.size(); ++i)
1552 eIt = eIdMap.find(perIt->second[i].id);
1555 *vCoMap[eIt->second.first],
1556 *vCoMap[eIt->second.second]
1559 NekDouble cx = 0.5*(w[0](0)-v[0](0)+w[1](0)-v[1](0));
1560 NekDouble cy = 0.5*(w[0](1)-v[0](1)+w[1](1)-v[1](1));
1561 NekDouble cz = 0.5*(w[0](2)-v[0](2)+w[1](2)-v[1](2));
1563 int vMap[2] = {-1,-1};
1564 for (j = 0; j < 2; ++j)
1569 for (k = 0; k < 2; ++k)
1575 if (sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y)+(z1-z)*(z1-z))
1585 ASSERTL0(vMap[0] >= 0 && vMap[1] >= 0,
1586 "Unable to align periodic vertices.");
1587 ASSERTL0((vMap[0] == 0 || vMap[0] == 1) &&
1588 (vMap[1] == 0 || vMap[1] == 1) &&
1589 (vMap[0] != vMap[1]),
1590 "Unable to align periodic vertices.");
1603 for (perIt = periodicVerts.begin();
1604 perIt != periodicVerts.end(); ++perIt)
1606 if (locVerts.count(perIt->first) > 0)
1612 for (perIt = periodicEdges.begin();
1613 perIt != periodicEdges.end(); ++perIt)
1615 if (locEdges.count(perIt->first) > 0)
1627 as<LocalRegions::Expansion2D>();
1629 int offset =
m_trace->GetPhys_Offset(traceEl->GetElmtId());
1632 if (traceEl->GetLeftAdjacentElementFace () == -1 ||
1633 traceEl->GetRightAdjacentElementFace() == -1)
1643 int traceGeomId = traceEl->GetGeom2D()->GetGlobalID();
1649 fwd = traceGeomId == min(traceGeomId,pIt->second[0].id);
1654 GetTraceToUniversalMapUnique(offset) >= 0;
1658 else if (traceEl->GetLeftAdjacentElementFace () != -1 &&
1659 traceEl->GetRightAdjacentElementFace() != -1)
1663 (traceEl->GetLeftAdjacentElementExp().get()) ==
1668 ASSERTL2(
false,
"Unconnected trace element!");
1700 Array<OneD, NekDouble> &Bwd)
1707 const Array<OneD, const NekDouble> &field,
1708 Array<OneD, NekDouble> &Fwd,
1709 Array<OneD, NekDouble> &Bwd)
1713 int cnt, n, e,
npts, offset, phys_offset;
1714 Array<OneD,NekDouble> e_tmp;
1716 Array<OneD, Array<OneD, StdRegions::StdExpansionSharedPtr> >
1721 boost::unordered_map<int,pair<int,int> >
::iterator it3;
1730 for(cnt = n = 0; n < nexp; ++n)
1734 for(e = 0; e < exp3d->GetNfaces(); ++e, ++cnt)
1736 offset =
m_trace->GetPhys_Offset(
1737 elmtToTrace[n][e]->GetElmtId());
1742 exp3d->GetFacePhysVals(e, elmtToTrace[n][e],
1743 field + phys_offset,
1744 e_tmp = Fwd + offset);
1748 exp3d->GetFacePhysVals(e, elmtToTrace[n][e],
1749 field + phys_offset,
1750 e_tmp = Bwd + offset);
1768 id2 =
m_trace->GetPhys_Offset(
1769 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
1786 id2 =
m_trace->GetPhys_Offset(
1787 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
1790 "method not set up for non-zero Neumann "
1791 "boundary condition");
1800 ASSERTL0(
false,
"Method only set up for Dirichlet, Neumann "
1801 "and Robin conditions.");
1817 Array<OneD, NekDouble> &outarray)
1820 "Field is not in physical space.");
1826 const Array<OneD, const NekDouble> &inarray,
1827 Array<OneD, NekDouble> &outarray)
1831 int n,e,offset,phys_offset;
1832 Array<OneD,NekDouble> e_tmp;
1833 Array<OneD, Array<OneD, StdRegions::StdExpansionSharedPtr> >
1837 "input array is of insufficient length");
1840 for(n = 0; n < nexp; ++n)
1844 for(e = 0; e < (*m_exp)[n]->GetNfaces(); ++e)
1846 offset =
m_trace->GetPhys_Offset(elmtToTrace[n][e]->GetElmtId());
1847 (*m_exp)[n]->GetFacePhysVals(e, elmtToTrace[n][e],
1848 inarray + phys_offset,
1849 e_tmp = outarray + offset);
1873 const Array<OneD, const NekDouble> &Fn,
1874 Array<OneD, NekDouble> &outarray)
1876 int e,n,offset, t_offset;
1877 Array<OneD, NekDouble> e_outarray;
1878 Array<OneD, Array<OneD, StdRegions::StdExpansionSharedPtr> >
1884 e_outarray = outarray+offset;
1885 for(e = 0; e < (*m_exp)[n]->GetNfaces(); ++e)
1887 t_offset =
m_trace->GetPhys_Offset(
1888 elmtToTrace[n][e]->GetElmtId());
1889 (*m_exp)[n]->AddFaceNormBoundaryInt(e,
1920 const Array<OneD, const NekDouble> &Fwd,
1921 const Array<OneD, const NekDouble> &Bwd,
1922 Array<OneD, NekDouble> &outarray)
1924 int e,n,offset, t_offset;
1925 Array<OneD, NekDouble> e_outarray;
1926 Array<OneD, Array<OneD, StdRegions::StdExpansionSharedPtr> >
1932 for(e = 0; e < (*m_exp)[n]->GetNfaces(); ++e)
1934 t_offset =
m_trace->GetPhys_Offset(elmtToTrace[n][e]->GetElmtId());
1939 (*m_exp)[n]->AddFaceNormBoundaryInt(
1940 e, elmtToTrace[n][e], Fwd + t_offset,
1941 e_outarray = outarray+offset);
1945 (*m_exp)[n]->AddFaceNormBoundaryInt(
1946 e, elmtToTrace[n][e], Bwd + t_offset,
1947 e_outarray = outarray+offset);
1958 Array<OneD, int> &ElmtID,
1959 Array<OneD, int> &FaceID)
1961 map<int,int> globalIdMap;
1976 globalIdMap[exp3d->GetGeom3D()->GetGlobalID()] = i;
1986 if(ElmtID.num_elements() != nbcs)
1988 ElmtID = Array<OneD, int>(nbcs);
1991 if(FaceID.num_elements() != nbcs)
1993 FaceID = Array<OneD, int>(nbcs);
2002 as<LocalRegions::Expansion2D>();
2005 graph3D->GetElementsFromFace(exp2d->GetGeom2D());
2007 ElmtID[cnt] = globalIdMap[(*tmp)[0]->
2008 m_Element->GetGlobalID()];
2009 FaceID[cnt] = (*tmp)[0]->m_FaceIndx;
2018 const Array<OneD, const NekDouble> &inarray,
2019 Array<OneD, NekDouble> &outarray,
2023 const Array<OneD, const NekDouble> &dirForcing)
2025 int i,j,n,cnt,cnt1,nbndry;
2031 Array<OneD,NekDouble> e_f, e_l;
2042 int GloBndDofs =
m_traceMap->GetNumGlobalBndCoeffs();
2043 int NumDirichlet =
m_traceMap->GetNumLocalDirBndCoeffs();
2051 Array<OneD,NekDouble> BndSol =
m_trace->UpdateCoeffs();
2054 Array<OneD,NekDouble> BndRhs(GloBndDofs,0.0);
2061 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2062 Array<OneD, NekDouble> loc_lambda(LocBndCoeffs);
2070 for(cnt = cnt1 = n = 0; n < nexp; ++n)
2076 e_l = loc_lambda + cnt1;
2083 Floc =
Transpose(*(HDGLamToU->GetBlock(n,n)))*ElmtFce;
2101 id =
m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(cnt++);
2110 id =
m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(cnt++);
2120 if(GloBndDofs - NumDirichlet > 0)
2137 m_traceMap->GlobalToLocalBnd(BndSol,loc_lambda);
2140 out = (*InvHDGHelm)*F + (*HDGLamToU)*LocLambda;
2153 const Array<OneD,const NekDouble> &inarray,
2154 Array<OneD, NekDouble> &outarray,
2157 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2158 Array<OneD, NekDouble> loc_lambda(LocBndCoeffs);
2162 m_traceMap->GlobalToLocalBnd(inarray, loc_lambda);
2163 LocLambda = (*HDGHelm) * LocLambda;
2164 m_traceMap->AssembleBnd(loc_lambda,outarray);
2183 map<int, RobinBCInfoSharedPtr> returnval;
2184 Array<OneD, int> ElmtID,FaceID;
2194 Array<OneD, NekDouble> Array_tmp;
2198 for(e = 0; e < locExpList->GetExpSize(); ++e)
2201 elmtid = ElmtID[cnt+e];
2203 if(returnval.count(elmtid) != 0)
2205 rInfo->next = returnval.find(elmtid)->second;
2207 returnval[elmtid] = rInfo;
2237 Array<OneD, NekDouble> &outarray)
2239 int i,cnt,f,ncoeff_face;
2240 Array<OneD, NekDouble> force, out_tmp,qrhs,qrhs1;
2241 Array<OneD, Array< OneD, StdRegions::StdExpansionSharedPtr> >
2244 int eid,nq_elmt, nm_elmt;
2245 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2246 Array<OneD, NekDouble> loc_lambda(LocBndCoeffs), face_lambda;
2247 Array<OneD, NekDouble> tmp_coeffs;
2250 face_lambda = loc_lambda;
2259 nq_elmt = (*m_exp)[eid]->GetTotPoints();
2260 nm_elmt = (*m_exp)[eid]->GetNcoeffs();
2261 qrhs = Array<OneD, NekDouble>(nq_elmt);
2262 qrhs1 = Array<OneD, NekDouble>(nq_elmt);
2263 force = Array<OneD, NekDouble>(2*nm_elmt);
2264 out_tmp = force + nm_elmt;
2267 int num_points0 = (*m_exp)[eid]->GetBasis(0)->GetNumPoints();
2268 int num_points1 = (*m_exp)[eid]->GetBasis(1)->GetNumPoints();
2269 int num_points2 = (*m_exp)[eid]->GetBasis(2)->GetNumPoints();
2270 int num_modes0 = (*m_exp)[eid]->GetBasis(0)->GetNumModes();
2271 int num_modes1 = (*m_exp)[eid]->GetBasis(1)->GetNumModes();
2272 int num_modes2 = (*m_exp)[eid]->GetBasis(2)->GetNumModes();
2277 int nFaces = (*m_exp)[eid]->GetNfaces();
2278 Array<OneD, Array<OneD, NekDouble> > faceCoeffs(nFaces);
2279 for(f = 0; f < nFaces; ++f)
2281 ncoeff_face = elmtToTrace[eid][f]->GetNcoeffs();
2282 faceCoeffs[f] = Array<OneD, NekDouble>(ncoeff_face);
2283 Vmath::Vcopy(ncoeff_face, face_lambda, 1, faceCoeffs[f], 1);
2284 exp->SetFaceToGeomOrientation(f, faceCoeffs[f]);
2285 face_lambda = face_lambda + ncoeff_face;
2329 ASSERTL0(
false,
"Wrong shape type, HDG postprocessing is not implemented");
2335 (*m_exp)[eid]->DGDeriv(
2337 elmtToTrace[eid], faceCoeffs, out_tmp);
2338 (*m_exp)[eid]->BwdTrans(out_tmp,qrhs);
2339 ppExp->IProductWRTDerivBase(0,qrhs,force);
2343 (*m_exp)[eid]->DGDeriv(
2345 elmtToTrace[eid], faceCoeffs, out_tmp);
2346 (*m_exp)[eid]->BwdTrans(out_tmp,qrhs);
2347 ppExp->IProductWRTDerivBase(1,qrhs,out_tmp);
2352 (*m_exp)[eid]->DGDeriv(
2354 elmtToTrace[eid], faceCoeffs, out_tmp);
2355 (*m_exp)[eid]->BwdTrans(out_tmp,qrhs);
2356 ppExp->IProductWRTDerivBase(2,qrhs,out_tmp);
2360 (*m_exp)[eid]->BwdTrans(
2362 force[0] = (*m_exp)[eid]->Integral(qrhs);
2375 Array<OneD, NekDouble> work(nq_elmt);
2376 ppExp->BwdTrans(out.
GetPtr(), work);
2377 (*m_exp)[eid]->FwdTrans(work,
2416 const std::string varName,
2425 for (i = 0; i < nbnd; ++i)
2431 npoints = locExpList->GetNpoints();
2433 Array<OneD, NekDouble> x0(npoints, 0.0);
2434 Array<OneD, NekDouble> x1(npoints, 0.0);
2435 Array<OneD, NekDouble> x2(npoints, 0.0);
2437 locExpList->GetCoords(x0, x1, x2);
2442 string filebcs = boost::static_pointer_cast<
2456 condition.
Evaluate(x0, x1, x2, time,
2457 locExpList->UpdatePhys());
2459 locExpList->FwdTrans_BndConstrained(
2460 locExpList->GetPhys(),
2461 locExpList->UpdateCoeffs());
2472 condition.
Evaluate(x0, x1, x2, time,
2473 locExpList->UpdatePhys());
2475 locExpList->IProductWRTBase(locExpList->GetPhys(),
2476 locExpList->UpdateCoeffs());
2491 condition.
Evaluate(x0, x1, x2, time,
2492 locExpList->UpdatePhys());
2494 locExpList->IProductWRTBase(locExpList->GetPhys(),
2495 locExpList->UpdateCoeffs());
2499 coeff.Evaluate(x0, x1, x2, time,
2500 locExpList->UpdatePhys());
2505 ASSERTL0(
false,
"This type of BC not implemented yet");