Nektar++
FieldConvert.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: FieldConvert.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: Field conversion utility.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 
35 #include <FieldUtils/Module.h>
38 #include <boost/algorithm/string.hpp>
39 #include <boost/program_options.hpp>
40 #include <string>
41 
42 using namespace std;
43 using namespace Nektar;
44 using namespace Nektar::FieldUtils;
45 
46 void CheckModules(vector<ModuleSharedPtr> &modules);
47 
48 void PrintExecutionSequence(vector<ModuleSharedPtr> &modules);
49 
50 void RunModule(ModuleSharedPtr module, po::variables_map &vm, bool verbose);
51 
52 int main(int argc, char *argv[])
53 {
54  LibUtilities::Timer timer;
55  timer.Start();
56 
57  po::options_description desc("Available options");
58 
59  // clang-format off
60  desc.add_options()
61  ("help,h", "Produce this help message.")
62  ("modules-list,l", "Print the list of available modules.")
63  ("output-points,n", po::value<int>(),
64  "Output at n equipspaced points along the "
65  "collapsed coordinates (for .dat, .vtu).")
66  ("output-points-hom-z", po::value<int>(),
67  "Number of planes in the z-direction for output of "
68  "Homogeneous 1D expansion(for .dat, .vtu).")
69  ("error,e", "Write error of fields for regression checking")
70  ("forceoutput,f", "Force the output to be written without any checks")
71  ("range,r", po::value<string>(),
72  "Define output range i.e. (-r xmin,xmax,ymin,ymax,zmin,zmax) "
73  "in which any vertex is contained.")
74  ("noequispaced", "Do not use equispaced output.")
75  ("nparts", po::value<int>(),
76  "Define nparts if running serial problem to mimic "
77  "parallel run with many partitions.")
78  ("npz", po::value<int>(),
79  "Used to define number of partitions in z for Homogeneous1D "
80  "expansions for parallel runs.")
81  ("npt", po::value<int>(),
82  "Used to define number of partitions in time for Parareal runs. ")
83  ("onlyshape", po::value<string>(),
84  "Only use element with defined shape type i.e. -onlyshape "
85  " Tetrahedron")
86  ("part-only", po::value<int>(),
87  "Partition into specified npart partitions and exit")
88  ("part-only-overlapping", po::value<int>(),
89  "Partition into specified npart overlapping partitions and exit")
90  ("modules-opt,p", po::value<string>(),
91  "Print options for a module.")
92  ("module,m", po::value<vector<string>>(),
93  "Specify modules which are to be used.")
94  ("useSessionVariables", "Use variables defined in session for output")
95  ("useSessionExpansion", "Use expansion defined in session.")
96  ("verbose,v", "Enable verbose mode.");
97  // clang-format on
98 
99  po::options_description hidden("Hidden options");
100  hidden.add_options()("input-file", po::value<vector<string>>(),
101  "Input filename");
102 
103  po::options_description cmdline_options;
104  cmdline_options.add(hidden).add(desc);
105 
106  po::options_description visible("Allowed options");
107  visible.add(desc);
108 
109  po::positional_options_description p;
110  p.add("input-file", -1);
111 
112  po::variables_map vm;
113 
114  try
115  {
116  po::store(po::command_line_parser(argc, argv)
117  .options(cmdline_options)
118  .positional(p)
119  .run(),
120  vm);
121  po::notify(vm);
122  }
123  catch (const std::exception &e)
124  {
125  cerr << e.what() << endl;
126  cerr << desc;
127  return 1;
128  }
129 
130  // If NEKTAR_DISABLE_BACKUPS environment variable is set, enable the
131  // forceoutput option.
132  if (std::getenv("NEKTAR_DISABLE_BACKUPS") != nullptr)
133  {
134  vm.insert(std::make_pair("forceoutput", po::variable_value()));
135  }
136 
137  // Print available modules.
138  if (vm.count("modules-list"))
139  {
141  return 1;
142  }
143 
144  if (vm.count("modules-opt"))
145  {
146  vector<string> tmp1;
147  boost::split(tmp1, vm["modules-opt"].as<string>(),
148  boost::is_any_of(":"));
149 
150  if (tmp1.size() != 2)
151  {
152  cerr << "ERROR: To specify a module, use one of in, out or proc "
153  << "together with the filename; for example in:vtk." << endl;
154  return 1;
155  }
156 
157  if (tmp1[0] != "in" && tmp1[0] != "out" && tmp1[0] != "proc")
158  {
159  cerr << "ERROR: Invalid module type " << tmp1[0] << endl;
160  return 1;
161  }
162 
164 
165  if (tmp1[0] == "in")
166  {
167  t = eInputModule;
168  }
169  else if (tmp1[0] == "out")
170  {
171  t = eOutputModule;
172  }
173  else if (tmp1[0] == "proc")
174  {
175  t = eProcessModule;
176  }
177 
178  FieldSharedPtr f = std::shared_ptr<Field>(new Field());
179  ModuleSharedPtr mod =
180  GetModuleFactory().CreateInstance(ModuleKey(t, tmp1[1]), f);
181  cerr << "Options for module " << tmp1[1] << ":" << endl;
182  mod->PrintConfig();
183  return 1;
184  }
185 
186  if (vm.count("help") || vm.count("input-file") != 1)
187  {
188  cerr << "Usage: FieldConvert [options] "
189  "[inputfile.xml] inputfile.ext1 outputfile.ext2"
190  << endl;
191  cout << desc;
192  cout << endl;
193  cout << "Example Usage: \n" << endl;
194  cout << "\t FieldConvert -m vorticity file.xml file.fld file_vort.fld "
195  << endl;
196  cout << "(This will add vorticity to file file.fld and put it in a "
197  "new file file_vort.fld. \n file.xml is a Nektar XML input "
198  "file containing the geometry.) "
199  << endl;
200  cout << endl;
201  cout << "\t FieldConvert file.xml file_vort.fld file_vort.dat " << endl;
202  cout << "(process file_vort.fld and make a tecplot output "
203  "file_vort.dat. file.xml is a\n Nektar XML input file "
204  "containing the geometry.) "
205  << endl;
206 
207  return 1;
208  }
209 
210  ASSERTL0(vm.count("input-file"),
211  "Must specify input(s) and/or output file.");
212  vector<string> inout = vm["input-file"].as<vector<string>>();
213 
214  /*
215  * Process list of modules. Each element of the vector of module
216  * strings can be in the following form:
217  *
218  * modname:arg1=a:arg2=b:arg3=c:arg4:arg5=asd
219  *
220  * where the only required argument is 'modname', specifing the
221  * name of the module to load.
222  */
223  FieldSharedPtr f = std::shared_ptr<Field>(new Field());
224  int nParts = 1;
225  int MPInprocs = 1;
226  int MPIrank = 0;
228 
229  if (LibUtilities::GetCommFactory().ModuleExists("ParallelMPI"))
230  {
231  // get hold of parallel communicator first
232  MPIComm = LibUtilities::GetCommFactory().CreateInstance("ParallelMPI",
233  argc, argv);
234 
235  if (vm.count("nparts"))
236  {
237  // work out number of processors to run in serial over partitions
238  MPInprocs = MPIComm->GetSpaceComm()->GetSize();
239  MPIrank = MPIComm->GetSpaceComm()->GetRank();
240 
241  nParts = vm["nparts"].as<int>();
242 
244  "Serial", argc, argv);
245  }
246  else
247  {
248  f->m_comm = MPIComm;
249  }
250  }
251  else
252  {
253  if (vm.count("nparts"))
254  {
255  nParts = vm["nparts"].as<int>();
256  }
257 
258  f->m_comm =
259  LibUtilities::GetCommFactory().CreateInstance("Serial", argc, argv);
260  }
261 
262  // For parallel-in-time
263  if (vm.count("npt"))
264  {
265  for (auto &io : inout)
266  {
267  fs::path inpath = io;
268  fs::path outpath = inpath.parent_path();
269  if (outpath.extension() == ".pit")
270  {
271  fs::path ftype = inpath.extension();
272  string filename = inpath.stem().string();
273  size_t start = filename.find_last_of("_") + 1;
274  int index =
275  atoi(filename.substr(start, filename.size()).c_str());
276  outpath /= filename.substr(0, start) +
277  std::to_string(index + f->m_comm->GetRank() %
278  vm["npt"].as<int>()) +
279  ftype.string();
280  io = outpath.string();
281  }
282  }
283  }
284 
285  vector<ModuleSharedPtr> modules;
286  vector<string> modcmds;
287  ModuleKey module;
288  ModuleSharedPtr mod;
289 
290  if (vm.count("verbose"))
291  {
292  f->m_verbose = true;
293  }
294 
295  if (vm.count("module"))
296  {
297  modcmds = vm["module"].as<vector<string>>();
298  }
299 
300  // Add input and output modules to beginning and end of this vector.
301  modcmds.insert(modcmds.begin(), inout.begin(), inout.end() - 1);
302  modcmds.push_back(*(inout.end() - 1));
303 
304  int nInput = inout.size() - 1;
305 
306  // For special case of part-only or part-only-overlapping options
307  // only require a single input file and so reset the nInputs to be
308  // of size inout.size(). Since the code will exit before reaching
309  // any output module this seems to work as expected
310  if (vm.count("part-only") || vm.count("part-only-overlapping"))
311  {
312  nInput = inout.size();
313  }
314 
315  InputModuleSharedPtr inputModule;
316  string outfilename;
317 
318  for (int i = 0; i < modcmds.size(); ++i)
319  {
320  // First split each command by the colon separator.
321  vector<string> tmp1;
322  int offset = 1;
323 
324  boost::split(tmp1, modcmds[i], boost::is_any_of(":"));
325 
326  if (i < nInput || i == modcmds.size() - 1)
327  {
328  // assume all modules are input unless last, or specified to be :out
329  module.first = (i < nInput ? eInputModule : eOutputModule);
330  if (tmp1.size() > 1 && tmp1.back() == "out")
331  {
332  module.first = eOutputModule;
333  tmp1.pop_back();
334  }
335 
336  // If no colon detected, automatically detect mesh type from
337  // file extension. Otherwise override and use tmp1[1] as the
338  // module to load. This also allows us to pass options to
339  // input/output modules. So, for example, to override
340  // filename.xml to be read as vtk, you use:
341  //
342  // filename.xml:vtk:opt1=arg1:opt2=arg2
343  if (tmp1.size() == 1)
344  {
345  // First, let's try to guess the input format if we're dealing
346  // with input files.
347  string guess;
348 
349  if (module.first == eInputModule)
350  {
351  guess = InputModule::GuessFormat(tmp1[0]);
352  }
353 
354  // Found file type.
355  if (guess != "")
356  {
357  if (f->m_verbose)
358  {
359  cout << "Using input module " << guess
360  << " for: " << tmp1[0] << endl;
361  }
362 
363  module.second = guess;
364  tmp1.push_back(string("infile=" + tmp1[0]));
365  }
366  else
367  {
368  int dot = tmp1[0].find_last_of('.') + 1;
369  string ext = tmp1[0].substr(dot, tmp1[0].length() - dot);
370 
371  // Remove trailing separator from extension to allow
372  // folder inputs using file.fld/
373  if (ext.back() == fs::path::preferred_separator)
374  {
375  ext.pop_back();
376  }
377 
378  if (ext == "gz")
379  {
380  string tmp2 = tmp1[0].substr(0, dot - 1);
381  dot = tmp2.find_last_of('.') + 1;
382  ext = tmp1[0].substr(dot, tmp1[0].length() - dot);
383  }
384 
385  module.second = ext;
386  tmp1.push_back(string(module.first == eInputModule
387  ? "infile="
388  : "outfile=") +
389  tmp1[0]);
390  }
391  }
392  else
393  {
394  module.second = tmp1[1];
395  tmp1.push_back(string(module.first == eInputModule
396  ? "infile="
397  : "outfile=") +
398  tmp1[0]);
399  offset++;
400  }
401  }
402  else
403  {
404  module.first = eProcessModule;
405  module.second = tmp1[0];
406  }
407 
408  // Create module.
409  mod = GetModuleFactory().CreateInstance(module, f);
410  modules.push_back(mod);
411 
412  if (module.first == eInputModule)
413  {
414  inputModule = std::dynamic_pointer_cast<InputModule>(mod);
415  inputModule->AddFile(module.second, tmp1[0]);
416  }
417  else if (module.first == eOutputModule)
418  {
419  outfilename = tmp1[0];
420  if (nParts > 1)
421  {
422  // if nParts is specified then ensure output modules
423  // write out mutipile files
424  mod->RegisterConfig("writemultiplefiles");
425  }
426  }
427  // Set options for this module.
428  for (int j = offset; j < tmp1.size(); ++j)
429  {
430  vector<string> tmp2;
431  boost::split(tmp2, tmp1[j], boost::is_any_of("="));
432 
433  if (tmp2.size() == 1)
434  {
435  mod->RegisterConfig(tmp2[0]);
436  }
437  else if (tmp2.size() == 2)
438  {
439  mod->RegisterConfig(tmp2[0], tmp2[1]);
440  }
441  else
442  {
443  cerr << "ERROR: Invalid module configuration: format is "
444  << "either :arg or :arg=val" << endl;
445  abort();
446  }
447  }
448 
449  // Ensure configuration options have been set.
450  mod->SetDefaults();
451  }
452 
453  // Include equispacedoutput module if needed
454  Array<OneD, int> modulesCount(SIZE_ModulePriority, 0);
455  for (int i = 0; i < modules.size(); ++i)
456  {
457  ++modulesCount[modules[i]->GetModulePriority()];
458  }
459  if (modulesCount[eModifyPts] != 0 && modulesCount[eCreatePts] == 0 &&
460  modulesCount[eConvertExpToPts] == 0)
461  {
462  module.first = eProcessModule;
463  module.second = string("equispacedoutput");
464  mod = GetModuleFactory().CreateInstance(module, f);
465  modules.push_back(mod);
466  mod->SetDefaults();
467  }
468 
469  // Check if modules provided are compatible
470  CheckModules(modules);
471  // Can't have ContField with range option (because of boundaries)
472  if (vm.count("range") && f->m_declareExpansionAsContField)
473  {
474  ASSERTL0(false, "Can't use range option with module requiring "
475  "a continuous expansion.");
476  }
477 
478  bool verbose = (f->m_verbose && f->m_comm->TreatAsRankZero());
479  if (verbose)
480  {
481  PrintExecutionSequence(modules);
482  }
483 
484  // Loop on partitions if required
485  LibUtilities::CommSharedPtr defComm = f->m_comm;
487  for (int p = MPIrank; p < nParts; p += MPInprocs)
488  {
489  // write out which partition is being processed and defined a
490  // new serial communicator
491  if (nParts > 1)
492  {
493  cout << endl << "Processing partition: " << p << endl;
494 
495  int rank = p;
496  f->ClearField();
497  partComm = std::shared_ptr<FieldConvertComm>(
498  new FieldConvertComm(argc, argv, nParts, rank));
499  }
500 
501  // Run field process.
502  for (int n = 0; n < SIZE_ModulePriority; ++n)
503  {
504  ModulePriority priority = static_cast<ModulePriority>(n);
505 
506  if (nParts > 1)
507  {
508  if (((priority == eCreateGraph) || (priority == eOutput)))
509  {
510  f->m_comm = partComm;
511  }
512  else
513  {
514  f->m_comm = defComm;
515  }
516  }
517 
518  for (int i = 0; i < modules.size(); ++i)
519  {
520  if (modules[i]->GetModulePriority() == priority)
521  {
522  RunModule(modules[i], vm, verbose);
523  }
524  }
525  }
526  }
527 
528  // write out Info file if required.
529  if (nParts > 1)
530  {
531  int i;
532  // check to see if we have created a fld file.
533  for (i = 0; i < modules.size(); ++i)
534  {
535  if (boost::iequals(modules[i]->GetModuleName(), "OutputFld"))
536  {
537  break;
538  }
539  }
540 
541  if (i != modules.size())
542  {
543  if (MPInprocs > 1)
544  {
545  MPIComm->GetSpaceComm()->Block();
546  }
547 
548  if (MPIrank == 0)
549  {
550  module.first = eOutputModule;
551  module.second = string("info");
552  mod = GetModuleFactory().CreateInstance(module, f);
553 
554  mod->RegisterConfig("nparts",
555  boost::lexical_cast<string>(nParts));
556  mod->SetDefaults();
557 
558  if (f->m_writeBndFld)
559  {
560  // find ending of output file and insert _b1, _b2
561  int dot = outfilename.find_last_of('.') + 1;
562  string ext =
563  outfilename.substr(dot, outfilename.length() - dot);
564  string name = outfilename.substr(0, dot - 1);
565 
566  for (int b = 0; b < f->m_bndRegionsToWrite.size(); ++b)
567  {
568  string outfilenew = name + "_b" +
569  boost::lexical_cast<string>(
570  f->m_bndRegionsToWrite[b]) +
571  "." + ext;
572  mod->RegisterConfig("outfile", outfilenew);
573  RunModule(mod, vm, verbose);
574  }
575  }
576  else
577  {
578  mod->RegisterConfig("outfile", outfilename);
579  RunModule(mod, vm, verbose);
580  }
581  }
582  }
583  }
584 
585  if (verbose)
586  {
587  timer.Stop();
588  NekDouble cpuTime = timer.TimePerTest(1);
589 
590  stringstream ss;
591  ss << cpuTime << "s";
592  cout << "Total CPU Time: " << setw(8) << left << ss.str() << endl;
593  }
594 
595  if (MPInprocs > 1)
596  {
597  MPIComm->GetSpaceComm()->Block();
598  MPIComm->GetSpaceComm()->Finalise();
599  }
600 
601  return 0;
602 }
603 
604 // This function checks validity conditions for the list of modules provided
605 void CheckModules(vector<ModuleSharedPtr> &modules)
606 {
607  // Count number of modules by priority
608  Array<OneD, int> modulesCount(SIZE_ModulePriority, 0);
609  for (int i = 0; i < modules.size(); ++i)
610  {
611  ++modulesCount[modules[i]->GetModulePriority()];
612  }
613 
614  // Modules of type eModifyFieldData require a eCreateFieldData module
615  if (modulesCount[eModifyFieldData] != 0 &&
616  modulesCount[eCreateFieldData] == 0)
617  {
618  stringstream ss;
619  ss << "Module(s): ";
620  for (int i = 0; i < modules.size(); ++i)
621  {
622  if (modules[i]->GetModulePriority() == eModifyFieldData)
623  {
624  ss << modules[i]->GetModuleName() << " ";
625  }
626  }
627  ss << "require fld input.";
628  ASSERTL0(false, ss.str());
629  }
630 
631  // Modules of type eFillExp require eCreateGraph without eCreateFieldData
632  if (modulesCount[eFillExp] != 0)
633  {
634  if (modulesCount[eCreateGraph] == 0 ||
635  modulesCount[eCreateFieldData] != 0)
636  {
637  stringstream ss;
638  ss << "Module(s): ";
639  for (int i = 0; i < modules.size(); ++i)
640  {
641  if (modules[i]->GetModulePriority() == eFillExp)
642  {
643  ss << modules[i]->GetModuleName() << " ";
644  }
645  }
646  ss << "require xml input without fld input.";
647  ASSERTL0(false, ss.str());
648  }
649  }
650 
651  // Modules of type eModifyExp and eBndExtraction
652  // require a eCreateGraph module
653  if ((modulesCount[eModifyExp] != 0 || modulesCount[eBndExtraction] != 0) &&
654  modulesCount[eCreateGraph] == 0)
655  {
656  stringstream ss;
657  ss << "Module(s): ";
658  for (int i = 0; i < modules.size(); ++i)
659  {
660  if (modules[i]->GetModulePriority() == eModifyExp ||
661  modules[i]->GetModulePriority() == eBndExtraction)
662  {
663  ss << modules[i]->GetModuleName() << " ";
664  }
665  }
666  ss << "require xml input.";
667  ASSERTL0(false, ss.str());
668  }
669 
670  // Modules of type eCreatePts should not be used with xml or fld inputs
671  if (modulesCount[eCreatePts] != 0)
672  {
673  if (modulesCount[eCreateGraph] != 0 ||
674  modulesCount[eCreateFieldData] != 0)
675  {
676  stringstream ss;
677  ss << "Module(s): ";
678  for (int i = 0; i < modules.size(); ++i)
679  {
680  if (modules[i]->GetModulePriority() == eCreatePts)
681  {
682  ss << modules[i]->GetModuleName() << " ";
683  }
684  }
685  ss << "should not use xml or fld inputs.";
686  ASSERTL0(false, ss.str());
687  }
688  }
689 
690  // Modules of type eConvertExpToPts require eCreateGraph, but are not
691  // compatible with eBndExtraction
692  if (modulesCount[eConvertExpToPts] != 0)
693  {
694  if (modulesCount[eCreateGraph] == 0)
695  {
696  stringstream ss;
697  ss << "Module(s): ";
698  for (int i = 0; i < modules.size(); ++i)
699  {
700  if (modules[i]->GetModulePriority() == eConvertExpToPts)
701  {
702  ss << modules[i]->GetModuleName() << " ";
703  }
704  }
705  ss << "require xml input.";
706  ASSERTL0(false, ss.str());
707  }
708  if (modulesCount[eBndExtraction] != 0)
709  {
710  stringstream ss;
711  ss << "Module(s): ";
712  for (int i = 0; i < modules.size(); ++i)
713  {
714  if (modules[i]->GetModulePriority() == eBndExtraction)
715  {
716  ss << modules[i]->GetModuleName() << " ";
717  }
718  }
719  ss << "is not compatible with module(s): ";
720  for (int i = 0; i < modules.size(); ++i)
721  {
722  if (modules[i]->GetModulePriority() == eConvertExpToPts)
723  {
724  ss << modules[i]->GetModuleName() << " ";
725  }
726  }
727  ss << ".";
728  ASSERTL0(false, ss.str());
729  }
730  }
731 }
732 
733 void PrintExecutionSequence(vector<ModuleSharedPtr> &modules)
734 {
735  bool first = true;
736  cout << "Execution sequence:" << endl;
737  for (int n = 0; n < SIZE_ModulePriority; ++n)
738  {
739  ModulePriority priority = static_cast<ModulePriority>(n);
740  for (int i = 0; i < modules.size(); ++i)
741  {
742  if (modules[i]->GetModulePriority() == priority)
743  {
744  if (first)
745  {
746  cout << "\t" << modules[i]->GetModuleName();
747  first = false;
748  }
749  else
750  {
751  cout << " -> " << modules[i]->GetModuleName();
752  }
753  }
754  }
755  }
756  cout << endl;
757 }
758 
759 void RunModule(ModuleSharedPtr module, po::variables_map &vm, bool verbose)
760 {
761  LibUtilities::Timer moduleTimer;
762  if (verbose)
763  {
764  moduleTimer.Start();
765 
766  cout << module->GetModuleName() << ": "
767  << module->GetModuleDescription() << endl;
768  }
769  module->Process(vm);
770  cout.flush();
771  if (verbose)
772  {
773  moduleTimer.Stop();
774  NekDouble cpuTime = moduleTimer.TimePerTest(1);
775 
776  stringstream ss;
777  ss << cpuTime << "s";
778  cout << module->GetModuleName() << " CPU Time: " << setw(8) << left
779  << ss.str() << endl;
780  }
781 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
int main(int argc, char *argv[])
void PrintExecutionSequence(vector< ModuleSharedPtr > &modules)
void RunModule(ModuleSharedPtr module, po::variables_map &vm, bool verbose)
void CheckModules(vector< ModuleSharedPtr > &modules)
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
void PrintAvailableClasses(std::ostream &pOut=std::cout)
Prints the available classes to stdout.
Definition: NekFactory.hpp:232
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
Definition: Timer.cpp:68
std::shared_ptr< Field > FieldSharedPtr
Definition: Field.hpp:991
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:317
std::shared_ptr< InputModule > InputModuleSharedPtr
Definition: Module.h:285
std::shared_ptr< Module > ModuleSharedPtr
Definition: Module.h:321
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49
CommFactory & GetCommFactory()
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble