Nektar++
Functions
FieldConvert.cpp File Reference
#include <FieldUtils/Module.h>
#include <LibUtilities/BasicUtils/FileSystem.h>
#include <LibUtilities/BasicUtils/Timer.h>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <string>

Go to the source code of this file.

Functions

void CheckModules (vector< ModuleSharedPtr > &modules)
 
void PrintExecutionSequence (vector< ModuleSharedPtr > &modules)
 
void RunModule (ModuleSharedPtr module, po::variables_map &vm, bool verbose)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ CheckModules()

void CheckModules ( vector< ModuleSharedPtr > &  modules)

Definition at line 585 of file FieldConvert.cpp.

586 {
587  // Count number of modules by priority
588  Array<OneD, int> modulesCount(SIZE_ModulePriority, 0);
589  for (int i = 0; i < modules.size(); ++i)
590  {
591  ++modulesCount[modules[i]->GetModulePriority()];
592  }
593 
594  // Modules of type eModifyFieldData require a eCreateFieldData module
595  if (modulesCount[eModifyFieldData] != 0 &&
596  modulesCount[eCreateFieldData] == 0)
597  {
598  stringstream ss;
599  ss << "Module(s): ";
600  for (int i = 0; i < modules.size(); ++i)
601  {
602  if (modules[i]->GetModulePriority() == eModifyFieldData)
603  {
604  ss << modules[i]->GetModuleName() << " ";
605  }
606  }
607  ss << "require fld input.";
608  ASSERTL0(false, ss.str());
609  }
610 
611  // Modules of type eFillExp require eCreateGraph without eCreateFieldData
612  if (modulesCount[eFillExp] != 0)
613  {
614  if (modulesCount[eCreateGraph] == 0 ||
615  modulesCount[eCreateFieldData] != 0)
616  {
617  stringstream ss;
618  ss << "Module(s): ";
619  for (int i = 0; i < modules.size(); ++i)
620  {
621  if (modules[i]->GetModulePriority() == eFillExp)
622  {
623  ss << modules[i]->GetModuleName() << " ";
624  }
625  }
626  ss << "require xml input without fld input.";
627  ASSERTL0(false, ss.str());
628  }
629  }
630 
631  // Modules of type eModifyExp and eBndExtraction
632  // require a eCreateGraph module
633  if ((modulesCount[eModifyExp] != 0 || modulesCount[eBndExtraction] != 0) &&
634  modulesCount[eCreateGraph] == 0)
635  {
636  stringstream ss;
637  ss << "Module(s): ";
638  for (int i = 0; i < modules.size(); ++i)
639  {
640  if (modules[i]->GetModulePriority() == eModifyExp ||
641  modules[i]->GetModulePriority() == eBndExtraction)
642  {
643  ss << modules[i]->GetModuleName() << " ";
644  }
645  }
646  ss << "require xml input.";
647  ASSERTL0(false, ss.str());
648  }
649 
650  // Modules of type eCreatePts should not be used with xml or fld inputs
651  if (modulesCount[eCreatePts] != 0)
652  {
653  if (modulesCount[eCreateGraph] != 0 ||
654  modulesCount[eCreateFieldData] != 0)
655  {
656  stringstream ss;
657  ss << "Module(s): ";
658  for (int i = 0; i < modules.size(); ++i)
659  {
660  if (modules[i]->GetModulePriority() == eCreatePts)
661  {
662  ss << modules[i]->GetModuleName() << " ";
663  }
664  }
665  ss << "should not use xml or fld inputs.";
666  ASSERTL0(false, ss.str());
667  }
668  }
669 
670  // Modules of type eConvertExpToPts require eCreateGraph, but are not
671  // compatible with eBndExtraction
672  if (modulesCount[eConvertExpToPts] != 0)
673  {
674  if (modulesCount[eCreateGraph] == 0)
675  {
676  stringstream ss;
677  ss << "Module(s): ";
678  for (int i = 0; i < modules.size(); ++i)
679  {
680  if (modules[i]->GetModulePriority() == eConvertExpToPts)
681  {
682  ss << modules[i]->GetModuleName() << " ";
683  }
684  }
685  ss << "require xml input.";
686  ASSERTL0(false, ss.str());
687  }
688  if (modulesCount[eBndExtraction] != 0)
689  {
690  stringstream ss;
691  ss << "Module(s): ";
692  for (int i = 0; i < modules.size(); ++i)
693  {
694  if (modules[i]->GetModulePriority() == eBndExtraction)
695  {
696  ss << modules[i]->GetModuleName() << " ";
697  }
698  }
699  ss << "is not compatible with module(s): ";
700  for (int i = 0; i < modules.size(); ++i)
701  {
702  if (modules[i]->GetModulePriority() == eConvertExpToPts)
703  {
704  ss << modules[i]->GetModuleName() << " ";
705  }
706  }
707  ss << ".";
708  ASSERTL0(false, ss.str());
709  }
710  }
711 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215

References ASSERTL0, Nektar::FieldUtils::eBndExtraction, Nektar::FieldUtils::eConvertExpToPts, Nektar::FieldUtils::eCreateFieldData, Nektar::FieldUtils::eCreateGraph, Nektar::FieldUtils::eCreatePts, Nektar::FieldUtils::eFillExp, Nektar::FieldUtils::eModifyExp, Nektar::FieldUtils::eModifyFieldData, and Nektar::FieldUtils::SIZE_ModulePriority.

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 52 of file FieldConvert.cpp.

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",
62  "Produce this help message.")
63  ("modules-list,l",
64  "Print the list of available modules.")
65  ("output-points,n", po::value<int>(),
66  "Output at n equipspaced points along the "
67  "collapsed coordinates (for .dat, .vtu).")
68  ("output-points-hom-z", po::value<int>(),
69  "Number of planes in the z-direction for output of "
70  "Homogeneous 1D expansion(for .dat, .vtu).")
71  ("error,e",
72  "Write error of fields for regression checking")
73  ("forceoutput,f",
74  "Force the output to be written without any checks")
75  ("range,r", po::value<string>(),
76  "Define output range i.e. (-r xmin,xmax,ymin,ymax,zmin,zmax) "
77  "in which any vertex is contained.")
78  ("noequispaced",
79  "Do not use equispaced output.")
80  ("nparts", po::value<int>(),
81  "Define nparts if running serial problem to mimic "
82  "parallel run with many partitions.")
83  ("npz", po::value<int>(),
84  "Used to define number of partitions in z for Homogeneous1D "
85  "expansions for parallel runs.")
86  ("onlyshape", po::value<string>(),
87  "Only use element with defined shape type i.e. -onlyshape "
88  " Tetrahedron")
89  ("part-only", po::value<int>(),
90  "Partition into specified npart partitions and exit")
91  ("part-only-overlapping", po::value<int>(),
92  "Partition into specified npart overlapping partitions and exit")
93  ("modules-opt,p", po::value<string>(),
94  "Print options for a module.")
95  ("module,m", po::value<vector<string> >(),
96  "Specify modules which are to be used.")
97  ("useSessionVariables",
98  "Use variables defined in session for output")
99  ("useSessionExpansion",
100  "Use expansion defined in session.")
101  ("verbose,v",
102  "Enable verbose mode.");
103  // clang-format on
104 
105  po::options_description hidden("Hidden options");
106 
107  // clang-format off
108  hidden.add_options()
109  ("input-file", po::value<vector<string> >(), "Input filename");
110  // clang-format on
111 
112  po::options_description cmdline_options;
113  cmdline_options.add(hidden).add(desc);
114 
115  po::options_description visible("Allowed options");
116  visible.add(desc);
117 
118  po::positional_options_description p;
119  p.add("input-file", -1);
120 
121  po::variables_map vm;
122 
123  try
124  {
125  po::store(po::command_line_parser(argc, argv)
126  .options(cmdline_options)
127  .positional(p)
128  .run(),
129  vm);
130  po::notify(vm);
131  }
132  catch (const std::exception &e)
133  {
134  cerr << e.what() << endl;
135  cerr << desc;
136  return 1;
137  }
138 
139 #ifdef NEKTAR_DISABLE_BACKUPS
140  vm.insert(std::make_pair("forceoutput", po::variable_value()));
141 #endif
142 
143  // Print available modules.
144  if (vm.count("modules-list"))
145  {
147  return 1;
148  }
149 
150  if (vm.count("modules-opt"))
151  {
152  vector<string> tmp1;
153  boost::split(tmp1, vm["modules-opt"].as<string>(),
154  boost::is_any_of(":"));
155 
156  if (tmp1.size() != 2)
157  {
158  cerr << "ERROR: To specify a module, use one of in, out or proc "
159  << "together with the filename; for example in:vtk." << endl;
160  return 1;
161  }
162 
163  if (tmp1[0] != "in" && tmp1[0] != "out" && tmp1[0] != "proc")
164  {
165  cerr << "ERROR: Invalid module type " << tmp1[0] << endl;
166  return 1;
167  }
168 
169  ModuleType t;
170 
171  if (tmp1[0] == "in")
172  {
173  t = eInputModule;
174  }
175  else if (tmp1[0] == "out")
176  {
177  t = eOutputModule;
178  }
179  else if (tmp1[0] == "proc")
180  {
181  t = eProcessModule;
182  }
183 
184  FieldSharedPtr f = std::shared_ptr<Field>(new Field());
185  ModuleSharedPtr mod =
186  GetModuleFactory().CreateInstance(ModuleKey(t, tmp1[1]), f);
187  cerr << "Options for module " << tmp1[1] << ":" << endl;
188  mod->PrintConfig();
189  return 1;
190  }
191 
192  if (vm.count("help") || vm.count("input-file") != 1)
193  {
194  cerr << "Usage: FieldConvert [options] inputfile.ext1 outputfile.ext2"
195  << endl;
196  cout << desc;
197  cout << endl;
198  cout << "Example Usage: \n" << endl;
199  cout << "\t FieldConvert -m vorticity file.xml file.fld file_vort.fld "
200  << endl;
201  cout << "(This will add vorticity to file file.fld and put it in a "
202  "new file file_vort.fld) "
203  << endl;
204  cout << endl;
205  cout << "\t FieldConvert file.xml file_vort.fld file_vort.dat " << endl;
206  cout << "(process file_vort.fld and make a tecplot output "
207  "file_vort.dat) "
208  << endl;
209 
210  return 1;
211  }
212 
213  ASSERTL0(vm.count("input-file"),
214  "Must specify input(s) and/or output file.");
215  vector<string> inout = vm["input-file"].as<vector<string>>();
216 
217  /*
218  * Process list of modules. Each element of the vector of module
219  * strings can be in the following form:
220  *
221  * modname:arg1=a:arg2=b:arg3=c:arg4:arg5=asd
222  *
223  * where the only required argument is 'modname', specifing the
224  * name of the module to load.
225  */
226  FieldSharedPtr f = std::shared_ptr<Field>(new Field());
227  int nParts = 1;
228  int MPInprocs = 1;
229  int MPIrank = 0;
231 
232  if (LibUtilities::GetCommFactory().ModuleExists("ParallelMPI"))
233  {
234  // get hold of parallel communicator first
235  MPIComm = LibUtilities::GetCommFactory().CreateInstance("ParallelMPI",
236  argc, argv);
237 
238  if (vm.count("nparts"))
239  {
240  // work out number of processors to run in serial over partitions
241  MPInprocs = MPIComm->GetSize();
242  MPIrank = MPIComm->GetRank();
243 
244  nParts = vm["nparts"].as<int>();
245 
247  "Serial", argc, argv);
248  }
249  else
250  {
251  f->m_comm = MPIComm;
252  }
253  }
254  else
255  {
256  if (vm.count("nparts"))
257  {
258  nParts = vm["nparts"].as<int>();
259  }
260 
261  f->m_comm =
262  LibUtilities::GetCommFactory().CreateInstance("Serial", argc, argv);
263  }
264 
265  vector<ModuleSharedPtr> modules;
266  vector<string> modcmds;
267  ModuleKey module;
268  ModuleSharedPtr mod;
269 
270  if (vm.count("verbose"))
271  {
272  f->m_verbose = true;
273  }
274 
275  if (vm.count("module"))
276  {
277  modcmds = vm["module"].as<vector<string>>();
278  }
279 
280  // Add input and output modules to beginning and end of this vector.
281  modcmds.insert(modcmds.begin(), inout.begin(), inout.end() - 1);
282  modcmds.push_back(*(inout.end() - 1));
283 
284  int nInput = inout.size() - 1;
285 
286  // For special case of part-only or part-only-overlapping options
287  // only require a single input file and so reset the nInputs to be
288  // of size inout.size(). Since the code will exit before reaching
289  // any output module this seems to work as expected
290  if (vm.count("part-only") || vm.count("part-only-overlapping"))
291  {
292  nInput = inout.size();
293  }
294 
295  InputModuleSharedPtr inputModule;
296  string outfilename;
297 
298  for (int i = 0; i < modcmds.size(); ++i)
299  {
300  // First split each command by the colon separator.
301  vector<string> tmp1;
302  int offset = 1;
303 
304  boost::split(tmp1, modcmds[i], boost::is_any_of(":"));
305 
306  if (i < nInput || i == modcmds.size() - 1)
307  {
308  // assume all modules are input unless last, or specified to be :out
309  module.first = (i < nInput ? eInputModule : eOutputModule);
310  if (tmp1.size() > 1 && tmp1.back() == "out")
311  {
312  module.first = eOutputModule;
313  tmp1.pop_back();
314  }
315 
316  // If no colon detected, automatically detect mesh type from
317  // file extension. Otherwise override and use tmp1[1] as the
318  // module to load. This also allows us to pass options to
319  // input/output modules. So, for example, to override
320  // filename.xml to be read as vtk, you use:
321  //
322  // filename.xml:vtk:opt1=arg1:opt2=arg2
323  if (tmp1.size() == 1)
324  {
325  // First, let's try to guess the input format if we're dealing
326  // with input files.
327  string guess;
328 
329  if (module.first == eInputModule)
330  {
331  guess = InputModule::GuessFormat(tmp1[0]);
332  }
333 
334  // Found file type.
335  if (guess != "")
336  {
337  if (f->m_verbose)
338  {
339  cout << "Using input module " << guess
340  << " for: " << tmp1[0] << endl;
341  }
342 
343  module.second = guess;
344  tmp1.push_back(string("infile=" + tmp1[0]));
345  }
346  else
347  {
348  int dot = tmp1[0].find_last_of('.') + 1;
349  string ext = tmp1[0].substr(dot, tmp1[0].length() - dot);
350 
351  // Remove trailing separator from extension to allow
352  // folder inputs using file.fld/
353  if (ext.back() == fs::path::preferred_separator)
354  {
355  ext.pop_back();
356  }
357 
358  if (ext == "gz")
359  {
360  string tmp2 = tmp1[0].substr(0, dot - 1);
361  dot = tmp2.find_last_of('.') + 1;
362  ext = tmp1[0].substr(dot, tmp1[0].length() - dot);
363  }
364 
365  module.second = ext;
366  tmp1.push_back(string(module.first == eInputModule
367  ? "infile="
368  : "outfile=") +
369  tmp1[0]);
370  }
371  }
372  else
373  {
374  module.second = tmp1[1];
375  tmp1.push_back(string(module.first == eInputModule
376  ? "infile="
377  : "outfile=") +
378  tmp1[0]);
379  offset++;
380  }
381  }
382  else
383  {
384  module.first = eProcessModule;
385  module.second = tmp1[0];
386  }
387 
388  // Create module.
389  mod = GetModuleFactory().CreateInstance(module, f);
390  modules.push_back(mod);
391 
392  if (module.first == eInputModule)
393  {
394  inputModule = std::dynamic_pointer_cast<InputModule>(mod);
395  inputModule->AddFile(module.second, tmp1[0]);
396  }
397  else if (module.first == eOutputModule)
398  {
399  outfilename = tmp1[0];
400  if (nParts > 1)
401  {
402  // if nParts is specified then ensure output modules
403  // write out mutipile files
404  mod->RegisterConfig("writemultiplefiles");
405  }
406  }
407  // Set options for this module.
408  for (int j = offset; j < tmp1.size(); ++j)
409  {
410  vector<string> tmp2;
411  boost::split(tmp2, tmp1[j], boost::is_any_of("="));
412 
413  if (tmp2.size() == 1)
414  {
415  mod->RegisterConfig(tmp2[0]);
416  }
417  else if (tmp2.size() == 2)
418  {
419  mod->RegisterConfig(tmp2[0], tmp2[1]);
420  }
421  else
422  {
423  cerr << "ERROR: Invalid module configuration: format is "
424  << "either :arg or :arg=val" << endl;
425  abort();
426  }
427  }
428 
429  // Ensure configuration options have been set.
430  mod->SetDefaults();
431  }
432 
433  // Include equispacedoutput module if needed
434  Array<OneD, int> modulesCount(SIZE_ModulePriority, 0);
435  for (int i = 0; i < modules.size(); ++i)
436  {
437  ++modulesCount[modules[i]->GetModulePriority()];
438  }
439  if (modulesCount[eModifyPts] != 0 && modulesCount[eCreatePts] == 0 &&
440  modulesCount[eConvertExpToPts] == 0)
441  {
442  module.first = eProcessModule;
443  module.second = string("equispacedoutput");
444  mod = GetModuleFactory().CreateInstance(module, f);
445  modules.push_back(mod);
446  mod->SetDefaults();
447  }
448 
449  // Check if modules provided are compatible
450  CheckModules(modules);
451  // Can't have ContField with range option (because of boundaries)
452  if (vm.count("range") && f->m_declareExpansionAsContField)
453  {
454  ASSERTL0(false, "Can't use range option with module requiring "
455  "a continuous expansion.");
456  }
457 
458  bool verbose = (f->m_verbose && f->m_comm->TreatAsRankZero());
459  if (verbose)
460  {
461  PrintExecutionSequence(modules);
462  }
463 
464  // Loop on partitions if required
465  LibUtilities::CommSharedPtr defComm = f->m_comm;
467  for (int p = MPIrank; p < nParts; p += MPInprocs)
468  {
469  // write out which partition is being processed and defined a
470  // new serial communicator
471  if (nParts > 1)
472  {
473  cout << endl << "Processing partition: " << p << endl;
474 
475  int rank = p;
476  f->ClearField();
477  partComm = std::shared_ptr<FieldConvertComm>(
478  new FieldConvertComm(argc, argv, nParts, rank));
479  }
480 
481  // Run field process.
482  for (int n = 0; n < SIZE_ModulePriority; ++n)
483  {
484  ModulePriority priority = static_cast<ModulePriority>(n);
485 
486  if (nParts > 1)
487  {
488  if (((priority == eCreateGraph) || (priority == eOutput)))
489  {
490  f->m_comm = partComm;
491  }
492  else
493  {
494  f->m_comm = defComm;
495  }
496  }
497 
498  for (int i = 0; i < modules.size(); ++i)
499  {
500  if (modules[i]->GetModulePriority() == priority)
501  {
502  RunModule(modules[i], vm, verbose);
503  }
504  }
505  }
506  }
507 
508  // write out Info file if required.
509  if (nParts > 1)
510  {
511  int i;
512  // check to see if we have created a fld file.
513  for (i = 0; i < modules.size(); ++i)
514  {
515  if (boost::iequals(modules[i]->GetModuleName(), "OutputFld"))
516  {
517  break;
518  }
519  }
520 
521  if (i != modules.size())
522  {
523  if (MPInprocs > 1)
524  {
525  MPIComm->Block();
526  }
527 
528  if (MPIrank == 0)
529  {
530  module.first = eOutputModule;
531  module.second = string("info");
532  mod = GetModuleFactory().CreateInstance(module, f);
533 
534  mod->RegisterConfig("nparts",
535  boost::lexical_cast<string>(nParts));
536  mod->SetDefaults();
537 
538  if (f->m_writeBndFld)
539  {
540  // find ending of output file and insert _b1, _b2
541  int dot = outfilename.find_last_of('.') + 1;
542  string ext =
543  outfilename.substr(dot, outfilename.length() - dot);
544  string name = outfilename.substr(0, dot - 1);
545 
546  for (int b = 0; b < f->m_bndRegionsToWrite.size(); ++b)
547  {
548  string outfilenew = name + "_b" +
549  boost::lexical_cast<string>(
550  f->m_bndRegionsToWrite[b]) +
551  "." + ext;
552  mod->RegisterConfig("outfile", outfilenew);
553  RunModule(mod, vm, verbose);
554  }
555  }
556  else
557  {
558  mod->RegisterConfig("outfile", outfilename);
559  RunModule(mod, vm, verbose);
560  }
561  }
562  }
563  }
564 
565  if (verbose)
566  {
567  timer.Stop();
568  NekDouble cpuTime = timer.TimePerTest(1);
569 
570  stringstream ss;
571  ss << cpuTime << "s";
572  cout << "Total CPU Time: " << setw(8) << left << ss.str() << endl;
573  }
574 
575  if (MPInprocs > 1)
576  {
577  MPIComm->Block();
578  MPIComm->Finalise();
579  }
580 
581  return 0;
582 }
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:989
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:285
std::shared_ptr< InputModule > InputModuleSharedPtr
Definition: Module.h:253
std::shared_ptr< Module > ModuleSharedPtr
Definition: Module.h:289
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49
CommFactory & GetCommFactory()
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
double NekDouble

