Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OutputTecplot.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: OutputTecplot.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 limitations 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: Dat file format output.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <set>
37 #include <string>
38 #include <iomanip>
39 using namespace std;
40 
41 #include "OutputTecplot.h"
42 
43 namespace Nektar
44 {
45 namespace Utilities
46 {
47 
48 ModuleKey OutputTecplot::m_className =
50  ModuleKey(eOutputModule, "dat"), OutputTecplot::create,
51  "Writes a Tecplot file.");
52 
53 OutputTecplot::OutputTecplot(FieldSharedPtr f) : OutputModule(f)
54 {
55  m_requireEquiSpaced = true;
56 }
57 
59 {
60 }
61 
62 void OutputTecplot::Process(po::variables_map &vm)
63 {
64  m_doError = (vm.count("error") == 1)? true: false;
65 
66  if (m_f->m_verbose)
67  {
68  cout << "OutputTecplot: Writing file..." << endl;
69  }
70 
71  // Do nothing if no expansion defined
72  if(m_f->m_fieldPts == NullFieldPts &&!m_f->m_exp.size())
73  {
74  return;
75  }
76 
77  // Extract the output filename and extension
78  string filename = m_config["outfile"].as<string>();
79 
80  if(m_f->m_fieldPts != NullFieldPts)
81  {
82  int dim = m_f->m_fieldPts->m_ptsDim;
83  // Write solution.
84  ofstream outfile(filename.c_str());
85 
86  switch(dim)
87  {
88  case 1:
89  outfile << "VARIABLES = x";
90  break;
91  case 2:
92  outfile << "VARIABLES = x y";
93  break;
94  case 3:
95  outfile << "VARIABLES = x y z";
96  break;
97  }
98 
99  for(int i = 0; i < m_f->m_fieldPts->m_fields.size(); ++i)
100  {
101  outfile << " " << m_f->m_fieldPts->m_fields[i];
102  }
103  outfile << endl;
104 
105  switch(m_f->m_fieldPts->m_ptype)
106  {
107  case Utilities::ePtsFile:
108  case Utilities::ePtsLine:
109  outfile << " ZONE I="
110  << m_f->m_fieldPts->m_pts[0].num_elements()
111  << " F=POINT" << endl;
112  break;
114  outfile << " ZONE I=" << m_f->m_fieldPts->m_npts[0]
115  << " J=" << m_f->m_fieldPts->m_npts[1]
116  << " F=POINT" << endl;
117  break;
118  }
119 
120  for(int i = 0; i < m_f->m_fieldPts->m_pts[0].num_elements(); ++i)
121  {
122  for(int j = 0; j < dim; ++j)
123  {
124  outfile << std::setw(12)
125  << m_f->m_fieldPts->m_pts[j][i] << " ";
126  }
127 
128  for(int j = 0; j < m_f->m_fieldPts->m_fields.size(); ++j)
129  {
130  outfile << std::setw(12) << m_f->m_data[j][i] << " ";
131  }
132  outfile << endl;
133  }
134  }
135  else
136  {
137  // Amend for parallel output if required
138  if(m_f->m_session->GetComm()->GetSize() != 1)
139  {
140  int dot = filename.find_last_of('.');
141  string ext = filename.substr(dot,filename.length()-dot);
142  string procId = "_P" + boost::lexical_cast<std::string>(
143  m_f->m_session->GetComm()->GetRank());
144  string start = filename.substr(0,dot);
145  filename = start + procId + ext;
146  }
147 
148  // Write solution.
149  ofstream outfile(filename.c_str());
150  std::string var;
151  if(m_f->m_fielddef.size())
152  {
153  var = m_f->m_fielddef[0]->m_fields[0];
154 
155  for (int j = 1; j < m_f->m_fielddef[0]->m_fields.size(); ++j)
156  {
157  var = var + ", " + m_f->m_fielddef[0]->m_fields[j];
158  }
159  }
160 
161  WriteTecplotHeader(outfile,var);
162  WriteTecplotZone(outfile);
163  if(var.length()) // see if any variables are defined
164  {
165  for(int j = 0; j < m_f->m_exp.size(); ++j)
166  {
167  WriteTecplotField(j,outfile);
168  }
169  }
170 
171  WriteTecplotConnectivity(outfile);
172  }
173 
174  cout << "Written file: " << filename << endl;
175 }
176 /**
177  * Write Tecplot Files Header
178  * @param outfile Output file name.
179  * @param var variables names
180  */
181 void OutputTecplot::WriteTecplotHeader(std::ofstream &outfile,
182  std::string var)
183 {
184  int coordim = m_f->m_exp[0]->GetExp(0)->GetCoordim();
185  MultiRegions::ExpansionType HomoExpType = m_f->m_exp[0]->GetExpType();
186 
187  if(HomoExpType == MultiRegions::e3DH1D)
188  {
189  coordim +=1;
190  }
191  else if (HomoExpType == MultiRegions::e3DH2D)
192  {
193  coordim += 2;
194  }
195 
196  outfile << "Variables = x";
197 
198  if(coordim == 2)
199  {
200  outfile << ", y";
201  }
202  else if (coordim == 3)
203  {
204  outfile << ", y, z";
205  }
206 
207  if(var.length())
208  {
209  outfile << ", "<< var << std::endl << std::endl;
210  }
211  else
212  {
213  outfile << std::endl << std::endl;
214  }
215 }
216 
217 
218 /**
219  * Write Tecplot Files Zone
220  * @param outfile Output file name.
221  * @param expansion Expansion that is considered
222  */
223 void OutputTecplot::WriteTecplotZone(std::ofstream &outfile,
224  int expansion)
225 {
226  if(expansion == -1) //write as full block zone
227  {
228  int i,j;
229  int coordim = m_f->m_exp[0]->GetCoordim(0);
230  int totpoints = m_f->m_exp[0]->GetTotPoints();
231  MultiRegions::ExpansionType HomoExpType = m_f->m_exp[0]->GetExpType();
232 
233  Array<OneD,NekDouble> coords[3];
234 
235  coords[0] = Array<OneD,NekDouble>(totpoints);
236  coords[1] = Array<OneD,NekDouble>(totpoints);
237  coords[2] = Array<OneD,NekDouble>(totpoints);
238 
239  m_f->m_exp[0]->GetCoords(coords[0],coords[1],coords[2]);
240 
241  if (m_doError)
242  {
243  NekDouble l2err;
244  std::string coordval[] = {"x","y","z"};
245  int rank = m_f->m_session->GetComm()->GetRank();
246 
247  for(int i = 0; i < coordim; ++i)
248  {
249  l2err = m_f->m_exp[0]->L2(coords[i]);
250  if(rank == 0)
251  {
252  cout << "L 2 error (variable "
253  << coordval[i] << ") : " << l2err << endl;
254  }
255  }
256  }
257 
258  int numBlocks = GetNumTecplotBlocks();
259  int nBases = m_f->m_exp[0]->GetExp(0)->GetNumBases();
260 
261  if (HomoExpType == MultiRegions::e3DH1D)
262  {
263  nBases += 1;
264  coordim += 1;
265  int nPlanes = m_f->m_exp[0]->GetZIDs().num_elements();
266  NekDouble tmp = numBlocks * (nPlanes-1);
267  numBlocks = (int)tmp;
268  }
269  else if (HomoExpType == MultiRegions::e3DH2D)
270  {
271  nBases += 2;
272  coordim += 1;
273  }
274 
275 
276  outfile << "Zone, N=" << totpoints << ", E="<<
277  numBlocks << ", F=FEBlock" ;
278 
279  switch(nBases)
280  {
281  case 1:
282  outfile << ", ET=LINESEG" << std::endl;
283  break;
284  case 2:
285  outfile << ", ET=QUADRILATERAL" << std::endl;
286  break;
287  case 3:
288  outfile << ", ET=BRICK" << std::endl;
289  break;
290  }
291 
292  // write out coordinates in block format
293  for(j = 0; j < coordim; ++j)
294  {
295  for(i = 0; i < totpoints; ++i)
296  {
297  outfile << coords[j][i] << " ";
298  if((!(i % 1000))&&i)
299  {
300  outfile << std::endl;
301  }
302  }
303  outfile << std::endl;
304  }
305 
306  }
307  else
308  {
309  m_f->m_exp[0]->WriteTecplotZone(outfile,expansion);
310  }
311 }
312 
314 {
315  int returnval = 0;
316 
317  if(m_f->m_exp[0]->GetExp(0)->GetNumBases() == 1)
318  {
319  for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
320  {
321  returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1);
322  }
323  }
324  else if(m_f->m_exp[0]->GetExp(0)->GetNumBases() == 2)
325  {
326  for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
327  {
328  returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
329  (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1);
330  }
331  }
332  else
333  {
334  for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
335  {
336  returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
337  (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1)*
338  (m_f->m_exp[0]->GetExp(i)->GetNumPoints(2)-1);
339  }
340  }
341 
342  return returnval;
343 }
344 
345 
346 /**
347  * Write Tecplot Files Field
348  * @param outfile Output file name.
349  * @param expansion Expansion that is considered
350  */
351 void OutputTecplot::WriteTecplotField(const int field,
352  std::ofstream &outfile,
353  int expansion)
354 {
355 
356  if(expansion == -1) //write as full block zone
357  {
358  int totpoints = m_f->m_exp[0]->GetTotPoints();
359 
360  if(m_f->m_exp[field]->GetPhysState() == false)
361  {
362  m_f->m_exp[field]->BwdTrans(m_f->m_exp[field]->GetCoeffs(),
363  m_f->m_exp[field]->UpdatePhys());
364  }
365 
366  if (m_doError)
367  {
368  NekDouble l2err = m_f->m_exp[0]->L2(m_f->m_exp[field]->UpdatePhys());
369 
370  if(m_f->m_session->GetComm()->GetRank() == 0)
371  {
372  cout << "L 2 error (variable "
373  << m_f->m_fielddef[0]->m_fields[field] << ") : "
374  << l2err << endl;
375  }
376  }
377  else
378  {
379  for(int i = 0; i < totpoints; ++i)
380  {
381  outfile << m_f->m_exp[field]->GetPhys()[i] << " ";
382  if((!(i % 1000))&&i)
383  {
384  outfile << std::endl;
385  }
386  }
387  }
388  outfile << std::endl;
389  }
390  else
391  {
392  m_f->m_exp[field]->WriteTecplotField(outfile,expansion);
393  }
394 }
395 
396 void OutputTecplot::WriteTecplotConnectivity(std::ofstream &outfile)
397 {
398  int i,j,k,l;
399  int nbase = m_f->m_exp[0]->GetExp(0)->GetNumBases();
400  int cnt = 0;
401 
402  for(i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
403  {
404  if(nbase == 1)
405  {
406  int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
407 
408  for(k = 1; k < np0; ++k)
409  {
410  outfile << cnt + k +1 << " ";
411  outfile << cnt + k << endl;
412  }
413 
414  cnt += np0;
415  }
416  else if(nbase == 2)
417  {
418  int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
419  int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);
420  int totPoints = m_f->m_exp[0]->GetTotPoints();
421  int nPlanes = 1;
422 
423  if (m_f->m_exp[0]->GetExpType() == MultiRegions::e3DH1D)
424  {
425  nPlanes = m_f->m_exp[0]->GetZIDs().num_elements();
426  totPoints = m_f->m_exp[0]->GetPlane(0)->GetTotPoints();
427 
428 
429  for(int n = 1; n < nPlanes; ++n)
430  {
431  for(j = 1; j < np1; ++j)
432  {
433  for(k = 1; k < np0; ++k)
434  {
435  outfile << cnt + (n-1)*totPoints + (j-1)*np0 + k
436  << " ";
437  outfile << cnt + (n-1)*totPoints + (j-1)*np0 + k + 1
438  << " ";
439  outfile << cnt + (n-1)*totPoints + j*np0 + k + 1
440  << " ";
441  outfile << cnt + (n-1)*totPoints + j*np0 + k
442  << " ";
443 
444  outfile << cnt + n*totPoints + (j-1)*np0 + k
445  << " ";
446  outfile << cnt + n*totPoints + (j-1)*np0 + k + 1
447  << " ";
448  outfile << cnt + n*totPoints + j*np0 + k + 1
449  << " ";
450  outfile << cnt + n*totPoints + j*np0 + k << endl;
451  }
452  }
453  }
454  cnt += np0*np1;
455  }
456  else
457  {
458  for(j = 1; j < np1; ++j)
459  {
460  for(k = 1; k < np0; ++k)
461  {
462  outfile << cnt + (j-1)*np0 + k << " ";
463  outfile << cnt + (j-1)*np0 + k +1 << " ";
464  outfile << cnt + j*np0 + k +1 << " ";
465  outfile << cnt + j*np0 + k << endl;
466  }
467  }
468  cnt += np0*np1;
469  }
470  }
471  else if(nbase == 3)
472  {
473  int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
474  int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);
475  int np2 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(2);
476 
477  for(j = 1; j < np2; ++j)
478  {
479  for(k = 1; k < np1; ++k)
480  {
481  for(l = 1; l < np0; ++l)
482  {
483  outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l << " ";
484  outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l +1 << " ";
485  outfile << cnt + (j-1)*np0*np1 + k*np0 + l +1 << " ";
486  outfile << cnt + (j-1)*np0*np1 + k*np0 + l << " ";
487 
488  outfile << cnt + j*np0*np1 + (k-1)*np0 + l << " ";
489  outfile << cnt + j*np0*np1 + (k-1)*np0 + l +1 << " ";
490  outfile << cnt + j*np0*np1 + k*np0 + l +1 << " ";
491  outfile << cnt + j*np0*np1 + k*np0 + l << endl;
492  }
493  }
494  }
495  cnt += np0*np1*np2;
496  }
497  else
498  {
499  ASSERTL0(false,"Not set up for this dimension");
500  }
501 
502  }
503 }
504 
505 }
506 }
507 
508 
509 
510