36 #include <boost/core/ignore_unused.hpp> 48 #include <boost/algorithm/string/predicate.hpp> 54 namespace MultiRegions
66 DisContField2D::DisContField2D(
void)
68 m_bndCondExpansions(),
76 const bool DeclareCoeffPhysArrays)
93 *std::dynamic_pointer_cast<ExpList1D>(In.
m_trace),
94 DeclareCoeffPhysArrays);
105 const std::string &variable,
106 const bool SetUpJustDG,
107 const bool DeclareCoeffPhysArrays,
109 :
ExpList2D(pSession, graph2D, DeclareCoeffPhysArrays, variable,
120 if (variable.compare(
"DefaultVar") != 0)
124 DeclareCoeffPhysArrays);
126 if (DeclareCoeffPhysArrays)
152 for(e = 0; e < locExpList->GetExpSize(); ++e)
155 (*m_exp)[ElmtID[cnt+e]]->
156 as<LocalRegions::Expansion2D>();
158 locExpList->GetExp(e)->
159 as<LocalRegions::Expansion1D>();
161 locExpList->GetExp(e)->
162 as<LocalRegions::Expansion> ();
164 exp2d->SetEdgeExp(EdgeID[cnt+e], exp1d);
165 exp1d->SetAdjacentElementExp(EdgeID[cnt+e], exp2d);
170 if(
m_session->DefinesSolverInfo(
"PROJECTION"))
172 std::string ProjectStr =
174 if((ProjectStr ==
"MixedCGDG") ||
175 (ProjectStr ==
"Mixed_CG_Discontinuous"))
199 const std::string &variable,
200 const bool SetUpJustDG,
201 const bool DeclareCoeffPhysArrays):
207 if(variable.compare(
"DefaultVar") != 0)
212 if (DeclareCoeffPhysArrays)
240 for(e = 0; e < locExpList->GetExpSize(); ++e)
243 = (*m_exp)[ElmtID[cnt+e]]->
244 as<LocalRegions::Expansion2D>();
246 = locExpList->GetExp(e)->
247 as<LocalRegions::Expansion1D>();
249 = locExpList->GetExp(e)->
250 as<LocalRegions::Expansion> ();
252 exp2d->SetEdgeExp(EdgeID[cnt+e], exp1d);
253 exp1d->SetAdjacentElementExp(EdgeID[cnt+e],
261 if (
m_session->DefinesSolverInfo(
"PROJECTION"))
263 std::string ProjectStr =
266 if ((ProjectStr ==
"MixedCGDG") ||
267 (ProjectStr ==
"Mixed_CG_Discontinuous"))
322 for (e = 0; e < locExpList->GetExpSize(); ++e)
325 = (*m_exp)[ElmtID[cnt+e]]->
326 as<LocalRegions::Expansion2D>();
328 = locExpList->GetExp(e)->
329 as<LocalRegions::Expansion1D>();
331 = locExpList->GetExp(e)->
332 as<LocalRegions::Expansion> ();
334 exp2d->SetEdgeExp(EdgeID[cnt+e], exp1d);
335 exp1d->SetAdjacentElementExp(EdgeID[cnt+e],
358 "Routine currently only tested for HybridDGHelmholtz");
361 "The local to global map is not set up for the requested " 370 (*m_globalBndMat)[mkey] = glo_matrix;
374 glo_matrix = matrixIter->second;
409 if (
m_session->DefinesCmdLineArgument(
"verbose"))
411 m_traceMap->PrintStats(std::cout, variable);
415 &elmtToTrace = m_traceMap->GetElmtToTrace();
422 for (
int i = 0; i <
m_exp->size(); ++i)
424 for (
int j = 0; j < (*m_exp)[i]->GetNedges(); ++j)
431 exp2d->SetEdgeExp (j, exp1d);
432 exp1d->SetAdjacentElementExp(j, exp2d);
440 for (
int i = 0; i <
m_trace->GetExpSize(); ++i)
445 int offset =
m_trace->GetPhys_Offset(i);
446 int traceGeomId = traceEl->GetGeom1D()->GetGlobalID();
451 if (traceGeomId != min(pIt->second[0].id, traceGeomId))
453 traceEl->GetLeftAdjacentElementExp()->NegateEdgeNormal(
454 traceEl->GetLeftAdjacentElementEdge());
457 else if (m_traceMap->GetTraceToUniversalMapUnique(offset) < 0)
459 traceEl->GetLeftAdjacentElementExp()->NegateEdgeNormal(
460 traceEl->GetLeftAdjacentElementEdge());
475 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
482 std::unordered_map<int,pair<int,int> > perEdgeToExpMap;
483 for (cnt = n = 0; n <
m_exp->size(); ++n)
485 for (e = 0; e < (*m_exp)[n]->GetNedges(); ++e, ++cnt)
488 (*
m_exp)[n]->GetGeom()->GetEid(e));
492 perEdgeToExpMap[it->first] = make_pair(n, e);
500 for (
int i = 0; i <
m_exp->size(); ++i)
502 for (
int j = 0; j < (*m_exp)[i]->GetNedges(); ++j, ++cnt)
510 for (
int n = 0; n <
m_exp->size(); ++n)
512 for (
int e = 0; e < (*m_exp)[n]->GetNedges(); ++e, ++cnt)
514 int edgeGeomId = (*m_exp)[n]->GetGeom()->GetEid(e);
515 int offset =
m_trace->GetPhys_Offset(
516 elmtToTrace[n][e]->GetElmtId());
524 auto it2 = perEdgeToExpMap.find(ent.
id);
526 if (it2 == perEdgeToExpMap.end())
529 GetRowComm()->GetSize() > 1 && !ent.
isLocal)
535 ASSERTL1(
false,
"Periodic edge not found!");
540 "Periodic edge in non-forward space?");
542 int offset2 =
m_trace->GetPhys_Offset(
543 elmtToTrace[it2->second.first][it2->second.second]->
548 int nquad = elmtToTrace[n][e]->GetNumPoints(0);
550 vector<int> tmpBwd(nquad);
551 vector<int> tmpFwd(nquad);
555 for (
int i = 0; i < nquad; ++i)
557 tmpBwd[i] = offset2 + i;
558 tmpFwd[i] = offset + i;
563 for (
int i = 0; i < nquad; ++i)
565 tmpBwd[i] = offset2 + i;
566 tmpFwd[i] = offset + nquad - i - 1;
570 for (
int i = 0; i < nquad; ++i)
594 bool returnval =
true;
614 int vSame = (returnval?1:0);
638 const std::string &variable,
639 const bool DeclareCoeffPhysArrays)
654 for (
auto &it : bregions)
660 DeclareCoeffPhysArrays, variable,
664 m_bndConditions[cnt] = bc;
666 std::string type = m_bndConditions[cnt]->GetUserDefined();
672 || boost::iequals(type,
"I") || boost::iequals(type,
"CalcBC"))
694 const std::string &variable)
704 m_graph->GetCompositeOrdering();
706 m_graph->GetBndRegionOrdering();
713 map<int,int> perComps;
714 map<int,vector<int>> allVerts;
716 map<int, pair<int, StdRegions::Orientation>> allEdges;
718 int region1ID, region2ID, i, j, k, cnt;
722 for(i = 0; i < (*m_exp).size(); ++i)
724 for(j = 0; j < (*m_exp)[i]->GetNverts(); ++j)
726 int id = (*m_exp)[i]->GetGeom()->GetVid(j);
732 for (
auto &it : bregions)
735 bconditions, it.first, variable);
737 if (locBCond->GetBoundaryConditionType()
744 region1ID = it.first;
745 region2ID = std::static_pointer_cast<
747 locBCond)->m_connectedBoundaryRegion;
752 if (vComm->GetSize() == 1)
754 cId1 = it.second->begin()->first;
755 cId2 = bregions.find(region2ID)->second->begin()->first;
759 cId1 = bndRegOrder.find(region1ID)->second[0];
760 cId2 = bndRegOrder.find(region2ID)->second[0];
764 "Boundary region "+boost::lexical_cast<
string>(
765 region1ID)+
" should only contain 1 composite.");
770 vector<unsigned int> tmpOrder;
772 for (i = 0; i < c->m_geomVec.size(); ++i)
775 std::dynamic_pointer_cast<
777 ASSERTL0(segGeom,
"Unable to cast to shared ptr");
780 m_graph->GetElementsFromEdge(segGeom);
782 "The periodic boundaries belong to " 783 "more than one element of the mesh");
789 allEdges[c->m_geomVec[i]->GetGlobalID()] =
790 make_pair(elmt->at(0).second,
791 geom->GetEorient(elmt->at(0).second));
795 if (vComm->GetSize() == 1)
797 tmpOrder.push_back(c->m_geomVec[i]->GetGlobalID());
800 vector<int> vertList(2);
801 vertList[0] = segGeom->GetVid(0);
802 vertList[1] = segGeom->GetVid(1);
803 allVerts[c->m_geomVec[i]->GetGlobalID()] = vertList;
806 if (vComm->GetSize() == 1)
808 compOrder[it.second->begin()->first] = tmpOrder;
813 if (perComps.count(cId1) == 0)
815 if (perComps.count(cId2) == 0)
817 perComps[cId1] = cId2;
821 std::stringstream ss;
822 ss <<
"Boundary region " << cId2 <<
" should be " 823 <<
"periodic with " << perComps[cId2] <<
" but " 824 <<
"found " << cId1 <<
" instead!";
825 ASSERTL0(perComps[cId2] == cId1, ss.str());
830 std::stringstream ss;
831 ss <<
"Boundary region " << cId1 <<
" should be " 832 <<
"periodic with " << perComps[cId1] <<
" but " 833 <<
"found " << cId2 <<
" instead!";
834 ASSERTL0(perComps[cId1] == cId1, ss.str());
839 int n = vComm->GetSize();
840 int p = vComm->GetRank();
846 edgecounts[
p] = allEdges.size();
850 for (i = 1; i < n; ++i)
852 edgeoffset[i] = edgeoffset[i-1] + edgecounts[i-1];
861 auto sIt = allEdges.begin();
863 for (i = 0; sIt != allEdges.end(); ++sIt)
865 edgeIds [edgeoffset[
p] + i ] = sIt->first;
866 edgeIdx [edgeoffset[
p] + i ] = sIt->second.first;
867 edgeOrient[edgeoffset[
p] + i ] = sIt->second.second;
868 edgeVerts [edgeoffset[
p] + i++] = allVerts[sIt->first].size();
891 for (i = 0; i < n; ++i)
893 if (edgecounts[i] > 0)
896 edgecounts[i], edgeVerts + edgeoffset[i], 1);
905 for (i = 1; i < n; ++i)
907 vertoffset[i] = vertoffset[i-1] + procVerts[i-1];
911 for (i = 0, sIt = allEdges.begin(); sIt != allEdges.end(); ++sIt)
913 for (j = 0; j < allVerts[sIt->first].size(); ++j)
915 vertIds[vertoffset[
p] + i++] = allVerts[sIt->first][j];
922 map<int, StdRegions::Orientation> orientMap;
923 map<int, vector<int> > vertMap;
925 for (cnt = i = 0; i < totEdges; ++i)
927 ASSERTL0(orientMap.count(edgeIds[i]) == 0,
928 "Already found edge in orientation map!");
946 orientMap[edgeIds[i]] = o;
948 vector<int> verts(edgeVerts[i]);
950 for (j = 0; j < edgeVerts[i]; ++j)
952 verts[j] = vertIds[cnt++];
954 vertMap[edgeIds[i]] = verts;
960 map<int,int> allCompPairs;
969 for (
auto &cIt : perComps)
972 const int id1 = cIt.first;
973 const int id2 = cIt.second;
974 std::string id1s = boost::lexical_cast<
string>(id1);
975 std::string id2s = boost::lexical_cast<
string>(id2);
977 if (compMap.count(id1) > 0)
982 if (compMap.count(id2) > 0)
988 "Both composites not found on this process!");
993 map<int,int> compPairs;
996 "Unable to find composite "+id1s+
" in order map.");
998 "Unable to find composite "+id2s+
" in order map.");
999 ASSERTL0(compOrder[id1].size() == compOrder[id2].size(),
1000 "Periodic composites "+id1s+
" and "+id2s+
1001 " should have the same number of elements.");
1002 ASSERTL0(compOrder[id1].size() > 0,
1003 "Periodic composites "+id1s+
" and "+id2s+
1007 for (i = 0; i < compOrder[id1].size(); ++i)
1009 int eId1 = compOrder[id1][i];
1010 int eId2 = compOrder[id2][i];
1012 ASSERTL0(compPairs.count(eId1) == 0,
1015 if (compPairs.count(eId2) != 0)
1017 ASSERTL0(compPairs[eId2] == eId1,
"Pairing incorrect");
1019 compPairs[eId1] = eId2;
1025 for (i = 0; i < 2; ++i)
1032 if (c[i]->m_geomVec.size() > 0)
1034 for (j = 0; j < c[i]->m_geomVec.size(); ++j)
1036 locEdges.insert(c[i]->m_geomVec[j]->GetGlobalID());
1042 for (
auto &pIt : compPairs)
1044 int ids [2] = {pIt.first, pIt.second};
1045 bool local[2] = {locEdges.count(pIt.first) > 0,
1046 locEdges.count(pIt.second) > 0};
1048 ASSERTL0(orientMap.count(ids[0]) > 0 &&
1049 orientMap.count(ids[1]) > 0,
1050 "Unable to find edge in orientation map.");
1052 allCompPairs[pIt.first ] = pIt.second;
1053 allCompPairs[pIt.second] = pIt.first;
1055 for (i = 0; i < 2; ++i)
1062 int other = (i+1) % 2;
1065 orientMap[ids[i]] == orientMap[ids[other]] ?
1074 for (i = 0; i < 2; ++i)
1076 int other = (i+1) % 2;
1079 orientMap[ids[i]] == orientMap[ids[other]] ?
1084 vector<int> perVerts1 = vertMap[ids[i]];
1085 vector<int> perVerts2 = vertMap[ids[other]];
1087 map<int, pair<int, bool> > tmpMap;
1090 tmpMap[perVerts1[0]] = make_pair(
1091 perVerts2[0], locVerts.count(perVerts2[0]) > 0);
1092 tmpMap[perVerts1[1]] = make_pair(
1093 perVerts2[1], locVerts.count(perVerts2[1]) > 0);
1097 tmpMap[perVerts1[0]] = make_pair(
1098 perVerts2[1], locVerts.count(perVerts2[1]) > 0);
1099 tmpMap[perVerts1[1]] = make_pair(
1100 perVerts2[0], locVerts.count(perVerts2[0]) > 0);
1103 for (
auto &mIt : tmpMap)
1109 auto perIt = periodicVerts.find(mIt.first);
1111 if (perIt == periodicVerts.end())
1113 periodicVerts[mIt.first].push_back(ent2);
1114 perIt = periodicVerts.find(mIt.first);
1119 for (j = 0; j < perIt->second.size(); ++j)
1121 if (perIt->second[j].id == mIt.second.first)
1130 perIt->second.push_back(ent2);
1139 pairSizes[
p] = allCompPairs.size();
1147 for (i = 1; i < n; ++i)
1149 pairOffsets[i] = pairOffsets[i-1] + pairSizes[i-1];
1155 cnt = pairOffsets[
p];
1157 for (
auto &pIt : allCompPairs)
1159 first [cnt ] = pIt.first;
1160 second[cnt++] = pIt.second;
1166 allCompPairs.clear();
1168 for(cnt = 0; cnt < totPairSizes; ++cnt)
1170 allCompPairs[first[cnt]] = second[cnt];
1176 for (cnt = i = 0; i < totEdges; ++i)
1178 int edgeId = edgeIds[i];
1180 ASSERTL0(allCompPairs.count(edgeId) > 0,
1181 "Unable to find matching periodic edge.");
1183 int perEdgeId = allCompPairs[edgeId];
1185 for (j = 0; j < edgeVerts[i]; ++j, ++cnt)
1187 int vId = vertIds[cnt];
1189 auto perId = periodicVerts.find(vId);
1191 if (perId == periodicVerts.end())
1198 orientMap[edgeId] == orientMap[perEdgeId] ?
1199 vertMap[perEdgeId][(j+1)%2] : vertMap[perEdgeId][j];
1203 locVerts.count(perVertexId) > 0);
1205 periodicVerts[vId].push_back(ent);
1212 for (
auto &perIt : periodicVerts)
1215 for (i = 0; i < perIt.second.size(); ++i)
1217 auto perIt2 = periodicVerts.find(perIt.second[i].id);
1218 ASSERTL0(perIt2 != periodicVerts.end(),
1219 "Couldn't find periodic vertex.");
1221 for (j = 0; j < perIt2->second.size(); ++j)
1223 if (perIt2->second[j].id == perIt.first)
1229 for (k = 0; k < perIt.second.size(); ++k)
1231 if (perIt2->second[j].id == perIt.second[k].id)
1240 perIt.second.push_back(perIt2->second[j]);
1248 for (
auto &perIt : periodicVerts)
1250 if (locVerts.count(perIt.first) > 0)
1261 as<LocalRegions::Expansion1D>();
1265 if (traceEl->GetLeftAdjacentElementEdge () == -1 ||
1266 traceEl->GetRightAdjacentElementEdge() == -1)
1276 int traceGeomId = traceEl->GetGeom1D()->GetGlobalID();
1281 fwd = traceGeomId == min(traceGeomId,pIt->second[0].id);
1285 int offset =
m_trace->GetPhys_Offset(traceEl->GetElmtId());
1288 GetTraceToUniversalMapUnique(offset) >= 0;
1292 else if ( traceEl->GetLeftAdjacentElementEdge () != -1 &&
1293 traceEl->GetRightAdjacentElementEdge() != -1 )
1296 fwd = ( traceEl->GetLeftAdjacentElementExp().get() == (*m_exp)[n].get() );
1300 ASSERTL2(
false,
"Unconnected trace element!" );
1347 int cnt, n, e, npts, phys_offset;
1366 GetNFwdLocTracePts();
1379 for(cnt = n = 0; n < nexp; ++n)
1384 for(e = 0; e < exp2d->GetNedges(); ++e, ++cnt)
1386 int offset =
m_trace->GetPhys_Offset(
1387 elmtToTrace[n][e]->GetElmtId());
1391 exp2d->GetEdgePhysVals(e, elmtToTrace[n][e],
1392 field + phys_offset,
1393 e_tmp = Fwd + offset);
1397 exp2d->GetEdgePhysVals(e, elmtToTrace[n][e],
1398 field + phys_offset,
1399 e_tmp = Bwd + offset);
1419 GetBndCondTraceToGlobalTraceMap(cnt+e));
1437 "Method not set up for non-zero Neumann " 1438 "boundary condition");
1439 id2 =
m_trace->GetPhys_Offset(
1440 m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
1450 "Method not set up for this boundary condition.");
1470 "Field must be in physical state to extract trace space.");
1493 Vmath::Zero(outarray.num_elements(), outarray, 1);
1499 InterpLocEdgesToTrace(0,tracevals,outarray);
1500 m_traceMap->UniversalTraceAssemble(outarray);
1506 int n, e, offset, phys_offset;
1512 "input array is of insufficient length");
1515 for(n = 0; n < nexp; ++n)
1519 for(e = 0; e < (*m_exp)[n]->GetNedges(); ++e)
1521 offset =
m_trace->GetPhys_Offset(
1522 elmtToTrace[n][e]->GetElmtId());
1523 (*m_exp)[n]->GetEdgePhysVals(e, elmtToTrace[n][e],
1524 inarray + phys_offset,
1525 e_tmp = outarray + offset);
1536 int e, n, offset, t_offset;
1544 for(e = 0; e < (*m_exp)[n]->GetNedges(); ++e)
1546 t_offset =
GetTrace()->GetPhys_Offset(
1547 elmtToTrace[n][e]->GetElmtId());
1549 (*m_exp)[n]->AddEdgeNormBoundaryInt(
1550 e,elmtToTrace[n][e],
1553 e_outarray = outarray+offset);
1584 m_trace->IProductWRTBase(Fn, Fcoeffs);
1591 int e, n, offset, t_offset;
1599 for(e = 0; e < (*m_exp)[n]->GetNedges(); ++e)
1601 t_offset =
GetTrace()->GetPhys_Offset(
1602 elmtToTrace[n][e]->GetElmtId());
1603 (*m_exp)[n]->AddEdgeNormBoundaryInt(
1604 e, elmtToTrace[n][e],
1606 e_outarray = outarray+offset);
1640 int e,n,offset, t_offset;
1648 for (e = 0; e < (*m_exp)[n]->GetNedges(); ++e)
1650 t_offset =
GetTrace()->GetPhys_Offset(
1651 elmtToTrace[n][e]->GetElmtId());
1656 (*m_exp)[n]->AddEdgeNormBoundaryInt(
1657 e, elmtToTrace[n][e], Fwd+t_offset,
1658 e_outarray = outarray+offset);
1662 (*m_exp)[n]->AddEdgeNormBoundaryInt(
1663 e, elmtToTrace[n][e], Bwd+t_offset,
1664 e_outarray = outarray+offset);
1681 map<int, int> globalIdMap;
1690 globalIdMap[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
1710 as<LocalRegions::Expansion1D>();
1713 m_graph->GetElementsFromEdge(exp1d->GetGeom1D());
1716 (*tmp)[0].first->GetGlobalID()];
1717 m_BCtoEdgMap[cnt] = (*tmp)[0].second;
1726 std::shared_ptr<ExpList> &result,
1727 const bool DeclareCoeffPhysArrays)
1730 int offsetOld, offsetNew;
1731 std::vector<unsigned int> eIDs;
1737 for (cnt = n = 0; n < i; ++n)
1745 eIDs.push_back(ElmtID[cnt+n]);
1751 (*
this, eIDs, DeclareCoeffPhysArrays);
1754 if( DeclareCoeffPhysArrays)
1757 for (n = 0; n < result->GetExpSize(); ++n)
1759 nq =
GetExp(ElmtID[cnt+n])->GetTotPoints();
1761 offsetNew = result->GetPhys_Offset(n);
1763 tmp2 = result->UpdatePhys()+ offsetNew, 1);
1765 nq =
GetExp(ElmtID[cnt+n])->GetNcoeffs();
1767 offsetNew = result->GetCoeff_Offset(n);
1769 tmp2 = result->UpdateCoeffs()+ offsetNew, 1);
1802 int i,e,ncoeff_edge;
1812 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
1816 edge_lambda = loc_lambda;
1824 int nEdges = (*m_exp)[i]->GetNedges();
1827 for(e = 0; e < nEdges; ++e)
1829 edgedir = (*m_exp)[i]->GetEorient(e);
1830 ncoeff_edge = elmtToTrace[i][e]->GetNcoeffs();
1832 Vmath::Vcopy(ncoeff_edge, edge_lambda, 1, edgeCoeffs[e], 1);
1833 elmtToTrace[i][e]->SetCoeffsToOrientation(
1834 edgedir, edgeCoeffs[e], edgeCoeffs[e]);
1835 edge_lambda = edge_lambda + ncoeff_edge;
1838 (*m_exp)[i]->DGDeriv(dir,
1842 out_tmp = out_d+cnt);
1843 cnt += (*m_exp)[i]->GetNcoeffs();
1859 const bool PhysSpaceForcing)
1862 boost::ignore_unused(flags, varfactors, dirForcing);
1863 int i,j,n,cnt,cnt1,nbndry;
1873 if(PhysSpaceForcing)
1886 int GloBndDofs =
m_traceMap->GetNumGlobalBndCoeffs();
1887 int NumDirichlet =
m_traceMap->GetNumLocalDirBndCoeffs();
1908 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
1917 for(cnt = cnt1 = n = 0; n < nexp; ++n)
1919 nbndry = (*m_exp)[n]->NumDGBndryCoeffs();
1921 e_ncoeffs = (*m_exp)[n]->GetNcoeffs();
1923 e_l = loc_lambda + cnt1;
1930 Floc =
Transpose(*(HDGLamToU->GetBlock(n,n)))*ElmtFce;
1949 id =
m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(cnt++);
1961 id =
m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(cnt++);
1968 ASSERTL0(
false,
"HDG implementation does not support " 1969 "periodic boundary conditions at present.");
1977 if(GloBndDofs - NumDirichlet > 0)
1996 m_traceMap->GlobalToLocalBnd(BndSol,loc_lambda);
1999 out = (*InvHDGHelm)*F + (*HDGLamToU)*LocLambda;
2017 boost::ignore_unused(coeffstate);
2019 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2024 m_traceMap->GlobalToLocalBnd(inarray, loc_lambda);
2025 LocLambda = (*HDGHelm) * LocLambda;
2026 m_traceMap->AssembleBnd(loc_lambda,outarray);
2044 map<int, RobinBCInfoSharedPtr> returnval;
2060 int npoints = locExpList->GetNpoints();
2066 locExpList->GetCoords(x0, x1, x2);
2069 std::static_pointer_cast<
2074 coeffeqn.
Evaluate(x0, x1, x2, 0.0, coeffphys);
2076 for(e = 0; e < locExpList->GetExpSize(); ++e)
2082 Array_tmp = coeffphys +
2083 locExpList->GetPhys_Offset(e));
2085 elmtid = ElmtID[cnt+e];
2087 if(returnval.count(elmtid) != 0)
2089 rInfo->next = returnval.find(elmtid)->second;
2091 returnval[elmtid] = rInfo;
2123 int i,cnt,e,ncoeff_edge;
2130 int nq_elmt, nm_elmt;
2131 int LocBndCoeffs =
m_traceMap->GetNumLocalBndCoeffs();
2136 edge_lambda = loc_lambda;
2141 nq_elmt = (*m_exp)[i]->GetTotPoints();
2142 nm_elmt = (*m_exp)[i]->GetNcoeffs();
2146 out_tmp = force + nm_elmt;
2149 int num_points0 = (*m_exp)[i]->GetBasis(0)->GetNumPoints();
2150 int num_points1 = (*m_exp)[i]->GetBasis(1)->GetNumPoints();
2151 int num_modes0 = (*m_exp)[i]->GetBasis(0)->GetNumModes();
2152 int num_modes1 = (*m_exp)[i]->GetBasis(1)->GetNumModes();
2157 int nEdges = (*m_exp)[i]->GetNedges();
2160 for(e = 0; e < (*m_exp)[i]->GetNedges(); ++e)
2162 edgedir = (*m_exp)[i]->GetEorient(e);
2163 ncoeff_edge = elmtToTrace[i][e]->GetNcoeffs();
2165 Vmath::Vcopy(ncoeff_edge, edge_lambda, 1, edgeCoeffs[e], 1);
2166 elmtToTrace[i][e]->SetCoeffsToOrientation(
2167 edgedir, edgeCoeffs[e], edgeCoeffs[e]);
2168 edge_lambda = edge_lambda + ncoeff_edge;
2196 ASSERTL0(
false,
"Wrong shape type, HDG postprocessing is not implemented");
2202 (*m_exp)[i]->DGDeriv(
2204 elmtToTrace[i], edgeCoeffs, out_tmp);
2205 (*m_exp)[i]->BwdTrans(out_tmp,qrhs);
2207 ppExp->IProductWRTDerivBase(0,qrhs,force);
2211 (*m_exp)[i]->DGDeriv(
2213 elmtToTrace[i], edgeCoeffs, out_tmp);
2215 (*m_exp)[i]->BwdTrans(out_tmp,qrhs);
2217 ppExp->IProductWRTDerivBase(1,qrhs,out_tmp);
2222 (*m_exp)[i]->BwdTrans(
2224 force[0] = (*m_exp)[i]->Integral(qrhs);
2238 ppExp->BwdTrans(out.
GetPtr(), work);
2239 (*m_exp)[i]->FwdTrans(work, tmp_coeffs = outarray +
m_coeff_offset[i]);
2257 const std::string varName,
2261 boost::ignore_unused(x3_in);
2269 for (i = 0; i < nbnd; ++i)
2275 npoints = locExpList->GetNpoints();
2283 locExpList->GetCoords(x0, x1, x2);
2287 locExpList->GetCoords(x0, x1, x2);
2295 = std::static_pointer_cast<
2307 std::static_pointer_cast<
2310 m_dirichletCondition;
2312 condition.
Evaluate(x0, x1, x2, time,
2313 locExpList->UpdatePhys());
2316 locExpList->FwdTrans_BndConstrained(
2317 locExpList->GetPhys(),
2318 locExpList->UpdateCoeffs());
2334 std::static_pointer_cast<
2338 condition.
Evaluate(x0, x1, x2, time,
2339 locExpList->UpdatePhys());
2342 locExpList->IProductWRTBase(
2343 locExpList->GetPhys(),
2344 locExpList->UpdateCoeffs());
2361 std::static_pointer_cast<
2365 condition.
Evaluate(x0, x1, x2, time,
2366 locExpList->UpdatePhys());
2369 locExpList->IProductWRTBase(
2370 locExpList->GetPhys(),
2371 locExpList->UpdateCoeffs());
2380 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)
virtual void v_ExtractTracePhys(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This method extracts the trace (edges in 2D) from the field inarray and puts the values in outarray...
#define ASSERTL0(condition, msg)
virtual void v_Reset()
Reset geometry information, metrics, matrix managers and geometry information.
std::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
void FindPeriodicEdges(const SpatialDomains::BoundaryConditions &bcs, const std::string &variable)
Determine the periodic edges and vertices for the given graph.
virtual void v_AddTraceIntegral(const Array< OneD, const NekDouble > &Fx, const Array< OneD, const NekDouble > &Fy, Array< OneD, NekDouble > &outarray)
int id
Geometry ID of entity.
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)
Array< OneD, int > m_BCtoElmMap
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< std::vector< std::pair< GeometrySharedPtr, int > > > GeometryLinkSharedPtr
std::vector< int > m_periodicFwdCopy
A vector indicating degress of freedom which need to be copied from forwards to backwards space in ca...
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
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)
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
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...
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
GlobalLinSysSharedPtr GetGlobalBndLinSys(const GlobalLinSysKey &mkey)
Lagrange Polynomials using the Gauss points .
std::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
std::shared_ptr< NeumannBoundaryCondition > NeumannBCShPtr
std::map< int, CompositeSharedPtr > CompositeMap
PeriodicMap m_periodicEdges
A map which identifies pairs of periodic edges.
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal)
std::map< ConstFactorType, NekDouble > ConstFactorMap
PeriodicMap m_periodicVerts
A map which identifies groups of periodic vertices.
void GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
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.
std::shared_ptr< Basis > BasisSharedPtr
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
int GetExpSize(void)
This function returns the number of elements in the expansion.
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
virtual std::map< int, RobinBCInfoSharedPtr > v_GetRobinBCInfo()
Search through the edge expansions and identify which ones have Robin/Mixed type boundary conditions...
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...
Gauss Radau pinned at x=-1, .
std::shared_ptr< RobinBoundaryCondition > RobinBCShPtr
Principle Orthogonal Functions .
bool SameTypeOfBoundaryConditions(const DisContField2D &In)
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Base class for all multi-elemental spectral/hp expansions.
std::shared_ptr< TriGeom > TriGeomSharedPtr
DisContField2D()
Default constructor.
LocTraceToTraceMapSharedPtr m_locTraceToTraceMap
Array< OneD, MultiRegions::ExpListSharedPtr > m_bndCondExpansions
An object which contains the discretised boundary conditions.
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.
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)
virtual ~DisContField2D()
Default destructor.
std::vector< bool > m_leftAdjacentEdges
std::map< StdRegions::VarCoeffType, Array< OneD, NekDouble > > VarCoeffMap
int GetNcoeffs(void) const
Returns the total number of local degrees of freedom .
std::set< int > m_boundaryEdges
A set storing the global IDs of any boundary edges.
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.
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.
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
std::map< int, BoundaryConditionMapShPtr > BoundaryConditionCollection
Array< OneD, SpatialDomains::BoundaryConditionShPtr > m_bndConditions
An array which contains the information about the boundary condition on the different boundary region...
void ExtractFileBCs(const std::string &fileName, LibUtilities::CommSharedPtr comm, const std::string &varName, const std::shared_ptr< ExpList > locExpList)
bool IsLeftAdjacentEdge(const int n, const int e)
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
virtual void v_Reset()
Reset this field, so that geometry information can be updated.
static const NekDouble kNekUnsetDouble
Describe a linear system.
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Describes a matrix with ordering defined by a local to global map.
AssemblyMapDGSharedPtr m_traceMap
void SetUpDG(const std::string="DefaultVar")
Set up all DG member variables and maps.
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.
std::shared_ptr< Expansion > ExpansionSharedPtr
LibUtilities::CommSharedPtr m_comm
Communicator.
static AssemblyMapSharedPtr NullAssemblyMapSharedPtr
virtual void v_GetBndElmtExpansion(int i, std::shared_ptr< ExpList > &result, const bool DeclareCoeffPhysArrays)
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed t...
GlobalLinSysMapShPtr m_globalBndMat
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal)
std::shared_ptr< DirichletBoundaryCondition > DirichletBCShPtr
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
virtual void v_GetFwdBwdTracePhys(const Array< OneD, const NekDouble > &field, 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...
void EvaluateHDGPostProcessing(Array< OneD, NekDouble > &outarray)
Evaluate HDG post-processing to increase polynomial order of solution.
static SpatialDomains::BoundaryConditionShPtr GetBoundaryCondition(const SpatialDomains::BoundaryConditionCollection &collection, unsigned int index, const std::string &variable)
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
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...
Array< OneD, int > m_BCtoEdgMap
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.
void GenerateBoundaryConditionExpansion(const SpatialDomains::MeshGraphSharedPtr &graph2D, const SpatialDomains::BoundaryConditions &bcs, const std::string &variable, const bool DeclareCoeffPhysArrays=true)
This function discretises the boundary conditions by setting up a list of one-dimensional boundary ex...
virtual void v_GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
Set up a list of element IDs and edge IDs that link to the boundary conditions.
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
std::shared_ptr< SegGeom > SegGeomSharedPtr
int GetPhys_Offset(int n) const
Get the start offset position for a global list of m_phys correspoinding to element n...
NekDouble L2(const Array< OneD, const NekDouble > &inarray, const Array< OneD, const NekDouble > &soln=NullNekDouble1DArray)
This function calculates the error with respect to soln of the global spectral/hp element approximat...
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
NekDouble L2_DGDeriv(const int dir, const Array< OneD, const NekDouble > &soln)
Calculate the error of the derivative using the consistent DG evaluation of .
std::shared_ptr< ExpList1D > ExpList1DSharedPtr
Shared pointer to an ExpList1D object.
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
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.
std::shared_ptr< ExpList > & GetTrace()
std::map< StdRegions::ConstFactorType, Array< OneD, NekDouble > > VarFactorsMap