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 // License for the specific language governing rights and laimitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Field conversion utility.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <string>
37 #include <boost/algorithm/string.hpp>
38 #include <boost/program_options.hpp>
39 
40 #include "Module.h"
41 
42 using namespace std;
43 using namespace Nektar::Utilities;
44 
45 int main(int argc, char* argv[])
46 {
47  po::options_description desc("Available options");
48  desc.add_options()
49  ("help,h",
50  "Produce this help message.")
51  ("modules-list,l",
52  "Print the list of available modules.")
53  ("output-points,n", po::value<int>(),
54  "Output at n equipspaced points along the collapsed coordinates (for .dat, .vtk).")
55  ("error,e",
56  "Write error of fields for regression checking")
57  ("forceoutput,f",
58  "Force the output to be written without any checks")
59  ("range,r", po::value<string>(),
60  "Define output range i.e. (-r xmin,xmax,ymin,ymax,zmin,zmax) "
61  "in which any vertex is contained.")
62  ("nprocs", po::value<int>(),
63  "Used to define nprocs if running serial problem to mimic "
64  "parallel run.")
65  ("onlyshape", po::value<string>(),
66  "Only use element with defined shape type i.e. -onlyshape "
67  " Tetrahedron")
68  ("procid", po::value<int>(),
69  "Process as single procid of a partition of size nproc "
70  "(-nproc must be specified).")
71  ("modules-opt,p", po::value<string>(),
72  "Print options for a module.")
73  ("module,m", po::value<vector<string> >(),
74  "Specify modules which are to be used.")
75  ("useSessionVariables",
76  "Use variables defined in session for output")
77  ("verbose,v",
78  "Enable verbose mode.");
79 
80  po::options_description hidden("Hidden options");
81  hidden.add_options()
82  ("input-file", po::value<vector<string> >(), "Input filename");
83 
84  po::options_description cmdline_options;
85  cmdline_options.add(hidden).add(desc);
86 
87  po::options_description visible("Allowed options");
88  visible.add(desc);
89 
90  po::positional_options_description p;
91  p.add("input-file", -1);
92 
93  po::variables_map vm;
94 
95  try
96  {
97  po::store(po::command_line_parser(argc, argv).
98  options(cmdline_options).positional(p).run(), vm);
99  po::notify(vm);
100  }
101  catch (const std::exception& e)
102  {
103  cerr << e.what() << endl;
104  cerr << desc;
105  return 1;
106  }
107 
108  // Print available modules.
109  if (vm.count("modules-list"))
110  {
112  return 1;
113  }
114 
115  if (vm.count("modules-opt"))
116  {
117  vector<string> tmp1;
118  boost::split(tmp1, vm["modules-opt"].as<string>(),
119  boost::is_any_of(":"));
120 
121  if (tmp1.size() != 2)
122  {
123  cerr << "ERROR: To specify a module, use one of in, out or proc "
124  << "together with the filename; for example in:vtk." << endl;
125  return 1;
126  }
127 
128  if (tmp1[0] != "in" && tmp1[0] != "out" && tmp1[0] != "proc")
129  {
130  cerr << "ERROR: Invalid module type " << tmp1[0] << endl;
131  return 1;
132  }
133 
134  ModuleType t;
135 
136  if (tmp1[0] == "in")
137  {
138  t = eInputModule;
139  }
140  else if (tmp1[0] == "out")
141  {
142  t = eOutputModule;
143  }
144  else if (tmp1[0] == "proc")
145  {
146  t = eProcessModule;
147  }
148 
149  FieldSharedPtr f = boost::shared_ptr<Field>(new Field());
151  ModuleKey(t, tmp1[1]), f);
152  cerr << "Options for module " << tmp1[1] << ":" << endl;
153  mod->PrintConfig();
154  return 1;
155  }
156 
157  if (vm.count("help") || vm.count("input-file") != 1) {
158  cerr << "Usage: FieldConvert [options] inputfile.ext1 outputfile.ext2"
159  << endl;
160  cout << desc;
161  cout << endl;
162  cout << "Example Usage: \n" << endl;
163  cout << "\t FieldConvert -m vorticity file.xml file.fld file_vort.fld "
164  << endl;
165  cout << "(This will add vorticity to file file.fld and put it in a "
166  "new file file_vort.fld) " << endl;
167  cout << endl;
168  cout << "\t FieldConvert file.xml file_vort.fld file_vort.dat " << endl;
169  cout << "(process file_vort.fld and make a tecplot output "
170  "file_vort.dat) " << endl;
171 
172  return 1;
173  }
174 
175  ASSERTL0(vm.count("input-file"),
176  "Must specify input(s) and/or output file.");
177  vector<string> inout = vm["input-file"].as<vector<string> >();
178 
179 
180  /*
181  * Process list of modules. Each element of the vector of module strings can
182  * be in the following form:
183  *
184  * modname:arg1=a:arg2=b:arg3=c:arg4:arg5=asd
185  *
186  * where the only required argument is 'modname', specifing the name of the
187  * module to load.
188  */
189 
190  FieldSharedPtr f = boost::shared_ptr<Field>(new Field());
191  if (LibUtilities::GetCommFactory().ModuleExists("ParallelMPI"))
192  {
193  if(vm.count("procid"))
194  {
195  int nprocs, rank;
196 
197  ASSERTL0(vm.count("nprocs"),
198  "Must specify --nprocs when using --procid option");
199  nprocs = vm["nprocs"].as<int>();
200  rank = vm["procid"].as<int>();
201 
202  f->m_comm = boost::shared_ptr<FieldConvertComm>(
203  new FieldConvertComm(argc, argv, nprocs,rank));
204  }
205  else
206  {
208  "ParallelMPI", argc, argv);
209  }
210  }
211  else
212  {
214  "Serial", argc, argv);
215 
216  }
217 
218  vector<ModuleSharedPtr> modules;
219  vector<string> modcmds;
220 
221  if (vm.count("verbose"))
222  {
223  f->m_verbose = true;
224  }
225 
226  if (vm.count("module"))
227  {
228  modcmds = vm["module"].as<vector<string> >();
229  }
230 
231  // Add input and output modules to beginning and end of this vector.
232  modcmds.insert(modcmds.begin(), inout.begin(), inout.end()-1);
233  modcmds.push_back(*(inout.end()-1));
234  int nInput = inout.size()-1;
235 
236  InputModuleSharedPtr inputModule;
237 
238  for (int i = 0; i < modcmds.size(); ++i)
239  {
240  // First split each command by the colon separator.
241  vector<string> tmp1;
242  ModuleKey module;
243  int offset = 1;
244 
245  boost::split(tmp1, modcmds[i], boost::is_any_of(":"));
246 
247  if (i < nInput || i == modcmds.size() - 1)
248  {
249  module.first = (i < nInput ? eInputModule : eOutputModule);
250 
251  // If no colon detected, automatically detect mesh type from
252  // file extension. Otherwise override and use tmp1[1] as the
253  // module to load. This also allows us to pass options to
254  // input/output modules. So, for example, to override
255  // filename.xml to be read as vtk, you use:
256  //
257  // filename.xml:vtk:opt1=arg1:opt2=arg2
258  if (tmp1.size() == 1)
259  {
260  int dot = tmp1[0].find_last_of('.') + 1;
261  string ext = tmp1[0].substr(dot, tmp1[0].length() - dot);
262 
263  if(ext == "gz")
264  {
265  string tmp2 = tmp1[0].substr(0,dot-1);
266  dot = tmp2.find_last_of('.') + 1;
267  ext = tmp1[0].substr(dot,tmp1[0].length()-dot);
268  }
269 
270  module.second = ext;
271  tmp1.push_back(string(i < nInput ? "infile=" : "outfile=")
272  +tmp1[0]);
273  }
274  else
275  {
276  module.second = tmp1[1];
277  tmp1.push_back(string(i < nInput ? "infile=" : "outfile=")
278  +tmp1[0]);
279  offset++;
280  }
281  }
282  else
283  {
284  module.first = eProcessModule;
285  module.second = tmp1[0];
286  }
287 
288  // Create module.
289  ModuleSharedPtr mod;
290  mod = GetModuleFactory().CreateInstance(module, f);
291  modules.push_back(mod);
292 
293  if (i < nInput)
294  {
295  inputModule = boost::dynamic_pointer_cast<InputModule>(mod);
296  inputModule->AddFile(module.second, tmp1[0]);
297  }
298 
299  // Set options for this module.
300  for (int j = offset; j < tmp1.size(); ++j)
301  {
302  vector<string> tmp2;
303  boost::split(tmp2, tmp1[j], boost::is_any_of("="));
304 
305  if (tmp2.size() == 1)
306  {
307  mod->RegisterConfig(tmp2[0], "1");
308  }
309  else if (tmp2.size() == 2)
310  {
311  mod->RegisterConfig(tmp2[0], tmp2[1]);
312  }
313  else
314  {
315  cerr << "ERROR: Invalid module configuration: format is "
316  << "either :arg or :arg=val" << endl;
317  abort();
318  }
319  }
320 
321  // Ensure configuration options have been set.
322  mod->SetDefaults();
323  }
324 
325  // If any output module has to reset points then set intput modules to match
326  bool RequiresEquiSpaced = false;
327  for (int i = 0; i < modules.size(); ++i)
328  {
329  if(modules[i]->GetRequireEquiSpaced())
330  {
331  RequiresEquiSpaced = true;
332  }
333  }
334  if (RequiresEquiSpaced)
335  {
336  for (int i = 0; i < modules.size(); ++i)
337  {
338  modules[i]->SetRequireEquiSpaced(true);
339  }
340  }
341  // Run field process.
342  for (int i = 0; i < modules.size(); ++i)
343  {
344  modules[i]->Process(vm);
345  cout.flush();
346  }
347 
348  return 0;
349 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:135
void PrintAvailableClasses(std::ostream &pOut=std::cout)
Prints the available classes to stdout.
Definition: NekFactory.hpp:247
pair< ModuleType, string > ModuleKey
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
STL namespace.
CommFactory & GetCommFactory()
Definition: Comm.cpp:64
boost::shared_ptr< InputModule > InputModuleSharedPtr
bool ModuleExists(tKey idKey)
Checks if a particular module is available.
Definition: NekFactory.hpp:229
boost::shared_ptr< Module > ModuleSharedPtr
void AddFile(string fileType, string fileName)
boost::shared_ptr< Field > FieldSharedPtr
Definition: Field.hpp:677
ModuleFactory & GetModuleFactory()
Abstract base class for input modules.
int main(int argc, char *argv[])