Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
Nektar::FieldUtils::OutputVtk Class Referencefinal

Converter from fld to vtk. More...

#include <OutputVtk.h>

Inheritance diagram for Nektar::FieldUtils::OutputVtk:
[legend]

Public Member Functions

 OutputVtk (FieldSharedPtr f)
 
 ~OutputVtk () final=default
 
- Public Member Functions inherited from Nektar::FieldUtils::OutputVtkBase
 OutputVtkBase (FieldSharedPtr f)
 
virtual ~OutputVtkBase ()
 
- Public Member Functions inherited from Nektar::FieldUtils::OutputFileBase
 OutputFileBase (FieldSharedPtr f)
 
virtual ~OutputFileBase ()
 
- Public Member Functions inherited from Nektar::FieldUtils::OutputModule
 OutputModule (FieldSharedPtr p_f)
 
FIELD_UTILS_EXPORT void OpenStream ()
 Open a file for output. More...
 
- Public Member Functions inherited from Nektar::FieldUtils::Module
FIELD_UTILS_EXPORT Module (FieldSharedPtr p_f)
 
virtual ~Module ()=default
 
void Process (po::variables_map &vm)
 
std::string GetModuleName ()
 
std::string GetModuleDescription ()
 
const ConfigOptionGetConfigOption (const std::string &key) const
 
ModulePriority GetModulePriority ()
 
FIELD_UTILS_EXPORT void RegisterConfig (std::string key, std::string value="")
 Register a configuration option with a module. More...
 
FIELD_UTILS_EXPORT void PrintConfig ()
 Print out all configuration options for a module. More...
 
FIELD_UTILS_EXPORT void SetDefaults ()
 Sets default configuration options for those which have not been set. More...
 
FIELD_UTILS_EXPORT void AddFile (std::string fileType, std::string fileName)
 
FIELD_UTILS_EXPORT void EvaluateTriFieldAtEquiSpacedPts (LocalRegions::ExpansionSharedPtr &exp, const Array< OneD, const NekDouble > &infield, Array< OneD, NekDouble > &outfield)
 

Static Public Member Functions

static std::shared_ptr< Modulecreate (const FieldSharedPtr &f)
 Creates an instance of this class. More...
 
- Static Public Member Functions inherited from Nektar::FieldUtils::OutputVtkBase
static std::shared_ptr< Modulecreate (FieldSharedPtr f)
 Creates an instance of this class. More...
 

Static Public Attributes

static ModuleKey m_className
 
- Static Public Attributes inherited from Nektar::FieldUtils::OutputVtkBase
static ModuleKey m_className
 

Protected Member Functions

virtual std::string v_GetModuleName () override final
 
virtual void v_OutputFromPts (po::variables_map &vm) override final
 Write from pts to output file. More...
 
virtual void v_OutputFromExp (po::variables_map &vm) override final
 Write from m_exp to output file. More...
 
virtual void v_OutputFromData (po::variables_map &vm) override final
 Write from data to output file. More...
 
- Protected Member Functions inherited from Nektar::FieldUtils::OutputVtkBase
virtual fs::path v_GetPath (std::string &filename, po::variables_map &vm) override
 
virtual fs::path v_GetFullOutName (std::string &filename, po::variables_map &vm) override
 
std::string PrepareOutput (po::variables_map &vm)
 
- Protected Member Functions inherited from Nektar::FieldUtils::OutputFileBase
virtual void v_Process (po::variables_map &vm) override
 Write fld to output file. More...
 
virtual std::string v_GetModuleDescription () override
 
virtual ModulePriority v_GetModulePriority () override
 
fs::path GetPath (std::string &filename, po::variables_map &vm)
 
fs::path GetFullOutName (std::string &filename, po::variables_map &vm)
 
- Protected Member Functions inherited from Nektar::FieldUtils::Module
 Module ()
 

Protected Attributes

vtkSmartPointer< vtkUnstructuredGrid > m_vtkMesh
 Cache file for unstructured grid VTK mesh data. More...
 
int m_numPlanes = 1
 Number of planes if homogeneous. More...
 
bool m_extraPlane = false
 Flag if extra plane in case of fourier expansion in homogeneous dir. More...
 
bool m_cachedMesh = false
 Flag if mesh has been cached. More...
 
- Protected Attributes inherited from Nektar::FieldUtils::OutputFileBase
bool m_requireEquiSpaced
 
- Protected Attributes inherited from Nektar::FieldUtils::OutputModule
std::ofstream m_fldFile
 Output stream. More...
 
- Protected Attributes inherited from Nektar::FieldUtils::Module
std::map< std::string, ConfigOptionm_config
 List of configuration values. More...
 
std::set< std::string > m_allowedFiles
 List of allowed file formats. More...
 

Private Member Functions

vtkSmartPointer< vtkUnstructuredGrid > OutputFromExpHighOrder (po::variables_map &vm)
 Prepare high order Lagrange VTK output. More...
 
void AddFieldDataToVTKHighOrder (po::variables_map &vm, std::string &filename, vtkSmartPointer< vtkUnstructuredGrid > &vtkMesh)
 Add field data to high order Lagrange VTK output. More...
 
vtkSmartPointer< vtkUnstructuredGrid > OutputFromExpLowOrder ()
 Prepare low order VTK output. More...
 
void AddFieldDataToVTKLowOrder (po::variables_map &vm, std::string &filename, vtkSmartPointer< vtkUnstructuredGrid > &vtkMesh)
 Add field data to low order VTK output. More...
 
void OutputFromExpLowOrderMultiBlock (po::variables_map &vm, std::string &filename)
 Prepare low order multi-block VTK output & add field data. More...
 
void WriteVTK (vtkDataObject *vtkMesh, std::string &filename, po::variables_map &vm)
 Write VTK file using. More...
 
void WritePVtu (po::variables_map &vm)
 Write the parallel .pvtu file. More...
 

Additional Inherited Members

- Public Attributes inherited from Nektar::FieldUtils::Module
FieldSharedPtr m_f
 Field object. More...
 

Detailed Description

Converter from fld to vtk.

Definition at line 51 of file OutputVtk.h.

Constructor & Destructor Documentation

◆ OutputVtk()

