#include #include "FEAdaptor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { vtkSmartPointer VTKGrid; void BuildVTKGrid(unsigned int numberOfPoints, double* pointsData, unsigned int numberOfCells, unsigned int* cellsData) { // create the points information vtkNew pointArray; pointArray->SetNumberOfComponents(3); pointArray->SetArray(pointsData, static_cast(numberOfPoints*3), 1); vtkNew points; points->SetData(pointArray.GetPointer()); VTKGrid->SetPoints(points.GetPointer()); // create the cells VTKGrid->Allocate(static_cast(numberOfCells*9)); for(unsigned int cell=0;cellInsertNextCell(VTK_HEXAHEDRON, 8, tmp); } } void UpdateVTKAttributes(unsigned int numberOfPoints, double* velocityData, unsigned int numberOfCells, float* pressureData) { if(VTKGrid->GetPointData()->GetNumberOfArrays() == 0) { // velocity array vtkNew velocity; velocity->SetName("velocity"); velocity->SetNumberOfComponents(3); velocity->SetNumberOfTuples(static_cast(numberOfPoints)); VTKGrid->GetPointData()->AddArray(velocity.GetPointer()); } if(VTKGrid->GetCellData()->GetNumberOfArrays() == 0) { // pressure array vtkNew pressure; pressure->SetName("pressure"); pressure->SetNumberOfComponents(1); VTKGrid->GetCellData()->AddArray(pressure.GetPointer()); } vtkDoubleArray* velocity = vtkDoubleArray::SafeDownCast( VTKGrid->GetPointData()->GetArray("velocity")); // The velocity array is ordered as vx0,vx1,vx2,..,vy0,vy1,vy2,..,vz0,vz1,vz2,.. // so we need to create a full copy of it with VTK's ordering of // vx0,vy0,vz0,vx1,vy1,vz1,.. for(unsigned int i=0;iSetTupleValue(i, values); } vtkFloatArray* pressure = vtkFloatArray::SafeDownCast( VTKGrid->GetCellData()->GetArray("pressure")); // The pressure array is a scalar array so we can reuse // memory as long as we ordered the points properly. pressure->SetArray(pressureData, static_cast(numberOfCells), 1); } void BuildVTKDataStructures(unsigned int numberOfPoints, double* points, double* velocity, unsigned int numberOfCells, unsigned int* cells, float* pressure) { if(VTKGrid == NULL) { // The grid structure isn't changing so we only build it // the first time it's needed. If we needed the memory // we could delete it and rebuild as necessary. VTKGrid = vtkSmartPointer::New(); BuildVTKGrid(numberOfPoints, points, numberOfCells, cells); } UpdateVTKAttributes(numberOfPoints, velocity, numberOfCells, pressure); } } void CatalystCoProcess(unsigned int numberOfPoints, double* pointsData, unsigned int numberOfCells, unsigned int* cellsData, double* velocityData, float* pressureData, double time, unsigned int timeStep, int lastTimeStep) { vtkCPProcessor* processor = vtkCPAdaptorAPI::GetCoProcessor(); vtkCPDataDescription* dataDescription = vtkCPAdaptorAPI::GetCoProcessorData(); if(processor == NULL || dataDescription == NULL) { cerr << "ERROR: Catalyst not properly initialized.\n"; return; } dataDescription->AddInput("input"); dataDescription->SetTimeData(time, timeStep); if(lastTimeStep == true) { // assume that we want to all the pipelines to execute if it // is the last time step. dataDescription->ForceOutputOn(); } if(processor->RequestDataDescription(dataDescription) != 0) { BuildVTKDataStructures(numberOfPoints, pointsData, velocityData, numberOfCells, cellsData, pressureData); dataDescription->GetInputDescriptionByName("input")->SetGrid(VTKGrid); processor->CoProcess(dataDescription); } } void CatalystFinalize() { // Used to free grid if it was used if(VTKGrid) { VTKGrid = NULL; } }