37#include <boost/geometry.hpp>
41namespace bg = boost::geometry;
42namespace bgi = boost::geometry::index;
67 ASSERTL0(expInField.size() == expOutField.size(),
68 "number of fields does not match");
69 ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
70 "too many dimensions in inField");
71 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
72 "too many dimensions in outField");
74 "only direct evaluation supported for this interpolation");
76 int nFields = max((
int)expInField.size(), (
int)expOutField.size());
77 int nOutPts = expOutField[0]->GetTotPoints();
88 int outDim = expOutField[0]->GetCoordim(0) + outNumHomDir;
92 for (
int i = 0; i < outDim; ++i)
98 expOutField[0]->GetCoords(pts[0]);
100 else if (outDim == 2)
102 expOutField[0]->GetCoords(pts[0], pts[1]);
104 else if (outDim == 3)
106 expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
111 for (
int f = 0; f < expOutField.size(); ++f)
113 tmpPts->AddField(expOutField[f]->GetPhys(),
"DefaultVar");
116 Interpolate(expInField, tmpPts, def_value);
118 for (
int i = 0; i < nFields; i++)
120 int ptsi = outDim + i;
121 for (
int j = 0; j < nOutPts; ++j)
123 expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
144 ASSERTL0(expInField.size() == ptsOutField->GetNFields(),
145 "number of fields does not match");
146 ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
147 "too many dimesions in inField");
148 ASSERTL0(ptsOutField->GetDim() <= GetDim(),
149 "too many dimesions in outField");
150 ASSERTL0(ptsOutField->GetDim() >= expInField[0]->GetCoordim(0),
151 "too few dimesions in outField");
153 "only direct evaluation supported for this interpolation");
155 "interpolation from 3DH2D expansion unsupported");
157 m_ptsOutField = ptsOutField;
159 int nInDim = expInField[0]->GetCoordim(0);
160 int nOutPts = m_ptsOutField->GetNpoints();
164 for (
int i = 0; i < nOutPts; ++i)
168 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
170 coords[j] = m_ptsOutField->GetPointVal(j, i);
174 elmtid = expInField[0]->GetExpIndex(
181 for (
int j = 0; j < nInDim; ++j)
183 Lcoords[j] = std::max(Lcoords[j], -1.0);
184 Lcoords[j] = std::min(Lcoords[j], 1.0);
189 int offset = expInField[0]->GetPhys_Offset(elmtid);
191 for (
int f = 0; f < expInField.size(); ++f)
198 ASSERTL0(expInField[f]->GetWaveSpace(),
199 "interpolation from 3DH1D/2DH1D requires field in "
201 NekDouble lHom = expInField[f]->GetHomoLen();
203 2. * M_PI * fmod(coords[nInDim], lHom) / lHom;
205 expInField[f]->GetHomogeneousBasis()->GetZ().size();
208 expInField[f]->GetZIDs();
211 for (
size_t n = 0; n < planes.size(); ++n)
213 auto planeExp = expInField[f]->GetPlane(planes[n]);
214 coeff = planeExp->GetExp(elmtid)->StdPhysEvaluate(
215 Lcoords, planeExp->GetPhys() + offset);
221 else if (planes[n] == 1)
223 value += cos(0.5 * nPlanes * BetaT) * coeff;
225 else if (planes[n] % 2 == 0)
227 NekDouble phase = (planes[n] >> 1) * BetaT;
228 value += cos(phase) * coeff;
232 NekDouble phase = (planes[n] >> 1) * BetaT;
233 value += -sin(phase) * coeff;
239 value = expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
240 Lcoords, expInField[f]->GetPhys() + offset);
243 if ((boost::math::isnan)(value))
245 ASSERTL0(
false,
"new value is not a number");
249 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
256 for (
int f = 0; f < expInField.size(); ++f)
258 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
263 int progress = int(100 * i / nOutPts);
264 if (m_progressCallback && progress > lastProg)
266 m_progressCallback(i, nOutPts);
284 ASSERTL0(expOutField.size() == ptsInField->GetNFields(),
285 "number of fields does not match");
286 ASSERTL0(ptsInField->GetDim() <= GetDim(),
"too many dimesions in inField");
287 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
288 "too many dimesions in outField");
290 m_ptsInField = ptsInField;
292 int nFields = max((
int)ptsInField->GetNFields(), (
int)expOutField.size());
293 int nOutPts = expOutField[0]->GetTotPoints();
294 int outNumHomDir = 0;
304 int outDim = expOutField[0]->GetCoordim(0) + outNumHomDir;
308 for (
int i = 0; i < outDim; ++i)
314 expOutField[0]->GetCoords(pts[0]);
316 else if (outDim == 2)
318 expOutField[0]->GetCoords(pts[0], pts[1]);
320 else if (outDim == 3)
322 expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
328 for (
int f = 0; f < expOutField.size(); ++f)
330 tmpPts->AddField(expOutField[f]->GetPhys(),
331 m_ptsInField->GetFieldName(f));
336 for (
int i = 0; i < nFields; i++)
338 int ptsi = outDim + i;
339 for (
int j = 0; j < nOutPts; ++j)
341 expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
#define ASSERTL0(condition, msg)
A class that contains algorithms for interpolation between pts fields, expansions and different meshe...
FIELD_UTILS_EXPORT void Interpolate(const T expInField, T &expOutField, NekDouble def_value=0.0)
Interpolate from an expansion to an expansion.
void Interpolate(const LibUtilities::PtsFieldSharedPtr ptsInField, LibUtilities::PtsFieldSharedPtr &ptsOutField)
Interpolate from a pts field to a pts field.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< PtsField > PtsFieldSharedPtr
static const NekDouble kGeomFactorsTol
The above copyright notice and this permission notice shall be included.