Nektar::FieldUtils::OutputVtk::OutputVtk ( FieldSharedPtr  f)
explicit

Definition at line 59 of file OutputVtk.cpp.

59  : OutputVtkBase(std::move(f))
60 {
61  m_requireEquiSpaced = true;
62  m_config["legacy"] =
63  ConfigOption(true, "0", "Output using legacy manual file writers");
64  m_config["highorder"] = ConfigOption(
65  true, "0", "Output using new high-order Lagrange elements");
66  m_config["multiblock"] = ConfigOption(
67  true, "0", "Output using multi-blocks to separate composites");
68  m_config["uncompress"] = ConfigOption(true, "0", "Uncompress xml sections");
69 }
std::map< std::string, ConfigOption > m_config
List of configuration values.
Definition: Module.h:263

References Nektar::FieldUtils::Module::m_config, and Nektar::FieldUtils::OutputFileBase::m_requireEquiSpaced.

◆ ~OutputVtk()

Nektar::FieldUtils::OutputVtk::~OutputVtk ( )
finaldefault

Member Function Documentation

◆ AddFieldDataToVTKHighOrder()

void Nektar::FieldUtils::OutputVtk::AddFieldDataToVTKHighOrder ( po::variables_map &  vm,
std::string &  filename,
vtkSmartPointer< vtkUnstructuredGrid > &  vtkMesh 
)
private

Add field data to high order Lagrange VTK output.

Definition at line 1431 of file OutputVtk.cpp.

1434 {
1435  // Convert expansion to an equispaced points field
1436  if (m_cachedMesh)
1437  {
1438  auto equispaced =
1440  equispaced->Process(vm);
1441  }
1442  LibUtilities::PtsFieldSharedPtr fPts = m_f->m_fieldPts;
1443 
1444  int nPts = static_cast<int>(fPts->GetNpoints());
1445  int dim = static_cast<int>(fPts->GetDim());
1446 
1447  Array<OneD, Array<OneD, NekDouble>> pts;
1448  fPts->GetPts(pts);
1449 
1450  // Insert field information
1451  for (int i = 0; i < fPts->GetNFields(); ++i)
1452  {
1453  vtkNew<vtkDoubleArray> fieldData;
1454  fieldData->SetArray(&pts[dim + i][0], nPts, 1);
1455  fieldData->SetName(&fPts->GetFieldName(i)[0]);
1456  vtkMesh->GetPointData()->AddArray(fieldData.GetPointer());
1457  }
1458 
1459  WriteVTK(vtkMesh, filename, vm);
1460 }
FieldSharedPtr m_f
Field object.
Definition: Module.h:234
void WriteVTK(vtkDataObject *vtkMesh, std::string &filename, po::variables_map &vm)
Write VTK file using.
Definition: OutputVtk.cpp:1462
bool m_cachedMesh
Flag if mesh has been cached.
Definition: OutputVtk.h:91
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< PtsField > PtsFieldSharedPtr
Definition: PtsField.h:190

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), m_cachedMesh, Nektar::FieldUtils::Module::m_f, and WriteVTK().

Referenced by v_OutputFromExp().

◆ AddFieldDataToVTKLowOrder()

void Nektar::FieldUtils::OutputVtk::AddFieldDataToVTKLowOrder ( po::variables_map &  vm,
std::string &  filename,
vtkSmartPointer< vtkUnstructuredGrid > &  vtkMesh 
)
private

Add field data to low order VTK output.

Definition at line 979 of file OutputVtk.cpp.

982 {
983  // Insert field information we iterate by element from first plane to last,
984  // while the fld file iterates by plane from first element to last
985  int nElmts = static_cast<int>(m_f->m_exp[0]->GetNumElmts());
986  int numPtsPerPlane = m_f->m_exp[0]->GetTotPoints() / m_numPlanes;
987  for (int v = 0; v < m_f->m_variables.size(); ++v)
988  {
989  vtkNew<vtkDoubleArray> fieldData;
990  for (int i = 0; i < nElmts; ++i)
991  {
992  int elmtOffset = m_f->m_exp[v]->GetPhys_Offset(i);
993  int nPtsPerElmtPerPlane = m_f->m_exp[v]->GetExp(i)->GetTotPoints();
994 
995  for (int j = 0; j < m_numPlanes; ++j)
996  {
997  int planeOffset = j * numPtsPerPlane;
998  for (int k = 0; k < nPtsPerElmtPerPlane; ++k)
999  {
1000  fieldData->InsertNextValue(
1001  m_f->m_exp[v]->GetPhys()[elmtOffset + planeOffset + k]);
1002  }
1003  }
1004 
1005  // if extra plane we copy the first plane values in to last plane
1006  if (m_extraPlane)
1007  {
1008  for (int k = 0; k < nPtsPerElmtPerPlane; ++k)
1009  {
1010  fieldData->InsertNextValue(
1011  m_f->m_exp[v]->GetPhys()[elmtOffset + k]);
1012  }
1013  }
1014  }
1015 
1016  fieldData->SetName(&m_f->m_variables[v][0]);
1017  vtkMesh->GetPointData()->AddArray(fieldData.GetPointer());
1018  }
1019 
1020  WriteVTK(vtkMesh, filename, vm);
1021 }
bool m_extraPlane
Flag if extra plane in case of fourier expansion in homogeneous dir.
Definition: OutputVtk.h:88
int m_numPlanes
Number of planes if homogeneous.
Definition: OutputVtk.h:85

References m_extraPlane, Nektar::FieldUtils::Module::m_f, m_numPlanes, and WriteVTK().

Referenced by v_OutputFromExp().

◆ create()

static std::shared_ptr<Module> Nektar::FieldUtils::OutputVtk::create ( const FieldSharedPtr f)
inlinestatic

Creates an instance of this class.

Definition at line 55 of file OutputVtk.h.

56  {
58  }

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

◆ OutputFromExpHighOrder()

vtkSmartPointer< vtkUnstructuredGrid > Nektar::FieldUtils::OutputVtk::OutputFromExpHighOrder ( po::variables_map &  vm)
private

Prepare high order Lagrange VTK output.

Definition at line 1302 of file OutputVtk.cpp.

