Nektar++
Functions
NekMesh.cpp File Reference
#include <LibUtilities/BasicConst/GitRevision.h>
#include <LibUtilities/BasicUtils/Timer.h>
#include <boost/algorithm/string.hpp>
#include <boost/asio/ip/host_name.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
#include <string>
#include <NekMesh/Module/Module.h>

Go to the source code of this file.

Functions

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

Function Documentation

◆ main()

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

Definition at line 51 of file NekMesh.cpp.

52{
53 po::options_description desc("Available options");
54
55 // clang-format off
56 desc.add_options()
57 ("help,h", "Produce this help message.")
58 ("forceoutput,f", "Force the output to be written without any checks")
59 ("modules-list,l", "Print the list of available modules.")
60 ("modules-opt,p", po::value<string>(),
61 "Print options for a module.")
62 ("module,m", po::value<vector<string> >(),
63 "Specify modules which are to be used.")
64 ("verbose,v", "Enable verbose output.");
65 // clang-format on
66
67 po::options_description hidden("Hidden options");
68
69 // clang-format off
70 hidden.add_options()
71 ("input-file", po::value<vector<string> >(), "Input filename");
72 // clang-format on
73
74 po::options_description cmdline_options;
75 cmdline_options.add(hidden).add(desc);
76
77 po::positional_options_description p;
78 p.add("input-file", -1);
79
80 po::variables_map vm;
81
82 try
83 {
84 po::store(po::command_line_parser(argc, argv)
85 .options(cmdline_options)
86 .positional(p)
87 .run(),
88 vm);
89 po::notify(vm);
90 }
91 catch (const std::exception &e)
92 {
93 cerr << e.what() << endl;
94 cerr << desc;
95 return 1;
96 }
97
98 // If NEKTAR_DISABLE_BACKUPS environment variable is set, enable the
99 // forceoutput option.
100 if (std::getenv("NEKTAR_DISABLE_BACKUPS") != nullptr)
101 {
102 vm.insert(std::make_pair("forceoutput", po::variable_value()));
103 }
104
105 // Create a logger.
106 auto logOutput = std::make_shared<StreamOutput>(std::cout);
107 Logger log(logOutput, vm.count("verbose") ? VERBOSE : INFO);
108
109 // Print available modules.
110 if (vm.count("modules-list"))
111 {
113 return 1;
114 }
115
116 if (vm.count("modules-opt"))
117 {
118 vector<string> tmp1;
119 boost::split(tmp1, vm["modules-opt"].as<string>(),
120 boost::is_any_of(":"));
121
122 if (tmp1.size() != 2)
123 {
124 cerr << "ERROR: To specify a module, use one of in, out or proc "
125 << "together with the filename; for example in:vtk." << endl;
126 return 1;
127 }
128
129 if (tmp1[0] != "in" && tmp1[0] != "out" && tmp1[0] != "proc")
130 {
131 cerr << "ERROR: Invalid module type (in, out, or proc): " << tmp1[0]
132 << endl;
133 return 1;
134 }
135
137
138 if (tmp1[0] == "in")
139 {
140 t = eInputModule;
141 }
142 else if (tmp1[0] == "out")
143 {
144 t = eOutputModule;
145 }
146 else if (tmp1[0] == "proc")
147 {
148 t = eProcessModule;
149 }
150
151 MeshSharedPtr m = std::shared_ptr<Mesh>(new Mesh());
152 ModuleSharedPtr mod =
153 GetModuleFactory().CreateInstance(ModuleKey(t, tmp1[1]), m);
154 cerr << "Options for module " << tmp1[1] << ":" << endl;
155 mod->SetLogger(log);
156 mod->PrintConfig();
157 return 1;
158 }
159
160 if (vm.count("help") || vm.count("input-file") != 1)
161 {
162 cerr << "Usage: NekMesh [options] inputfile.ext1 outputfile.ext2"
163 << endl;
164 cout << desc;
165 return 1;
166 }
167
168 vector<string> inout = vm["input-file"].as<vector<string>>();
169
170 if (inout.size() != 2)
171 {
172 cerr << "ERROR: You must specify an input and output file." << endl;
173 return 1;
174 }
175
176 /*
177 * Process list of modules. Each element of the vector of module strings can
178 * be in the following form:
179 *
180 * modname:arg1=a:arg2=b:arg3=c:arg4:arg5=asd
181 *
182 * where the only required argument is 'modname', specifing the name of the
183 * module to load.
184 */
185
186 MeshSharedPtr mesh = std::shared_ptr<Mesh>(new Mesh());
187
188 // Add provenance information to mesh.
189 stringstream ss;
190 for (int i = 1; i < argc; i++)
191 {
192 ss << argv[i] << " ";
193 }
194 mesh->m_metadata["NekMeshCommandLine"] = ss.str();
195
196 vector<ModuleSharedPtr> modules;
197 vector<string> modcmds;
198
199 if (vm.count("module"))
200 {
201 modcmds = vm["module"].as<vector<string>>();
202 }
203
204 bool forceOutput = vm.count("forceoutput");
205
206 // Add input and output modules to beginning and end of this vector.
207 modcmds.insert(modcmds.begin(), inout[0]);
208 modcmds.push_back(inout[1]);
209
210 // Keep track of maximum string length for nicer verbose output.
211 size_t maxModName = 0;
212
213 for (int i = 0; i < modcmds.size(); ++i)
214 {
215 // First split each command by the colon separator.
216 vector<string> tmp1;
217 ModuleKey module;
218 int offset = 1;
219
220 boost::split(tmp1, modcmds[i], boost::is_any_of(":"));
221
222 if (i == 0 || i == modcmds.size() - 1)
223 {
224 module.first = (i == 0 ? eInputModule : eOutputModule);
225
226 // If no colon detected, automatically detect mesh type from
227 // file extension. Otherwise override and use tmp1[1] as the
228 // module to load. This also allows us to pass options to
229 // input/output modules. So, for example, to override
230 // filename.xml to be read as vtk, you use:
231 //
232 // filename.xml:vtk:opt1=arg1:opt2=arg2
233 if (tmp1.size() == 1)
234 {
235 int dot = tmp1[0].find_last_of('.') + 1;
236 string ext = tmp1[0].substr(dot, tmp1[0].length() - dot);
237
238 if (ext == "gz")
239 {
240 string tmp = tmp1[0].substr(0, tmp1[0].length() - 3);
241 dot = tmp.find_last_of('.') + 1;
242 ext = tmp.substr(dot, tmp.length() - dot);
243 }
244
245 module.second = ext;
246 tmp1.push_back(string(i == 0 ? "infile=" : "outfile=") +
247 tmp1[0]);
248 }
249 else
250 {
251 module.second = tmp1[1];
252 tmp1.push_back(string(i == 0 ? "infile=" : "outfile=") +
253 tmp1[0]);
254 offset++;
255 }
256 }
257 else
258 {
259 module.first = eProcessModule;
260 module.second = tmp1[0];
261 }
262
263 // Create module.
264 ModuleSharedPtr mod = GetModuleFactory().CreateInstance(module, mesh);
265 mod->SetLogger(log);
266 modules.push_back(mod);
267
268 // Set options for this module.
269 for (int j = offset; j < tmp1.size(); ++j)
270 {
271 vector<string> tmp2;
272 boost::split(tmp2, tmp1[j], boost::is_any_of("="));
273
274 if (tmp2.size() == 1)
275 {
276 mod->RegisterConfig(tmp2[0]);
277 }
278 else if (tmp2.size() == 2)
279 {
280 mod->RegisterConfig(tmp2[0], tmp2[1]);
281 }
282 else
283 {
284 cerr << "ERROR: Invalid module configuration: format is "
285 << "either :arg or :arg=val" << endl;
286 return 1;
287 }
288 }
289
290 if (i == modcmds.size() - 1 && forceOutput)
291 {
292 mod->RegisterConfig("forceoutput", "true");
293 }
294
295 // Ensure configuration options have been set.
296 mod->SetDefaults();
297
298 // Track maximum module name length.
299 std::string modName = mod->GetModuleName();
300 maxModName = std::max(maxModName, modName.length());
301 }
302
303 log.SetPrefixLen(maxModName);
304
305 // Run mesh process.
306 for (int i = 0; i < modules.size(); ++i)
307 {
309 t.Start();
310 try
311 {
312 modules[i]->GetLogger().SetPrefixLen(maxModName);
313 modules[i]->Process();
314 }
315 catch (NekMeshError &e)
316 {
317 return 1;
318 }
319 t.Stop();
320
321 log.SetPrefix(modules[i]->GetModuleName());
322 log(VERBOSE) << " - Elapsed time: " << t.TimePerTest(1) << "s."
323 << std::endl;
324 }
325
326 return 0;
327}
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::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:317
std::shared_ptr< Module > ModuleSharedPtr
Definition: Module.h:321
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49
scalarT< T > log(scalarT< T > in)
Definition: scalar.hpp:303

References Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::FieldUtils::eInputModule, Nektar::FieldUtils::eOutputModule, Nektar::FieldUtils::eProcessModule, Nektar::FieldUtils::GetModuleFactory(), tinysimd::log(), CG_Iterations::Mesh, CellMLToNektar.cellml_metadata::p, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::PrintAvailableClasses(), CellMLToNektar.translators::run(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), and Nektar::LibUtilities::Timer::TimePerTest().