37#include <boost/geometry.hpp>
41namespace bg = boost::geometry;
42namespace bgi = boost::geometry::index;
65 ASSERTL0(expInField.size() == expOutField.size(),
66 "number of fields does not match");
67 ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
68 "too many dimensions in inField");
69 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
70 "too many dimensions in outField");
72 "only direct evaluation supported for this interpolation");
74 int nFields = max((
int)expInField.size(), (
int)expOutField.size());
75 int nOutPts = expOutField[0]->GetTotPoints();
86 int outDim = expOutField[0]->GetCoordim(0) + outNumHomDir;
90 for (
int i = 0; i < outDim; ++i)
96 expOutField[0]->GetCoords(pts[0]);
100 expOutField[0]->GetCoords(pts[0], pts[1]);
102 else if (outDim == 3)
104 expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
109 for (
int f = 0; f < expOutField.size(); ++f)
111 tmpPts->AddField(expOutField[f]->GetPhys(),
"DefaultVar");
114 Interpolate(expInField, tmpPts, def_value, tolerance);
116 for (
int i = 0; i < nFields; i++)
118 int ptsi = outDim + i;
119 for (
int j = 0; j < nOutPts; ++j)
121 expOutField[i]->UpdatePhys()[j] = tmpPts->GetPointVal(ptsi, j);
142 ASSERTL0(expInField.size() == ptsOutField->GetNFields(),
143 "number of fields does not match");
144 ASSERTL0(expInField[0]->GetCoordim(0) <= GetDim(),
145 "too many dimesions in inField");
146 ASSERTL0(ptsOutField->GetDim() <= GetDim(),
147 "too many dimesions in outField");
148 ASSERTL0(ptsOutField->GetDim() >= expInField[0]->GetCoordim(0),
149 "too few dimesions in outField");
151 "only direct evaluation supported for this interpolation");
153 "interpolation from 3DH2D expansion unsupported");
155 m_ptsOutField = ptsOutField;
157 int nInDim = expInField[0]->GetCoordim(0);
158 int nOutPts = m_ptsOutField->GetNpoints();
162 for (
int i = 0; i < nOutPts; ++i)
166 for (
int j = 0; j < m_ptsOutField->GetDim(); ++j)
168 coords[j] = m_ptsOutField->GetPointVal(j, i);
172 elmtid = expInField[0]->GetExpIndex(coords, Lcoords,
179 for (
int j = 0; j < nInDim; ++j)
181 Lcoords[j] = std::max(Lcoords[j], -1.0);
182 Lcoords[j] = std::min(Lcoords[j], 1.0);
187 int offset = expInField[0]->GetPhys_Offset(elmtid);
189 for (
int f = 0; f < expInField.size(); ++f)
196 ASSERTL0(expInField[f]->GetWaveSpace(),
197 "interpolation from 3DH1D/2DH1D requires field in "
199 NekDouble lHom = expInField[f]->GetHomoLen();
201 2. * M_PI * fmod(coords[nInDim], lHom) / lHom;
203 expInField[f]->GetHomogeneousBasis()->GetZ().size();
206 expInField[f]->GetZIDs();
209 for (
size_t n = 0; n < planes.size(); ++n)
211 auto planeExp = expInField[f]->GetPlane(planes[n]);
212 coeff = planeExp->GetExp(elmtid)->StdPhysEvaluate(
213 Lcoords, planeExp->GetPhys() + offset);
219 else if (planes[n] == 1)
221 value += cos(0.5 * nPlanes * BetaT) * coeff;
223 else if (planes[n] % 2 == 0)
225 NekDouble phase = (planes[n] >> 1) * BetaT;
226 value += cos(phase) * coeff;
230 NekDouble phase = (planes[n] >> 1) * BetaT;
231 value += -sin(phase) * coeff;
237 value = expInField[f]->GetExp(elmtid)->StdPhysEvaluate(
238 Lcoords, expInField[f]->GetPhys() + offset);
241 if ((boost::math::isnan)(value))
243 ASSERTL0(
false,
"new value is not a number");
247 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
254 for (
int f = 0; f < expInField.size(); ++f)
256 m_ptsOutField->SetPointVal(m_ptsOutField->GetDim() + f, i,
261 int progress = int(100 * i / nOutPts);
262 if (m_progressCallback && progress > lastProg)
264 m_progressCallback(i, nOutPts);
282 ASSERTL0(expOutField.size() == ptsInField->GetNFields(),
283 "number of fields does not match");
284 ASSERTL0(ptsInField->GetDim() <= GetDim(),
"too many dimesions in inField");
285 ASSERTL0(expOutField[0]->GetCoordim(0) <= GetDim(),
286 "too many dimesions in outField");
288 m_ptsInField = ptsInField;
290 int nFields = max((
int)ptsInField->GetNFields(), (
int)expOutField.size());
291 int nOutPts = expOutField[0]->GetTotPoints();
292 int outNumHomDir = 0;
302 int outDim = expOutField[0]->GetCoordim(0) + outNumHomDir;
306 for (
int i = 0; i < outDim; ++i)
312 expOutField[0]->GetCoords(pts[0]);
314 else if (outDim == 2)
316 expOutField[0]->GetCoords(pts[0], pts[1]);
318 else if (outDim == 3)
320 expOutField[0]->GetCoords(pts[0], pts[1], pts[2]);
326 for (
int f = 0; f < expOutField.size(); ++f)
328 tmpPts->AddField(expOutField[f]->GetPhys(),
329 m_ptsInField->GetFieldName(f));
334 for (
int i = 0; i < nFields; i++)
336 int ptsi = outDim + i;
337 for (
int j = 0; j < nOutPts; ++j)
339 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., NekDouble tolerance=NekConstants::kFindDistanceMin)
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