1304 {
1305  ASSERTL0(
1306  m_f->m_numHomogeneousDir == 0,
1307  "High order VTK is not implemented for homogeneous expansion types.")
1308 
1309  // Save shapetypes before convert to equispaced because that nukes the
1310  // explist
1311  std::vector<LibUtilities::ShapeType> sType;
1312  for (auto &i : *m_f->m_exp[0]->GetExp())
1313  {
1314  sType.emplace_back(i->GetGeom()->GetShapeType());
1315  }
1316 
1317  // Convert expansion to an equispaced points field
1318  auto equispaced =
1320  equispaced->Process(vm);
1321 
1322  // Insert points
1323  vtkNew<vtkPoints> vtkPoints;
1324  LibUtilities::PtsFieldSharedPtr fPts = m_f->m_fieldPts;
1325  vtkPoints->SetDataType(VTK_DOUBLE);
1326 
1327  Array<OneD, Array<OneD, NekDouble>> pts;
1328  fPts->GetPts(pts);
1329 
1330  int dim = static_cast<int>(fPts->GetDim());
1331  int nPts = static_cast<int>(fPts->GetNpoints());
1332  switch (dim)
1333  {
1334  case 3:
1335  for (int i = 0; i < nPts; ++i)
1336  {
1337  vtkPoints->InsertNextPoint(pts[0][i], pts[1][i], pts[2][i]);
1338  }
1339  break;
1340  case 2:
1341  for (int i = 0; i < nPts; ++i)
1342  {
1343  vtkPoints->InsertNextPoint(pts[0][i], pts[1][i], 0.0);
1344  }
1345  break;
1346  case 1:
1347  for (int i = 0; i < nPts; ++i)
1348  {
1349  vtkPoints->InsertNextPoint(pts[0][i], 0.0, 0.0);
1350  }
1351  break;
1352  default:
1353  break;
1354  }
1355 
1356  // Mesh file to output
1357  vtkSmartPointer<vtkUnstructuredGrid> vtkMesh =
1358  vtkSmartPointer<vtkUnstructuredGrid>::New();
1359  vtkMesh->SetPoints(vtkPoints.GetPointer());
1360 
1361  // Cache ordering for shape type & npts so we aren't recreating mappings
1362  std::unordered_map<size_t, std::vector<long long>> mappingCache;
1363 
1364  // Get offset per element in a vector from ppe
1365  std::vector<int> ppe = m_f->m_fieldPts->GetPointsPerElement();
1366  Array<OneD, int> ppeOffset(ppe.size() + 1, 0.0);
1367  std::partial_sum(ppe.begin(), ppe.end(), &ppeOffset[1]);
1368 
1369  // Insert elements
1370  for (int i = 0; i < ppe.size(); ++i)
1371  {
1372  // Construct inverse of input reordering.
1373  // First try to find it in our mapping cache.
1374  auto oIt = mappingCache.find(key2(sType[i], ppe[i]));
1375  if (oIt == mappingCache.end())
1376  {
1377  std::vector<long long> p(ppe[i]);
1378  std::iota(p.begin(), p.end(), 0);
1379  switch (sType[i])
1380  {
1382  p = quadTensorNodeOrdering(p);
1383  break;
1385  p = triTensorNodeOrdering(p);
1386  break;
1388  p = tetTensorNodeOrdering(p);
1389  break;
1391  p = hexTensorNodeOrdering(p);
1392  break;
1393  case LibUtilities::ePrism:
1394  p = prismTensorNodeOrdering(p);
1395  break;
1396  default:
1398  "High-order VTU output not set up for the " +
1399  static_cast<std::string>(
1400  LibUtilities::ShapeTypeMap[sType[i]]) +
1401  " shape type.");
1402  break;
1403  }
1404 
1405  // Invert the ordering as this is for spectral -> recursive (VTU)
1406  std::vector<long long> inv(ppe[i]);
1407  for (int j = 0; j < ppe[i]; ++j)
1408  {
1409  inv[p[j]] = j;
1410  }
1411 
1412  oIt =
1413  mappingCache.insert(std::make_pair(key2(sType[i], ppe[i]), inv))
1414  .first;
1415  }
1416 
1417  // Add offset to reordering
1418  std::vector<long long> p = oIt->second;
1419  for (long long &j : p)
1420  {
1421  j += ppeOffset[i];
1422  }
1423 
1424  vtkMesh->InsertNextCell(GetHighOrderVtkCellType(sType[i]), ppe[i],
1425  &p[0]);
1426  }
1427 
1428  return vtkMesh;
1429 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
const char *const ShapeTypeMap[SIZE_ShapeType]
Definition: ShapeType.hpp:79

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::ErrorUtil::efatal, Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::FieldUtils::Module::m_f, NEKERROR, CellMLToNektar.cellml_metadata::p, and Nektar::LibUtilities::ShapeTypeMap.

Referenced by v_OutputFromExp().

◆ OutputFromExpLowOrder()

vtkSmartPointer< vtkUnstructuredGrid > Nektar::FieldUtils::OutputVtk::OutputFromExpLowOrder ( )
private

Prepare low order VTK output.

Definition at line 856 of file OutputVtk.cpp.

