36 #include <boost/geometry.hpp>
41 namespace bg = boost::geometry;
42 namespace bgi = boost::geometry::index;
63 void Interpolator::Interpolate(
64 const vector<MultiRegions::ExpListSharedPtr> expInField,
65 vector<MultiRegions::ExpListSharedPtr> &expOutField,
68 ASSERTL0(expInField.size() == expOutField.size(),
69 "number of fields does not match");
70 ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
71 "too many dimesions in inField");
72 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
73 "too many dimesions in outField");
75 "only direct evaluation supported for this interpolation");
77 m_expInField = expInField;
78 m_expOutField = expOutField;
80 int nFields = max((
int)expInField.size(), (
int)m_expOutField.size());
81 int nOutPts = m_expOutField[0]->GetTotPoints();
92 int outDim = m_expOutField[0]->GetCoordim(0) + outNumHomDir;
96 for (
int i = 0; i < outDim; ++i)
102 m_expOutField[0]->GetCoords(pts[0]);
104 else if (outDim == 2)
106 m_expOutField[0]->GetCoords(pts[0], pts[1]);
108 else if (outDim == 3)
110 m_expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
115 for (
int f = 0; f < expOutField.size(); ++f)
117 tmpPts->AddField(m_expOutField[f]->GetPhys(),
"DefaultVar");
121 Interpolate(m_expInField, tmpPts, def_value);
124 for (
int i = 0; i < nFields; i++)
126 int ptsi = outDim + i;
127 for (
int j = 0; j < nOutPts; ++j)
129 m_expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
145 void Interpolator::Interpolate(
146 const vector<MultiRegions::ExpListSharedPtr> expInField,
150 ASSERTL0(expInField.size() == ptsOutField->GetNFields(),
151 "number of fields does not match");
152 ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
153 "too many dimesions in inField");
154 ASSERTL0(ptsOutField->GetDim() <= GetDim(),
155 "too many dimesions in outField");
156 ASSERTL0(ptsOutField->GetDim() >= expInField[0]->GetCoordim(0),
157 "too few dimesions in outField");
159 "only direct evaluation supported for this interpolation");
161 "interpolation from 3DH2D expansion unsupported");
163 m_expInField = expInField;
164 m_ptsOutField = ptsOutField;
166 int nInDim = expInField[0]->GetCoordim(0);
167 int nOutPts = m_ptsOutField->GetNpoints();
171 for (
int i = 0; i < nOutPts; ++i)
175 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
177 coords[j] = m_ptsOutField->GetPointVal(j, i);
181 elmtid = m_expInField[0]->GetExpIndex(
189 for(
int j = 0; j < nInDim; ++j)
191 Lcoords[j] = std::max(Lcoords[j], -1.0);
192 Lcoords[j] = std::min(Lcoords[j], 1.0);
197 int offset = m_expInField[0]->GetPhys_Offset(elmtid);
199 for (
int f = 0; f < m_expInField.size(); ++f)
205 ASSERTL0(m_expInField[f]->GetWaveSpace(),
206 "interpolation from 3DH1D/2DH1D requires field in wavespace");
207 NekDouble lHom = m_expInField[f]->GetHomoLen();
208 NekDouble BetaT = 2.*M_PI*fmod (coords[nInDim], lHom) / lHom;
209 int nPlanes = m_expInField[f]->GetHomogeneousBasis()->GetZ().size();
213 for (
size_t n = 0; n < planes.size(); ++n)
215 auto planeExp = m_expInField[f]->GetPlane(planes[n]);
216 coeff = planeExp->GetExp(elmtid)->StdPhysEvaluate(
217 Lcoords, planeExp->GetPhys() + offset);
222 else if (planes[n] == 1)
224 value += cos(0.5*nPlanes*BetaT)*coeff;
226 else if (planes[n]%2 == 0)
228 NekDouble phase = (planes[n]>>1) * BetaT;
229 value += cos(phase)*coeff;
233 NekDouble phase = (planes[n]>>1) * BetaT;
234 value += - sin(phase)*coeff;
240 value = m_expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
241 Lcoords, m_expInField[f]->GetPhys() + offset);
244 if ((boost::math::isnan)(value))
246 ASSERTL0(
false,
"new value is not a number");
250 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
257 for (
int f = 0; f < m_expInField.size(); ++f)
259 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
264 int progress = int(100 * i / nOutPts);
265 if (m_progressCallback && progress > lastProg)
267 m_progressCallback(i, nOutPts);
281 void Interpolator::Interpolate(
283 vector<MultiRegions::ExpListSharedPtr> &expOutField)
285 ASSERTL0(expOutField.size() == ptsInField->GetNFields(),
286 "number of fields does not match");
287 ASSERTL0(ptsInField->GetDim() <= GetDim(),
"too many dimesions in inField");
288 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
289 "too many dimesions in outField");
291 m_ptsInField = ptsInField;
292 m_expOutField = expOutField;
294 int nFields = max((
int)ptsInField->GetNFields(), (
int)m_expOutField.size());
295 int nOutPts = m_expOutField[0]->GetTotPoints();
296 int outNumHomDir = 0;
306 int outDim = m_expOutField[0]->GetCoordim(0) + outNumHomDir;
310 for (
int i = 0; i < outDim; ++i)
316 m_expOutField[0]->GetCoords(pts[0]);
318 else if (outDim == 2)
320 m_expOutField[0]->GetCoords(pts[0], pts[1]);
322 else if (outDim == 3)
324 m_expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
329 for (
int f = 0; f < expOutField.size(); ++f)
331 tmpPts->AddField(m_expOutField[f]->GetPhys(),
332 m_ptsInField->GetFieldName(f));
336 LibUtilities::Interpolator::Interpolate(m_ptsInField, tmpPts);
339 for (
int i = 0; i < nFields; i++)
341 int ptsi = outDim + i;
342 for (
int j = 0; j < nOutPts; ++j)
344 m_expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
349 void Interpolator::Interpolate(
353 LibUtilities::Interpolator::Interpolate(ptsInField, ptsOutField);
#define ASSERTL0(condition, msg)
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< PtsField > PtsFieldSharedPtr
static const NekDouble kGeomFactorsTol
The above copyright notice and this permission notice shall be included.