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