857 {
858  // Mesh file to output
859  vtkSmartPointer<vtkUnstructuredGrid> vtkMesh =
860  vtkSmartPointer<vtkUnstructuredGrid>::New();
861 
862  // Cache ordering so we aren't recreating mappings
863  std::unordered_map<size_t, std::vector<long long>> mappingCache;
864 
865  // Choose cell types and num quad points based on dimension
866  int nDim = m_f->m_exp[0]->GetShapeDimension();
867  int nHomoDir = m_f->m_numHomogeneousDir;
868 
869  auto type = (nDim + nHomoDir == 3) ? VTK_HEXAHEDRON
870  : (nDim + nHomoDir == 2) ? VTK_QUAD
871  : VTK_LINE;
872  int nQpts = (nDim + nHomoDir == 3) ? 8 : (nDim + nHomoDir == 2) ? 4 : 2;
873 
874  // Fill homogeneous info
875  if (nHomoDir != 0)
876  {
877  ASSERTL0(nHomoDir == 1 &&
878  m_f->m_exp[0]->GetExpType() == MultiRegions::e3DH1D,
879  "Only regular expansions and the 3DH1D homogeneous expansion "
880  "are supported in the new VTK writer. Please use the 'legacy' "
881  "option for all other expansion types.")
882 
883  m_numPlanes = m_f->m_exp[0]->GetHomogeneousBasis()->GetNumModes();
884  // Extra plane if fourier
885  m_extraPlane = (m_f->m_exp[0]->GetHomogeneousBasis()->GetBasisType() ==
886  LibUtilities::eFourier &&
887  m_f->m_exp[0]->GetHomogeneousBasis()->GetPointsType() ==
888  LibUtilities::eFourierEvenlySpaced);
889  }
890 
891  // Insert points
892  vtkNew<vtkPoints> vtkPoints;
893  vtkPoints->SetDataType(VTK_DOUBLE);
894 
895  int offset = 0;
896  int nElmts = static_cast<int>(m_f->m_exp[0]->GetNumElmts());
897  for (int i = 0; i < nElmts; ++i)
898  {
899  Array<OneD, int> nquad(3, 0);
900  for (int j = 0; j < nDim; ++j)
901  {
902  nquad[j] = m_f->m_exp[0]->GetExp(i)->GetNumPoints(j);
903  }
904 
905  // Add homogeneous direction num points
906  if (nHomoDir != 0)
907  {
908  nquad[nDim] = m_numPlanes;
909 
910  // Add extra plane if fourier
911  if (m_extraPlane)
912  {
913  nquad[nDim]++;
914  }
915  }
916 
917  // Get total points by multiplying all nquads together (accounts for
918  // homo)
919  int nPts = nquad[0];
920  for (int j = 1; j < nDim + nHomoDir; ++j)
921  {
922  nPts *= nquad[j];
923  }
924 
925  // Get all coordinates at quadrature points in this element
926  Array<OneD, NekDouble> x(nPts, 0.0), y(nPts, 0.0), z(nPts, 0.0);
927  m_f->m_exp[0]->GetCoords(i, x, y, z);
928 
929  // If add extra plane for fourier need to fill last plane coordinates
930  if (m_extraPlane)
931  {
932  // Copy x & y to extra plane
933  Array<OneD, NekDouble> tmp;
934  Vmath::Vcopy(nquad[0] * nquad[1], x, 1,
935  tmp = x + (nquad[2] - 1) * nquad[0] * nquad[1], 1);
936  Vmath::Vcopy(nquad[0] * nquad[1], y, 1,
937  tmp = y + (nquad[2] - 1) * nquad[0] * nquad[1], 1);
938 
939  // Fill z on extra plane
940  NekDouble zDouble = z[nquad[0] * nquad[1] * (nquad[2] - 1) - 1] +
941  (z[nquad[0] * nquad[1]] - z[0]);
942  Vmath::Fill(nquad[0] * nquad[1], zDouble,
943  tmp = z + (nquad[2] - 1) * nquad[0] * nquad[1], 1);
944  }
945 
946  // Insert points in to vtk mesh
947  for (int j = 0; j < nPts; ++j)
948  {
949  vtkPoints->InsertNextPoint(x[j], y[j], z[j]);
950  }
951 
952  // Insert elements
953  auto oIt = mappingCache.find(key3(nquad[0], nquad[1], nquad[2]));
954  if (oIt == mappingCache.end())
955  {
956  auto p = lowOrderMapping(nDim + nHomoDir, nquad);
957  oIt = mappingCache
958  .insert(
959  std::make_pair(key3(nquad[0], nquad[1], nquad[2]), p))
960  .first;
961  }
962 
963  auto p = oIt->second;
964  std::for_each(p.begin(), p.end(),
965  [offset](long long &d) { d += offset; });
966  for (int j = 0; j < p.size(); j += nQpts)
967  {
968  vtkMesh->InsertNextCell(type, nQpts, &p[j]);
969  }
970 
971  offset += nPts;
972  }
973 
974  vtkMesh->SetPoints(vtkPoints.GetPointer());
975 
976  return vtkMesh;
977 }
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:76
@ eFourier
Fourier Expansion .
Definition: BasisType.h:57
double NekDouble
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255

References ASSERTL0, Nektar::MultiRegions::e3DH1D, Nektar::LibUtilities::eFourier, Nektar::LibUtilities::eFourierEvenlySpaced, Vmath::Fill(), m_extraPlane, Nektar::FieldUtils::Module::m_f, m_numPlanes, CellMLToNektar.cellml_metadata::p, and Vmath::Vcopy().

Referenced by v_OutputFromExp().

◆ OutputFromExpLowOrderMultiBlock()

void Nektar::FieldUtils::OutputVtk::OutputFromExpLowOrderMultiBlock ( po::variables_map &  vm,
std::string &  filename 
)
private

Prepare low order multi-block VTK output & add field data.

Definition at line 1023 of file OutputVtk.cpp.

