You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1246 lines
34 KiB
1246 lines
34 KiB
2 years ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: $RCSfile: vtkEnSightWriter.cxx,v $
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
Copyright (c) Sandia Corporation
|
||
|
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
||
|
----------------------------------------------------------------------------*/
|
||
|
|
||
|
/* TODO
|
||
|
*
|
||
|
*
|
||
|
* check that data was written
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "vtkEnSightWriter.h"
|
||
|
|
||
|
#include "vtkToolkits.h" // for VTK_USE_PARALLEL
|
||
|
#ifdef VTK_USE_PARALLEL
|
||
|
# include "vtkMultiProcessController.h"
|
||
|
#endif
|
||
|
|
||
|
#include "vtkBitArray.h"
|
||
|
#include "vtkByteSwap.h"
|
||
|
#include "vtkCellArray.h"
|
||
|
#include "vtkCellData.h"
|
||
|
#include "vtkCharArray.h"
|
||
|
#include "vtkDataSet.h"
|
||
|
#include "vtkDoubleArray.h"
|
||
|
#include "vtkErrorCode.h"
|
||
|
#include "vtkFieldData.h"
|
||
|
#include "vtkFloatArray.h"
|
||
|
#include "vtkInformation.h"
|
||
|
#include "vtkIntArray.h"
|
||
|
#include "vtkLongArray.h"
|
||
|
#include "vtkLookupTable.h"
|
||
|
#include "vtkObjectFactory.h"
|
||
|
#include "vtkPointData.h"
|
||
|
#include "vtkPoints.h"
|
||
|
#include "vtkShortArray.h"
|
||
|
#include "vtkUnsignedCharArray.h"
|
||
|
#include "vtkUnsignedIntArray.h"
|
||
|
#include "vtkUnsignedLongArray.h"
|
||
|
#include "vtkUnsignedShortArray.h"
|
||
|
|
||
|
#include "vtkPriorityQueue.h"
|
||
|
|
||
|
#include "vtkUnstructuredGrid.h"
|
||
|
#include "vtkModelMetadata.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <math.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
#include <vtkstd/vector>
|
||
|
#include <vtkstd/list>
|
||
|
#include <vtkstd/map>
|
||
|
#include <vtkstd/algorithm>
|
||
|
|
||
|
// If we are building against a slightly older VTK version,
|
||
|
// these cell types are not defined, and won't occur in the input
|
||
|
|
||
|
#ifndef VTK_QUADRATIC_WEDGE
|
||
|
# define VTK_QUADRATIC_WEDGE 26
|
||
|
# define VTK_QUADRATIC_PYRAMID 27
|
||
|
#endif
|
||
|
|
||
|
// this undef is required on the hp. vtkMutexLock ends up including
|
||
|
// /usr/inclue/dce/cma_ux.h which has the gall to #define write as cma_write
|
||
|
|
||
|
#ifdef write
|
||
|
# undef write
|
||
|
#endif
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
vtkStandardNewMacro(vtkEnSightWriter);
|
||
|
vtkCxxRevisionMacro(vtkEnSightWriter, "$Revision: 1.3 $");
|
||
|
|
||
|
vtkCxxSetObjectMacro(vtkEnSightWriter, ModelMetadata, vtkModelMetadata);
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Created object with no filename and timestep 0
|
||
|
vtkEnSightWriter::vtkEnSightWriter()
|
||
|
{
|
||
|
|
||
|
this->BaseName = NULL;
|
||
|
this->FileName = NULL;
|
||
|
this->TimeStep = 0;
|
||
|
this->ModelMetadata = NULL;
|
||
|
this->Path=NULL;
|
||
|
this->GhostLevelMultiplier=10000;
|
||
|
this->GhostLevel = 0;
|
||
|
this->TransientGeometry=false;
|
||
|
this->ProcessNumber=0;
|
||
|
this->NumberOfProcesses=1;
|
||
|
this->NumberOfBlocks=0;
|
||
|
this->BlockIDs=0;
|
||
|
this->TmpInput = NULL;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
vtkEnSightWriter::~vtkEnSightWriter()
|
||
|
{
|
||
|
if (this->ModelMetadata)
|
||
|
{
|
||
|
this->ModelMetadata->Delete();
|
||
|
this->ModelMetadata = NULL;
|
||
|
}
|
||
|
|
||
|
this->SetBaseName(NULL);
|
||
|
this->SetFileName(NULL);
|
||
|
this->SetPath(NULL);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::PrintSelf(ostream& os, vtkIndent indent)
|
||
|
{
|
||
|
this->Superclass::PrintSelf(os,indent);
|
||
|
|
||
|
os << indent << "FileName: "
|
||
|
<< (this->FileName ? this->FileName : "(none)") << "\n";
|
||
|
os << indent << "Path: "
|
||
|
<< (this->Path ? this->Path : "(none)") << "\n";
|
||
|
os << indent << "BaseName: "
|
||
|
<< (this->BaseName ? this->BaseName : "(none)") << "\n";
|
||
|
|
||
|
if (this->ModelMetadata !=NULL)
|
||
|
{
|
||
|
this->ModelMetadata->PrintSelf(os,indent.GetNextIndent());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << indent << "ModelMetadata: (none)" << "\n";
|
||
|
}
|
||
|
|
||
|
os << indent << "TimeStep: " << this->TimeStep << "\n";
|
||
|
os << indent << "TransientGeometry: " << this->TransientGeometry << "\n";
|
||
|
os << indent << "ProcessNumber: " << this->ProcessNumber << endl;
|
||
|
os << indent << "NumberOfProcesses: " << this->NumberOfProcesses << endl;
|
||
|
os << indent << "NumberOfBlocks: " << this->NumberOfBlocks << endl;
|
||
|
os << indent << "BlockIDs: " << this->BlockIDs << endl;
|
||
|
os << indent << "GhostLevel: " << this->GhostLevel << endl;
|
||
|
}
|
||
|
|
||
|
int vtkEnSightWriter::FillInputPortInformation( int vtkNotUsed(port), vtkInformation* info )
|
||
|
{
|
||
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkUnstructuredGrid");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Specify the input data or filter.
|
||
|
void vtkEnSightWriter::SetInput(vtkUnstructuredGrid *input)
|
||
|
{
|
||
|
this->Superclass::SetInput(0, input);
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
// Specify the input data or filter.
|
||
|
vtkUnstructuredGrid *vtkEnSightWriter::GetInput()
|
||
|
{
|
||
|
if (this->GetNumberOfInputConnections(0) < 1)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
else if (this->TmpInput)
|
||
|
{
|
||
|
return this->TmpInput;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return (vtkUnstructuredGrid *)(this->Superclass::GetInput());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteData()
|
||
|
{
|
||
|
int i;
|
||
|
unsigned int ui;
|
||
|
int blockCount=0;
|
||
|
vtkstd::list<int>::iterator iter;
|
||
|
|
||
|
if (this->TmpInput)
|
||
|
{
|
||
|
this->TmpInput->Delete();
|
||
|
this->TmpInput = NULL;
|
||
|
}
|
||
|
|
||
|
//figure out process ID
|
||
|
|
||
|
this->ProcessNumber = 0;
|
||
|
this->NumberOfProcesses = 1;
|
||
|
|
||
|
#ifdef VTK_USE_PARALLEL
|
||
|
vtkMultiProcessController *c = vtkMultiProcessController::GetGlobalController();
|
||
|
|
||
|
if (c != NULL)
|
||
|
{
|
||
|
this->ProcessNumber=c->GetLocalProcessId();
|
||
|
this->NumberOfProcesses = c->GetNumberOfProcesses();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
vtkUnstructuredGrid *input=this->GetInput();
|
||
|
|
||
|
if (this->GhostLevel > input->GetUpdateGhostLevel())
|
||
|
{
|
||
|
// re-execute pipeline if necessary to obtain ghost cells
|
||
|
|
||
|
input->SetUpdateGhostLevel(this->GhostLevel);
|
||
|
input->Update();
|
||
|
}
|
||
|
|
||
|
int deletemmd = 0;
|
||
|
|
||
|
if (this->ModelMetadata == NULL)
|
||
|
{
|
||
|
vtkDataSet *in = static_cast<vtkDataSet *>(input);
|
||
|
int hasMetadata = vtkModelMetadata::HasMetadata(in);
|
||
|
|
||
|
if (hasMetadata)
|
||
|
{
|
||
|
vtkModelMetadata *mmd = vtkModelMetadata::New();
|
||
|
mmd->Unpack(in, 0);
|
||
|
this->ModelMetadata = mmd;
|
||
|
deletemmd = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//get the BlockID Cell Array
|
||
|
vtkDataArray *BlockData=input->GetCellData()->GetScalars("BlockId");
|
||
|
|
||
|
if (BlockData==NULL || strcmp(BlockData->GetName(),"BlockId"))
|
||
|
{
|
||
|
BlockData=NULL;
|
||
|
}
|
||
|
|
||
|
if (this->ModelMetadata)
|
||
|
{
|
||
|
// Remove special ID arrays created by Exodus reader, required for
|
||
|
// interpreting metadata attached to input.
|
||
|
|
||
|
this->TmpInput = vtkUnstructuredGrid::New();
|
||
|
this->TmpInput->ShallowCopy(input);
|
||
|
|
||
|
vtkDataArray *da = this->TmpInput->GetCellData()->GetArray("GlobalElementId");
|
||
|
if (da)
|
||
|
{
|
||
|
this->TmpInput->GetCellData()->RemoveArray("GlobalElementId");
|
||
|
}
|
||
|
da = this->TmpInput->GetPointData()->GetArray("GlobalNodeId");
|
||
|
if (da)
|
||
|
{
|
||
|
this->TmpInput->GetPointData()->RemoveArray("GlobalNodeId");
|
||
|
}
|
||
|
da = this->TmpInput->GetCellData()->GetArray("BlockId");
|
||
|
if (da)
|
||
|
{
|
||
|
this->TmpInput->GetCellData()->RemoveArray("BlockId");
|
||
|
}
|
||
|
|
||
|
input = this->TmpInput;
|
||
|
}
|
||
|
|
||
|
this->ComputeNames();
|
||
|
|
||
|
if (!this->BaseName)
|
||
|
{
|
||
|
vtkErrorMacro("A FileName or Path/BaseName must be specified.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->SanitizeFileName(this->BaseName);
|
||
|
|
||
|
char** blockNames=NULL;
|
||
|
int * elementIDs=NULL;
|
||
|
char charBuffer[512];
|
||
|
char fileBuffer[512];
|
||
|
sprintf(charBuffer,"%s/%s.%d.%05d.geo",
|
||
|
this->Path,this->BaseName,this->ProcessNumber,
|
||
|
this->TimeStep);
|
||
|
|
||
|
//open the geometry file
|
||
|
//only if timestep 0 and not transient geometry or transient geometry
|
||
|
FILE *fd=NULL;
|
||
|
if (this->ShouldWriteGeometry())
|
||
|
{
|
||
|
if (!(fd=OpenFile(charBuffer)))
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//Get the FILE's for Point Data Fields
|
||
|
vtkstd::vector<FILE*> pointArrayFiles;
|
||
|
int NumPointArrays=input->GetPointData()->GetNumberOfArrays();
|
||
|
for (i=0;i<NumPointArrays;i++)
|
||
|
{
|
||
|
strcpy(fileBuffer,input->GetPointData()->GetArray(i)->GetName());
|
||
|
this->SanitizeFileName(fileBuffer);
|
||
|
sprintf(charBuffer,"%s/%s.%d.%05d_n.%s",this->Path,this->BaseName,this->ProcessNumber,
|
||
|
this->TimeStep,fileBuffer);
|
||
|
FILE* ftemp=OpenFile(charBuffer);
|
||
|
if (!ftemp)
|
||
|
return;
|
||
|
pointArrayFiles.push_back(ftemp);
|
||
|
|
||
|
//write the description line to the file
|
||
|
WriteStringToFile(fileBuffer,ftemp);
|
||
|
}
|
||
|
|
||
|
//Get the FILE's for Cell Data Fields
|
||
|
vtkstd::vector<FILE*> cellArrayFiles;
|
||
|
int NumCellArrays=input->GetCellData()->GetNumberOfArrays();
|
||
|
for (i=0;i<NumCellArrays;i++)
|
||
|
{
|
||
|
|
||
|
strcpy(fileBuffer,input->GetCellData()->GetArray(i)->GetName());
|
||
|
this->SanitizeFileName(fileBuffer);
|
||
|
sprintf(charBuffer,"%s/%s.%d.%05d_c.%s",this->Path,this->BaseName,this->ProcessNumber,
|
||
|
this->TimeStep,fileBuffer);
|
||
|
FILE* ftemp=OpenFile(charBuffer);
|
||
|
if (!ftemp)
|
||
|
return;
|
||
|
cellArrayFiles.push_back(ftemp);
|
||
|
|
||
|
//write the description line to the file
|
||
|
WriteStringToFile(fileBuffer,ftemp);
|
||
|
}
|
||
|
|
||
|
//write the header information
|
||
|
if (this->ShouldWriteGeometry())
|
||
|
{
|
||
|
this->WriteStringToFile("C Binary",fd);
|
||
|
this->WriteStringToFile("Written by VTK EnSight Writer",fd);
|
||
|
//if (this->Title)
|
||
|
// this->WriteStringToFile(this->Title,fd);
|
||
|
//else
|
||
|
if (this->ModelMetadata)
|
||
|
{
|
||
|
this->WriteStringToFile(this->ModelMetadata->GetTitle(),fd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->WriteStringToFile("No Title was Specified",fd);
|
||
|
}
|
||
|
//we will specify node and element ID's
|
||
|
this->WriteStringToFile("node id given\n",fd);
|
||
|
this->WriteStringToFile("element id given\n",fd);
|
||
|
}
|
||
|
|
||
|
//get the Ghost Cell Array if it exists
|
||
|
vtkDataArray *GhostData=input->GetCellData()->GetScalars("vtkGhostLevels");
|
||
|
//if the strings are not the same then we did not get the ghostData array
|
||
|
if (GhostData==NULL || strcmp(GhostData->GetName(),"vtkGhostLevels"))
|
||
|
{
|
||
|
GhostData=NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//data structure to get all the cells for a certain part
|
||
|
//basically sort by part# and cell type
|
||
|
vtkstd::map <int, vtkstd::vector <int> > CellsByPart;
|
||
|
|
||
|
//just a list of part numbers
|
||
|
vtkstd::list<int> partNumbers;
|
||
|
|
||
|
//get all the part numbers in the unstructured grid and sort the cells
|
||
|
//by part number
|
||
|
for (i=0;i<input->GetNumberOfCells();i++)
|
||
|
{
|
||
|
int key=1;
|
||
|
if (BlockData)
|
||
|
key=(int)(BlockData->GetTuple(i)[0]);
|
||
|
else
|
||
|
cout << "No BlockID was found\n";
|
||
|
if (CellsByPart.count(key)==0)
|
||
|
{
|
||
|
CellsByPart[key]=vtkstd::vector < int >() ;
|
||
|
}
|
||
|
CellsByPart[key].push_back(i);
|
||
|
partNumbers.push_back(key);
|
||
|
|
||
|
}
|
||
|
|
||
|
//remove the duplicates from the partNumbers
|
||
|
partNumbers.sort();
|
||
|
partNumbers.unique();
|
||
|
|
||
|
//get the block names from the exodus model if they exist
|
||
|
if (this->ModelMetadata)
|
||
|
{
|
||
|
blockNames=this->ModelMetadata->GetBlockElementType();
|
||
|
elementIDs=this->ModelMetadata->GetBlockIds();
|
||
|
}
|
||
|
|
||
|
//write out each part
|
||
|
for (iter=partNumbers.begin();iter!=partNumbers.end();iter++)
|
||
|
{
|
||
|
unsigned int j;
|
||
|
vtkstd::list<int>::iterator iter2;
|
||
|
int part=*iter;
|
||
|
|
||
|
//write the part Header
|
||
|
if (this->ShouldWriteGeometry())
|
||
|
{
|
||
|
blockCount+=1;
|
||
|
this->WriteStringToFile("part",fd);
|
||
|
this->WriteIntToFile(part,fd);
|
||
|
//cout << "part is " << part << endl;
|
||
|
int exodusIndex=-1;
|
||
|
if (elementIDs)
|
||
|
{
|
||
|
exodusIndex=this->GetExodusModelIndex(elementIDs,
|
||
|
(int)this->ModelMetadata->GetNumberOfBlocks(),part);
|
||
|
}
|
||
|
if (exodusIndex!=-1)
|
||
|
{
|
||
|
sprintf(charBuffer,"Exodus-%s-%d",blockNames[exodusIndex],part);
|
||
|
this->WriteStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->WriteStringToFile("VTK Part",fd);
|
||
|
}
|
||
|
this->WriteStringToFile("coordinates",fd);
|
||
|
}
|
||
|
|
||
|
//write the part header for data files
|
||
|
for (j=0;j<pointArrayFiles.size();j++)
|
||
|
{
|
||
|
this->WriteStringToFile("part",pointArrayFiles[j]);
|
||
|
this->WriteIntToFile(part,pointArrayFiles[j]);
|
||
|
this->WriteStringToFile("coordinates",pointArrayFiles[j]);
|
||
|
}
|
||
|
for (j=0;j<cellArrayFiles.size();j++)
|
||
|
{
|
||
|
this->WriteStringToFile("part",cellArrayFiles[j]);
|
||
|
this->WriteIntToFile(part,cellArrayFiles[j]);
|
||
|
}
|
||
|
|
||
|
//list of VTK Node Indices per part
|
||
|
vtkstd::list<int> NodesPerPart;
|
||
|
|
||
|
//map that goes from NodeID to the order, used for element connectivity
|
||
|
vtkstd::map<int, int> NodeIdToOrder;
|
||
|
|
||
|
//get a list of all the nodes used for a particular part
|
||
|
for (j=0;j<CellsByPart[part].size();j++)
|
||
|
{
|
||
|
vtkCell* cell=input->GetCell(CellsByPart[part][j]);
|
||
|
vtkIdList* points=cell->GetPointIds();
|
||
|
for (int k=0;k<points->GetNumberOfIds();k++)
|
||
|
{
|
||
|
NodesPerPart.push_back(points->GetId(k));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//remove the duplicate Node ID's
|
||
|
NodesPerPart.sort();
|
||
|
NodesPerPart.unique();
|
||
|
|
||
|
//write the number of nodes
|
||
|
if (this->ShouldWriteGeometry())
|
||
|
{
|
||
|
this->WriteIntToFile(NodesPerPart.size(),fd);
|
||
|
|
||
|
|
||
|
//write the Node ID's to the file
|
||
|
//also set up the NodeID->order map
|
||
|
int NodeCount=0;
|
||
|
for (iter2=NodesPerPart.begin();iter2!=NodesPerPart.end();iter2++)
|
||
|
{
|
||
|
this->WriteIntToFile(*iter2,fd);
|
||
|
NodeIdToOrder[*iter2]=NodeCount+1;
|
||
|
NodeCount++;
|
||
|
}
|
||
|
|
||
|
|
||
|
//EnSight format requires all the X's, then all the Y's, then all the Z's
|
||
|
//write the X Coordinates
|
||
|
|
||
|
vtkPoints* inputPoints=input->GetPoints();
|
||
|
for (iter2=NodesPerPart.begin();iter2!=NodesPerPart.end();iter2++)
|
||
|
{
|
||
|
this->WriteFloatToFile((float)(inputPoints->GetPoint(*iter2)[0]),fd);
|
||
|
}
|
||
|
for (iter2=NodesPerPart.begin();iter2!=NodesPerPart.end();iter2++)
|
||
|
{
|
||
|
this->WriteFloatToFile((float)(inputPoints->GetPoint(*iter2)[1]),fd);
|
||
|
}
|
||
|
for (iter2=NodesPerPart.begin();iter2!=NodesPerPart.end();iter2++)
|
||
|
{
|
||
|
this->WriteFloatToFile((float)(inputPoints->GetPoint(*iter2)[2]),fd);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//write the Node Data for this part
|
||
|
for (j=0;j<pointArrayFiles.size();j++)
|
||
|
{
|
||
|
vtkDataArray* DataArray=input->GetPointData()->GetArray(j);
|
||
|
//figure out what type of data it is
|
||
|
int DataSize=DataArray->GetNumberOfComponents();
|
||
|
|
||
|
for (int CurrentDimension=0;
|
||
|
CurrentDimension<DataSize;
|
||
|
CurrentDimension++)
|
||
|
{
|
||
|
for (vtkstd::list<int>::iterator k=NodesPerPart.begin();
|
||
|
k!=NodesPerPart.end();k++)
|
||
|
{
|
||
|
this->WriteFloatToFile((float)
|
||
|
(DataArray->
|
||
|
GetTuple(*k)[CurrentDimension]),
|
||
|
pointArrayFiles[j]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//now we need to sort the cell list by element type
|
||
|
//map is indexed by cell type has a vector of cell ID's
|
||
|
vtkstd::map<int, vtkstd::vector<int> > CellsByElement;
|
||
|
for (j=0;j<CellsByPart[part].size();j++)
|
||
|
{
|
||
|
int CellType=input->GetCell(CellsByPart[part][j])->GetCellType();
|
||
|
int ghostLevel=0;
|
||
|
if (GhostData)
|
||
|
{
|
||
|
ghostLevel=(int)(GhostData->GetTuple(CellsByPart[part][j])[0]);
|
||
|
if (ghostLevel>1) ghostLevel=1;
|
||
|
}
|
||
|
//we want to sort out the ghost cells from the normal cells
|
||
|
//so the element type will be ghostMultiplier*ghostLevel+elementType
|
||
|
CellType+=ghostLevel*GhostLevelMultiplier;
|
||
|
if (CellsByElement.count(CellType)==0)
|
||
|
{
|
||
|
CellsByElement[CellType]=vtkstd::vector < int >() ;
|
||
|
}
|
||
|
CellsByElement[CellType].push_back(CellsByPart[part][j]);
|
||
|
}
|
||
|
|
||
|
//now we need to go through each element type that EnSight understands
|
||
|
vtkstd::vector<int> elementTypes;
|
||
|
|
||
|
//list the types that EnSight understands
|
||
|
//the noticeable absences are the ones without a fixed number of Nodes
|
||
|
//for the ghost cell types
|
||
|
elementTypes.push_back(VTK_VERTEX);
|
||
|
elementTypes.push_back(VTK_LINE);
|
||
|
elementTypes.push_back(VTK_TRIANGLE);
|
||
|
elementTypes.push_back(VTK_QUAD);
|
||
|
elementTypes.push_back(VTK_TETRA);
|
||
|
elementTypes.push_back(VTK_HEXAHEDRON);
|
||
|
elementTypes.push_back(VTK_PYRAMID);
|
||
|
elementTypes.push_back(VTK_QUADRATIC_EDGE);
|
||
|
elementTypes.push_back(VTK_QUADRATIC_TRIANGLE);
|
||
|
elementTypes.push_back(VTK_QUADRATIC_QUAD);
|
||
|
elementTypes.push_back(VTK_QUADRATIC_TETRA);
|
||
|
elementTypes.push_back(VTK_QUADRATIC_HEXAHEDRON);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_VERTEX);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_LINE);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_TRIANGLE);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_QUAD);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_TETRA);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_HEXAHEDRON);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_PYRAMID);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_QUADRATIC_EDGE);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_QUADRATIC_TRIANGLE);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_QUADRATIC_QUAD);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_QUADRATIC_TETRA);
|
||
|
elementTypes.push_back(this->GhostLevelMultiplier+VTK_QUADRATIC_HEXAHEDRON);
|
||
|
|
||
|
//write out each type of element
|
||
|
if (this->ShouldWriteGeometry())
|
||
|
{
|
||
|
for (j=0;j<elementTypes.size();j++)
|
||
|
{
|
||
|
unsigned int k;
|
||
|
int elementType=elementTypes[j];
|
||
|
if (CellsByElement.count(elementType)>0)
|
||
|
{
|
||
|
//switch on element type to write correct type to file
|
||
|
this->WriteElementTypeToFile(elementType,fd);
|
||
|
|
||
|
//number of elements
|
||
|
this->WriteIntToFile(CellsByElement[elementType].size(),fd);
|
||
|
|
||
|
//element ID's
|
||
|
for (k=0;k<CellsByElement[elementType].size();k++)
|
||
|
{
|
||
|
int CellId=CellsByElement[elementType][k];
|
||
|
this->WriteIntToFile(CellId,fd);
|
||
|
}
|
||
|
|
||
|
//element conenctivity information
|
||
|
for (k=0;k<CellsByElement[elementType].size();k++)
|
||
|
{
|
||
|
int CellId=CellsByElement[elementType][k];
|
||
|
vtkIdList *PointIds=input->GetCell(CellId)->GetPointIds();
|
||
|
for (int m=0;m<PointIds->GetNumberOfIds();m++)
|
||
|
{
|
||
|
int PointId=PointIds->GetId(m);
|
||
|
this->WriteIntToFile(NodeIdToOrder[PointId],fd);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//write the Cell Data for this part
|
||
|
for (j=0;j<cellArrayFiles.size();j++)
|
||
|
{
|
||
|
vtkDataArray* DataArray=input->GetCellData()->GetArray(j);
|
||
|
//figure out what type of data it is
|
||
|
int DataSize=DataArray->GetNumberOfComponents();
|
||
|
|
||
|
for (int CurrentDimension=0;
|
||
|
CurrentDimension<DataSize;
|
||
|
CurrentDimension++)
|
||
|
{
|
||
|
for (unsigned int k=0;k<elementTypes.size();k++)
|
||
|
{
|
||
|
if (CellsByElement[elementTypes[k]].size()>0)
|
||
|
{
|
||
|
this->WriteElementTypeToFile(elementTypes[k],
|
||
|
cellArrayFiles[j]);
|
||
|
for (unsigned int m=0;m<CellsByElement[elementTypes[k]].size();m++)
|
||
|
{
|
||
|
this->WriteFloatToFile
|
||
|
((float)(DataArray->GetTuple(CellsByElement[elementTypes[k]]
|
||
|
[m])[CurrentDimension]),
|
||
|
cellArrayFiles[j]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
//now write the empty blocks
|
||
|
//use the block list in the exodus model if it exists, otherwise
|
||
|
//use the BlockID list if that exists.
|
||
|
|
||
|
if (this->ModelMetadata)
|
||
|
{
|
||
|
blockNames=this->ModelMetadata->GetBlockElementType();
|
||
|
elementIDs=this->ModelMetadata->GetBlockIds();
|
||
|
this->NumberOfBlocks=(int)this->ModelMetadata->GetNumberOfBlocks();
|
||
|
}
|
||
|
else if (this->BlockIDs)
|
||
|
{
|
||
|
elementIDs=this->BlockIDs;
|
||
|
}
|
||
|
|
||
|
if (elementIDs)
|
||
|
{
|
||
|
//cout << "have " << this->NumberOfBlocks << " blocks " << endl;
|
||
|
for (i=0;i<this->NumberOfBlocks;i++)
|
||
|
{
|
||
|
unsigned int j;
|
||
|
//figure out if the part was already written
|
||
|
int part=elementIDs[i];
|
||
|
if ( vtkstd::find(partNumbers.begin(), partNumbers.end(), part)
|
||
|
== partNumbers.end() )
|
||
|
{
|
||
|
//no information about the part was written to the output files
|
||
|
//so write some empty information
|
||
|
if (this->ShouldWriteGeometry())
|
||
|
{
|
||
|
blockCount+=1;
|
||
|
this->WriteStringToFile("part",fd);
|
||
|
this->WriteIntToFile(part,fd);
|
||
|
|
||
|
int exodusIndex =
|
||
|
this->GetExodusModelIndex(elementIDs,this->NumberOfBlocks,part);
|
||
|
|
||
|
if (exodusIndex!=-1 && blockNames)
|
||
|
{
|
||
|
sprintf(charBuffer,"Exodus-%s-%d",blockNames[exodusIndex],part);
|
||
|
this->WriteStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->WriteStringToFile("VTK Part",fd);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//write the part header for data files
|
||
|
for (j=0;j<pointArrayFiles.size();j++)
|
||
|
{
|
||
|
this->WriteStringToFile("part",pointArrayFiles[j]);
|
||
|
this->WriteIntToFile(part,pointArrayFiles[j]);
|
||
|
}
|
||
|
for (j=0;j<cellArrayFiles.size();j++)
|
||
|
{
|
||
|
this->WriteStringToFile("part",cellArrayFiles[j]);
|
||
|
this->WriteIntToFile(part,cellArrayFiles[j]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//cout << "wrote " << blockCount << "parts\n";
|
||
|
if (this->TmpInput)
|
||
|
{
|
||
|
this->TmpInput->Delete();
|
||
|
this->TmpInput = NULL;
|
||
|
}
|
||
|
|
||
|
//close all the files
|
||
|
if (fd)
|
||
|
{
|
||
|
fclose(fd);
|
||
|
}
|
||
|
|
||
|
for (ui=0;ui<cellArrayFiles.size();ui++)
|
||
|
{
|
||
|
fclose(cellArrayFiles[ui]);
|
||
|
}
|
||
|
for (ui=0;ui<pointArrayFiles.size();ui++)
|
||
|
{
|
||
|
fclose(pointArrayFiles[ui]);
|
||
|
}
|
||
|
|
||
|
if (deletemmd)
|
||
|
{
|
||
|
this->ModelMetadata->Delete();
|
||
|
this->ModelMetadata = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteCaseFile(int TotalTimeSteps)
|
||
|
{
|
||
|
|
||
|
vtkUnstructuredGrid *input=this->GetInput();
|
||
|
int i;
|
||
|
|
||
|
this->ComputeNames();
|
||
|
|
||
|
if (!this->BaseName)
|
||
|
{
|
||
|
vtkErrorMacro("A FileName or Path/BaseName must be specified.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
char charBuffer[512];
|
||
|
sprintf(charBuffer,"%s/%s.%d.case",this->Path,this->BaseName,this->ProcessNumber);
|
||
|
|
||
|
//open the geometry file
|
||
|
FILE *fd=NULL;
|
||
|
if (!(fd=OpenFile(charBuffer)))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->WriteTerminatedStringToFile("FORMAT\n",fd);
|
||
|
this->WriteTerminatedStringToFile("type: ensight gold\n\n",fd);
|
||
|
this->WriteTerminatedStringToFile("\nGEOMETRY\n",fd);
|
||
|
|
||
|
//write the geometry file
|
||
|
if (!this->TransientGeometry)
|
||
|
{
|
||
|
sprintf(charBuffer,"model: %s.%d.00000.geo\n",this->BaseName,this->ProcessNumber);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sprintf(charBuffer,"model: 1 %s.%d.*****.geo\n",this->BaseName,this->ProcessNumber);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
|
||
|
this->WriteTerminatedStringToFile("\nVARIABLE\n",fd);
|
||
|
|
||
|
char fileBuffer[512];
|
||
|
|
||
|
//write the Node variable files
|
||
|
for (i=0;i<input->GetPointData()->GetNumberOfArrays();i++)
|
||
|
{
|
||
|
|
||
|
strcpy(fileBuffer,input->GetPointData()->GetArray(i)->GetName());
|
||
|
// skip arrays that were not written
|
||
|
if (strcmp(fileBuffer,"GlobalElementId")==0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if (strcmp(fileBuffer,"GlobalNodeId")==0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if (strcmp(fileBuffer,"BlockId")==0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
this->SanitizeFileName(fileBuffer);
|
||
|
//figure out what kind of data it is
|
||
|
char SmallBuffer[16];
|
||
|
switch(input->GetPointData()->GetArray(i)->GetNumberOfComponents())
|
||
|
{
|
||
|
case(1):
|
||
|
strcpy(SmallBuffer,"scalar");
|
||
|
break;
|
||
|
case(3):
|
||
|
strcpy(SmallBuffer,"vector");
|
||
|
break;
|
||
|
case(6):
|
||
|
strcpy(SmallBuffer,"tensor");
|
||
|
break;
|
||
|
case(9):
|
||
|
strcpy(SmallBuffer,"tensor9");
|
||
|
break;
|
||
|
}
|
||
|
if (TotalTimeSteps<=1)
|
||
|
{
|
||
|
sprintf(charBuffer,"%s per node: %s_n %s.%d.00000_n.%s\n",
|
||
|
SmallBuffer,
|
||
|
fileBuffer,
|
||
|
this->BaseName,
|
||
|
this->ProcessNumber,
|
||
|
fileBuffer);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sprintf(charBuffer,"%s per node: 1 %s_n %s.%d.*****_n.%s\n",
|
||
|
SmallBuffer,
|
||
|
fileBuffer,
|
||
|
this->BaseName,
|
||
|
this->ProcessNumber,
|
||
|
fileBuffer);
|
||
|
|
||
|
|
||
|
}
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
|
||
|
//write the cell variable files
|
||
|
for (i=0;i<input->GetCellData()->GetNumberOfArrays();i++)
|
||
|
{
|
||
|
//figure out what kind of data it is
|
||
|
char SmallBuffer[16];
|
||
|
|
||
|
strcpy(fileBuffer,input->GetCellData()->GetArray(i)->GetName());
|
||
|
// skip arrays that were not written
|
||
|
if (strcmp(fileBuffer,"GlobalElementId")==0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if (strcmp(fileBuffer,"GlobalNodeId")==0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if (strcmp(fileBuffer,"BlockId")==0)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
this->SanitizeFileName(fileBuffer);
|
||
|
switch(input->GetCellData()->GetArray(i)->GetNumberOfComponents())
|
||
|
{
|
||
|
case(1):
|
||
|
strcpy(SmallBuffer,"scalar");
|
||
|
break;
|
||
|
case(3):
|
||
|
strcpy(SmallBuffer,"vector");
|
||
|
break;
|
||
|
case(6):
|
||
|
strcpy(SmallBuffer,"tensor");
|
||
|
break;
|
||
|
case(9):
|
||
|
strcpy(SmallBuffer,"tensor9");
|
||
|
break;
|
||
|
}
|
||
|
if (TotalTimeSteps<=1)
|
||
|
{
|
||
|
sprintf(charBuffer,"%s per element: %s_c %s.%d.00000_c.%s\n",
|
||
|
SmallBuffer,
|
||
|
fileBuffer,
|
||
|
this->BaseName,
|
||
|
this->ProcessNumber,
|
||
|
fileBuffer);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sprintf(charBuffer,"%s per element: 1 %s_c %s.%d.*****_c.%s\n",
|
||
|
SmallBuffer,
|
||
|
fileBuffer,
|
||
|
this->BaseName,
|
||
|
this->ProcessNumber,
|
||
|
fileBuffer);
|
||
|
}
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
|
||
|
//write time information if we have multiple timesteps
|
||
|
if (TotalTimeSteps>1)
|
||
|
{
|
||
|
this->WriteTerminatedStringToFile("\nTIME\n",fd);
|
||
|
this->WriteTerminatedStringToFile("time set: 1\n",fd);
|
||
|
sprintf(charBuffer,"number of steps: %d\n",TotalTimeSteps);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
this->WriteTerminatedStringToFile("filename start number: 00000\n",fd);
|
||
|
this->WriteTerminatedStringToFile("filename increment: 00001\n",fd);
|
||
|
this->WriteTerminatedStringToFile("time values: \n",fd);
|
||
|
for (i=0;i<TotalTimeSteps;i++)
|
||
|
{
|
||
|
double timestep=i;
|
||
|
if (this->ModelMetadata)
|
||
|
{
|
||
|
timestep=this->ModelMetadata->GetTimeStepValues()[i];
|
||
|
}
|
||
|
|
||
|
sprintf(charBuffer,"%f ",timestep);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
if (i%6==0 && i>0)
|
||
|
{
|
||
|
this->WriteTerminatedStringToFile("\n",fd);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteSOSCaseFile(int numProcs)
|
||
|
{
|
||
|
this->ComputeNames();
|
||
|
|
||
|
if (!this->BaseName)
|
||
|
{
|
||
|
vtkErrorMacro("A FileName or Path/BaseName must be specified.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->SanitizeFileName(this->BaseName);
|
||
|
|
||
|
char charBuffer[512];
|
||
|
sprintf(charBuffer,"%s/%s.case.sos",this->Path,this->BaseName);
|
||
|
|
||
|
FILE *fd=NULL;
|
||
|
if (!(fd=OpenFile(charBuffer)))
|
||
|
return;
|
||
|
|
||
|
this->WriteTerminatedStringToFile("FORMAT\n",fd);
|
||
|
this->WriteTerminatedStringToFile("type: master_server gold\n\n",fd);
|
||
|
|
||
|
this->WriteTerminatedStringToFile("SERVERS\n",fd);
|
||
|
sprintf(charBuffer,"number of servers: %d\n\n",numProcs);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
|
||
|
//write the servers section with placeholders for the ensight server
|
||
|
//location and server name
|
||
|
int i=0;
|
||
|
for (i=0;i<numProcs;i++)
|
||
|
{
|
||
|
sprintf(charBuffer, "#Server %d\n",i);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
this->WriteTerminatedStringToFile("#-------\n",fd);
|
||
|
sprintf(charBuffer, "machine id: MID%05d\n",i);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
|
||
|
this->WriteTerminatedStringToFile("executable: MEX\n",fd);
|
||
|
sprintf(charBuffer, "data_path: %s\n",this->Path);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
sprintf(charBuffer,"casefile: %s.%d.case\n\n",this->BaseName,i);
|
||
|
this->WriteTerminatedStringToFile(charBuffer,fd);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteStringToFile(const char* cstring, FILE* file)
|
||
|
{
|
||
|
char cbuffer[80];
|
||
|
strncpy(cbuffer,cstring,80);
|
||
|
fwrite(cbuffer, sizeof(char),80,file);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteTerminatedStringToFile(const char* cstring, FILE* file)
|
||
|
{
|
||
|
char cbuffer[512];
|
||
|
strncpy(cbuffer,cstring,512);
|
||
|
fwrite(cbuffer, sizeof(char),strlen(cbuffer),file);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteIntToFile(const int i,FILE* file)
|
||
|
{
|
||
|
//char cbuffer[80];
|
||
|
//sprintf(cbuffer,"%d",i);
|
||
|
fwrite(&i, sizeof(int),1,file);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteFloatToFile(const float f,FILE* file)
|
||
|
{
|
||
|
//char cbuffer[80];
|
||
|
//sprintf(cbuffer,"%d",i);
|
||
|
fwrite(&f, sizeof(float),1,file);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::WriteElementTypeToFile(int elementType,FILE* fd)
|
||
|
{
|
||
|
int ghostLevel=elementType/GhostLevelMultiplier;
|
||
|
elementType=elementType%GhostLevelMultiplier;
|
||
|
if (ghostLevel==0)
|
||
|
{
|
||
|
switch(elementType)
|
||
|
{
|
||
|
case(VTK_VERTEX):
|
||
|
this->WriteStringToFile("point",fd);
|
||
|
break;
|
||
|
case(VTK_LINE):
|
||
|
this->WriteStringToFile("bar2",fd);
|
||
|
break;
|
||
|
case(VTK_TRIANGLE):
|
||
|
this->WriteStringToFile("tria3",fd);
|
||
|
break;
|
||
|
case(VTK_QUAD):
|
||
|
this->WriteStringToFile("quad4",fd);
|
||
|
break;
|
||
|
case(VTK_TETRA):
|
||
|
this->WriteStringToFile("tetra4",fd);
|
||
|
break;
|
||
|
case(VTK_HEXAHEDRON):
|
||
|
this->WriteStringToFile("hexa8",fd);
|
||
|
break;
|
||
|
case(VTK_PYRAMID):
|
||
|
this->WriteStringToFile("pyramid5",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_EDGE):
|
||
|
this->WriteStringToFile("bar3",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_TRIANGLE):
|
||
|
this->WriteStringToFile("tria6",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_QUAD):
|
||
|
this->WriteStringToFile("quad8",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_TETRA):
|
||
|
this->WriteStringToFile("tetra10",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_HEXAHEDRON):
|
||
|
this->WriteStringToFile("hexa20",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_PYRAMID):
|
||
|
this->WriteStringToFile("pyramid13",fd);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch(elementType)
|
||
|
{
|
||
|
case(VTK_VERTEX):
|
||
|
this->WriteStringToFile("g_point",fd);
|
||
|
break;
|
||
|
case(VTK_LINE):
|
||
|
this->WriteStringToFile("g_bar2",fd);
|
||
|
break;
|
||
|
case(VTK_TRIANGLE):
|
||
|
this->WriteStringToFile("g_tria3",fd);
|
||
|
break;
|
||
|
case(VTK_QUAD):
|
||
|
this->WriteStringToFile("g_quad4",fd);
|
||
|
break;
|
||
|
case(VTK_TETRA):
|
||
|
this->WriteStringToFile("g_tetra4",fd);
|
||
|
break;
|
||
|
case(VTK_HEXAHEDRON):
|
||
|
this->WriteStringToFile("g_hexa8",fd);
|
||
|
break;
|
||
|
case(VTK_PYRAMID):
|
||
|
this->WriteStringToFile("g_pyramid5",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_EDGE):
|
||
|
this->WriteStringToFile("g_bar3",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_TRIANGLE):
|
||
|
this->WriteStringToFile("g_tria6",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_QUAD):
|
||
|
this->WriteStringToFile("g_quad8",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_TETRA):
|
||
|
this->WriteStringToFile("g_tetra10",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_HEXAHEDRON):
|
||
|
this->WriteStringToFile("g_hexa20",fd);
|
||
|
break;
|
||
|
case(VTK_QUADRATIC_PYRAMID):
|
||
|
this->WriteStringToFile("g_pyramid13",fd);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
bool vtkEnSightWriter::ShouldWriteGeometry()
|
||
|
{
|
||
|
return ((this->TransientGeometry || (!this->TransientGeometry && this->TimeStep==0)));
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::SanitizeFileName(char* name)
|
||
|
{
|
||
|
|
||
|
char buffer[512];
|
||
|
unsigned int i;
|
||
|
int BufferPosition=0;
|
||
|
for (i=0;i<strlen(name);i++)
|
||
|
{
|
||
|
if (name[i]!='/')
|
||
|
{
|
||
|
buffer[BufferPosition]=name[i];
|
||
|
BufferPosition++;
|
||
|
}
|
||
|
}
|
||
|
buffer[BufferPosition]=0;
|
||
|
for (i=0;i<strlen(buffer);i++)
|
||
|
{
|
||
|
name[i]=buffer[i];
|
||
|
}
|
||
|
name[strlen(buffer)]=0;
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
FILE* vtkEnSightWriter::OpenFile(char* name)
|
||
|
{
|
||
|
FILE * fd=fopen(name,"wb");
|
||
|
|
||
|
if (fd == NULL)
|
||
|
{
|
||
|
vtkErrorMacro("Error opening " << name
|
||
|
<< ": " << strerror(errno));
|
||
|
return NULL;
|
||
|
}
|
||
|
return fd;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
int vtkEnSightWriter::GetExodusModelIndex(int *elementArray,int numberElements,int partID)
|
||
|
{
|
||
|
int i;
|
||
|
for (i=0;i<numberElements;i++)
|
||
|
{
|
||
|
if (elementArray[i]==partID)
|
||
|
return i;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::DefaultNames()
|
||
|
{
|
||
|
char *path = new char [4];
|
||
|
char *base = new char [20];
|
||
|
strcpy(path, "./");
|
||
|
strcpy(base, "EnSightWriter.out");
|
||
|
|
||
|
this->SetPath(path);
|
||
|
this->SetBaseName(base);
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkEnSightWriter::ComputeNames()
|
||
|
{
|
||
|
if (this->Path && this->BaseName)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!this->FileName)
|
||
|
{
|
||
|
this->DefaultNames();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// FileName = Path/BaseName.digits.digits
|
||
|
|
||
|
char *path = NULL;
|
||
|
char *base = NULL;
|
||
|
|
||
|
char *f = this->FileName;
|
||
|
|
||
|
while (!isgraph(*f)) f++; // find first printable character
|
||
|
|
||
|
if (!*f)
|
||
|
{
|
||
|
// FileName is garbage
|
||
|
DefaultNames();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
char *buf = new char [strlen(f) + 1];
|
||
|
strcpy(buf, f);
|
||
|
|
||
|
char *slash = strrchr(buf, '/'); // final slash
|
||
|
|
||
|
if (slash)
|
||
|
{
|
||
|
*slash = 0;
|
||
|
path = new char [strlen(buf) + 1];
|
||
|
strcpy(path, buf);
|
||
|
f = slash + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
path = new char [4];
|
||
|
strcpy(path, "./");
|
||
|
|
||
|
f = buf;
|
||
|
}
|
||
|
|
||
|
char *firstChar = f;
|
||
|
while (*f && (*f != '.')) f++;
|
||
|
*f = 0;
|
||
|
|
||
|
base = new char [strlen(firstChar) + 1];
|
||
|
strcpy(base, firstChar);
|
||
|
|
||
|
this->SetPath(path);
|
||
|
this->SetBaseName(base);
|
||
|
|
||
|
delete [] buf;
|
||
|
}
|