References ASSERTL0, CheckModules(), Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::FieldUtils::eConvertExpToPts, Nektar::FieldUtils::eCreateGraph, Nektar::FieldUtils::eCreatePts, Nektar::FieldUtils::eInputModule, Nektar::FieldUtils::eModifyPts, Nektar::FieldUtils::eOutput, Nektar::FieldUtils::eOutputModule, Nektar::FieldUtils::eProcessModule, Nektar::LibUtilities::GetCommFactory(), Nektar::FieldUtils::GetModuleFactory(), CellMLToNektar.pycml::name, CellMLToNektar.cellml_metadata::p, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::PrintAvailableClasses(), PrintExecutionSequence(), CellMLToNektar.translators::run(), RunModule(), Nektar::FieldUtils::SIZE_ModulePriority, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

◆ PrintExecutionSequence()

void PrintExecutionSequence ( vector< ModuleSharedPtr > &  modules)

Definition at line 713 of file FieldConvert.cpp.

714 {
715  bool first = true;
716  cout << "Execution sequence:" << endl;
717  for (int n = 0; n < SIZE_ModulePriority; ++n)
718  {
719  ModulePriority priority = static_cast<ModulePriority>(n);
720  for (int i = 0; i < modules.size(); ++i)
721  {
722  if (modules[i]->GetModulePriority() == priority)
723  {
724  if (first)
725  {
726  cout << "\t" << modules[i]->GetModuleName();
727  first = false;
728  }
729  else
730  {
731  cout << " -> " << modules[i]->GetModuleName();
732  }
733  }
734  }
735  }
736  cout << endl;
737 }

References Nektar::FieldUtils::SIZE_ModulePriority.

Referenced by main().

◆ RunModule()

void RunModule ( ModuleSharedPtr  module,
po::variables_map &  vm,
bool  verbose 
)

Definition at line 739 of file FieldConvert.cpp.

740 {
741  LibUtilities::Timer moduleTimer;
742  if (verbose)
743  {
744  moduleTimer.Start();
745 
746  cout << module->GetModuleName() << ": "
747  << module->GetModuleDescription() << endl;
748  }
749  module->Process(vm);
750  cout.flush();
751  if (verbose)
752  {
753  moduleTimer.Stop();
754  NekDouble cpuTime = moduleTimer.TimePerTest(1);
755 
756  stringstream ss;
757  ss << cpuTime << "s";
758  cout << module->GetModuleName() << " CPU Time: " << setw(8) << left
759  << ss.str() << endl;
760  }
761 }

References Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().

Referenced by main().