1025 {
1026  ASSERTL0(
1027  m_f->m_numHomogeneousDir == 0,
1028  "Multi block VTK is not implemented for homogeneous expansion types.")
1029 
1030  ASSERTL0(m_f->m_comm->GetSpaceComm()->IsSerial(),
1031  "Multi block VTK is not implemented in parallel.")
1032 
1033  int dim = m_f->m_graph->GetMeshDimension();
1034 
1035  // Create mappings from geometry id to expansion ids
1036  std::array<std::map<int, std::pair<int, int>>, 4> geomIdToExpId;
1037  int nElmts = static_cast<int>(m_f->m_exp[0]->GetNumElmts());
1038  for (int i = 0; i < nElmts; ++i)
1039  {
1040  auto geom = m_f->m_exp[0]->GetExp(i)->GetGeom();
1041  geomIdToExpId[geom->GetShapeDim()][geom->GetGlobalID()] =
1042  std::make_pair(i, -1);
1043 
1044  for (int j = 0; j < geom->GetNumFaces(); ++j)
1045  {
1046  geomIdToExpId[2][geom->GetFid(j)] = std::make_pair(i, j);
1047  }
1048 
1049  for (int j = 0; j < geom->GetNumEdges(); ++j)
1050  {
1051  geomIdToExpId[1][geom->GetEid(j)] = std::make_pair(i, j);
1052  }
1053  }
1054 
1055  // Cache ordering so we aren't recreating mappings
1056  std::unordered_map<size_t, std::vector<long long>> mappingCache;
1057 
1058  std::map<int, vtkNew<vtkUnstructuredGrid>> vtkMesh;
1059  std::map<int, SpatialDomains::CompositeSharedPtr> composites =
1060  m_f->m_graph->GetComposites();
1061  std::map<int, std::string> compositeNames;
1062  for (auto &comp : composites)
1063  {
1064  // Vector of field data
1065  std::vector<vtkNew<vtkDoubleArray>> fieldData(m_f->m_variables.size());
1066 
1067  // Insert points
1068  vtkNew<vtkPoints> vtkPoints;
1069  vtkPoints->SetDataType(VTK_DOUBLE);
1070 
1071  int compId = comp.first;
1072  std::vector<std::shared_ptr<SpatialDomains::Geometry>> geomVec =
1073  comp.second->m_geomVec;
1074 
1075  unsigned int offset = 0;
1076  for (auto &geom : geomVec)
1077  {
1078  int geomId = geom->GetGlobalID();
1079  int sDim = geom->GetShapeDim();
1080  auto type = (sDim == 3) ? VTK_HEXAHEDRON
1081  : (sDim == 2) ? VTK_QUAD
1082  : VTK_LINE;
1083  int nQpts = (sDim == 3) ? 8 : (sDim == 2) ? 4 : 2;
1084 
1086  m_f->m_exp[0]->GetExp(geomIdToExpId[sDim][geomId].first);
1087 
1088  unsigned int nPts = exp->GetTotPoints();
1089  Array<OneD, NekDouble> x(nPts, 0.0), y(nPts, 0.0), z(nPts, 0.0);
1090  exp->GetCoords(x, y, z);
1091 
1092  int offsetPhys = m_f->m_exp[0]->GetPhys_Offset(
1093  geomIdToExpId[sDim][geomId].first);
1094  if (sDim == dim)
1095  {
1096  for (int j = 0; j < nPts; ++j)
1097  {
1098  vtkPoints->InsertNextPoint(x[j], y[j], z[j]);
1099 
1100  // Add field data
1101  for (int k = 0; k < m_f->m_variables.size(); ++k)
1102  {
1103  fieldData[k]->InsertNextValue(
1104  m_f->m_exp[k]->GetPhys()[j + offsetPhys]);
1105  }
1106  }
1107  }
1108  else
1109  {
1110  Array<OneD, int> pointsMap;
1111  exp->GetTracePhysMap(geomIdToExpId[sDim][geomId].second,
1112  pointsMap);
1113  for (int j : pointsMap)
1114  {
1115  vtkPoints->InsertNextPoint(x[j], y[j], z[j]);
1116 
1117  // Add field data
1118  for (int k = 0; k < m_f->m_variables.size(); ++k)
1119  {
1120  fieldData[k]->InsertNextValue(
1121  m_f->m_exp[k]->GetPhys()[offsetPhys + j]);
1122  }
1123  }
1124 
1125  exp = exp->GetTraceExp(geomIdToExpId[sDim][geomId].second);
1126  nPts = pointsMap.size();
1127  }
1128 
1129  Array<OneD, int> nquad(3, 0);
1130  for (int j = 0; j < sDim; ++j)
1131  {
1132  nquad[j] = exp->GetNumPoints(j);
1133  }
1134 
1135  auto oIt = mappingCache.find(key3(nquad[0], nquad[1], nquad[2]));
1136  if (oIt == mappingCache.end())
1137  {
1138  auto p = lowOrderMapping(sDim, nquad);
1139  oIt = mappingCache
1140  .insert(std::make_pair(
1141  key3(nquad[0], nquad[1], nquad[2]), p))
1142  .first;
1143  }
1144 
1145  auto p = oIt->second;
1146  std::for_each(p.begin(), p.end(),
1147  [offset](long long &d) { d += offset; });
1148 
1149  for (int j = 0; j < p.size(); j += nQpts)
1150  {
1151  vtkMesh[compId]->InsertNextCell(type, nQpts, &p[j]);
1152  }
1153 
1154  offset += nPts;
1155  }
1156 
1157  vtkMesh[compId]->SetPoints(vtkPoints.GetPointer());
1158 
1159  // Add all fields to vtkMesh
1160  for (int k = 0; k < m_f->m_variables.size(); ++k)
1161  {
1162  fieldData[k]->SetName(&m_f->m_variables[k][0]);
1163  vtkMesh[compId]->GetPointData()->AddArray(
1164  fieldData[k].GetPointer());
1165  }
1166 
1167  // Find composite names if exists and store in map
1168  // Set name as boundary label if it exists otherwise index ID
1169  compositeNames[compId] = "Composite ID " + std::to_string(compId);
1170  auto clabels = m_f->m_graph->GetCompositesLabels();
1171  auto oIt = clabels.find(compId);
1172  if (oIt != clabels.end())
1173  {
1174  compositeNames[compId] = oIt->second;
1175  }
1176  }
1177 
1178  // Main multi-block set
1179  vtkNew<vtkMultiBlockDataSet> mainBlock;
1180 
1181  std::set<int> compSet;
1182 
1183  // Fill domain multi blocks from composites
1184  vtkNew<vtkMultiBlockDataSet> mainDomainBlock;
1185  auto domains = m_f->m_graph->GetDomain();
1186  std::vector<vtkNew<vtkMultiBlockDataSet>> domainMultiBlocks(domains.size());
1187  for (int i = 0; i < domains.size(); ++i)
1188  {
1189  auto dom = domains[i];
1190 
1191  // Loop over composites and see if in domain
1192  for (auto &comp : composites)
1193  {
1194  int compId = comp.first;
1195  if (dom.find(compId) != dom.end())
1196  {
1197  unsigned int nBlock = domainMultiBlocks[i]->GetNumberOfBlocks();
1198  domainMultiBlocks[i]->SetBlock(nBlock,
1199  vtkMesh[compId].GetPointer());
1200  domainMultiBlocks[i]->GetMetaData(nBlock)->Set(
1201  vtkCompositeDataSet::NAME(),
1202  compositeNames[compId].c_str());
1203  compSet.insert(compId);
1204  }
1205  }
1206 
1207  unsigned int nBlock = mainDomainBlock->GetNumberOfBlocks();
1208  mainDomainBlock->SetBlock(nBlock, domainMultiBlocks[i].GetPointer());
1209  mainDomainBlock->GetMetaData(nBlock)->Set(
1210  vtkCompositeDataSet::NAME(),
1211  ("Domain ID " + std::to_string(i)).c_str());
1212  }
1213 
1214  if (mainDomainBlock->GetNumberOfBlocks() != 0)
1215  {
1216  auto nBlock = static_cast<unsigned int>(mainBlock->GetNumberOfBlocks());
1217  mainBlock->SetBlock(nBlock, mainDomainBlock.GetPointer());
1218  mainBlock->GetMetaData(nBlock)->Set(vtkCompositeDataSet::NAME(),
1219  "Domains");
1220  }
1221 
1222  // Fill boundary multi blocks from composites
1223  SpatialDomains::BoundaryConditions bcs(m_f->m_session,
1224  m_f->m_exp[0]->GetGraph());
1226  bcs.GetBoundaryRegions();
1227 
1228  vtkNew<vtkMultiBlockDataSet> mainBoundaryBlock;
1229  std::vector<vtkNew<vtkMultiBlockDataSet>> boundaryMultiBlocks(
1230  bregions.size());
1231  int cnt = 0;
1232  for (auto &boundary : bregions)
1233  {
1234  // Loop over composites and see if in boundary
1235  for (auto &comp : composites)
1236  {
1237  int compId = comp.first;
1238  if (boundary.second->find(compId) != boundary.second->end())
1239  {
1240  unsigned int nBlock =
1241  boundaryMultiBlocks[cnt]->GetNumberOfBlocks();
1242  boundaryMultiBlocks[cnt]->SetBlock(
1243  nBlock, vtkMesh[compId].GetPointer());
1244  boundaryMultiBlocks[cnt]->GetMetaData(nBlock)->Set(
1245  vtkCompositeDataSet::NAME(),
1246  compositeNames[compId].c_str());
1247  compSet.insert(compId);
1248  }
1249  }
1250 
1251  unsigned int nBlock = mainBoundaryBlock->GetNumberOfBlocks();
1252  mainBoundaryBlock->SetBlock(nBlock,
1253  boundaryMultiBlocks[cnt++].GetPointer());
1254 
1255  // Set name as boundary label if it exists otherwise index ID
1256  std::string name = "Boundary ID " + std::to_string(boundary.first);
1257  auto blabels = bcs.GetBoundaryLabels();
1258  auto oIt = blabels.find(boundary.first);
1259  if (oIt != blabels.end())
1260  {
1261  name = oIt->second;
1262  }
1263 
1264  mainBoundaryBlock->GetMetaData(nBlock)->Set(vtkCompositeDataSet::NAME(),
1265  name.c_str());
1266  }
1267 
1268  if (mainBoundaryBlock->GetNumberOfBlocks() != 0)
1269  {
1270  auto nBlock = static_cast<unsigned int>(mainBlock->GetNumberOfBlocks());
1271  mainBlock->SetBlock(nBlock, mainBoundaryBlock.GetPointer());
1272  mainBlock->GetMetaData(nBlock)->Set(vtkCompositeDataSet::NAME(),
1273  "Boundaries");
1274  }
1275 
1276  // Include all other composites (not domains or boundaries)
1277  vtkNew<vtkMultiBlockDataSet> compsMultiBlocks;
1278  cnt = 0;
1279  for (auto &comp : composites)
1280  {
1281  int compId = comp.first;
1282  if (compSet.find(compId) == compSet.end())
1283  {
1284  unsigned int nBlock = compsMultiBlocks->GetNumberOfBlocks();
1285  compsMultiBlocks->SetBlock(nBlock, vtkMesh[compId].GetPointer());
1286  compsMultiBlocks->GetMetaData(nBlock)->Set(
1287  vtkCompositeDataSet::NAME(), compositeNames[compId].c_str());
1288  }
1289  }
1290 
1291  if (compsMultiBlocks->GetNumberOfBlocks() != 0)
1292  {
1293  auto nBlock = static_cast<unsigned int>(mainBlock->GetNumberOfBlocks());
1294  mainBlock->SetBlock(nBlock, compsMultiBlocks.GetPointer());
1295  mainBlock->GetMetaData(nBlock)->Set(vtkCompositeDataSet::NAME(),
1296  "Other composites");
1297  }
1298 
1299  WriteVTK(mainBlock.GetPointer(), filename, vm);
1300 }
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:68
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition: Conditions.h:210

