37 #include <boost/core/ignore_unused.hpp> 51 namespace MultiRegions
70 ExpList2D::ExpList2D():
90 const bool DeclareCoeffPhysArrays):
91 ExpList(In,DeclareCoeffPhysArrays)
102 const std::vector<unsigned int> &eIDs,
103 const bool DeclareCoeffPhysArrays,
105 ExpList(In,eIDs,DeclareCoeffPhysArrays)
137 const bool DeclareCoeffPhysArrays,
138 const std::string &var,
152 = graph2D->GetExpansions(var);
154 for (
auto &expIt : expansions)
159 if ((TriangleGeom = std::dynamic_pointer_cast<SpatialDomains
160 ::TriGeom>(expIt.second->m_geomShPtr)))
163 = expIt.second->m_basisKeyVector[0];
165 = expIt.second->m_basisKeyVector[1];
178 Ntri->SetElmtId(elmtid++);
179 (*m_exp).push_back(Ntri);
186 tri->SetElmtId(elmtid++);
187 (*m_exp).push_back(tri);
194 else if ((QuadrilateralGeom = std::dynamic_pointer_cast<
198 = expIt.second->m_basisKeyVector[0];
200 = expIt.second->m_basisKeyVector[1];
205 quad->SetElmtId(elmtid++);
206 (*m_exp).push_back(quad);
213 ASSERTL0(
false,
"dynamic cast to a proper Geometry2D " 220 for(
int i = 0; i < (*m_exp).size(); ++i)
222 (*m_exp)[i]->SetElmtId(i);
234 if (DeclareCoeffPhysArrays)
263 const bool DeclareCoeffPhysArrays,
276 for (
auto &expIt : expansions)
281 if ((TriangleGeom = std::dynamic_pointer_cast<SpatialDomains
282 ::TriGeom>(expIt.second->m_geomShPtr)))
285 = expIt.second->m_basisKeyVector[0];
287 = expIt.second->m_basisKeyVector[1];
300 Ntri->SetElmtId(elmtid++);
301 (*m_exp).push_back(Ntri);
308 tri->SetElmtId(elmtid++);
309 (*m_exp).push_back(tri);
316 else if ((QuadrilateralGeom = std::dynamic_pointer_cast<
320 = expIt.second->m_basisKeyVector[0];
322 = expIt.second->m_basisKeyVector[1];
327 quad->SetElmtId(elmtid++);
328 (*m_exp).push_back(quad);
335 ASSERTL0(
false,
"dynamic cast to a proper Geometry2D " 350 if (DeclareCoeffPhysArrays)
407 graph2D->GetExpansions();
413 for (
auto &expIt : expansions)
418 if ((TriangleGeom = std::dynamic_pointer_cast<SpatialDomains::
419 TriGeom>(expIt.second->m_geomShPtr)))
426 Ntri->SetElmtId(elmtid++);
427 (*m_exp).push_back(Ntri);
433 tri->SetElmtId(elmtid++);
434 (*m_exp).push_back(tri);
442 else if ((QuadrilateralGeom = std::dynamic_pointer_cast<
447 quad->SetElmtId(elmtid++);
448 (*m_exp).push_back(quad);
456 "dynamic cast to a proper Geometry2D failed");
498 const bool DeclareCoeffPhysArrays,
499 const std::string variable,
503 boost::ignore_unused(periodicFaces, variable);
507 int i, j, id, elmtid=0;
520 for (i = 0; i < bndCond.num_elements(); ++i)
522 if (bndCond[i]->GetBoundaryConditionType()
525 for (j = 0; j < bndConstraint[i]->GetExpSize(); ++j)
528 ->GetExp(j)->GetBasis(0)->GetBasisKey();
530 ->GetExp(j)->GetBasis(1)->GetBasisKey();
531 exp2D = bndConstraint[i]->GetExp(j)
536 if((FaceQuadGeom = std::dynamic_pointer_cast<
541 facesDone.insert(FaceQuadGeom->GetGlobalID());
542 FaceQuadExp->SetElmtId(elmtid++);
543 (*m_exp).push_back(FaceQuadExp);
546 else if((FaceTriGeom = std::dynamic_pointer_cast<
551 facesDone.insert(FaceTriGeom->GetGlobalID());
552 FaceTriExp->SetElmtId(elmtid++);
553 (*m_exp).push_back(FaceTriExp);
557 ASSERTL0(
false,
"dynamic cast to a proper face geometry failed");
565 LibUtilities::BasisKey> > > faceOrders;
567 for(i = 0; i < locexp.size(); ++i)
570 for (j = 0; j < exp3D->GetNfaces(); ++j)
572 FaceGeom = exp3D->
GetGeom3D()->GetFace(j);
573 id = FaceGeom->GetGlobalID();
575 if(facesDone.count(
id) != 0)
579 auto it = faceOrders.find(
id);
581 if (it == faceOrders.end())
583 LibUtilities::BasisKey face_dir0
584 = locexp[i]->DetFaceBasisKey(j,0);
585 LibUtilities::BasisKey face_dir1
586 = locexp[i]->DetFaceBasisKey(j,1);
592 std::make_pair(face_dir0, face_dir1))));
596 LibUtilities::BasisKey face0 =
597 locexp[i]->DetFaceBasisKey(j,0);
598 LibUtilities::BasisKey face1 =
599 locexp[i]->DetFaceBasisKey(j,1);
600 LibUtilities::BasisKey existing0 =
601 it->second.second.first;
602 LibUtilities::BasisKey existing1 =
603 it->second.second.second;
614 if ((np22 >= np12 || np21 >= np11) &&
615 (nm22 >= nm12 || nm21 >= nm11))
619 else if((np22 < np12 || np21 < np11) &&
620 (nm22 < nm12 || nm21 < nm11))
622 it->second.second.first = face0;
623 it->second.second.second = face1;
628 "inappropriate number of points/modes (max " 629 "num of points is not set with max order)");
636 int nproc = vComm->GetSize();
637 int facepr = vComm->GetRank();
644 for(i = 0; i < locexp.size(); ++i)
646 fCnt += locexp[i]->GetNfaces();
652 faceCnt[facepr] = fCnt;
658 for (i = 1; i < nproc; ++i)
660 fTotOffsets[i] = fTotOffsets[i-1] + faceCnt[i-1];
671 int cntr = fTotOffsets[facepr];
673 for(i = 0; i < locexp.size(); ++i)
679 for(j = 0; j < nfaces; ++j, ++cntr)
681 LibUtilities::BasisKey face_dir0
682 = locexp[i]->DetFaceBasisKey(j,0);
683 LibUtilities::BasisKey face_dir1
684 = locexp[i]->DetFaceBasisKey(j,1);
686 FacesTotID[cntr] = exp3D->GetGeom3D()->GetFid(j);
700 for (i = 0; i < totFaceCnt; ++i)
702 auto it = faceOrders.find(FacesTotID[i]);
704 if (it == faceOrders.end())
709 LibUtilities::BasisKey existing0 =
710 it->second.second.first;
711 LibUtilities::BasisKey existing1 =
712 it->second.second.second;
713 LibUtilities::BasisKey face0(
717 LibUtilities::BasisKey face1(
731 if ((np22 >= np12 || np21 >= np11) &&
732 (nm22 >= nm12 || nm21 >= nm11))
736 else if((np22 < np12 || np21 < np11) &&
737 (nm22 < nm12 || nm21 < nm11))
739 it->second.second.first = face0;
740 it->second.second.second = face1;
745 "inappropriate number of points/modes (max " 746 "num of points is not set with max order)");
751 for (
auto &it : faceOrders)
753 FaceGeom = it.second.first;
755 if ((FaceQuadGeom = std::dynamic_pointer_cast<
760 it.second.second.second,
762 FaceQuadExp->SetElmtId(elmtid++);
763 (*m_exp).push_back(FaceQuadExp);
765 else if ((FaceTriGeom = std::dynamic_pointer_cast<
770 it.second.second.second,
772 FaceTriExp->SetElmtId(elmtid++);
773 (*m_exp).push_back(FaceTriExp);
787 if(DeclareCoeffPhysArrays)
811 const std::string variable,
835 for (
auto &compIt : domain)
840 for (
auto &compIt : domain)
842 for (j = 0; j < compIt.second->m_geomVec.size(); ++j)
844 if ((TriangleGeom = std::dynamic_pointer_cast<
848 = graph3D->GetFaceBasisKey(TriangleGeom, 0, variable);
850 = graph3D->GetFaceBasisKey(TriangleGeom,1,variable);
852 if (graph3D->GetExpansions().begin()->second->
853 m_basisKeyVector[0].GetBasisType() ==
856 ASSERTL0(
false,
"This method needs sorting");
862 Ntri->SetElmtId(elmtid++);
863 (*m_exp).push_back(Ntri);
870 tri->SetElmtId(elmtid++);
871 (*m_exp).push_back(tri);
880 else if ((QuadrilateralGeom = std::dynamic_pointer_cast<
884 = graph3D->GetFaceBasisKey(QuadrilateralGeom, 0,
887 = graph3D->GetFaceBasisKey(QuadrilateralGeom, 1,
893 quad->SetElmtId(elmtid++);
894 (*m_exp).push_back(quad);
903 "dynamic cast to a proper Geometry2D failed");
936 int i,j,f_npoints,offset;
939 for(i = 0; i <
m_exp->size(); ++i)
942 f_npoints = (*m_exp)[i]->GetNumPoints(0)*
943 (*m_exp)[i]->GetNumPoints(1);
947 for(j = 0; j < f_npoints; ++j)
950 if(Vn[offset + j] > 0.0)
952 Upwind[offset + j] = Fwd[offset + j];
956 Upwind[offset + j] = Bwd[offset + j];
977 for (
int i = 0; i < nquad2; ++i)
979 for (
int j = 0; j < nquad1; ++j)
981 out[i*nquad1 + j] = in[j*nquad2 + i];
987 for (
int i = 0; i < nquad2; ++i)
989 for (
int j = 0; j < nquad1; ++j)
991 out[i*nquad1 + j] = in[i*nquad1 + j];
1002 for (
int i = 0; i < nquad2; ++i)
1004 for (
int j = 0; j < nquad1/2; ++j)
1006 swap(out[i*nquad1 + j],
1007 out[i*nquad1 + nquad1-j-1]);
1018 for (
int j = 0; j < nquad1; ++j)
1020 for (
int i = 0; i < nquad2/2; ++i)
1022 swap(out[i*nquad1 + j],
1023 out[(nquad2-i-1)*nquad1 + j]);
1044 ASSERTL1(normals.num_elements() >= coordim,
1045 "Output vector does not have sufficient dimensions to " 1049 for (i = 0; i <
m_exp->size(); ++i)
1057 int faceNum = traceExp->GetLeftAdjacentElementFace();
1061 = exp3D->GetFaceNormal(faceNum);
1068 int fromid0,fromid1;
1082 = exp3D->DetFaceBasisKey(faceNum, fromid0);
1084 = exp3D->DetFaceBasisKey(faceNum, fromid1);
1086 = traceExp->GetBasis(0)->GetBasisKey();
1088 = traceExp->GetBasis(1)->GetBasisKey();
1093 for (j = 0; j < coordim; ++j)
1097 locNormals[j], traceNormals);
1104 tmp = normals[j]+offset);
1115 for (i = 0; i <
m_exp->size(); ++i)
1117 for (j = 0; j < (*m_exp)[i]->GetNedges(); ++j)
1119 (*m_exp)[i]->ComputeEdgeNormal(j);
1146 std::ostream &outfile,
1150 boost::ignore_unused(istrip);
1153 int nquad0 = (*m_exp)[expansion]->GetNumPoints(0);
1154 int nquad1 = (*m_exp)[expansion]->GetNumPoints(1);
1155 int ntot = nquad0*nquad1;
1156 int ntotminus = (nquad0-1)*(nquad1-1);
1162 (*m_exp)[expansion]->GetCoords(coords[0],coords[1],coords[2]);
1164 outfile <<
" <Piece NumberOfPoints=\"" 1165 << ntot <<
"\" NumberOfCells=\"" 1166 << ntotminus <<
"\">" << endl;
1167 outfile <<
" <Points>" << endl;
1168 outfile <<
" <DataArray type=\"Float64\" " 1169 <<
"NumberOfComponents=\"3\" format=\"ascii\">" << endl;
1171 for (i = 0; i < ntot; ++i)
1173 for (j = 0; j < 3; ++j)
1175 outfile << setprecision(8) << scientific
1176 << (float)coords[j][i] <<
" ";
1181 outfile <<
" </DataArray>" << endl;
1182 outfile <<
" </Points>" << endl;
1183 outfile <<
" <Cells>" << endl;
1184 outfile <<
" <DataArray type=\"Int32\" " 1185 <<
"Name=\"connectivity\" format=\"ascii\">" << endl;
1186 for (i = 0; i < nquad0-1; ++i)
1188 for (j = 0; j < nquad1-1; ++j)
1190 outfile << j*nquad0 + i <<
" " 1191 << j*nquad0 + i + 1 <<
" " 1192 << (j+1)*nquad0 + i + 1 <<
" " 1193 << (j+1)*nquad0 + i << endl;
1197 outfile <<
" </DataArray>" << endl;
1198 outfile <<
" <DataArray type=\"Int32\" " 1199 <<
"Name=\"offsets\" format=\"ascii\">" << endl;
1200 for (i = 0; i < ntotminus; ++i)
1202 outfile << i*4+4 <<
" ";
1205 outfile <<
" </DataArray>" << endl;
1206 outfile <<
" <DataArray type=\"UInt8\" " 1207 <<
"Name=\"types\" format=\"ascii\">" << endl;
1208 for (i = 0; i < ntotminus; ++i)
1213 outfile <<
" </DataArray>" << endl;
1214 outfile <<
" </Cells>" << endl;
1215 outfile <<
" <PointData>" << endl;
1230 int pt0 = (*m_exp)[i]->GetNumPoints(0);
1231 int pt1 = (*m_exp)[i]->GetNumPoints(1);
1232 int npt0 = (int) pt0*scale;
1233 int npt1 = (int) pt1*scale;
1236 (*
m_exp)[i]->GetPointsType(0));
1238 (*
m_exp)[i]->GetPointsType(1));
1242 (*
m_exp)[i]->GetBasis(1)->GetPointsKey(),
1243 &inarray[cnt],newPointsKey0,
1244 newPointsKey1,&outarray[cnt1]);
1262 int pt0 = (*m_exp)[i]->GetNumPoints(0);
1263 int pt1 = (*m_exp)[i]->GetNumPoints(1);
1264 int npt0 = (int) pt0*scale;
1265 int npt1 = (int) pt1*scale;
1268 (*
m_exp)[i]->GetPointsType(0));
1270 (*
m_exp)[i]->GetPointsType(1));
1277 (*
m_exp)[i]->GetBasis(0)->GetPointsKey(),
1278 (*
m_exp)[i]->GetBasis(1)->GetPointsKey(),
int GetNumPoints() const
Return points order at which basis is defined.
#define ASSERTL0(condition, msg)
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Expansion3DSharedPtr GetLeftAdjacentElementExp() const
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
std::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
NekOptimize::GlobalOptParamSharedPtr m_globalOptParam
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
BasisType GetBasisType() const
Return type of expansion basis.
std::map< int, CompositeSharedPtr > CompositeMap
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
PointsKey GetPointsKey() const
Return distribution of points.
int GetExpSize(void)
This function returns the number of elements in the expansion.
virtual void v_PhysInterp1DScaled(const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual ~ExpList2D()
Destructor.
std::vector< ExpansionSharedPtr > ExpansionVector
std::shared_ptr< NodalTriExp > NodalTriExpSharedPtr
void Upwind(const Array< OneD, const Array< OneD, NekDouble > > &Vec, const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &Upwind)
void Interp2D(const BasisKey &fbasis0, const BasisKey &fbasis1, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, const BasisKey &tbasis1, Array< OneD, NekDouble > &to)
this function interpolates a 2D function evaluated at the quadrature points of the 2D basis...
std::shared_ptr< Expansion3D > Expansion3DSharedPtr
virtual void v_SetUpPhysNormals()
Set up the normals on each expansion.
Base class for all multi-elemental spectral/hp expansions.
std::shared_ptr< TriGeom > TriGeomSharedPtr
int GetNumModes() const
Returns the order of the basis.
SpatialDomains::Geometry2DSharedPtr GetGeom2D() const
Array< OneD, int > m_phys_offset
Offset of elemental data into the array m_phys.
PointsType GetPointsType() const
Return type of quadrature.
bool m_physState
The state of the array m_phys.
int m_ncoeffs
The total number of local degrees of freedom. m_ncoeffs .
void SetCoeffPhysOffsets()
Definition of the total number of degrees of freedom and quadrature points and offsets to access data...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Principle Orthogonal Functions .
LibUtilities::SessionReaderSharedPtr m_session
Session.
Defines a specification for a set of points.
std::vector< std::shared_ptr< Geometry > > m_geomVec
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
LibUtilities::CommSharedPtr m_comm
Communicator.
virtual void v_WriteVtkPieceHeader(std::ostream &outfile, int expansion, int istrip)
SpatialDomains::Geometry3DSharedPtr GetGeom3D() const
void v_GetNormals(Array< OneD, Array< OneD, NekDouble > > &normals)
For each local element, copy the normals stored in the element list into the array normals...
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
virtual void v_ReadGlobalOptimizationParameters()
ExpList2D()
Default constructor.
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
void ReadGlobalOptimizationParameters()
void v_Upwind(const Array< OneD, const NekDouble > &Vn, const Array< OneD, const NekDouble > &Fwd, const Array< OneD, const NekDouble > &Bwd, Array< OneD, NekDouble > &Upwind)
Upwind the Fwd and Bwd states based on the one- dimensional normal velocity field given by Vn...
std::shared_ptr< TriExp > TriExpSharedPtr
void CreateCollections(Collections::ImplementationType ImpType=Collections::eNoImpType)
Construct collections of elements containing a single element type and polynomial order from the list...
int GetNfaces() const
This function returns the number of faces of the expansion domain.
int GetCoordim(int eid)
This function returns the dimension of the coordinates of the element eid.
void SetExpType(ExpansionType Type)
Returns the type of the expansion.
virtual void v_PhysGalerkinProjection1DScaled(const NekDouble scale, const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
std::shared_ptr< QuadExp > QuadExpSharedPtr
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Describes the specification for a Basis.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
void PhysGalerkinProject2D(const BasisKey &fbasis0, const BasisKey &fbasis1, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, const BasisKey &tbasis1, Array< OneD, NekDouble > &to)
2D Nodal Electrostatic Points on a Triangle
std::map< int, ExpansionShPtr > ExpansionMap
void AlignFace(const StdRegions::Orientation orient, const int nquad1, const int nquad2, const Array< OneD, const NekDouble > &in, Array< OneD, NekDouble > &out)
Helper function to re-align face to a given orientation.