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 
45 static std::string npts = LibUtilities::SessionReader::RegisterCmdLineArgument(
46  "NumberOfPoints","n","Define number of points to dump output");
47 
48 namespace Nektar
49 {
50 namespace Utilities
51 {
52 
53 ModuleKey InputXml::m_className[5] = {
55  ModuleKey(eInputModule, "xml"), InputXml::create,
56  "Reads Xml file."),
58  ModuleKey(eInputModule, "xml.gz"), InputXml::create,
59  "Reads Xml file."),
60 };
61 
62 
63 /**
64  * @brief Set up InputXml object.
65  *
66  */
67 InputXml::InputXml(FieldSharedPtr f) : InputModule(f)
68 {
69  m_allowedFiles.insert("xml");
70  m_allowedFiles.insert("xml.gz");
71  m_allowedFiles.insert("fld"); // these files could be allowed with xml files
72  m_allowedFiles.insert("chk");
73  m_allowedFiles.insert("rst");
74 }
75 
76 
77 /**
78  *
79  */
81 {
82 }
83 
84 
85 /**
86  *
87  */
88 void InputXml::Process(po::variables_map &vm)
89 {
90  Timer timer, timerpart;
91 
92  //check for multiple calls to inputXml due to split xml
93  //files. If so just return
94  int expsize = m_f->m_exp.size();
95  m_f->m_comm->AllReduce(expsize,LibUtilities::ReduceMax);
96 
97  if(expsize != 0)
98  {
99  return;
100  }
101 
102  if(m_f->m_verbose)
103  {
104  if(m_f->m_comm->GetRank() == 0)
105  {
106  cout << "Processing input xml file" << endl;
107  timer.Start();
108  timerpart.Start();
109  }
110  }
111 
112  // check to see if fld file defined so can use in
113  // expansion defintion if required
114  string fldending;
115  bool fldfilegiven = true;
116 
117  //Determine appropriate field input
118  if(m_f->m_inputfiles.count("fld") != 0)
119  {
120  fldending = "fld";
121  }
122  else if(m_f->m_inputfiles.count("chk") != 0)
123  {
124  fldending = "chk";
125  }
126  else if (m_f->m_inputfiles.count("rst") != 0)
127  {
128  fldending = "rst";
129  }
130  else
131  {
132  fldfilegiven = false;
133  }
134 
135  string xml_ending = "xml";
136  string xml_gz_ending = "xml.gz";
137 
138  std::vector<std::string> files;
139  // load .xml ending
140  for (int i = 0; i < m_f->m_inputfiles[xml_ending].size(); ++i)
141  {
142  files.push_back(m_f->m_inputfiles[xml_ending][i]);
143  }
144 
145  // load any .xml.gz endings
146  for (int j =0; j < m_f->m_inputfiles[xml_gz_ending].size(); ++j)
147  {
148  files.push_back(m_f->m_inputfiles[xml_gz_ending][j]);
149  }
150 
153 
154 
155  // define range to process output
156  if(vm.count("range"))
157  {
158  vector<NekDouble> values;
160  vm["range"].as<string>().c_str(), values),
161  "Failed to interpret range string");
162 
163  ASSERTL0(values.size() > 1,
164  "Do not have minimum values of xmin,xmax");
165  ASSERTL0(values.size() % 2 == 0,
166  "Do not have an even number of range values");
167 
168  int nvalues = values.size()/2;
171 
172  rng->m_doZrange = false;
173  rng->m_doYrange = false;
174  rng->m_checkShape = false;
175 
176  switch(nvalues)
177  {
178  case 3:
179  rng->m_doZrange = true;
180  rng->m_zmin = values[4];
181  rng->m_zmax = values[5];
182  case 2:
183  rng->m_doYrange = true;
184  rng->m_ymin = values[2];
185  rng->m_ymax = values[3];
186  case 1:
187  rng->m_doXrange = true;
188  rng->m_xmin = values[0];
189  rng->m_xmax = values[1];
190  break;
191  default:
192  ASSERTL0(false,"too many values specfied in range");
193  }
194  }
195 
196  // define range to only take a single shape.
197  if(vm.count("onlyshape"))
198  {
200  {
203  rng->m_doXrange = false;
204  rng->m_doYrange = false;
205  rng->m_doZrange = false;
206  }
207 
208  rng->m_checkShape = true;
209 
210  string shapematch =
211  boost::to_upper_copy(vm["onlyshape"].as<string>());
212  int i;
213  for(i = 0; i < LibUtilities::SIZE_ShapeType; ++i)
214  {
215  string shapeval = LibUtilities::ShapeTypeMap[i];
216  boost::to_upper(shapeval);
217  if(shapematch.compare(shapeval) == 0)
218  {
219  rng->m_shapeType = (LibUtilities::ShapeType)i;
220  break;
221  }
222  }
223  ASSERTL0(i != LibUtilities::SIZE_ShapeType,
224  "Failed to find shape type in -onlyshape command line "
225  "argument");
226  }
227 
228  // Set up command lines options that will be passed through to SessionReader
229  vector<string> cmdArgs;
230  cmdArgs.push_back("FieldConvert");
231 
232  if(m_f->m_verbose)
233  {
234  cmdArgs.push_back("--verbose");
235  }
236 
237  if(vm.count("shared-filesystem"))
238  {
239  cmdArgs.push_back("--shared-filesystem");
240  }
241 
242  if(vm.count("part-only"))
243  {
244  cmdArgs.push_back("--part-only");
245  cmdArgs.push_back(
246  boost::lexical_cast<string>(vm["part-only"].as<int>()));
247  }
248 
249  if(vm.count("part-only-overlapping"))
250  {
251  cmdArgs.push_back("--part-only-overlapping");
252  cmdArgs.push_back(
253  boost::lexical_cast<string>(vm["part-only-overlapping"].as<int>()));
254  }
255 
256  int argc = cmdArgs.size();
257  const char **argv = new const char*[argc];
258  for (int i = 0; i < argc; ++i)
259  {
260  argv[i] = cmdArgs[i].c_str();
261  }
262 
264  CreateInstance(argc, (char **) argv, files, m_f->m_comm);
265 
266  // Free up memory.
267  delete [] argv;
268 
269  if(m_f->m_verbose)
270  {
271  if(m_f->m_comm->GetRank() == 0)
272  {
273  timerpart.Stop();
274  NekDouble cpuTime = timerpart.TimePerTest(1);
275 
276  stringstream ss;
277  ss << cpuTime << "s";
278  cout << "\t InputXml session reader CPU Time: " << setw(8) << left
279  << ss.str() << endl;
280  timerpart.Start();
281  }
282  }
283 
284  m_f->m_graph = SpatialDomains::MeshGraph::Read(m_f->m_session,rng);
286  ::AllocateSharedPtr(m_f->m_session->GetComm());
287 
288  if(m_f->m_verbose)
289  {
290  if(m_f->m_comm->GetRank() == 0)
291  {
292  timerpart.Stop();
293  NekDouble cpuTime = timerpart.TimePerTest(1);
294 
295  stringstream ss;
296  ss << cpuTime << "s";
297  cout << "\t InputXml mesh graph setup CPU Time: " << setw(8) << left
298  << ss.str() << endl;
299  timerpart.Start();
300  }
301  }
302 
303  // currently load all field (possibly could read data from
304  // expansion list but it is re-arranged in expansion)
305  const SpatialDomains::ExpansionMap &expansions = m_f->m_graph->GetExpansions();
306 
307  // if Range has been speficied it is possible to have a
308  // partition which is empty so ccheck this and return if
309  // no elements present.
310  if(!expansions.size())
311  {
312  return;
313  }
314 
315  m_f->m_exp.resize(1);
316 
317  // load fielddef header if fld file is defined. This gives
318  // precedence to Homogeneous definition in fld file
319  int NumHomogeneousDir = 0;
320  if(fldfilegiven)
321  {
322  // use original expansion to identify which elements are in
323  // this partition/subrange
324 
325  Array<OneD,int> ElementGIDs(expansions.size());
326  SpatialDomains::ExpansionMap::const_iterator expIt;
327 
328  int i = 0;
329  for (expIt = expansions.begin(); expIt != expansions.end(); ++expIt)
330  {
331  ElementGIDs[i++] = expIt->second->m_geomShPtr->GetGlobalID();
332  }
333 
334  m_f->m_fld->Import(m_f->m_inputfiles[fldending][0],m_f->m_fielddef,
337  ElementGIDs);
338  NumHomogeneousDir = m_f->m_fielddef[0]->m_numHomogeneousDir;
339 
340  //----------------------------------------------
341  // Set up Expansion information to use mode order from field
342  m_f->m_graph->SetExpansions(m_f->m_fielddef);
343  }
344  else
345  {
346  if(m_f->m_session->DefinesSolverInfo("HOMOGENEOUS"))
347  {
348  std::string HomoStr = m_f->m_session->GetSolverInfo("HOMOGENEOUS");
349 
350  if((HomoStr == "HOMOGENEOUS1D") || (HomoStr == "Homogeneous1D")
351  || (HomoStr == "1D") || (HomoStr == "Homo1D"))
352  {
353  NumHomogeneousDir = 1;
354  }
355  if((HomoStr == "HOMOGENEOUS2D") || (HomoStr == "Homogeneous2D")
356  || (HomoStr == "2D") || (HomoStr == "Homo2D"))
357  {
358  NumHomogeneousDir = 2;
359  }
360  }
361  }
362 
363  // reset expansion defintion to use equispaced points if required.
364  if(m_requireEquiSpaced || vm.count("output-points"))
365  {
366  int nPointsNew = 0;
367 
368  if(vm.count("output-points"))
369  {
370  nPointsNew = vm["output-points"].as<int>();
371  }
372 
373 
374  m_f->m_graph->SetExpansionsToEvenlySpacedPoints(nPointsNew);
375  }
376  else
377  {
378  if(vm.count("output-points"))
379  {
380  int nPointsNew = vm["output-points"].as<int>();
381  m_f->m_graph->SetExpansionsToPointOrder(nPointsNew);
382  }
383  }
384 
385  if(m_f->m_verbose)
386  {
387  if(m_f->m_comm->GetRank() == 0)
388  {
389  timerpart.Stop();
390  NekDouble cpuTime = timerpart.TimePerTest(1);
391 
392  stringstream ss;
393  ss << cpuTime << "s";
394  cout << "\t InputXml setexpansion CPU Time: " << setw(8) << left
395  << ss.str() << endl;
396  timerpart.Start();
397  }
398  }
399 
400  if(m_f->m_verbose)
401  {
402  if(m_f->m_comm->GetRank() == 0)
403  {
404  timerpart.Stop();
405  NekDouble cpuTime = timerpart.TimePerTest(1);
406 
407  stringstream ss;
408  ss << cpuTime << "s";
409  cout << "\t InputXml setexpansion CPU Time: " << setw(8) << left
410  << ss.str() << endl;
411  timerpart.Start();
412  }
413  }
414 
415  // Override number of planes with value from cmd line
416  if(NumHomogeneousDir == 1 && vm.count("output-points-hom-z"))
417  {
418  int expdim = m_f->m_graph->GetMeshDimension();
419  m_f->m_fielddef[0]->m_numModes[expdim] = vm["output-points-hom-z"].as<int>();
420  }
421 
422  m_f->m_exp[0] = m_f->SetUpFirstExpList(NumHomogeneousDir,fldfilegiven);
423 
424  if(m_f->m_verbose)
425  {
426  if(m_f->m_comm->GetRank() == 0)
427  {
428  timerpart.Stop();
429  NekDouble cpuTime = timerpart.TimePerTest(1);
430 
431  stringstream ss1;
432 
433  ss1 << cpuTime << "s";
434  cout << "\t InputXml set first exp CPU Time: " << setw(8) << left
435  << ss1.str() << endl;
436 
437 
438  timer.Stop();
439  cpuTime = timer.TimePerTest(1);
440 
441  stringstream ss;
442  ss << cpuTime << "s";
443  cout << "InputXml CPU Time: " << setw(8) << left
444  << ss.str() << endl;
445 
446  }
447  }
448 }
449 }
450 }
#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:119
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:45
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