References ASSERTL0, Nektar::SpatialDomains::BoundaryConditions::GetBoundaryLabels(), Nektar::SpatialDomains::BoundaryConditions::GetBoundaryRegions(), Nektar::FieldUtils::Module::m_f, CellMLToNektar.pycml::name, CellMLToNektar.cellml_metadata::p, and WriteVTK().

Referenced by v_OutputFromExp().

◆ v_GetModuleName()

virtual std::string Nektar::FieldUtils::OutputVtk::v_GetModuleName ( )
inlinefinaloverrideprotectedvirtual

Reimplemented from Nektar::FieldUtils::OutputVtkBase.

Definition at line 67 of file OutputVtk.h.

68  {
69  return "OutputVtk";
70  }

◆ v_OutputFromData()

void Nektar::FieldUtils::OutputVtk::v_OutputFromData ( po::variables_map &  vm)
finaloverrideprotectedvirtual

Write from data to output file.

Reimplemented from Nektar::FieldUtils::OutputVtkBase.

Definition at line 1596 of file OutputVtk.cpp.

1597 {
1598  boost::ignore_unused(vm);
1600  "OutputVtk can't write using only FieldData. You may need "
1601  "to add a mesh XML file to your input files.");
1602 }

References Nektar::ErrorUtil::efatal, and NEKERROR.

◆ v_OutputFromExp()

void Nektar::FieldUtils::OutputVtk::v_OutputFromExp ( po::variables_map &  vm)
finaloverrideprotectedvirtual

Write from m_exp to output file.

Reimplemented from Nektar::FieldUtils::OutputVtkBase.

Definition at line 1609 of file OutputVtk.cpp.

