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 
43 
44 #include "OutputTecplot.h"
45 
46 namespace Nektar
47 {
48 namespace Utilities
49 {
50 
51 ModuleKey OutputTecplot::m_className =
53  ModuleKey(eOutputModule, "dat"), OutputTecplot::create,
54  "Writes a Tecplot file.");
55 
56 OutputTecplot::OutputTecplot(FieldSharedPtr f) : OutputModule(f)
57 {
58 
59  if(f->m_setUpEquiSpacedFields)
60  {
62  }
63  else
64  {
65  m_requireEquiSpaced = true;
67  }
68 
69 }
70 
72 {
73 }
74 
75 void OutputTecplot::Process(po::variables_map &vm)
76 {
77  LibUtilities::PtsFieldSharedPtr fPts = m_f->m_fieldPts;
78 
79  m_doError = (vm.count("error") == 1)? true: false;
80 
81  // Do nothing if no expansion defined
82  if (fPts == LibUtilities::NullPtsField && !m_f->m_exp.size())
83  {
84  return;
85  }
86 
87  if (m_f->m_verbose)
88  {
89  if(m_f->m_comm->TreatAsRankZero())
90  {
91  cout << "OutputTecplot: Writing file..." << endl;
92  }
93  }
94 
95 
96  // Extract the output filename and extension
97  string filename = m_config["outfile"].as<string>();
98 
99  int nprocs = m_f->m_comm->GetSize();
100  int rank = m_f->m_comm->GetRank();
101  // Amend for parallel output if required
102  if(nprocs != 1)
103  {
104  int dot = filename.find_last_of('.');
105  string ext = filename.substr(dot,filename.length()-dot);
106  string procId = "_P" + boost::lexical_cast<std::string>(rank);
107  string start = filename.substr(0,dot);
108  filename = start + procId + ext;
109  }
110 
111  if(fPts != LibUtilities::NullPtsField)
112  {
113  int i = 0;
114  int j = 0;
115  int dim = fPts->GetDim();
116 
117  if(fPts->GetNpoints() == 0)
118  {
119  return;
120  }
121 
122  // Write solution.
123  ofstream outfile(filename.c_str());
124 
125  // points type
126  LibUtilities::PtsType pType = fPts->GetPtsType();
127 
128  vector<Array<OneD, int> > ptsConn;
129  fPts->GetConnectivity(ptsConn);
130 
131  // only dump header info for all proces if ptsType is for
132  // TriBlock or TetBlock
133  if((pType > LibUtilities::ePtsBox)||(rank == 0))
134  {
135  switch(dim)
136  {
137  case 1:
138  outfile << "VARIABLES = x";
139  break;
140  case 2:
141  outfile << "VARIABLES = x,y";
142  break;
143  case 3:
144  outfile << "VARIABLES = x,y,z";
145  break;
146  }
147 
148  for(i = 0; i < fPts->GetNFields(); ++i)
149  {
150  outfile << "," << fPts->GetFieldName(i);
151  }
152  outfile << endl;
153  }
154 
155  bool DumpAsFEPoint = true;
156  switch(fPts->GetPtsType())
157  {
160  {
161  if(rank == 0)
162  {
163  outfile << " ZONE I="
164  << fPts->GetNpoints()
165  << " F=POINT" << endl;
166  }
167  break;
168  }
170  {
171  if(rank == 0)
172  {
173  outfile << " ZONE I=" << fPts->GetPointsPerEdge(0)
174  << " J=" << fPts->GetPointsPerEdge(1)
175  << " F=POINT" << endl;
176  }
177  break;
178  }
180  {
181  if(rank == 0)
182  {
183  outfile << " ZONE I=" << fPts->GetPointsPerEdge(0)
184  << " J=" << fPts->GetPointsPerEdge(1)
185  << " K=" << fPts->GetPointsPerEdge(2)
186  << " F=POINT" << endl;
187  }
188  break;
189  }
190  break;
192  {
193  int numBlocks = 0;
194  for(i = 0; i < ptsConn.size(); ++i)
195  {
196  numBlocks +=
197  ptsConn[i].num_elements()/3;
198  }
199  outfile << "Zone, N="
200  << fPts->GetNpoints()
201  << ", E=" << numBlocks
202  << ", F=FEBlock" << ", ET=TRIANGLE"
203  << std::endl;
204  DumpAsFEPoint = false;
205  break;
206  }
208  {
209  int numBlocks = 0;
210  for(i = 0; i < ptsConn.size(); ++i)
211  {
212  numBlocks +=
213  ptsConn[i].num_elements()/4;
214  }
215  outfile << "Zone, N="
216  << fPts->GetNpoints()
217  << ", E=" << numBlocks
218  << ", F=FEBlock" << ", ET=TETRAHEDRON"
219  << std::endl;
220  DumpAsFEPoint = false;
221  break;
222  }
223  default:
224  ASSERTL0(false, "ptsType not supported yet.");
225  }
226 
227  if(DumpAsFEPoint) // dump in point format
228  {
229  for(i = 0; i < fPts->GetNpoints(); ++i)
230  {
231  for(j = 0; j < dim; ++j)
232  {
233  outfile << std::setw(12)
234  << fPts->GetPointVal(j, i) << " ";
235  }
236 
237  for(j = 0; j < fPts->GetNFields(); ++j)
238  {
239  outfile << std::setw(12)
240  << m_f->m_data[j][i] << " ";
241  }
242  outfile << endl;
243  }
244 
245 
246 
247  if (m_doError)
248  {
249  NekDouble l2err;
250  std::string coordval[] = {"x","y","z"};
251  int rank = m_f->m_comm->GetRank();
252 
253  for(i = 0; i < dim; ++i)
254  {
255  // calculate rms value
256  l2err = 0.0;
257  for(j = 0; j < fPts->GetNpoints(); ++j)
258  {
259  l2err += fPts->GetPointVal(i,j)*fPts->GetPointVal(i,j);
260  }
261  m_f->m_comm->AllReduce(l2err, LibUtilities::ReduceSum);
262 
263  int npts = fPts->GetNpoints();
264  m_f->m_comm->AllReduce(npts, LibUtilities::ReduceSum);
265 
266  l2err /= npts;
267  l2err = sqrt(l2err);
268 
269  if(rank == 0)
270  {
271  cout << "L 2 error (variable "
272  << coordval[i] << ") : "
273  << l2err << endl;
274  }
275  }
276 
277  for(i = 0; i < fPts->GetNFields(); ++i)
278  {
279  // calculate rms value
280  l2err = 0.0;
281  for(j = 0; j < fPts->GetNpoints(); ++j)
282  {
283  l2err += m_f->m_data[i][j]*m_f->m_data[i][j];
284  }
285  m_f->m_comm->AllReduce(l2err,
287 
288  int npts = fPts->GetNpoints();
289  m_f->m_comm->AllReduce(npts,
291 
292  l2err /= npts;
293  l2err = sqrt(l2err);
294 
295  if(rank == 0)
296  {
297  cout << "L 2 error (variable "
298  << fPts->GetFieldName(i) << ") : "
299  << l2err << endl;
300  }
301  }
302  }
303 
304  m_f->m_comm->Block();
305  }
306  else // dump in block format
307  {
308  for(j = 0; j < dim + fPts->GetNFields(); ++j)
309  {
310  for(i = 0; i < fPts->GetNpoints(); ++i)
311  {
312  outfile << fPts->GetPointVal(j, i) << " ";
313  if((!(i % 1000))&&i)
314  {
315  outfile << std::endl;
316  }
317  }
318  outfile << endl;
319  }
320 
321  // dump connectivity data if it exists
322  for(i = 0; i < ptsConn.size();++i)
323  {
324  for(j = 0; j < ptsConn[i].num_elements(); ++j)
325  {
326  outfile << ptsConn[i][j] +1 << " ";
327  if( ( !(j % 10 * dim) ) && j )
328  {
329  outfile << std::endl;
330  }
331  }
332  }
333 
334  if (m_doError)
335  {
336  NekDouble l2err;
337  std::string coordval[] = {"x","y","z"};
338  int rank = m_f->m_comm->GetRank();
339 
340  for(int i = 0; i < dim + fPts->GetNFields(); ++i)
341  {
342  // calculate rms value
343  l2err = 0.0;
344  for(j = 0; j < fPts->GetNpoints(); ++j)
345  {
346  l2err += fPts->GetPointVal(i,j)*fPts->GetPointVal(i,j);
347  }
348  m_f->m_comm->AllReduce(l2err,
350 
351  int npts = fPts->GetNpoints();
352  m_f->m_comm->AllReduce(npts,
354 
355  l2err /= npts;
356  l2err = sqrt(l2err);
357 
358  if(rank == 0)
359  {
360  if(i < dim)
361  {
362  cout << "L 2 error (variable "
363  << coordval[i] << ") : "
364  << l2err << endl;
365  }
366  else
367  {
368  cout << "L 2 error (variable "
369  << fPts->GetFieldName(i-dim) << ") : "
370  << l2err << endl;
371  }
372  }
373  }
374  }
375  }
376  }
377  else
378  {
379 
380  // Write solution.
381  ofstream outfile(filename.c_str());
382  std::string var;
383  std::vector<LibUtilities::FieldDefinitionsSharedPtr> fDef =
384  m_f->m_fielddef;
385  if (fDef.size())
386  {
387  var = fDef[0]->m_fields[0];
388 
389  for (int j = 1; j < fDef[0]->m_fields.size(); ++j)
390  {
391  var = var + ", " + fDef[0]->m_fields[j];
392  }
393  }
394 
395  WriteTecplotHeader(outfile,var);
396  WriteTecplotZone(outfile);
397  if(var.length()) // see if any variables are defined
398  {
399  for(int j = 0; j < m_f->m_exp.size(); ++j)
400  {
401  WriteTecplotField(j,outfile);
402  }
403  }
404 
405  WriteTecplotConnectivity(outfile);
406  }
407 
408  cout << "Written file: " << filename << endl;
409 }
410 
411 /**
412  * Write Tecplot Files Header
413  * @param outfile Output file name.
414  * @param var variables names
415  */
416 void OutputTecplot::WriteTecplotHeader(std::ofstream &outfile,
417  std::string var)
418 {
419  int coordim = m_f->m_exp[0]->GetExp(0)->GetCoordim();
420  MultiRegions::ExpansionType HomoExpType = m_f->m_exp[0]->GetExpType();
421 
422  if(HomoExpType == MultiRegions::e3DH1D)
423  {
424  if(m_f->m_session->DefinesSolverInfo("ModeType")&&
425  boost::iequals(m_f->m_session->GetSolverInfo("ModeType"),"HalfMode"))
426  { // turn off for half mode case
427  }
428  else
429  {
430  coordim +=1;
431  }
432  }
433  else if (HomoExpType == MultiRegions::e3DH2D)
434  {
435  coordim += 2;
436  }
437 
438  outfile << "Variables = x";
439 
440  if(coordim == 2)
441  {
442  outfile << ", y";
443  }
444  else if (coordim == 3)
445  {
446  outfile << ", y, z";
447  }
448 
449  if(var.length())
450  {
451  outfile << ", "<< var << std::endl << std::endl;
452  }
453  else
454  {
455  outfile << std::endl << std::endl;
456  }
457 }
458 
459 
460 /**
461  * Write Tecplot Files Zone
462  * @param outfile Output file name.
463  * @param expansion Expansion that is considered
464  */
465 void OutputTecplot::WriteTecplotZone(std::ofstream &outfile)
466 {
467  switch(m_outputType)
468  {
469  case eFullBlockZone: //write as full block zone
470  {
471  int i,j;
472  int coordim = m_f->m_exp[0]->GetCoordim(0);
473  int totpoints = m_f->m_exp[0]->GetTotPoints();
474  MultiRegions::ExpansionType HomoExpType = m_f->m_exp[0]->GetExpType();
475 
476  Array<OneD,NekDouble> coords[3];
477 
478  coords[0] = Array<OneD,NekDouble>(totpoints);
479  coords[1] = Array<OneD,NekDouble>(totpoints);
480  coords[2] = Array<OneD,NekDouble>(totpoints);
481 
482  m_f->m_exp[0]->GetCoords(coords[0],coords[1],coords[2]);
483 
484  if (m_doError)
485  {
486  NekDouble l2err;
487  std::string coordval[] = {"x","y","z"};
488  int rank = m_f->m_comm->GetRank();
489 
490  for(int i = 0; i < coordim; ++i)
491  {
492  l2err = m_f->m_exp[0]->L2(coords[i]);
493  if(rank == 0)
494  {
495  cout << "L 2 error (variable "
496  << coordval[i] << ") : " << l2err << endl;
497  }
498  }
499  }
500 
501  int numBlocks = GetNumTecplotBlocks();
502  int nBases = m_f->m_exp[0]->GetExp(0)->GetNumBases();
503 
504  if (HomoExpType == MultiRegions::e3DH1D)
505  {
506  int nPlanes = m_f->m_exp[0]->GetZIDs().num_elements();
507  if(nPlanes == 1) // halfMode case
508  {
509  // do nothing
510  }
511  else
512  {
513  nBases += 1;
514  coordim += 1;
515  NekDouble tmp = numBlocks * (nPlanes-1);
516  numBlocks = (int)tmp;
517  }
518  }
519  else if (HomoExpType == MultiRegions::e3DH2D)
520  {
521  nBases += 2;
522  coordim += 1;
523  }
524 
525  outfile << "Zone, N=" << totpoints << ", E="<<
526  numBlocks << ", F=FEBlock" ;
527 
528  switch(nBases)
529  {
530  case 1:
531  outfile << ", ET=LINESEG" << std::endl;
532  break;
533  case 2:
534  outfile << ", ET=QUADRILATERAL" << std::endl;
535  break;
536  case 3:
537  outfile << ", ET=BRICK" << std::endl;
538  break;
539  }
540 
541  // write out coordinates in block format
542  for(j = 0; j < coordim; ++j)
543  {
544  for(i = 0; i < totpoints; ++i)
545  {
546  outfile << coords[j][i] << " ";
547  if((!(i % 1000))&&i)
548  {
549  outfile << std::endl;
550  }
551  }
552  outfile << std::endl;
553  }
554  break;
555  }
556  case eSeperateZones:
557  {
558  for(int i = 0; i < m_f->m_exp[0]->GetExpSize(); ++i)
559  {
560  m_f->m_exp[0]->WriteTecplotZone(outfile,i);
561  }
562  break;
563  }
565  ASSERTL0(false,
566  "Should not have this option in this method");
567  break;
568  }
569 }
570 
572 {
573  int returnval = 0;
574 
575  if(m_f->m_exp[0]->GetExp(0)->GetNumBases() == 1)
576  {
577  for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
578  {
579  returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1);
580  }
581  }
582  else if(m_f->m_exp[0]->GetExp(0)->GetNumBases() == 2)
583  {
584  for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
585  {
586  returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
587  (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1);
588  }
589  }
590  else
591  {
592  for(int i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
593  {
594  returnval += (m_f->m_exp[0]->GetExp(i)->GetNumPoints(0)-1)*
595  (m_f->m_exp[0]->GetExp(i)->GetNumPoints(1)-1)*
596  (m_f->m_exp[0]->GetExp(i)->GetNumPoints(2)-1);
597  }
598  }
599 
600  return returnval;
601 }
602 
603 
604 /**
605  * Write Tecplot Files Field
606  * @param outfile Output file name.
607  * @param expansion Expansion that is considered
608  */
609 void OutputTecplot::WriteTecplotField(const int field,
610  std::ofstream &outfile)
611 {
612 
613  if(m_outputType == eFullBlockZone) //write as full block zone
614  {
615  int totpoints = m_f->m_exp[0]->GetTotPoints();
616 
617  if(m_f->m_exp[field]->GetPhysState() == false)
618  {
619  m_f->m_exp[field]->BwdTrans(m_f->m_exp[field]->GetCoeffs(),
620  m_f->m_exp[field]->UpdatePhys());
621  }
622 
623  if (m_doError)
624  {
625  NekDouble l2err = m_f->m_exp[0]->L2(m_f->m_exp[field]->UpdatePhys());
626 
627  if(m_f->m_comm->GetRank() == 0)
628  {
629  cout << "L 2 error (variable "
630  << m_f->m_fielddef[0]->m_fields[field] << ") : "
631  << l2err << endl;
632  }
633  }
634  else
635  {
636  for(int i = 0; i < totpoints; ++i)
637  {
638  outfile << m_f->m_exp[field]->GetPhys()[i] << " ";
639  if((!(i % 1000))&&i)
640  {
641  outfile << std::endl;
642  }
643  }
644  }
645  outfile << std::endl;
646  }
647  else
648  {
649  for(int e = 0; e < m_f->m_exp[field]->GetExpSize(); ++e)
650  {
651  m_f->m_exp[field]->WriteTecplotField(outfile,e);
652  }
653  }
654 }
655 
656 void OutputTecplot::WriteTecplotConnectivity(std::ofstream &outfile)
657 {
658  int i,j,k,l;
659  int nbase = m_f->m_exp[0]->GetExp(0)->GetNumBases();
660  int cnt = 0;
661 
662  for(i = 0; i < m_f->m_exp[0]->GetNumElmts(); ++i)
663  {
664  cnt = m_f->m_exp[0]->GetPhys_Offset(i);
665 
666  if(nbase == 1)
667  {
668  int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
669 
670  for(k = 1; k < np0; ++k)
671  {
672  outfile << cnt + k +1 << " ";
673  outfile << cnt + k << endl;
674  }
675 
676  cnt += np0;
677  }
678  else if(nbase == 2)
679  {
680  int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
681  int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);
682  int totPoints = m_f->m_exp[0]->GetTotPoints();
683  int nPlanes = 1;
684 
685  if (m_f->m_exp[0]->GetExpType() == MultiRegions::e3DH1D)
686  {
687  nPlanes = m_f->m_exp[0]->GetZIDs().num_elements();
688 
689  if(nPlanes > 1) // default to 2D case for HalfMode when nPlanes = 1
690  {
691  totPoints = m_f->m_exp[0]->GetPlane(0)->GetTotPoints();
692 
693 
694  for(int n = 1; n < nPlanes; ++n)
695  {
696  for(j = 1; j < np1; ++j)
697  {
698  for(k = 1; k < np0; ++k)
699  {
700  outfile << cnt + (n-1)*totPoints + (j-1)*np0 + k
701  << " ";
702  outfile << cnt + (n-1)*totPoints + (j-1)*np0 + k + 1
703  << " ";
704  outfile << cnt + (n-1)*totPoints + j*np0 + k + 1
705  << " ";
706  outfile << cnt + (n-1)*totPoints + j*np0 + k
707  << " ";
708 
709  outfile << cnt + n*totPoints + (j-1)*np0 + k
710  << " ";
711  outfile << cnt + n*totPoints + (j-1)*np0 + k + 1
712  << " ";
713  outfile << cnt + n*totPoints + j*np0 + k + 1
714  << " ";
715  outfile << cnt + n*totPoints + j*np0 + k << endl;
716  }
717  }
718  }
719  cnt += np0*np1;
720  }
721  }
722 
723  if(nPlanes == 1)
724  {
725  for(j = 1; j < np1; ++j)
726  {
727  for(k = 1; k < np0; ++k)
728  {
729  outfile << cnt + (j-1)*np0 + k << " ";
730  outfile << cnt + (j-1)*np0 + k +1 << " ";
731  outfile << cnt + j*np0 + k +1 << " ";
732  outfile << cnt + j*np0 + k << endl;
733  }
734  }
735  }
736  }
737  else if(nbase == 3)
738  {
739  int np0 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(0);
740  int np1 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(1);
741  int np2 = m_f->m_exp[0]->GetExp(i)->GetNumPoints(2);
742 
743  for(j = 1; j < np2; ++j)
744  {
745  for(k = 1; k < np1; ++k)
746  {
747  for(l = 1; l < np0; ++l)
748  {
749  outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l << " ";
750  outfile << cnt + (j-1)*np0*np1 + (k-1)*np0 + l +1 << " ";
751  outfile << cnt + (j-1)*np0*np1 + k*np0 + l +1 << " ";
752  outfile << cnt + (j-1)*np0*np1 + k*np0 + l << " ";
753 
754  outfile << cnt + j*np0*np1 + (k-1)*np0 + l << " ";
755  outfile << cnt + j*np0*np1 + (k-1)*np0 + l +1 << " ";
756  outfile << cnt + j*np0*np1 + k*np0 + l +1 << " ";
757  outfile << cnt + j*np0*np1 + k*np0 + l << endl;
758  }
759  }
760  }
761  }
762  else
763  {
764  ASSERTL0(false,"Not set up for this dimension");
765  }
766 
767  }
768 }
769 
770 }
771 }
772 
773 
774 
775 
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
pair< ModuleType, string > ModuleKey
Abstract base class for output modules.
virtual void Process()=0
map< string, ConfigOption > m_config
List of configuration values.
STL namespace.
void WriteTecplotZone(std::ofstream &outfile)
FieldSharedPtr m_f
Field object.
boost::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:262
void WriteTecplotHeader(std::ofstream &outfile, std::string var)
static std::string npts
Definition: InputFld.cpp:43
double NekDouble
boost::shared_ptr< Field > FieldSharedPtr
Definition: Field.hpp:698
static PtsFieldSharedPtr NullPtsField
Definition: PtsField.h:263
void WriteTecplotField(const int field, std::ofstream &outfile)
void WriteTecplotConnectivity(std::ofstream &outfile)
ModuleFactory & GetModuleFactory()
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215