Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
InputXml.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: InputXml.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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Read xml file and set up expansions
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <string>
37 #include <iostream>
38 #include <iomanip>
39 using namespace std;
40 
42 
43 #include "InputXml.h"
44 using namespace Nektar;
45 
46 static std::string npts = LibUtilities::SessionReader::RegisterCmdLineArgument(
47  "NumberOfPoints","n","Define number of points to dump output");
48 
49 namespace Nektar
50 {
51 namespace Utilities
52 {
53 
54 ModuleKey InputXml::m_className[5] = {
56  ModuleKey(eInputModule, "xml"), InputXml::create,
57  "Reads Xml file."),
59  ModuleKey(eInputModule, "xml.gz"), InputXml::create,
60  "Reads Xml file."),
61 };
62 
63 
64 /**
65  * @brief Set up InputXml object.
66  *
67  */
68 InputXml::InputXml(FieldSharedPtr f) : InputModule(f)
69 {
70  m_allowedFiles.insert("xml");
71  m_allowedFiles.insert("xml.gz");
72  m_allowedFiles.insert("fld"); // these files could be allowed with xml files
73  m_allowedFiles.insert("chk");
74  m_allowedFiles.insert("rst");
75 }
76 
77 
78 /**
79  *
80  */
82 {
83 }
84 
85 
86 /**
87  *
88  */
89 void InputXml::Process(po::variables_map &vm)
90 {
91  Timer timer, timerpart;
92 
93  //check for multiple calls to inputXml due to split xml
94  //files. If so just return
95  int expsize = m_f->m_exp.size();
96  m_f->m_comm->AllReduce(expsize,LibUtilities::ReduceMax);
97 
98  if(expsize != 0)
99  {
100  return;
101  }
102 
103  if(m_f->m_verbose)
104  {
105  if(m_f->m_comm->GetRank() == 0)
106  {
107  cout << "Processing input xml file" << endl;
108  timer.Start();
109  timerpart.Start();
110  }
111  }
112 
113  // check to see if fld file defined so can use in
114  // expansion defintion if required
115  string fldending;
116  bool fldfilegiven = true;
117 
118  //Determine appropriate field input
119  if(m_f->m_inputfiles.count("fld") != 0)
120  {
121  fldending = "fld";
122  }
123  else if(m_f->m_inputfiles.count("chk") != 0)
124  {
125  fldending = "chk";
126  }
127  else if (m_f->m_inputfiles.count("rst") != 0)
128  {
129  fldending = "rst";
130  }
131  else
132  {
133  fldfilegiven = false;
134  }
135 
136  string xml_ending = "xml";
137  string xml_gz_ending = "xml.gz";
138 
139  std::vector<std::string> files;
140  // load .xml ending
141  for (int i = 0; i < m_f->m_inputfiles[xml_ending].size(); ++i)
142  {
143  files.push_back(m_f->m_inputfiles[xml_ending][i]);
144  }
145 
146  // load any .xml.gz endings
147  for (int j =0; j < m_f->m_inputfiles[xml_gz_ending].size(); ++j)
148  {
149  files.push_back(m_f->m_inputfiles[xml_gz_ending][j]);
150  }
151 
154 
155 
156  // define range to process output
157  if(vm.count("range"))
158  {
159  vector<NekDouble> values;
161  vm["range"].as<string>().c_str(), values),
162  "Failed to interpret range string");
163 
164  ASSERTL0(values.size() > 1,
165  "Do not have minimum values of xmin,xmax");
166  ASSERTL0(values.size() % 2 == 0,
167  "Do not have an even number of range values");
168 
169  int nvalues = values.size()/2;
172 
173  rng->m_doZrange = false;
174  rng->m_doYrange = false;
175  rng->m_checkShape = false;
176 
177  switch(nvalues)
178  {
179  case 3:
180  rng->m_doZrange = true;
181  rng->m_zmin = values[4];
182  rng->m_zmax = values[5];
183  case 2:
184  rng->m_doYrange = true;
185  rng->m_ymin = values[2];
186  rng->m_ymax = values[3];
187  case 1:
188  rng->m_doXrange = true;
189  rng->m_xmin = values[0];
190  rng->m_xmax = values[1];
191  break;
192  default:
193  ASSERTL0(false,"too many values specfied in range");
194  }
195  }
196 
197  // define range to only take a single shape.
198  if(vm.count("onlyshape"))
199  {
201  {
204  rng->m_doXrange = false;
205  rng->m_doYrange = false;
206  rng->m_doZrange = false;
207  }
208 
209  rng->m_checkShape = true;
210 
211  string shapematch =
212  boost::to_upper_copy(vm["onlyshape"].as<string>());
213  int i;
214  for(i = 0; i < LibUtilities::SIZE_ShapeType; ++i)
215  {
216  string shapeval = LibUtilities::ShapeTypeMap[i];
217  boost::to_upper(shapeval);
218  if(shapematch.compare(shapeval) == 0)
219  {
220  rng->m_shapeType = (LibUtilities::ShapeType)i;
221  break;
222  }
223  }
224  ASSERTL0(i != LibUtilities::SIZE_ShapeType,
225  "Failed to find shape type in -onlyshape command line "
226  "argument");
227  }
228 
229  // Set up command lines options that will be passed through to SessionReader
230  vector<string> cmdArgs;
231  cmdArgs.push_back("FieldConvert");
232 
233  if(m_f->m_verbose)
234  {
235  cmdArgs.push_back("--verbose");
236  }
237 
238  if(vm.count("shared-filesystem"))
239  {
240  cmdArgs.push_back("--shared-filesystem");
241  }
242 
243  if(vm.count("part-only"))
244  {
245  cmdArgs.push_back("--part-only");
246  cmdArgs.push_back(
247  boost::lexical_cast<string>(vm["part-only"].as<int>()));
248  }
249 
250  if(vm.count("part-only-overlapping"))
251  {
252  cmdArgs.push_back("--part-only-overlapping");
253  cmdArgs.push_back(
254  boost::lexical_cast<string>(vm["part-only-overlapping"].as<int>()));
255  }
256 
257  int argc = cmdArgs.size();
258  const char **argv = new const char*[argc];
259  for (int i = 0; i < argc; ++i)
260  {
261  argv[i] = cmdArgs[i].c_str();
262  }
263 
265  CreateInstance(argc, (char **) argv, files, m_f->m_comm);
266 
267  // Free up memory.
268  delete [] argv;
269 
270  if(m_f->m_verbose)
271  {
272  if(m_f->m_comm->GetRank() == 0)
273  {
274  timerpart.Stop();
275  NekDouble cpuTime = timerpart.TimePerTest(1);
276 
277  stringstream ss;
278  ss << cpuTime << "s";
279  cout << "\t InputXml session reader CPU Time: " << setw(8) << left
280  << ss.str() << endl;
281  timerpart.Start();
282  }
283  }
284 
285  m_f->m_graph = SpatialDomains::MeshGraph::Read(m_f->m_session,rng);
287  ::AllocateSharedPtr(m_f->m_session->GetComm());
288 
289  if(m_f->m_verbose)
290  {
291  if(m_f->m_comm->GetRank() == 0)
292  {
293  timerpart.Stop();
294  NekDouble cpuTime = timerpart.TimePerTest(1);
295 
296  stringstream ss;
297  ss << cpuTime << "s";
298  cout << "\t InputXml mesh graph setup CPU Time: " << setw(8) << left
299  << ss.str() << endl;
300  timerpart.Start();
301  }
302  }
303 
304  // currently load all field (possibly could read data from
305  // expansion list but it is re-arranged in expansion)
306  const SpatialDomains::ExpansionMap &expansions = m_f->m_graph->GetExpansions();
307 
308  // if Range has been speficied it is possible to have a
309  // partition which is empty so ccheck this and return if
310  // no elements present.
311  if(!expansions.size())
312  {
313  return;
314  }
315 
316  m_f->m_exp.resize(1);
317 
318  // load fielddef header if fld file is defined. This gives
319  // precedence to Homogeneous definition in fld file
320  int NumHomogeneousDir = 0;
321  if(fldfilegiven)
322  {
323  // use original expansion to identify which elements are in
324  // this partition/subrange
325 
326  Array<OneD,int> ElementGIDs(expansions.size());
327  SpatialDomains::ExpansionMap::const_iterator expIt;
328 
329  int i = 0;
330  for (expIt = expansions.begin(); expIt != expansions.end(); ++expIt)
331  {
332  ElementGIDs[i++] = expIt->second->m_geomShPtr->GetGlobalID();
333  }
334 
335  m_f->m_fld->Import(m_f->m_inputfiles[fldending][0],m_f->m_fielddef,
338  ElementGIDs);
339  NumHomogeneousDir = m_f->m_fielddef[0]->m_numHomogeneousDir;
340 
341  //----------------------------------------------
342  // Set up Expansion information to use mode order from field
343  m_f->m_graph->SetExpansions(m_f->m_fielddef);
344  }
345  else
346  {
347  if(m_f->m_session->DefinesSolverInfo("HOMOGENEOUS"))
348  {
349  std::string HomoStr = m_f->m_session->GetSolverInfo("HOMOGENEOUS");
350 
351  if((HomoStr == "HOMOGENEOUS1D") || (HomoStr == "Homogeneous1D")
352  || (HomoStr == "1D") || (HomoStr == "Homo1D"))
353  {
354  NumHomogeneousDir = 1;
355  }
356  if((HomoStr == "HOMOGENEOUS2D") || (HomoStr == "Homogeneous2D")
357  || (HomoStr == "2D") || (HomoStr == "Homo2D"))
358  {
359  NumHomogeneousDir = 2;
360  }
361  }
362  }
363 
364  // reset expansion defintion to use equispaced points if required.
365  if(m_requireEquiSpaced || vm.count("output-points"))
366  {
367  int nPointsNew = 0;
368 
369  if(vm.count("output-points"))
370  {
371  nPointsNew = vm["output-points"].as<int>();
372  }
373 
374 
375  m_f->m_graph->SetExpansionsToEvenlySpacedPoints(nPointsNew);
376  }
377  else
378  {
379  if(vm.count("output-points"))
380  {
381  int nPointsNew = vm["output-points"].as<int>();
382  m_f->m_graph->SetExpansionsToPointOrder(nPointsNew);
383  }
384  }
385 
386  if(m_f->m_verbose)
387  {
388  if(m_f->m_comm->GetRank() == 0)
389  {
390  timerpart.Stop();
391  NekDouble cpuTime = timerpart.TimePerTest(1);
392 
393  stringstream ss;
394  ss << cpuTime << "s";
395  cout << "\t InputXml setexpansion CPU Time: " << setw(8) << left
396  << ss.str() << endl;
397  timerpart.Start();
398  }
399  }
400 
401  if(m_f->m_verbose)
402  {
403  if(m_f->m_comm->GetRank() == 0)
404  {
405  timerpart.Stop();
406  NekDouble cpuTime = timerpart.TimePerTest(1);
407 
408  stringstream ss;
409  ss << cpuTime << "s";
410  cout << "\t InputXml setexpansion CPU Time: " << setw(8) << left
411  << ss.str() << endl;
412  timerpart.Start();
413  }
414  }
415 
416  // Override number of planes with value from cmd line
417  if(NumHomogeneousDir == 1 && vm.count("output-points-hom-z"))
418  {
419  int expdim = m_f->m_graph->GetMeshDimension();
420  m_f->m_fielddef[0]->m_numModes[expdim] = vm["output-points-hom-z"].as<int>();
421  }
422 
423  m_f->m_exp[0] = m_f->SetUpFirstExpList(NumHomogeneousDir,fldfilegiven);
424 
425  if(m_f->m_verbose)
426  {
427  if(m_f->m_comm->GetRank() == 0)
428  {
429  timerpart.Stop();
430  NekDouble cpuTime = timerpart.TimePerTest(1);
431 
432  stringstream ss1;
433 
434  ss1 << cpuTime << "s";
435  cout << "\t InputXml set first exp CPU Time: " << setw(8) << left
436  << ss1.str() << endl;
437 
438 
439  timer.Stop();
440  cpuTime = timer.TimePerTest(1);
441 
442  stringstream ss;
443  ss << cpuTime << "s";
444  cout << "InputXml CPU Time: " << setw(8) << left
445  << ss.str() << endl;
446 
447  }
448  }
449 }
450 }
451 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
pair< ModuleType, string > ModuleKey
static boost::shared_ptr< MeshGraph > Read(const LibUtilities::SessionReaderSharedPtr &pSession, DomainRangeShPtr &rng=NullDomainRangeShPtr)
Definition: MeshGraph.cpp:121
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
virtual void Process()=0
STL namespace.
FieldSharedPtr m_f
Field object.
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
void Stop()
Definition: Timer.cpp:62
static std::string npts
Definition: InputXml.cpp:46
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
Definition: FieldIO.h:55
boost::shared_ptr< DomainRange > DomainRangeShPtr
Definition: MeshGraph.h:157
double NekDouble
boost::shared_ptr< Field > FieldSharedPtr
Definition: Field.hpp:695
static DomainRangeShPtr NullDomainRangeShPtr
Definition: MeshGraph.h:158
void Start()
Definition: Timer.cpp:51
static bool GenerateUnOrderedVector(const char *const str, std::vector< NekDouble > &vec)
Definition: ParseUtils.hpp:128
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
Definition: Timer.cpp:108
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:54
std::map< int, ExpansionShPtr > ExpansionMap
Definition: MeshGraph.h:174
ModuleFactory & GetModuleFactory()
Abstract base class for input modules.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215