1610 {
1611  if (m_config["legacy"].m_beenSet)
1612  {
1613  ASSERTL0(!m_config["multiblock"].m_beenSet,
1614  "Multi block VTK is not implemented for legacy output.")
1615 
1616  ASSERTL0(!m_config["highorder"].m_beenSet,
1617  "High order VTK is not implemented for legacy output.")
1618 
1619  // No caching of mesh data in legacy output
1621  return;
1622  }
1623 
1624  // Extract the output filename and extension
1625  std::string filename = OutputVtkBase::PrepareOutput(vm);
1626 
1627  // Save mesh state (if using filter this allows us to only ProcessEquispaced
1628  // if needed)
1630 
1631  if (m_config["highorder"].m_beenSet)
1632  {
1633  ASSERTL0(!m_config["multiblock"].m_beenSet,
1634  "Multi block VTK is not implemented for high-order output.")
1635 
1636  if (!m_cachedMesh)
1637  {
1639  }
1640 
1641  AddFieldDataToVTKHighOrder(vm, filename, m_vtkMesh);
1642  }
1643  else if (m_config["multiblock"].m_beenSet)
1644  {
1645  // No mesh caching for multiblock due to complexity of field data
1646  OutputFromExpLowOrderMultiBlock(vm, filename);
1647  }
1648  else
1649  {
1650  if (!m_cachedMesh)
1651  {
1653  }
1654 
1655  AddFieldDataToVTKLowOrder(vm, filename, m_vtkMesh);
1656  }
1657 }
std::string PrepareOutput(po::variables_map &vm)
vtkSmartPointer< vtkUnstructuredGrid > OutputFromExpLowOrder()
Prepare low order VTK output.
Definition: OutputVtk.cpp:856
void AddFieldDataToVTKHighOrder(po::variables_map &vm, std::string &filename, vtkSmartPointer< vtkUnstructuredGrid > &vtkMesh)
Add field data to high order Lagrange VTK output.
Definition: OutputVtk.cpp:1431
void OutputFromExpLowOrderMultiBlock(po::variables_map &vm, std::string &filename)
Prepare low order multi-block VTK output & add field data.
Definition: OutputVtk.cpp:1023
vtkSmartPointer< vtkUnstructuredGrid > m_vtkMesh
Cache file for unstructured grid VTK mesh data.
Definition: OutputVtk.h:82
void AddFieldDataToVTKLowOrder(po::variables_map &vm, std::string &filename, vtkSmartPointer< vtkUnstructuredGrid > &vtkMesh)
Add field data to low order VTK output.
Definition: OutputVtk.cpp:979
vtkSmartPointer< vtkUnstructuredGrid > OutputFromExpHighOrder(po::variables_map &vm)
Prepare high order Lagrange VTK output.
Definition: OutputVtk.cpp:1302
virtual void v_OutputFromExp(po::variables_map &vm) override final
Write from m_exp to output file.
Definition: OutputVtk.cpp:1609

References AddFieldDataToVTKHighOrder(), AddFieldDataToVTKLowOrder(), ASSERTL0, m_cachedMesh, Nektar::FieldUtils::Module::m_config, m_vtkMesh, OutputFromExpHighOrder(), OutputFromExpLowOrder(), OutputFromExpLowOrderMultiBlock(), Nektar::FieldUtils::OutputVtkBase::PrepareOutput(), and Nektar::FieldUtils::OutputVtkBase::v_OutputFromExp().

◆ v_OutputFromPts()

void Nektar::FieldUtils::OutputVtk::v_OutputFromPts ( po::variables_map &  vm)
finaloverrideprotectedvirtual

Write from pts to output file.

Reimplemented from Nektar::FieldUtils::OutputVtkBase.

Definition at line 1604 of file OutputVtk.cpp.

1605 {
1607 }
virtual void v_OutputFromPts(po::variables_map &vm) override
Write from pts to output file.

References Nektar::FieldUtils::OutputVtkBase::v_OutputFromPts().

◆ WritePVtu()

void Nektar::FieldUtils::OutputVtk::WritePVtu ( po::variables_map &  vm)
private

Write the parallel .pvtu file.

Definition at line 1524 of file OutputVtk.cpp.

1525 {
1526  std::string filename = m_config["outfile"].as<std::string>();
1527  int dot = static_cast<int>(filename.find_last_of('.'));
1528  std::string body = filename.substr(0, dot);
1529  filename = body + ".pvtu";
1530 
1531  std::ofstream outfile(filename.c_str());
1532 
1533  int nprocs = m_f->m_comm->GetSpaceComm()->GetSize();
1534  std::string path =
1536 
1537  outfile << "<?xml version=\"1.0\"?>" << endl;
1538  outfile << "<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\" "
1539  << "byte_order=\"LittleEndian\">" << endl;
1540  outfile << " <PUnstructuredGrid GhostLevel=\"0\">" << endl;
1541 
1542  // Add time if exists
1543  if (!m_f->m_fieldMetaDataMap["Time"].empty())
1544  {
1545  outfile << " <FieldData> " << endl;
1546  outfile << " <DataArray type=\"Float64\" Name=\"TimeValue\" "
1547  "NumberOfTuples=\"1\" format=\"ascii\">"
1548  << endl;
1549  outfile << m_f->m_fieldMetaDataMap["Time"] << std::endl;
1550  outfile << " </DataArray>" << std::endl;
1551  outfile << " </FieldData> " << endl;
1552  }
1553 
1554  // Add point coordinates
1555  outfile << " <PPoints> " << endl;
1556  outfile << " <PDataArray type=\"Float64\" NumberOfComponents=\"" << 3
1557  << "\"/> " << endl;
1558  outfile << " </PPoints>" << endl;
1559 
1560  // Add cell information
1561  outfile << " <PCells>" << endl;
1562  outfile << " <PDataArray type=\"Int64\" Name=\"connectivity\" "
1563  "NumberOfComponents=\"1\"/>"
1564  << endl;
1565  outfile << " <PDataArray type=\"Int64\" Name=\"offsets\" "
1566  "NumberOfComponents=\"1\"/>"
1567  << endl;
1568  outfile << " <PDataArray type=\"UInt8\" Name=\"types\" "
1569  "NumberOfComponents=\"1\"/>"
1570  << endl;
1571  outfile << " </PCells>" << endl;
1572 
1573  // Add fields (point data)
1574  outfile << " <PPointData>" << endl;
1575  for (auto &var : m_f->m_variables)
1576  {
1577  outfile << " <PDataArray type=\"Float64\" Name=\"" << var << "\"/>"
1578  << endl;
1579  }
1580  outfile << " </PPointData>" << endl;
1581 
1582  // Add parallel files
1583  for (int i = 0; i < nprocs; ++i)
1584  {
1585  boost::format pad("P%1$07d.vtu");
1586  pad % i;
1587  outfile << " <Piece Source=\"" << path << "/" << pad.str() << "\"/>"
1588  << endl;
1589  }
1590  outfile << " </PUnstructuredGrid>" << endl;
1591  outfile << "</VTKFile>" << endl;
1592 
1593  cout << "Written file: " << filename << endl;
1594 }
virtual fs::path v_GetPath(std::string &filename, po::variables_map &vm) override
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:45

