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