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

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 574 of file FieldConvert.cpp.

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

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

702 {
703  bool first = true;
704  cout << "Execution sequence:" << endl;
705  for (int n = 0; n < SIZE_ModulePriority; ++n)
706  {
707  ModulePriority priority = static_cast<ModulePriority>(n);
708  for (int i = 0; i < modules.size(); ++i)
709  {
710  if(modules[i]->GetModulePriority() == priority)
711  {
712  if(first)
713  {
714  cout << "\t" << modules[i]->GetModuleName();
715  first = false;
716  }
717  else
718  {
719  cout << " -> " << modules[i]->GetModuleName();
720  }
721  }
722  }
723  }
724  cout << endl;
725 }

References Nektar::FieldUtils::SIZE_ModulePriority.

Referenced by main().

◆ RunModule()

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

Definition at line 727 of file FieldConvert.cpp.

728 {
729  LibUtilities::Timer moduleTimer;
730  if(verbose)
731  {
732  moduleTimer.Start();
733 
734  cout << module->GetModuleName() << ": "
735  << module->GetModuleDescription() << endl;
736  }
737  module->Process(vm);
738  cout.flush();
739  if(verbose)
740  {
741  moduleTimer.Stop();
742  NekDouble cpuTime = moduleTimer.TimePerTest(1);
743 
744  stringstream ss;
745  ss << cpuTime << "s";
746  cout << module->GetModuleName()
747  << " CPU Time: " << setw(8) << left
748  << ss.str() << endl;
749  }
750 }

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

Referenced by main().