References CellMLToNektar.pycml::format, Nektar::FieldUtils::Module::m_config, Nektar::FieldUtils::Module::m_f, Nektar::LibUtilities::PortablePath(), and Nektar::FieldUtils::OutputVtkBase::v_GetPath().

Referenced by WriteVTK().

◆ WriteVTK()

void Nektar::FieldUtils::OutputVtk::WriteVTK ( vtkDataObject *  vtkMesh,
std::string &  filename,
po::variables_map &  vm 
)
private

Write VTK file using.

Parameters
vtkMesh

Definition at line 1462 of file OutputVtk.cpp.

1464 {
1465  // Initialise base writer class as default structured grid writer
1466  vtkSmartPointer<vtkXMLWriter> vtkMeshWriter =
1467  vtkNew<vtkXMLUnstructuredGridWriter>().GetPointer();
1468 
1469  // If multi block we need to switch to the MultiBlock writer
1470  if (m_config["multiblock"].m_beenSet)
1471  {
1472  vtkMeshWriter = vtkNew<vtkXMLMultiBlockDataWriter>().GetPointer();
1473  }
1474 
1475  // Choose the correct extension based on which mesh writer is used
1476  int dot = static_cast<int>(filename.find_last_of('.'));
1477  std::string body = filename.substr(0, dot + 1);
1478  filename = body + vtkMeshWriter->GetDefaultFileExtension();
1479 
1480  // Set time information if exists
1481  if (!m_f->m_fieldMetaDataMap["Time"].empty())
1482  {
1483  vtkMesh->GetInformation()->Set(
1484  vtkDataObject::DATA_TIME_STEP(),
1485  std::stod(m_f->m_fieldMetaDataMap["Time"]));
1486  }
1487  else if (!m_f->m_fieldMetaDataMap["FinalTime"].empty())
1488  {
1489  vtkMesh->GetInformation()->Set(
1490  vtkDataObject::DATA_TIME_STEP(),
1491  std::stod(m_f->m_fieldMetaDataMap["FinalTime"]));
1492  }
1493 
1494  // Write out the new mesh in XML format (don't support legacy
1495  // format here as we still have standard OutputVtk.cpp)
1496  vtkMeshWriter->SetFileName(filename.c_str());
1497 
1498 #if VTK_MAJOR_VERSION <= 5
1499  vtkMeshWriter->SetInput(vtkMesh);
1500 #else
1501  vtkMeshWriter->SetInputData(vtkMesh);
1502 #endif
1503 
1504  if (m_config["uncompress"].m_beenSet)
1505  {
1506  vtkMeshWriter->SetDataModeToAscii();
1507  }
1508 
1509  vtkMeshWriter->Update();
1510 
1511  std::cout << "Written file: " << filename << std::endl;
1512 
1513  // Output parallel file information if needed - using a manual write.
1514  // We could use the VTK lib to do this, but that requires VTK with MPI
1515  // enabled & messing about with the parallel controller & changing
1516  // our file naming scheme as VTK forces _${proc-number} as a suffix...
1517  if (m_f->m_comm->GetSpaceComm()->TreatAsRankZero() &&
1518  !m_f->m_comm->GetSpaceComm()->IsSerial())
1519  {
1520  WritePVtu(vm);
1521  }
1522 }
void WritePVtu(po::variables_map &vm)
Write the parallel .pvtu file.
Definition: OutputVtk.cpp:1524

References Nektar::FieldUtils::Module::m_config, Nektar::FieldUtils::Module::m_f, and WritePVtu().

Referenced by AddFieldDataToVTKHighOrder(), AddFieldDataToVTKLowOrder(), and OutputFromExpLowOrderMultiBlock().

Member Data Documentation

◆ m_cachedMesh

bool Nektar::FieldUtils::OutputVtk::m_cachedMesh = false
protected

Flag if mesh has been cached.

Definition at line 91 of file OutputVtk.h.

Referenced by AddFieldDataToVTKHighOrder(), and v_OutputFromExp().

◆ m_className

ModuleKey Nektar::FieldUtils::OutputVtk::m_className
static
Initial value:
ModuleKey(eOutputModule, "vtu"), OutputVtk::create, "Writes a VTU file.")
static std::shared_ptr< Module > create(const FieldSharedPtr &f)
Creates an instance of this class.
Definition: OutputVtk.h:55
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:317
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49

Definition at line 60 of file OutputVtk.h.

◆ m_extraPlane

bool Nektar::FieldUtils::OutputVtk::m_extraPlane = false
protected

Flag if extra plane in case of fourier expansion in homogeneous dir.

Definition at line 88 of file OutputVtk.h.

Referenced by AddFieldDataToVTKLowOrder(), and OutputFromExpLowOrder().

◆ m_numPlanes

int Nektar::FieldUtils::OutputVtk::m_numPlanes = 1
protected

Number of planes if homogeneous.

Definition at line 85 of file OutputVtk.h.

Referenced by AddFieldDataToVTKLowOrder(), and OutputFromExpLowOrder().

◆ m_vtkMesh

vtkSmartPointer<vtkUnstructuredGrid> Nektar::FieldUtils::OutputVtk::m_vtkMesh
protected

Cache file for unstructured grid VTK mesh data.

Definition at line 82 of file OutputVtk.h.

Referenced by v_OutputFromExp().