40 #include <boost/geometry.hpp>
48 #include <boost/lexical_cast.hpp>
49 #include <boost/math/special_functions/fpclassify.hpp>
51 namespace bg = boost::geometry;
52 namespace bgi = boost::geometry::index;
59 ModuleKey ProcessInterpPoints::className =
62 ProcessInterpPoints::create,
63 "Interpolates a set of points to another, requires fromfld and "
64 "fromxml to be defined, a line, plane or block of points can be "
71 false,
"NotSet",
"Xml file from which to interpolate field");
74 "Need to specify fromxml=file.xml");
77 false,
"NotSet",
"Fld file from which to interpolate field");
80 "Need to specify fromfld=file.fld ");
83 ConfigOption(
false,
"-10000000",
"Lower bound for interpolation value");
85 ConfigOption(
false,
"10000000",
"Upper bound for interpolation value");
87 ConfigOption(
false,
"0",
"Default value if point is outside domain");
89 ConfigOption(
false,
"NotSet",
"Specify a line of N points using "
90 "line=N,x0,y0,z0,z1,y1,z1");
92 false,
"NotSet",
"Specify a plane of N1 x N2 points using "
93 "plane=N1,N2,x0,y0,z0,z1,y1,z1,x2,y2,z2,x3,"
96 false,
"NotSet",
"Specify a rectangular box of N1 x N2 x N3 points "
97 "using a box of points limited by box="
98 "N1,N2,N3,xmin,xmax,ymin,ymax,zmin,zmax");
102 "Parameters p0 and q to determine pressure coefficients "
103 "(box only currently)");
114 if (
m_f->m_comm->TreatAsRankZero())
116 cout <<
"ProcessInterpPoints: interpolating to points..." << endl;
120 int rank =
m_f->m_comm->GetRank();
121 int nprocs =
m_f->m_comm->GetSize();
127 if (
m_config[
"line"].as<string>().compare(
"NotSet") != 0)
129 string help =
m_config[
"line"].as<
string>();
130 vector<NekDouble> values;
132 m_config[
"line"].as<string>().c_str(), values),
133 "Failed to interpret line string");
136 "line string should contain 2 Dim+1 values "
137 "N,x0,y0,z0,x1,y1,z1");
140 ASSERTL0(std::modf(values[0], &tmp) == 0.0,
"N is not an integer");
141 ASSERTL0(values[0] > 1,
"N is not a valid number");
143 int dim = (values.size() - 1) / 2;
144 int npts = values[0];
147 for (
int i = 0; i < dim; ++i)
152 for (
int i = 0; i <
npts; ++i)
156 i / ((
NekDouble)(npts - 1)) * (values[dim + 1] - values[1]);
159 pts[1][i] = values[2] +
161 (values[dim + 2] - values[2]);
165 pts[2][i] = values[3] +
167 (values[dim + 3] - values[3]);
178 m_f->m_fieldPts->SetPointsPerEdge(ppe);
180 else if (
m_config[
"plane"].as<string>().compare(
"NotSet") != 0)
182 string help =
m_config[
"plane"].as<
string>();
183 vector<NekDouble> values;
185 m_config[
"plane"].as<string>().c_str(), values),
186 "Failed to interpret plane string");
189 "plane string should contain 4 Dim+2 values "
190 "N1,N2,x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3");
193 ASSERTL0(std::modf(values[0], &tmp) == 0.0,
"N1 is not an integer");
194 ASSERTL0(std::modf(values[1], &tmp) == 0.0,
"N2 is not an integer");
196 ASSERTL0(values[0] > 1,
"N1 is not a valid number");
197 ASSERTL0(values[1] > 1,
"N2 is not a valid number");
199 int dim = (values.size() - 2) / 4;
201 int npts1 = values[0];
202 int npts2 = values[1];
206 int totpts = npts1 * npts2;
207 int nlocpts = totpts / nprocs;
209 if (rank < nprocs - 1)
211 for (
int i = 0; i < dim; ++i)
219 for (
int j = 0; j < npts2; ++j)
221 for (
int i = 0; i < npts1; ++i)
224 if ((cnt >= rank * nlocpts) &&
225 (cnt < (rank + 1) * nlocpts))
230 (values[dim + 2] - values[2])) *
232 (values[3 * dim + 2] +
234 (values[2 * dim + 2] -
235 values[3 * dim + 2])) *
241 (values[dim + 3] - values[3])) *
243 (values[3 * dim + 3] +
245 (values[2 * dim + 3] -
246 values[3 * dim + 3])) *
254 (values[dim + 4] - values[4])) *
256 (values[3 * dim + 4] +
258 (values[2 * dim + 4] -
259 values[3 * dim + 4])) *
270 totpts = totpts - rank * nlocpts;
272 for (
int i = 0; i < dim; ++i)
280 for (
int j = 0; j < npts2; ++j)
282 for (
int i = 0; i < npts1; ++i)
285 if (cnt >= rank * nlocpts)
290 (values[dim + 2] - values[2])) *
292 (values[3 * dim + 2] +
294 (values[2 * dim + 2] -
295 values[3 * dim + 2])) *
301 (values[dim + 3] - values[3])) *
303 (values[3 * dim + 3] +
305 (values[2 * dim + 3] -
306 values[3 * dim + 3])) *
314 (values[dim + 4] - values[4])) *
316 (values[3 * dim + 4] +
318 (values[2 * dim + 4] -
319 values[3 * dim + 4])) *
330 ppe.push_back(npts1);
331 ppe.push_back(npts2);
336 m_f->m_fieldPts->SetPointsPerEdge(ppe);
338 else if (
m_config[
"box"].as<string>().compare(
"NotSet") != 0)
340 string help =
m_config[
"box"].as<
string>();
341 vector<NekDouble> values;
343 m_config[
"box"].as<string>().c_str(), values),
344 "Failed to interpret box string");
347 "box string should contain 9 values "
348 "N1,N2,N3,xmin,xmax,ymin,ymax,zmin,zmax");
352 int npts1 = values[0];
353 int npts2 = values[1];
354 int npts3 = values[2];
358 int totpts = npts1 * npts2 * npts3;
359 int nlocpts = totpts / nprocs;
361 if (rank < nprocs - 1)
365 for (
int i = 0; i < dim; ++i)
373 for (
int k = 0; k < npts3; ++k)
375 for (
int j = 0; j < npts2; ++j)
377 for (
int i = 0; i < npts1; ++i)
379 if ((cnt >= rank * nlocpts) &&
380 (cnt < (rank + 1) * nlocpts))
382 pts[0][cntloc] = values[3] +
384 (values[4] - values[3]);
385 pts[1][cntloc] = values[5] +
387 (values[6] - values[5]);
388 pts[2][cntloc] = values[7] +
390 (values[8] - values[7]);
400 totpts = totpts - rank * nlocpts;
402 for (
int i = 0; i < dim; ++i)
410 for (
int k = 0; k < npts3; ++k)
412 for (
int j = 0; j < npts2; ++j)
414 for (
int i = 0; i < npts1; ++i)
416 if (cnt >= rank * nlocpts)
418 pts[0][cntloc] = values[3] +
420 (values[4] - values[3]);
421 pts[1][cntloc] = values[5] +
423 (values[6] - values[5]);
424 pts[2][cntloc] = values[7] +
426 (values[8] - values[7]);
436 ppe.push_back(npts1);
437 ppe.push_back(npts2);
438 ppe.push_back(npts3);
443 m_f->m_fieldPts->SetPointsPerEdge(ppe);
444 vector<NekDouble> boxdim;
445 boxdim.assign(&values[3], &values[3] + 6);
446 m_f->m_fieldPts->SetBoxSize(boxdim);
452 std::vector<std::string> files;
455 fromField->m_session =
462 int coordim =
m_f->m_fieldPts->GetDim();
463 int npts =
m_f->m_fieldPts->GetNpoints();
465 m_f->m_fieldPts->GetPts(pts);
467 rng->m_checkShape =
false;
475 rng->m_doZrange =
true;
478 if (rng->m_zmax == rng->m_zmin)
484 rng->m_doYrange =
true;
488 rng->m_doXrange =
true;
493 ASSERTL0(
false,
"too many values specfied in range");
502 fromField->m_graph->GetExpansions();
505 SpatialDomains::ExpansionMap::const_iterator expIt;
508 for (expIt = expansions.begin(); expIt != expansions.end(); ++expIt)
510 ElementGIDs[i++] = expIt->second->m_geomShPtr->GetGlobalID();
515 ASSERTL0(i > 0,
"No elements are set. Are the interpolated points "
516 "wihtin the domain given by the xml files?");
518 string fromfld =
m_config[
"fromfld"].as<
string>();
519 m_f->FieldIOForFile(fromfld)->Import(
520 fromfld, fromField->m_fielddef, fromField->m_data,
523 int NumHomogeneousDir = fromField->m_fielddef[0]->m_numHomogeneousDir;
527 fromField->m_graph->SetExpansions(fromField->m_fielddef);
529 int nfields = fromField->m_fielddef[0]->m_fields.size();
531 fromField->m_exp.resize(nfields);
532 fromField->m_exp[0] = fromField->SetUpFirstExpList(NumHomogeneousDir,
true);
534 m_f->m_exp.resize(nfields);
537 for (i = 1; i < nfields; ++i)
539 fromField->m_exp[i] = fromField->AppendExpList(NumHomogeneousDir);
543 for (
int j = 0; j < nfields; ++j)
545 for (i = 0; i < fromField->m_fielddef.size(); i++)
547 fromField->m_exp[j]->ExtractDataToCoeffs(
548 fromField->m_fielddef[i], fromField->m_data[i],
549 fromField->m_fielddef[0]->m_fields[j],
550 fromField->m_exp[j]->UpdateCoeffs());
552 fromField->m_exp[j]->BwdTrans(fromField->m_exp[j]->GetCoeffs(),
553 fromField->m_exp[j]->UpdatePhys());
556 m_f->m_fieldPts->AddField(newPts,
557 fromField->m_fielddef[0]->m_fields[j]);
565 clamp_up, def_value);
567 if (!boost::iequals(
m_config[
"cp"].as<string>(),
"NotSet"))
574 vector<MultiRegions::ExpListSharedPtr> &field0,
580 ASSERTL0(pts->GetNFields() >= field0.size(),
"ptField has too few fields");
582 int nfields = field0.size();
585 if (
m_f->m_comm->GetRank() == 0)
591 if (
m_f->m_comm->GetRank() == 0)
596 for (
int f = 0; f < nfields; ++f)
598 for (
int i = 0; i < pts->GetNpoints(); ++i)
600 if (pts->GetPointVal(f, i) > clamp_up)
602 pts->SetPointVal(f, i, clamp_up);
604 else if (pts->GetPointVal(f, i) < clamp_low)
606 pts->SetPointVal(f, i, clamp_low);
615 int dim = pts->GetDim();
616 int nq1 = pts->GetNpoints();
622 vector<NekDouble> values;
624 m_config[
"cp"].as<string>().c_str(),values),
625 "Failed to interpret cp string");
628 "cp string should contain 2 values "
629 "p0 and q (=1/2 rho u^2)");
632 qinv = 1.0/values[1];
634 for(
int i = 0; i < pts->GetNFields(); ++i)
636 if(boost::iequals(pts->GetFieldName(i),
"p"))
641 if(boost::iequals(pts->GetFieldName(i),
"u")||
642 boost::iequals(pts->GetFieldName(i),
"v")||
643 boost::iequals(pts->GetFieldName(i),
"w"))
653 WARNINGL0(
false,
"Did not find velocity components for Cp0");
658 WARNINGL0(
false,
"Failed to find 'p' field to determine cp0");
664 for (f = 0; f < 2; ++f)
669 for (r = 0; r < nq1; r++)
673 data[0][r] = qinv*(pts->GetPointVal(dim + pfield, r) - p0);
678 for(
int i = 0; i < velid.size(); ++i)
680 q += 0.5*pts->GetPointVal(dim + velid[i], r)*
681 pts->GetPointVal(dim + velid[i], r);
683 data[1][r] = qinv*(pts->GetPointVal(dim + pfield, r)+q - p0);
690 pts->AddField(data[0],
"Cp");
693 pts->AddField(data[1],
"Cp0");
699 const int goal)
const
map< string, ConfigOption > m_config
List of configuration values.
#define ASSERTL0(condition, msg)
virtual ~ProcessInterpPoints()
static bool GenerateOrderedStringVector(const char *const str, std::vector< std::string > &vec)
A class that contains algorithms for interpolation between pts fields, expansions and different meshe...
void SetProgressCallback(FuncPointerT func, ObjectPointerT obj)
sets a callback funtion which gets called every time the interpolation progresses ...
int PrintProgressbar(const int position, const int goal, const string message, int lastprogress=-1)
Prints a progressbar.
static boost::shared_ptr< MeshGraph > Read(const LibUtilities::SessionReaderSharedPtr &pSession, DomainRangeShPtr &rng=NullDomainRangeShPtr)
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
Represents a command-line configuration option.
FIELD_UTILS_EXPORT void Interpolate(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
Interpolate from a pts field to a pts field.
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
pair< ModuleType, string > ModuleKey
boost::shared_ptr< PtsField > PtsFieldSharedPtr
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
virtual void Process(po::variables_map &vm)
Write mesh to output file.
boost::shared_ptr< Field > FieldSharedPtr
#define WARNINGL0(condition, msg)
boost::shared_ptr< DomainRange > DomainRangeShPtr
static PtsFieldSharedPtr NullPtsField
void PrintProgressbar(const int position, const int goal) const
static bool GenerateUnOrderedVector(const char *const str, std::vector< NekDouble > &vec)
Abstract base class for processing modules.
static FieldMetaDataMap NullFieldMetaDataMap
void InterpolateFieldToPts(vector< MultiRegions::ExpListSharedPtr > &field0, LibUtilities::PtsFieldSharedPtr &pts, NekDouble clamp_low, NekDouble clamp_up, NekDouble def_value)
std::map< int, ExpansionShPtr > ExpansionMap
ModuleFactory & GetModuleFactory()
FieldSharedPtr m_f
Field object.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.