37 #include <boost/geometry.hpp>
41 namespace bg = boost::geometry;
42 namespace 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]);
110 MemoryManager<LibUtilities::PtsField>::AllocateSharedPtr(outDim, pts);
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);
139 template <
typename T>
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);
280 template <
typename T>
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));
334 LibUtilities::Interpolator::Interpolate(m_ptsInField, tmpPts);
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);
346 template <
typename T>
352 if (exp1.size() != exp2.size())
354 NEKERROR(ErrorUtil::efatal,
"not the same mesh")
357 for (
int n = 0; n < exp1.size(); ++n)
361 if (exp1[n]->GetExpSize() != exp2[n]->GetExpSize())
363 NEKERROR(ErrorUtil::efatal,
"not the same mesh")
367 if (exp1[n]->GetTotPoints() == exp2[n]->GetTotPoints())
369 Vmath::Vcopy(exp1[n]->GetTotPoints(), exp1[n]->GetPhys(), 1,
370 exp2[n]->UpdatePhys(), 1);
376 exp1[n]->FwdTransLocalElmt(exp1[n]->GetPhys(),
377 exp1[n]->UpdateCoeffs());
379 for (
int i = 0; i < exp1[n]->GetExpSize(); ++i)
383 elmt2 = exp2[n]->GetExp(i);
386 int offset1 = exp1[n]->GetCoeff_Offset(i);
387 int offset2 = exp2[n]->GetCoeff_Offset(i);
392 std::vector<unsigned int> nummodes1(base1.size());
393 std::vector<LibUtilities::BasisType> btype1(base1.size());
394 for (
int j = 0; j < nummodes1.size(); ++j)
396 nummodes1[j] = base1[j]->GetNumModes();
397 btype1[j] = base1[j]->GetBasisType();
401 elmt2->ExtractDataToCoeffs(
402 &exp1[n]->GetCoeffs()[offset1], nummodes1, 0,
403 &exp2[n]->UpdateCoeffs()[offset2], btype1);
407 exp2[n]->BwdTrans(exp2[n]->GetCoeffs(), exp2[n]->UpdatePhys());
412 template <
typename T>
417 LibUtilities::Interpolator::Interpolate(ptsInField, ptsOutField);
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
A class that contains algorithms for interpolation between pts fields, expansions and different meshe...
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< PtsField > PtsFieldSharedPtr
std::shared_ptr< Expansion > ExpansionSharedPtr
static const NekDouble kGeomFactorsTol
The above copyright notice and this permission notice shall be included.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)