Nektar++
VtkToFld.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: VtkToFld.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:
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
36 #include <vtkPolyDataReader.h>
37 
38 #if VTK_MAJOR_VERSION >= 9
39 #include <limits>
40 #include <stdexcept>
41 #endif
42 
43 #include <vtkCellArray.h>
44 #include <vtkCellDataToPointData.h>
45 #include <vtkContourFilter.h>
46 #include <vtkPointData.h>
47 #include <vtkPoints.h>
48 #include <vtkPolyData.h>
49 
50 #include <boost/program_options.hpp>
51 namespace po = boost::program_options;
52 
58 #include <MultiRegions/ExpList.h>
60 
61 using namespace std;
62 using namespace Nektar;
63 
64 /**
65  * @brief Represents a vertex in the mesh.
66  *
67  * Each vertex has a 3-component coordinate and a scalar value associated with
68  * it. The factor provides a mechanism to specify precision of the coordinate
69  * comparison. Although coordinates are provided as floating-point numbers, they
70  * are stored as integers. The integer value is computed as
71  * floor (x * factor)
72  * Therefore a factor of 100 would ensure a precision of 0.01 in the comparison.
73  */
74 struct Vertex
75 {
76  Vertex(double pX, double pY, double pZ, double pScalar, double factor)
77  : x((int)floor(pX * factor)), y((int)floor(pY * factor)),
78  z((int)floor(pZ * factor)), scalar(pScalar)
79  {
80  }
81 
82  int x;
83  int y;
84  int z;
85  double scalar;
86 
87  bool operator==(const Vertex &v)
88  {
89  return (x == v.x && y == v.y && z == v.z);
90  }
91 };
92 typedef std::shared_ptr<Vertex> VertexSharedPtr;
93 
94 /// Define comparison operator for the vertex struct
95 bool operator==(const VertexSharedPtr &v1, const VertexSharedPtr &v2)
96 {
97  return v1->operator==(*v2);
98 }
99 
100 /**
101  * @brief Hash function for the Vertex struct used for defining sets.
102  */
104 {
105  std::size_t operator()(VertexSharedPtr const &p) const
106  {
107  return hash_combine(p->x, p->y, p->z);
108  }
109 };
110 
111 /// Define a set of Vertices with associated hash function
112 typedef std::unordered_set<VertexSharedPtr, VertexHash> VertexSet;
113 
114 /**
115  * Main function.
116  *
117  * Usage: VtkToFld session.xml input.vtk output.fld [options]
118  */
119 int main(int argc, char *argv[])
120 {
121  // Set up available options
122  po::options_description desc("Available options");
123 
124  // clang-format off
125  desc.add_options()
126  ("help,h", "Produce this help message.")
127  ("name,n", po::value<string>()->default_value("Intensity"),
128  "Name of field in VTK file to use for intensity.")
129  ("outname,m", po::value<string>()->default_value("intensity"),
130  "Name of field in output FLD file.")
131  ("precision,p", po::value<double>()->default_value(1),
132  "Precision of vertex matching.");
133  // clang-format on
134 
135  po::options_description hidden("Hidden options");
136 
137  // clang-format off
138  hidden.add_options()
139  ("file", po::value<vector<string> >(), "Input filename");
140  // clang-format on
141 
142  po::options_description cmdline_options;
143  cmdline_options.add(desc).add(hidden);
144 
145  po::positional_options_description p;
146  p.add("file", -1);
147 
148  po::variables_map vm;
149 
150  // Parse command-line options
151  try
152  {
153  po::store(po::command_line_parser(argc, argv)
154  .options(cmdline_options)
155  .positional(p)
156  .run(),
157  vm);
158  po::notify(vm);
159  }
160  catch (const std::exception &e)
161  {
162  cerr << e.what() << endl;
163  cerr << desc;
164  return 1;
165  }
166 
167  if (vm.count("help") || vm.count("file") == 0 ||
168  vm["file"].as<vector<string>>().size() != 3)
169  {
170  cerr << "Usage: VtkToFld session.xml intensity.vtk output.fld [options]"
171  << endl;
172  cerr << desc;
173  return 1;
174  }
175 
176  // Extract command-line argument values
177  std::vector<std::string> vFiles = vm["file"].as<vector<string>>();
178  const string infile = vFiles[1];
179  const string outfile = vFiles[2];
180  const double factor = vm["precision"].as<double>();
181  const string name = vm["name"].as<string>();
182  const string outname = vm["outname"].as<string>();
183 
184  std::vector<std::string> vFilenames;
188 
189  vFilenames.push_back(vFiles[0]);
190  vSession = LibUtilities::SessionReader::CreateInstance(2, argv, vFilenames);
191 
192  try
193  {
194  //----------------------------------------------
195  // Read in mesh from input file
196  graph2D = SpatialDomains::MeshGraph::Read(vSession);
197  //----------------------------------------------
198 
199  //----------------------------------------------
200  // Define Expansion
202  graph2D);
203  //----------------------------------------------
204 
205  //----------------------------------------------
206  // Set up coordinates of mesh
207  int coordim = Exp->GetCoordim(0);
208  int nq = Exp->GetNpoints();
209 
210  Array<OneD, NekDouble> xc0(nq, 0.0);
211  Array<OneD, NekDouble> xc1(nq, 0.0);
212  Array<OneD, NekDouble> xc2(nq, 0.0);
213 
214  switch (coordim)
215  {
216  case 2:
217  Exp->GetCoords(xc0, xc1);
218  break;
219  case 3:
220  Exp->GetCoords(xc0, xc1, xc2);
221  break;
222  default:
223  ASSERTL0(false, "Coordim not valid");
224  break;
225  }
226  //----------------------------------------------
227 
228  vtkPolyDataReader *vtkMeshReader = vtkPolyDataReader::New();
229  vtkMeshReader->SetFileName(infile.c_str());
230  vtkMeshReader->Update();
231 
232  vtkPolyData *vtkMesh = vtkMeshReader->GetOutput();
233  vtkCellDataToPointData *c2p = vtkCellDataToPointData::New();
234 #if VTK_MAJOR_VERSION <= 5
235  c2p->SetInput(vtkMesh);
236 #else
237  c2p->SetInputData(vtkMesh);
238 #endif
239  c2p->PassCellDataOn();
240  c2p->Update();
241  vtkPolyData *vtkDataAtPoints = c2p->GetPolyDataOutput();
242 
243  vtkPoints *vtkPoints = vtkMesh->GetPoints();
244  ASSERTL0(vtkPoints, "ERROR: cannot get points from mesh.");
245 
246  vtkCellArray *vtkPolys = vtkMesh->GetPolys();
247  ASSERTL0(vtkPolys, "ERROR: cannot get polygons from mesh.");
248 
249  vtkPointData *vtkPData = vtkDataAtPoints->GetPointData();
250  ASSERTL0(vtkPolys, "ERROR: cannot get point data from file.");
251 
252  VertexSet points;
253  VertexSet::iterator vIter;
254  double p[3];
255  double val;
256  double x, y, z;
257  int coeff_idx;
258  int i, j, n;
259 
260  if (!vtkDataAtPoints->GetPointData()->HasArray(name.c_str()))
261  {
262  n = vtkDataAtPoints->GetPointData()->GetNumberOfArrays();
263  cerr << "Input file '" << infile
264  << "' does not have a field named '" << name << "'" << endl;
265  cerr << "There are " << n << " arrays in this file." << endl;
266  for (int i = 0; i < n; ++i)
267  {
268  cerr << " "
269  << vtkDataAtPoints->GetPointData()->GetArray(i)->GetName()
270  << endl;
271  }
272  return 1;
273  }
274 
275  // Build up an unordered set of vertices from the VTK file. For each
276  // vertex a hashed value of the coordinates is generated to within a
277  // given tolerance.
278  n = vtkPoints->GetNumberOfPoints();
279  for (i = 0; i < n; ++i)
280  {
281  vtkPoints->GetPoint(i, p);
282  val = vtkPData->GetScalars(name.c_str())->GetTuple1(i);
283  std::shared_ptr<Vertex> v(
284  new Vertex(p[0], p[1], p[2], val, factor));
285  points.insert(v);
286  }
287 
288  // Now process each vertex of each element in the mesh
290  for (i = 0; i < Exp->GetNumElmts(); ++i)
291  {
292  StdRegions::StdExpansionSharedPtr e = Exp->GetExp(i);
293  for (j = 0; j < e->GetNverts(); ++j)
294  {
295  // Get the index of the coefficient corresponding to this vertex
296  coeff_idx = Exp->GetCoeff_Offset(i) + e->GetVertexMap(j);
297 
298  // Get the coordinates of the vertex
299  vert =
300  e->as<LocalRegions::Expansion2D>()->GetGeom2D()->GetVertex(
301  j);
302  vert->GetCoords(x, y, z);
303 
304  // Look up the vertex in the VertexSet
305  std::shared_ptr<Vertex> v(new Vertex(x, y, z, 0.0, factor));
306  vIter = points.find(v);
307 
308  // If not found, maybe the tolerance should be reduced?
309  // If found, record the scalar value from the VTK file in the
310  // corresponding coefficient.
311  if (vIter == points.end())
312  {
313  cerr << "Vertex " << i << " not found. Looking for (" << x
314  << ", " << y << ", " << z << ")" << endl;
315  }
316  else
317  {
318  Exp->UpdateCoeffs()[coeff_idx] = (*vIter)->scalar;
319  }
320  }
321  }
322  Exp->SetPhysState(false);
323 
324  //-----------------------------------------------
325  // Write solution to file
326  std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef =
327  Exp->GetFieldDefinitions();
328  std::vector<std::vector<NekDouble>> FieldData(FieldDef.size());
329 
330  for (i = 0; i < FieldDef.size(); ++i)
331  {
332  FieldDef[i]->m_fields.push_back(outname);
333  Exp->AppendFieldData(FieldDef[i], FieldData[i]);
334  }
335 
337  LibUtilities::FieldIO::CreateDefault(vSession);
338  vFld->Write(outfile, FieldDef, FieldData);
339  //-----------------------------------------------
340  }
341  catch (...)
342  {
343  cout << "An error occurred." << endl;
344  }
345 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
int main(int argc, char *argv[])
Definition: VtkToFld.cpp:119
bool operator==(const VertexSharedPtr &v1, const VertexSharedPtr &v2)
Define comparison operator for the vertex struct.
Definition: VtkToFld.cpp:95
std::unordered_set< VertexSharedPtr, VertexHash > VertexSet
Define a set of Vertices with associated hash function.
Definition: VtkToFld.cpp:112
std::shared_ptr< Vertex > VertexSharedPtr
Definition: VtkToFld.cpp:92
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
void GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2=NullNekDouble1DArray, Array< OneD, NekDouble > &coords_3=NullNekDouble1DArray)
this function returns the physical coordinates of the quadrature points of the expansion
Definition: StdExpansion.h:585
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:327
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:172
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
void hash_combine(std::size_t &seed)
Definition: HashUtils.hpp:46
Hash function for the Vertex struct used for defining sets.
Definition: VtkToFld.cpp:104
std::size_t operator()(VertexSharedPtr const &p) const
Definition: VtkToFld.cpp:105
Represents a vertex in the mesh.
Definition: VtkToFld.cpp:75
Vertex(double pX, double pY, double pZ, double pScalar, double factor)
Definition: VtkToFld.cpp:76
int y
Definition: VtkToFld.cpp:83
int z
Definition: VtkToFld.cpp:84
bool operator==(const Vertex &v)
Definition: VtkToFld.cpp:87
double scalar
Definition: VtkToFld.cpp:85
int x
Definition: VtkToFld.cpp:82