Nektar++
ProcessInterpField.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: ProcessInterpField.cpp
4//
5// For more information, please see: http://www.nektar.info/
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Interpolate one field to another.
32//
33////////////////////////////////////////////////////////////////////////////////
34#include <iostream>
35#include <string>
36
37#include <boost/core/ignore_unused.hpp>
38#include <boost/geometry.hpp>
39#include <boost/math/special_functions/fpclassify.hpp>
40
45
46#include "ProcessInterpField.h"
47
48using namespace std;
49namespace bg = boost::geometry;
50namespace bgi = boost::geometry::index;
51
52namespace Nektar
53{
54namespace FieldUtils
55{
56
60 "Interpolates one field to another, requires fromxml, "
61 "fromfld to be defined");
62
64{
65
66 m_config["fromxml"] = ConfigOption(
67 false, "NotSet", "Xml file from which to interpolate field");
68 m_config["fromfld"] = ConfigOption(
69 false, "NotSet", "Fld file from which to interpolate field");
70
71 m_config["clamptolowervalue"] =
72 ConfigOption(false, "-10000000", "Lower bound for interpolation value");
73 m_config["clamptouppervalue"] =
74 ConfigOption(false, "10000000", "Upper bound for interpolation value");
75 m_config["defaultvalue"] =
76 ConfigOption(false, "0", "Default value if point is outside domain");
77 m_config["realmodetoimag"] =
78 ConfigOption(false, "NotSet", "Take fields as sin mode");
79}
80
82{
83}
84
85void ProcessInterpField::v_Process(po::variables_map &vm)
86{
87 m_f->SetUpExp(vm);
88
89 FieldSharedPtr fromField = std::shared_ptr<Field>(new Field());
90
91 std::vector<std::string> files;
92
93 // set up session file for from field
94 char *argv[] = {const_cast<char *>("FieldConvert"), nullptr};
95 ParseUtils::GenerateVector(m_config["fromxml"].as<string>(), files);
97 1, argv, files,
98 LibUtilities::GetCommFactory().CreateInstance("Serial", 0, 0));
99
100 // Set up range based on min and max of local parallel partition
103
104 int numHomoDir = m_f->m_numHomogeneousDir;
105 int coordim = m_f->m_exp[0]->GetCoordim(0) + numHomoDir;
106 int npts = m_f->m_exp[0]->GetTotPoints();
108
109 for (int i = 0; i < coordim; ++i)
110 {
111 coords[i] = Array<OneD, NekDouble>(npts);
112 }
113
114 for (int i = coordim; i < 3; ++i)
115 {
116 coords[i] = NullNekDouble1DArray;
117 }
118
119 m_f->m_exp[0]->GetCoords(coords[0], coords[1], coords[2]);
120
121 rng->m_checkShape = false;
122 switch (coordim)
123 {
124 case 3:
125 rng->m_doZrange = true;
126 rng->m_zmin = Vmath::Vmin(npts, coords[2], 1);
127 rng->m_zmax = Vmath::Vmax(npts, coords[2], 1);
128 /* Falls through. */
129 case 2:
130 rng->m_doYrange = true;
131 rng->m_ymin = Vmath::Vmin(npts, coords[1], 1);
132 rng->m_ymax = Vmath::Vmax(npts, coords[1], 1);
133 /* Falls through. */
134 case 1:
135 rng->m_doXrange = true;
136 rng->m_xmin = Vmath::Vmin(npts, coords[0], 1);
137 rng->m_xmax = Vmath::Vmax(npts, coords[0], 1);
138 break;
139 default:
140 NEKERROR(ErrorUtil::efatal, "coordim should be <= 3");
141 }
142
143 // setup rng parameters.
144 fromField->m_graph =
145 SpatialDomains::MeshGraph::Read(fromField->m_session, rng);
146
147 // Read in local from field partitions
148 const SpatialDomains::ExpansionInfoMap &expansions =
149 fromField->m_graph->GetExpansionInfo();
150
151 // check for case where no elements are specified on this
152 // parallel partition
153 if (!expansions.size())
154 {
155 return;
156 }
157
158 Array<OneD, int> ElementGIDs(expansions.size());
159
160 int i = 0;
161 for (auto &expIt : expansions)
162 {
163 ElementGIDs[i++] = expIt.second->m_geomShPtr->GetGlobalID();
164 }
165
166 string fromfld = m_config["fromfld"].as<string>();
167 m_f->FieldIOForFile(fromfld)->Import(
168 fromfld, fromField->m_fielddef, fromField->m_data,
170
171 int fromNumHomoDir = fromField->m_fielddef[0]->m_numHomogeneousDir;
172 for (i = 0; i < fromField->m_fielddef.size(); ++i)
173 {
174 int d1 = fromField->m_fielddef[i]->m_basis.size();
175 d1 -= 1;
176 if (d1 >= 0 && (fromField->m_fielddef[i]->m_basis[d1] ==
178 fromField->m_fielddef[i]->m_basis[d1] ==
180 {
181 fromField->m_fielddef[i]->m_homogeneousZIDs[0] += 2;
182 fromField->m_fielddef[i]->m_numModes[d1] = 4;
183 fromField->m_fielddef[i]->m_basis[d1] = LibUtilities::eFourier;
184 }
185 }
186
187 //----------------------------------------------
188 // Set up Expansion information to use mode order from field
189 fromField->m_graph->SetExpansionInfo(fromField->m_fielddef);
190
191 int nfields = fromField->m_fielddef[0]->m_fields.size();
192
193 fromField->m_exp.resize(nfields);
194 fromField->m_exp[0] = fromField->SetUpFirstExpList(fromNumHomoDir, true);
195
196 m_f->m_exp.resize(nfields);
197
198 // declare auxiliary fields.
199 for (i = 1; i < nfields; ++i)
200 {
201 m_f->m_exp[i] = m_f->AppendExpList(numHomoDir);
202 fromField->m_exp[i] = fromField->AppendExpList(fromNumHomoDir);
203 }
204
205 // load field into expansion in fromfield.
206 set<int> sinmode;
207 if (m_config["realmodetoimag"].as<string>().compare("NotSet"))
208 {
209 ParseUtils::GenerateVariableSet(m_config["realmodetoimag"].as<string>(),
210 m_f->m_variables, sinmode);
211 }
212 for (int j = 0; j < nfields; ++j)
213 {
214 for (i = 0; i < fromField->m_fielddef.size(); i++)
215 {
216 fromField->m_exp[j]->ExtractDataToCoeffs(
217 fromField->m_fielddef[i], fromField->m_data[i],
218 fromField->m_fielddef[0]->m_fields[j],
219 fromField->m_exp[j]->UpdateCoeffs());
220 }
221 if (fromNumHomoDir == 1)
222 {
223 fromField->m_exp[j]->SetWaveSpace(true);
224 if (sinmode.count(j))
225 {
226 int Ncoeff = fromField->m_exp[j]->GetPlane(2)->GetNcoeffs();
228 Ncoeff, -1., fromField->m_exp[j]->GetPlane(2)->GetCoeffs(),
229 1, fromField->m_exp[j]->GetPlane(3)->UpdateCoeffs(), 1);
230 Vmath::Zero(Ncoeff,
231 fromField->m_exp[j]->GetPlane(2)->UpdateCoeffs(),
232 1);
233 }
234 }
235 fromField->m_exp[j]->BwdTrans(fromField->m_exp[j]->GetCoeffs(),
236 fromField->m_exp[j]->UpdatePhys());
237 }
238
239 int nq1 = m_f->m_exp[0]->GetTotPoints();
240
241 NekDouble clamp_low = m_config["clamptolowervalue"].as<NekDouble>();
242 NekDouble clamp_up = m_config["clamptouppervalue"].as<NekDouble>();
243 NekDouble def_value = m_config["defaultvalue"].as<NekDouble>();
244
245 for (int i = 0; i < nfields; i++)
246 {
247 for (int j = 0; j < nq1; ++j)
248 {
249 m_f->m_exp[i]->UpdatePhys()[j] = def_value;
250 }
251 }
252
254 if (m_f->m_verbose && m_f->m_comm->TreatAsRankZero())
255 {
257 }
258
259 interp.Interpolate(fromField->m_exp, m_f->m_exp);
260
261 if (m_f->m_verbose && m_f->m_comm->TreatAsRankZero())
262 {
263 cout << endl;
264 }
265
266 for (int i = 0; i < nfields; ++i)
267 {
268 for (int j = 0; j < nq1; ++j)
269 {
270 if (m_f->m_exp[i]->GetPhys()[j] > clamp_up)
271 {
272 m_f->m_exp[i]->UpdatePhys()[j] = clamp_up;
273 }
274 else if (m_f->m_exp[i]->GetPhys()[j] < clamp_low)
275 {
276 m_f->m_exp[i]->UpdatePhys()[j] = clamp_low;
277 }
278 }
279 m_f->m_exp[i]->FwdTransLocalElmt(m_f->m_exp[i]->GetPhys(),
280 m_f->m_exp[i]->UpdateCoeffs());
281 }
282 // save field names
283 m_f->m_variables = fromField->m_fielddef[0]->m_fields;
284}
285
287 const int goal) const
288{
289 LibUtilities::PrintProgressbar(position, goal, "Interpolating");
290}
291} // namespace FieldUtils
292} // namespace Nektar
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
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.
FieldSharedPtr m_f
Field object.
Definition: Module.h:234
std::map< std::string, ConfigOption > m_config
List of configuration values.
Definition: Module.h:263
void PrintProgressbar(const int position, const int goal) const
virtual void v_Process(po::variables_map &vm) override
Write mesh to output file.
static std::shared_ptr< Module > create(FieldSharedPtr f)
Creates an instance of this class.
Abstract base class for processing modules.
Definition: Module.h:292
void SetProgressCallback(FuncPointerT func, ObjectPointerT obj)
sets a callback funtion which gets called every time the interpolation progresses
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static bool GenerateVariableSet(const std::string &str, const std::vector< std::string > &variables, std::set< int > &out)
Generate a set of variable locations.
Definition: ParseUtils.cpp:166
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Definition: ParseUtils.cpp:131
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, LibUtilities::DomainRangeShPtr rng=LibUtilities::NullDomainRangeShPtr, bool fillGraph=true, SpatialDomains::MeshGraphSharedPtr partitionedGraph=nullptr)
Definition: MeshGraph.cpp:116
std::shared_ptr< Field > FieldSharedPtr
Definition: Field.hpp:991
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:317
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49
int PrintProgressbar(const int position, const int goal, const std::string message, int lastprogress=-1)
Prints a progressbar.
Definition: Progressbar.hpp:67
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:53
std::shared_ptr< DomainRange > DomainRangeShPtr
Definition: DomainRange.h:66
CommFactory & GetCommFactory()
@ eFourierHalfModeIm
Fourier Modified expansions with just the imaginary part of the first mode .
Definition: BasisType.h:70
@ eFourierHalfModeRe
Fourier Modified expansions with just the real part of the first mode .
Definition: BasisType.h:68
@ eFourier
Fourier Expansion .
Definition: BasisType.h:57
std::map< int, ExpansionInfoShPtr > ExpansionInfoMap
Definition: MeshGraph.h:143
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
static Array< OneD, NekDouble > NullNekDouble1DArray
double NekDouble
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.cpp:1045
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:245
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:487
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.cpp:940
Represents a command-line configuration option.
Definition: Module.h:131