44 #include <boost/math/special_functions/fpclassify.hpp>
53 ModuleKey ProcessEquiSpacedOutput::className =
56 ProcessEquiSpacedOutput::create,
57 "Write data as equi-spaced output using simplices to represent the data for connecting points");
63 f->m_setUpEquiSpacedFields =
true;
66 "Only process tetrahedral elements");
86 if(
m_f->m_comm->TreatAsRankZero())
88 cout <<
"Interpolating fields to equispaced..." << endl;
92 int coordim =
m_f->m_exp[0]->GetCoordim(0);
93 int shapedim =
m_f->m_exp[0]->GetExp(0)->GetShapeDimension();
94 int npts =
m_f->m_exp[0]->GetTotPoints();
97 int nel =
m_f->m_exp[0]->GetExpSize();
100 bool homogeneous1D =
false;
101 if (
m_f->m_fielddef.size())
103 if (
m_f->m_fielddef[0]->m_numHomogeneousDir == 1)
105 ASSERTL0(shapedim==2,
"Homogeneous only implemented for 3DH1D");
108 homogeneous1D =
true;
110 else if(
m_f->m_fielddef[0]->m_numHomogeneousDir == 2)
112 ASSERTL0(
false,
"Homegeneous2D case not supported");
117 if(
m_f->m_session->DefinesSolverInfo(
"HOMOGENEOUS"))
119 std::string HomoStr =
m_f->m_session->GetSolverInfo(
"HOMOGENEOUS");
121 if((HomoStr ==
"HOMOGENEOUS1D") || (HomoStr ==
"Homogeneous1D")
122 || (HomoStr ==
"1D") || (HomoStr ==
"Homo1D"))
124 ASSERTL0(shapedim==2,
"Homogeneous only implemented for 3DH1D");
127 homogeneous1D =
true;
129 if((HomoStr ==
"HOMOGENEOUS2D") || (HomoStr ==
"Homogeneous2D")
130 || (HomoStr ==
"2D") || (HomoStr ==
"Homo2D"))
132 ASSERTL0(
false,
"Homegeneous2D case not supported");
139 int newtotpoints = 0;
147 map<int,StdRegions::Orientation > face0orient;
148 set<int> prismorient;
152 vector<std::string> fieldNames;
154 vector<Array<OneD, int> > ptsConn;
157 for(
int i = 0; i < nel; ++i)
159 e =
m_f->m_exp[0]->GetExp(i);
163 int fid = e->GetGeom()->GetFid(0);
164 if(face0orient.count(fid))
166 prismorient.insert(i);
186 for(
int i = 0; i < nel; ++i)
188 e =
m_f->m_exp[0]->GetExp(i);
191 int fid = e->GetGeom()->GetFid(2);
193 if(face0orient.count(fid))
208 prismorient.insert(i);
215 prismorient.insert(i);
222 for(
int i = 0; i < nel; ++i)
224 e =
m_f->m_exp[0]->GetExp(i);
227 if(
m_f->m_exp[0]->GetExp(i)->DetShapeType() !=
234 switch(e->DetShapeType())
238 int npoints0 = e->GetBasis(0)->GetNumPoints();
246 int np0 = e->GetBasis(0)->GetNumPoints();
247 int np1 = e->GetBasis(1)->GetNumPoints();
248 int np = max(np0,np1);
255 int np0 = e->GetBasis(0)->GetNumPoints();
256 int np1 = e->GetBasis(1)->GetNumPoints();
257 int np = max(np0,np1);
265 int np0 = e->GetBasis(0)->GetNumPoints();
266 int np1 = e->GetBasis(1)->GetNumPoints();
267 int np2 = e->GetBasis(2)->GetNumPoints();
268 int np = max(np0,max(np1,np2));
276 int np0 = e->GetBasis(0)->GetNumPoints();
277 int np1 = e->GetBasis(1)->GetNumPoints();
278 int np2 = e->GetBasis(2)->GetNumPoints();
279 int np = max(np0,max(np1,np2));
287 int np0 = e->GetBasis(0)->GetNumPoints();
288 int np1 = e->GetBasis(1)->GetNumPoints();
289 int np2 = e->GetBasis(2)->GetNumPoints();
290 int np = max(np0,max(np1,np2));
298 int np0 = e->GetBasis(0)->GetNumPoints();
299 int np1 = e->GetBasis(1)->GetNumPoints();
300 int np2 = e->GetBasis(2)->GetNumPoints();
301 int np = max(np0,max(np1,np2));
313 ppe.push_back(newpoints);
314 newtotpoints += newpoints;
319 bool standard =
true;
321 if(prismorient.count(i))
326 e->GetSimplexEquiSpacedConnectivity(conn,standard);
331 if((prevNcoeffs != e->GetNcoeffs()) ||
332 (prevNpoints != e->GetTotPoints()))
334 prevNcoeffs = e->GetNcoeffs();
335 prevNpoints = e->GetTotPoints();
337 e->GetSimplexEquiSpacedConnectivity(conn);
341 for(
int j = 0; j < conn.num_elements(); ++j)
343 newconn[j] = conn[j] + cnt;
346 ptsConn.push_back(newconn);
350 if(
m_f->m_fielddef.size())
352 nfields =
m_f->m_exp.size();
361 for(
int i = 0; i < nfields + coordim; ++i)
367 for(
int i = 0; i < coordim; ++i)
372 for(
int i = coordim; i < 3; ++i)
377 m_f->m_exp[0]->GetCoords(coords[0],coords[1],coords[2]);
379 int nq1 =
m_f->m_exp[0]->GetTotPoints();
385 m_f->m_exp[0]->GetCoords(x1, y1, z1);
390 for(
int n = 0; n < coordim; ++n)
394 for(
int i = 0; i < nel; ++i)
396 m_f->m_exp[0]->GetExp(i)->PhysInterpToSimplexEquiSpaced(
398 tmp = pts[n] + cnt1);
400 cnt +=
m_f->m_exp[0]->GetExp(i)->GetTotPoints();
404 if(
m_f->m_fielddef.size())
406 ASSERTL0(
m_f->m_fielddef[0]->m_fields.size() ==
m_f->m_exp.size(),
407 "More expansion defined than fields");
409 for(
int n = 0; n <
m_f->m_exp.size(); ++n)
414 if(
m_config[
"modalenergy"].m_beenSet)
417 for(
int i = 0; i < nel; ++i)
421 cnt +=
m_f->m_exp[0]->GetExp(i)->GetTotPoints();
427 for(
int i = 0; i < nel; ++i)
429 m_f->m_exp[0]->GetExp(i)->PhysInterpToSimplexEquiSpaced(
431 tmp = pts[coordim + n] + cnt1);
433 cnt +=
m_f->m_exp[0]->GetExp(i)->GetTotPoints();
438 fieldNames.push_back(
m_f->m_fielddef[0]->m_fields[n]);
447 else if (shapedim == 3)
451 m_f->m_fieldPts->SetConnectivity(ptsConn);
461 int nel =
m_f->m_exp[0]->GetPlane(0)->GetExpSize();
462 int nPlanes =
m_f->m_exp[0]->GetZIDs().num_elements();
463 int npts =
m_f->m_fieldPts->GetNpoints();
464 int nptsPerPlane = npts/nPlanes;
466 if (
m_f->m_exp[0]->GetHomogeneousBasis()->GetBasisType() ==
468 &&
m_f->m_exp[0]->GetHomogeneousBasis()->GetPointsType() ==
473 m_f->m_fieldPts->GetPts(pts);
475 for (
int i = 0; i < pts.num_elements(); i++)
482 if (
m_f->m_comm->GetColumnComm()->GetSize() == 1)
488 pts[i], 1, extraPlane, 1);
498 int size =
m_f->m_comm->GetColumnComm()->GetSize();
499 int rank =
m_f->m_comm->GetColumnComm()->GetRank();
500 int fromRank = (rank+1) % size;
501 int toRank = (rank == 0) ? size-1 : rank-1;
504 m_f->m_comm->GetColumnComm()->SendRecv(toRank, send,
505 fromRank, extraPlane);
507 if (i == 2 && (rank == size - 1) )
510 extraPlane, 1, extraPlane, 1);
514 m_f->m_fieldPts->SetPts(newPts);
516 vector<Array<OneD, int> > oldConn;
518 m_f->m_fieldPts->GetConnectivity(oldConn);
519 vector<Array<OneD, int> > newConn = oldConn;
520 int connPerPlane = oldConn.size()/nPlanes;
521 for (
int i = 0; i < connPerPlane; i++)
524 for (
int j = 0; j < conn.num_elements(); j++)
526 conn[j] = oldConn[i][j] +
npts;
528 newConn.push_back(conn);
530 m_f->m_fieldPts->SetConnectivity(newConn);
533 npts += nptsPerPlane;
538 for(
int i = 0; i < nel; ++i)
540 e =
m_f->m_exp[0]->GetPlane(0)->GetExp(i);
542 int np0 = e->GetBasis(0)->GetNumPoints();
543 int np1 = e->GetBasis(1)->GetNumPoints();
544 int np = max(np0,np1);
545 maxN = max(np, maxN);
552 for(
int i = 0; i < nel; ++i)
554 e =
m_f->m_exp[0]->GetPlane(0)->GetExp(i);
555 int np0 = e->GetBasis(0)->GetNumPoints();
556 int np1 = e->GetBasis(1)->GetNumPoints();
557 int np = max(np0,np1);
558 switch(e->DetShapeType())
566 vId[cnt1] = e->GetGeom()->GetVid(0);
567 vId[cnt1+np-1] = e->GetGeom()->GetVid(1);
568 vId[cnt1+newpoints-1] = e->GetGeom()->GetVid(2);
574 for (
int n = 1; n < np-1; n++)
577 edgeOrient = e->GetGeom()->GetEorient(0);
580 vId[cnt1+n] = 4*nel + maxN*e->GetGeom()->GetEid(0) + n;
584 vId[cnt1+np-1-n] = 4*nel +
585 maxN*e->GetGeom()->GetEid(0) + n;
589 edgeOrient = e->GetGeom()->GetEorient(1);
593 vId[cnt1+np-1+edge1] = 4*nel +
594 maxN*e->GetGeom()->GetEid(1) + n;
599 vId[cnt1+newpoints-1-edge1] = 4*nel +
600 maxN*e->GetGeom()->GetEid(1) + n;
604 edgeOrient = e->GetGeom()->GetEorient(2);
608 vId[cnt1+newpoints-1-edge2] = 4*nel +
609 maxN*e->GetGeom()->GetEid(2) + n;
614 vId[cnt1+edge2] = 4*nel +
615 maxN*e->GetGeom()->GetEid(2) + n;
621 for (
int n = 1; n < np-1; n++)
623 for (
int m = 1; m < np-n-1; m++)
625 vId[cnt1+mode] = 4*nel + maxN*4*nel + cnt2;
638 vId[cnt1] = e->GetGeom()->GetVid(0);
639 vId[cnt1+np-1] = e->GetGeom()->GetVid(1);
640 vId[cnt1+np*np-1] = e->GetGeom()->GetVid(2);
641 vId[cnt1+np*(np-1)] = e->GetGeom()->GetVid(3);
645 for (
int n = 1; n < np-1; n++)
648 edgeOrient = e->GetGeom()->GetEorient(0);
651 vId[cnt1+n] = 4*nel + maxN*e->GetGeom()->GetEid(0) + n;
655 vId[cnt1+np-1-n] = 4*nel +
656 maxN*e->GetGeom()->GetEid(0) + n;
660 edgeOrient = e->GetGeom()->GetEorient(1);
663 vId[cnt1+np-1+n*np] = 4*nel +
664 maxN*e->GetGeom()->GetEid(1) + n;
668 vId[cnt1+np*np-1-n*np] = 4*nel +
669 maxN*e->GetGeom()->GetEid(1) + n;
673 edgeOrient = e->GetGeom()->GetEorient(2);
676 vId[cnt1+np*np-1-n] = 4*nel +
677 maxN*e->GetGeom()->GetEid(2) + n;
681 vId[cnt1+np*(np-1)+n] = 4*nel +
682 maxN*e->GetGeom()->GetEid(2) + n;
686 edgeOrient = e->GetGeom()->GetEorient(3);
689 vId[cnt1+np*(np-1)-n*np] = 4*nel +
690 maxN*e->GetGeom()->GetEid(3) + n;
694 vId[cnt1+n*np] = 4*nel +
695 maxN*e->GetGeom()->GetEid(3) + n;
700 for (
int n = 1; n < np-1; n++)
702 for (
int m = 1; m < np-1; m++)
704 vId[cnt1+m*np+n] = 4*nel + maxN*4*nel + cnt2;
719 vector<Array<OneD, int> > oldConn;
720 vector<Array<OneD, int> > newConn;
722 m_f->m_fieldPts->GetConnectivity(oldConn);
724 for(
int i = 0; i < nel; ++i)
726 int nTris = oldConn[i].num_elements()/3;
731 for(
int n = 0; n<nTris; n++)
734 int vId0 = vId[oldConn[i][3*n+0]];
735 int vId1 = vId[oldConn[i][3*n+1]];
736 int vId2 = vId[oldConn[i][3*n+2]];
740 if ( (vId0<vId1) && (vId0<vId2))
754 else if ( (vId1<vId0) && (vId1<vId2))
784 for (
int p = 0; p<nPlanes-1; p++)
786 conn[cnt2++] = oldConn[i+ p *nel][3*n+rot[0]];
787 conn[cnt2++] = oldConn[i+ p *nel][3*n+rot[1]];
788 conn[cnt2++] = oldConn[i+ p *nel][3*n+rot[2]];
789 conn[cnt2++] = oldConn[i+(p+1)*nel][3*n+rot[2]];
791 conn[cnt2++] = oldConn[i+ p *nel][3*n+rot[0]];
792 conn[cnt2++] = oldConn[i+ p *nel][3*n+rot[1]];
793 conn[cnt2++] = oldConn[i+(p+1)*nel][3*n+rot[2]];
794 conn[cnt2++] = oldConn[i+(p+1)*nel][3*n+rot[1]];
796 conn[cnt2++] = oldConn[i+ p *nel][3*n+rot[0]];
797 conn[cnt2++] = oldConn[i+(p+1)*nel][3*n+rot[1]];
798 conn[cnt2++] = oldConn[i+(p+1)*nel][3*n+rot[2]];
799 conn[cnt2++] = oldConn[i+(p+1)*nel][3*n+rot[0]];
802 newConn.push_back(conn);
804 m_f->m_fieldPts->SetConnectivity(newConn);
814 e =
m_f->m_exp[0]->GetExp(n);
816 switch(e->DetShapeType())
820 int np0 = e->GetBasis(0)->GetNumPoints();
821 int np1 = e->GetBasis(1)->GetNumPoints();
822 int np = max(np0,np1);
836 e->GetBasis(1)->GetBasisKey(),
844 int np0 = e->GetBasis(0)->GetNumPoints();
845 int np1 = e->GetBasis(1)->GetNumPoints();
846 int np = max(np0,np1);
858 e->GetBasis(1)->GetBasisKey(),
865 ASSERTL0(
false,
"Shape needs setting up");
#define ASSERTL0(condition, msg)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
pair< ModuleType, string > ModuleKey
static Array< OneD, NekDouble > NullNekDouble1DArray
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
void SetupEquiSpacedField(void)
map< string, ConfigOption > m_config
List of configuration values.
void GenOrthoModes(int n, const Array< OneD, const NekDouble > &phys, Array< OneD, NekDouble > &coeffs)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
FieldSharedPtr m_f
Field object.
Principle Orthogonal Functions .
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...
1D Evenly-spaced points using Fourier Fit
int getNumberOfCoefficients(int Na)
int getNumberOfCoefficients(int Na, int Nb)
Principle Orthogonal Functions .
Defines a specification for a set of points.
boost::shared_ptr< Expansion > ExpansionSharedPtr
boost::shared_ptr< Field > FieldSharedPtr
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
Represents a command-line configuration option.
int getNumberOfCoefficients(int Na, int Nb, int Nc)
virtual ~ProcessEquiSpacedOutput()
int getNumberOfCoefficients(int Na, int Nb)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
void SetHomogeneousConnectivity(void)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Describes the specification for a Basis.
ModuleFactory & GetModuleFactory()
Abstract base class for processing modules.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Forward transformation from physical space to coefficient space...