ParaView-5.0.1: Added the source-tree to ThirdParty-dev and patched as described in the README file

Resolves bug-report http://bugs.openfoam.org/view.php?id=2098
This commit is contained in:
Henry Weller
2016-05-30 21:20:56 +01:00
parent 1cce60aa78
commit eba760a6d6
24640 changed files with 6366069 additions and 0 deletions

View File

@ -0,0 +1,58 @@
cmake_minimum_required(VERSION 2.8.8)
project(CatalystCxxParticlePathExample)
set(USE_CATALYST ON CACHE BOOL "Link the simulator with Catalyst")
if(USE_CATALYST)
# we need 5.0 for the proper in situ particle path filter
find_package(ParaView 5.0 REQUIRED COMPONENTS vtkPVPythonCatalyst)
include("${PARAVIEW_USE_FILE}")
set(Adaptor_SRCS
FEAdaptor.cxx
)
add_library(CxxParticlePathExampleAdaptor ${Adaptor_SRCS})
target_link_libraries(CxxParticlePathExampleAdaptor vtkPVPythonCatalyst vtkParallelMPI)
add_definitions("-DUSE_CATALYST")
if(NOT PARAVIEW_USE_MPI)
message(SEND_ERROR "ParaView must be built with MPI enabled")
endif()
else()
find_package(MPI REQUIRED)
include_directories(${MPI_C_INCLUDE_PATH})
endif()
add_executable(CxxParticlePathExample FEDriver.cxx FEDataStructures.cxx)
if(USE_CATALYST)
target_link_libraries(CxxParticlePathExample LINK_PRIVATE CxxParticlePathExampleAdaptor)
include(vtkModuleMacros)
include(vtkMPI)
vtk_mpi_link(CxxParticlePathExample)
else()
target_link_libraries(CxxParticlePathExample LINK_PRIVATE ${MPI_LIBRARIES})
endif()
option(BUILD_TESTING "Build Testing" OFF)
# Setup testing.
if (BUILD_TESTING)
include(CTest)
if(PARAVIEW_TEST_OUTPUT_DIR)
set(TEST_OUTPUT_DIR ${PARAVIEW_TEST_OUTPUT_DIR})
else(PARAVIEW_TEST_OUTPUT_DIR)
set(TEST_OUTPUT_DIR "${CMAKE_BINARY_DIR}/Testing/Temporary")
endif(PARAVIEW_TEST_OUTPUT_DIR)
add_test(NAME CxxParticlePathExampleTest
COMMAND ${CMAKE_COMMAND}
-DCOPROCESSING_TEST_DRIVER:FILEPATH=$<TARGET_FILE:CxxParticlePathExample>
-DCOPROCESSING_TEST_DIR:PATH=${TEST_OUTPUT_DIR}
-DCOPROCESSING_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DPVBATCH:FILEPATH=$<TARGET_FILE:pvbatch>
-DMPIEXEC:FILEPATH=${MPIEXEC}
-DMPIEXEC_NUMPROC_FLAG:STRING=${MPIEXEC_NUMPROC_FLAG}
-DMPIEXEC_NUMPROCS=4
-DMPIEXEC_PREFLAGS:STRING=${MPIEXEC_PREFLAGS}
-DVTK_MPI_POSTFLAGS:STRING=${VTK_MPI_POSTFLAGS}
-P ${CMAKE_CURRENT_SOURCE_DIR}/ParticlePathTesting.cmake)
set_tests_properties(CxxParticlePathExampleTest PROPERTIES LABELS "PARAVIEW;CATALYST")
endif (BUILD_TESTING)

View File

@ -0,0 +1,142 @@
#include <iostream>
#include "FEAdaptor.h"
#include "FEDataStructures.h"
#include <vtkCellData.h>
#include <vtkCellType.h>
#include <vtkCPDataDescription.h>
#include <vtkCPInputDataDescription.h>
#include <vtkCPProcessor.h>
#include <vtkCPPythonScriptPipeline.h>
#include <vtkDoubleArray.h>
#include <vtkFloatArray.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPointData.h>
#include <vtkUnstructuredGrid.h>
namespace
{
vtkCPProcessor* Processor = NULL;
void BuildVTKGrid(Grid& grid, vtkUnstructuredGrid* vtkgrid)
{
// create the points information
vtkNew<vtkDoubleArray> pointArray;
pointArray->SetNumberOfComponents(3);
pointArray->SetArray(grid.GetPointsArray(), static_cast<vtkIdType>(grid.GetNumberOfPoints()*3), 1);
vtkNew<vtkPoints> points;
points->SetData(pointArray.GetPointer());
vtkgrid->SetPoints(points.GetPointer());
// create the cells
size_t numCells = grid.GetNumberOfCells();
vtkgrid->Allocate(static_cast<vtkIdType>(numCells*9));
for(size_t cell=0;cell<numCells;cell++)
{
unsigned int* cellPoints = grid.GetCellPoints(cell);
vtkIdType tmp[8] = {cellPoints[0], cellPoints[1], cellPoints[2], cellPoints[3],
cellPoints[4], cellPoints[5], cellPoints[6], cellPoints[7]};
vtkgrid->InsertNextCell(VTK_HEXAHEDRON, 8, tmp);
}
}
void UpdateVTKAttributes(Grid& grid, Attributes& attributes, vtkUnstructuredGrid* vtkgrid)
{
if(vtkgrid->GetPointData()->GetNumberOfArrays() == 0)
{
// velocity array
vtkNew<vtkDoubleArray> velocity;
velocity->SetName("velocity");
velocity->SetNumberOfComponents(3);
velocity->SetNumberOfTuples(static_cast<vtkIdType>(grid.GetNumberOfPoints()));
vtkgrid->GetPointData()->AddArray(velocity.GetPointer());
}
if(vtkgrid->GetCellData()->GetNumberOfArrays() == 0)
{
// pressure array
vtkNew<vtkFloatArray> 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,..
double* velocityData = attributes.GetVelocityArray();
vtkIdType numTuples = velocity->GetNumberOfTuples();
for(vtkIdType i=0;i<numTuples;i++)
{
double values[3] = {velocityData[i], velocityData[i+numTuples],
velocityData[i+2*numTuples]};
velocity->SetTupleValue(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.
float* pressureData = attributes.GetPressureArray();
pressure->SetArray(pressureData, static_cast<vtkIdType>(grid.GetNumberOfCells()), 1);
}
void BuildVTKDataStructures(Grid& grid, Attributes& attributes, vtkUnstructuredGrid* vtkgrid)
{
BuildVTKGrid(grid, vtkgrid);
UpdateVTKAttributes(grid, attributes, vtkgrid);
}
}
namespace FEAdaptor
{
void Initialize(std::vector<std::string>& scripts)
{
if(Processor == NULL)
{
Processor = vtkCPProcessor::New();
Processor->Initialize();
}
else
{
Processor->RemoveAllPipelines();
}
for(std::vector<std::string>::iterator it=scripts.begin();it!=scripts.end();it++)
{
vtkNew<vtkCPPythonScriptPipeline> pipeline;
pipeline->Initialize(it->c_str());
Processor->AddPipeline(pipeline.GetPointer());
}
}
void Finalize()
{
if(Processor)
{
Processor->Delete();
Processor = NULL;
}
}
void CoProcess(Grid& grid, Attributes& attributes, double time,
unsigned int timeStep, bool lastTimeStep)
{
vtkNew<vtkCPDataDescription> dataDescription;
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.GetPointer()) != 0)
{
vtkNew<vtkUnstructuredGrid> vtkgrid;
BuildVTKDataStructures(grid, attributes, vtkgrid.GetPointer());
dataDescription->GetInputDescriptionByName("input")->SetGrid(vtkgrid.GetPointer());
Processor->CoProcess(dataDescription.GetPointer());
}
}
} // end of Catalyst namespace

View File

@ -0,0 +1,20 @@
#ifndef FEADAPTOR_HEADER
#define FEADAPTOR_HEADER
class Attributes;
class Grid;
#include <string>
#include <vector>
namespace FEAdaptor
{
void Initialize(std::vector<std::string>& scripts);
void Finalize();
void CoProcess(Grid& grid, Attributes& attributes, double time,
unsigned int timeStep, bool lastTimeStep);
}
#endif

View File

@ -0,0 +1,154 @@
#include "FEDataStructures.h"
#include <mpi.h>
#include <iostream>
Grid::Grid()
{}
void Grid::Initialize(const unsigned int numPoints[3], const double spacing[3] )
{
if(numPoints[0] == 0 || numPoints[1] == 0 || numPoints[2] == 0)
{
std::cerr << "Must have a non-zero amount of points in each direction.\n";
}
// in parallel, we do a simple partitioning in the x-direction.
int mpiSize = 1;
int mpiRank = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
unsigned int startXPoint = mpiRank*numPoints[0]/mpiSize;
unsigned int endXPoint = (mpiRank+1)*numPoints[0]/mpiSize;
if(mpiSize != mpiRank+1)
{
endXPoint++;
}
// create the points -- slowest in the x and fastest in the z directions
double coord[3] = {0,0,0};
for(unsigned int i=startXPoint;i<endXPoint;i++)
{
coord[0] = i*spacing[0];
for(unsigned int j=0;j<numPoints[1];j++)
{
coord[1] = j*spacing[1];
for(unsigned int k=0;k<numPoints[2];k++)
{
coord[2] = k*spacing[2];
// add the coordinate to the end of the vector
std::copy(coord, coord+3, std::back_inserter(this->Points));
}
}
}
// create the hex cells
unsigned int cellPoints[8];
unsigned int numXPoints = endXPoint - startXPoint;
for(unsigned int i=0;i<numXPoints-1;i++)
{
for(unsigned int j=0;j<numPoints[1]-1;j++)
{
for(unsigned int k=0;k<numPoints[2]-1;k++)
{
cellPoints[0] = i*numPoints[1]*numPoints[2] +
j*numPoints[2] + k;
cellPoints[1] = (i+1)*numPoints[1]*numPoints[2] +
j*numPoints[2] + k;
cellPoints[2] = (i+1)*numPoints[1]*numPoints[2] +
(j+1)*numPoints[2] + k;
cellPoints[3] = i*numPoints[1]*numPoints[2] +
(j+1)*numPoints[2] + k;
cellPoints[4] = i*numPoints[1]*numPoints[2] +
j*numPoints[2] + k+1;
cellPoints[5] = (i+1)*numPoints[1]*numPoints[2] +
j*numPoints[2] + k+1;
cellPoints[6] = (i+1)*numPoints[1]*numPoints[2] +
(j+1)*numPoints[2] + k+1;
cellPoints[7] = i*numPoints[1]*numPoints[2] +
(j+1)*numPoints[2] + k+1;
std::copy(cellPoints, cellPoints+8, std::back_inserter(this->Cells));
}
}
}
}
size_t Grid::GetNumberOfPoints()
{
return this->Points.size()/3;
}
size_t Grid::GetNumberOfCells()
{
return this->Cells.size()/8;
}
double* Grid::GetPointsArray()
{
if(this->Points.empty())
{
return NULL;
}
return &(this->Points[0]);
}
double* Grid::GetPoint(size_t pointId)
{
if(pointId >= this->Points.size())
{
return NULL;
}
return &(this->Points[pointId*3]);
}
unsigned int* Grid::GetCellPoints(size_t cellId)
{
if(cellId >= this->Cells.size())
{
return NULL;
}
return &(this->Cells[cellId*8]);
}
Attributes::Attributes()
{
this->GridPtr = NULL;
}
void Attributes::Initialize(Grid* grid)
{
this->GridPtr = grid;
}
void Attributes::UpdateFields(double time)
{
size_t numPoints = this->GridPtr->GetNumberOfPoints();
this->Velocity.resize(numPoints*3);
for(size_t pt=0;pt<numPoints;pt++)
{
double* coord = this->GridPtr->GetPoint(pt);
this->Velocity[pt] = coord[1]*time;
//this->Velocity[pt] = time;
}
std::fill(this->Velocity.begin()+numPoints, this->Velocity.end(), 0.);
size_t numCells = this->GridPtr->GetNumberOfCells();
this->Pressure.resize(numCells);
std::fill(this->Pressure.begin(), this->Pressure.end(), 1.);
}
double* Attributes::GetVelocityArray()
{
if(this->Velocity.empty())
{
return NULL;
}
return &this->Velocity[0];
}
float* Attributes::GetPressureArray()
{
if(this->Pressure.empty())
{
return NULL;
}
return &this->Pressure[0];
}

View File

@ -0,0 +1,41 @@
#ifndef FEDATASTRUCTURES_HEADER
#define FEDATASTRUCTURES_HEADER
#include <cstddef>
#include <vector>
class Grid
{
public:
Grid();
void Initialize(const unsigned int numPoints[3], const double spacing[3]);
size_t GetNumberOfPoints();
size_t GetNumberOfCells();
double* GetPointsArray();
double* GetPoint(size_t pointId);
unsigned int* GetCellPoints(size_t cellId);
private:
std::vector<double> Points;
std::vector<unsigned int> Cells;
};
class Attributes
{
// A class for generating and storing point and cell fields.
// Velocity is stored at the points and pressure is stored
// for the cells. The current velocity profile is for a
// shearing flow with U(y,t) = y*t, V = 0 and W = 0.
// Pressure is constant through the domain.
public:
Attributes();
void Initialize(Grid* grid);
void UpdateFields(double time);
double* GetVelocityArray();
float* GetPressureArray();
private:
std::vector<double> Velocity;
std::vector<float> Pressure;
Grid* GridPtr;
};
#endif

View File

@ -0,0 +1,81 @@
#include "FEDataStructures.h"
#include <mpi.h>
#include <string>
#include <vector>
#ifdef USE_CATALYST
#include "FEAdaptor.h"
#endif
#include <stdlib.h>
#include <cstring>
// Example of a C++ adaptor for a simulation code
// where the simulation code has a fixed topology
// grid. We treat the grid as an unstructured
// grid even though in the example provided it
// would be best described as a vtkImageData.
// Also, the points are stored in an inconsistent
// manner with respect to the velocity vector.
// This is purposefully done to demonstrate
// the different approaches for getting data
// into Catalyst. The simulation can be run
// from a restarted time step with the
// -- restart <time step> command line argument.
// All other arguments are considered to be input
// script. Note that through configuration
// that the driver can be run without linking
// to Catalyst.
#include <unistd.h>
int main(int argc, char* argv[])
{
MPI_Init(&argc, &argv);
Grid grid;
unsigned int numPoints[3] = {70, 60, 44};
double spacing[3] = {1, 1.1, 1.3};
grid.Initialize(numPoints, spacing);
Attributes attributes;
attributes.Initialize(&grid);
// we are doing a restarted simulation
unsigned int startTimeStep = 0;
std::vector<std::string> scripts;
for(int i=1;i<argc;i++)
{
if(strcmp(argv[i], "--restart") == 0)
{
if(i+1 < argc)
{
startTimeStep = static_cast<unsigned int>(atoi(argv[2]));
i++;
}
}
else
{
scripts.push_back(argv[i]);
}
}
#ifdef USE_CATALYST
FEAdaptor::Initialize(scripts);
#endif
unsigned int numberOfTimeSteps = 50;
for(unsigned int timeStep=startTimeStep;timeStep<=startTimeStep+numberOfTimeSteps;timeStep++)
{
// use a time step length of 0.018
double time = timeStep * 0.018;
attributes.UpdateFields(time);
#ifdef USE_CATALYST
FEAdaptor::CoProcess(grid, attributes, time, timeStep, timeStep == numberOfTimeSteps+startTimeStep);
#endif
}
#ifdef USE_CATALYST
FEAdaptor::Finalize();
#endif
MPI_Finalize();
return 0;
}

View File

@ -0,0 +1,61 @@
# CoProcessing test expects the following arguments to be passed to cmake using
# -DFoo=BAR arguments.
# COPROCESSING_TEST_DRIVER -- path to CxxParticlePathExample
# COPROCESSING_TEST_DIR -- path to temporary dir
# COPROCESSING_SOURCE_DIR -- path to where the source code with the python scripts are
# PVBATCH
# MPIEXEC
# MPIEXEC_NUMPROC_FLAG
# MPIEXEC_NUMPROCS
# MPIEXEC_PREFLAGS
# VTK_MPI_POSTFLAGS
# remove result files generated by the test
file(REMOVE "${COPROCESSING_TEST_DIR}/particles*vtp" )
if(NOT EXISTS "${COPROCESSING_TEST_DRIVER}")
message(FATAL_ERROR "'${COPROCESSING_TEST_DRIVER}' does not exist")
endif()
message("Executing :
${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_NUMPROCS} ${MPIEXEC_PREFLAGS}
\"${COPROCESSING_TEST_DRIVER}\"
\"${COPROCESSING_SOURCE_DIR}/SampleScripts/particlepath.py\"")
execute_process(COMMAND
${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_NUMPROCS} ${MPIEXEC_PREFLAGS}
"${COPROCESSING_TEST_DRIVER}"
"${COPROCESSING_SOURCE_DIR}/SampleScripts/particlepath.py"
WORKING_DIRECTORY ${COPROCESSING_TEST_DIR}
RESULT_VARIABLE rv)
if(NOT rv EQUAL 0)
message(FATAL_ERROR "Test executable return value was ${rv}")
endif()
# below is the restarted "simulation"
message("Executing (restart):
${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_NUMPROCS} ${MPIEXEC_PREFLAGS}
\"${COPROCESSING_TEST_DRIVER}\" --restart 50
\"${COPROCESSING_SOURCE_DIR}/SampleScripts/particlepath.py\"")
execute_process(COMMAND
${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_NUMPROCS} ${MPIEXEC_PREFLAGS}
"${COPROCESSING_TEST_DRIVER}" --restart 50
"${COPROCESSING_SOURCE_DIR}/SampleScripts/particlepath.py"
WORKING_DIRECTORY ${COPROCESSING_TEST_DIR}
RESULT_VARIABLE rv)
if(NOT rv EQUAL 0)
message(FATAL_ERROR "Test executable (restart) return value was ${rv}")
endif()
message("Executing :
${PVBATCH} ${COPROCESSING_SOURCE_DIR}/TestScripts/verifyparticlepath.py ${COPROCESSING_TEST_DIR}")
execute_process(COMMAND "${PVBATCH}" "${COPROCESSING_SOURCE_DIR}/TestScripts/verifyparticlepath.py" "${COPROCESSING_TEST_DIR}"
RESULT_VARIABLE rv
WORKING_DIRECTORY ${COPROCESSING_TEST_DIR})
if(NOT rv EQUAL 0)
message(FATAL_ERROR "verifyparticlepath.py failed.")
endif()

View File

@ -0,0 +1,131 @@
from paraview.simple import *
from paraview import coprocessing
outputfrequency = 1
reinjectionfrequency = 70
# ----------------------- CoProcessor definition -----------------------
def CreateCoProcessor():
def _CreatePipeline(coprocessor, datadescription):
class Pipeline:
# state file generated using paraview version 4.4.0-117-ge0a3d77
# ----------------------------------------------------------------
# setup the data processing pipelines
# ----------------------------------------------------------------
#### disable automatic camera reset on 'Show'
paraview.simple._DisableFirstRenderCameraReset()
# create a new 'Line' for seed sources
line1 = Line()
line1.Point1 = [1., 1., 30.]
line1.Point2 = [1., 64., 30.]
# create a producer from a simulation input
fullgrid_99pvtu = coprocessor.CreateProducer(datadescription, 'input')
# create a new 'ParticlePath'
# disable resetting the cache so that the particle path filter works in situ
# and only updates from previously computed information.
particlePath1 = InSituParticlePath(Input=fullgrid_99pvtu, SeedSource=line1, DisableResetCache=1)
particlePath1.SelectInputVectors = ['POINTS', 'velocity']
# don't save particle locations from previous time steps. they can take
# up a surprising amount of memory for long running simulations.
particlePath1.ClearCache = 1
# if we're starting from a restarted simulation, the following are
# used to specify the time step for the restarted simulation and
# the input for the previously advected particles to continue
# advecting them
if datadescription.GetTimeStep() != 0:
restartparticles = XMLPartitionedPolydataReader(FileName='particles_50.pvtp')
particlePath1.RestartSource = restartparticles
particlePath1.FirstTimeStep = datadescription.GetTimeStep()
particlePath1.RestartedSimulation = 1
# create a new 'Parallel PolyData Writer'
parallelPolyDataWriter1 = servermanager.writers.XMLPPolyDataWriter(Input=particlePath1)
# register the writer with coprocessor
# and provide it with information such as the filename to use,
# how frequently to write the data, etc.
coprocessor.RegisterWriter(parallelPolyDataWriter1, filename='particles_%t.pvtp', freq=outputfrequency)
return Pipeline()
class CoProcessor(coprocessing.CoProcessor):
def CreatePipeline(self, datadescription):
self.Pipeline = _CreatePipeline(self, datadescription)
coprocessor = CoProcessor()
# these are the frequencies at which the coprocessor updates. for
# particle paths this is done every time step
freqs = {'input': [1]}
coprocessor.SetUpdateFrequencies(freqs)
return coprocessor
#--------------------------------------------------------------
# Global variables that will hold the pipeline for each timestep
# Creating the CoProcessor object, doesn't actually create the ParaView pipeline.
# It will be automatically setup when coprocessor.UpdateProducers() is called the
# first time.
coprocessor = CreateCoProcessor()
#--------------------------------------------------------------
# Enable Live-Visualizaton with ParaView
coprocessor.EnableLiveVisualization(False, 1)
# ---------------------- Data Selection method ----------------------
def RequestDataDescription(datadescription):
"Callback to populate the request for current timestep"
global coprocessor
if datadescription.GetForceOutput() == True:
# We are just going to request all fields and meshes from the simulation
# code/adaptor.
for i in range(datadescription.GetNumberOfInputDescriptions()):
datadescription.GetInputDescription(i).AllFieldsOn()
datadescription.GetInputDescription(i).GenerateMeshOn()
return
# setup requests for all inputs based on the requirements of the
# pipeline.
coprocessor.LoadRequestedData(datadescription)
# ------------------------ Processing method ------------------------
def DoCoProcessing(datadescription):
"Callback to do co-processing for current timestep"
global coprocessor
# Update the coprocessor by providing it the newly generated simulation data.
# If the pipeline hasn't been setup yet, this will setup the pipeline.
#if not coprocessor.__PipelineCreated:
coprocessor.UpdateProducers(datadescription)
# tell the particle path filter how far to integrate in time (i.e. our current time)
coprocessor.Pipeline.particlePath1.TerminationTime = datadescription.GetTime()
# specify reinjection frequency manually so that reinjection
# occurs based on the simulation time step to avoid restart issues since
# the particle path filter only knows how many time steps
# it has been updated. this is the same when the simulation has not been
# restarted.
timestep = datadescription.GetTimeStep()
if timestep % reinjectionfrequency == 0:
coprocessor.Pipeline.particlePath1.ForceReinjectionEveryNSteps = 1
else:
coprocessor.Pipeline.particlePath1.ForceReinjectionEveryNSteps = timestep+1
coprocessor.Pipeline.particlePath1.UpdatePipeline()
# Write output data, if appropriate.
coprocessor.WriteData(datadescription);
# Write image capture (Last arg: rescale lookup table), if appropriate.
coprocessor.WriteImages(datadescription, rescale_lookuptable=False)
# Live Visualization, if enabled.
coprocessor.DoLiveVisualization(datadescription, "localhost", 22222)

View File

@ -0,0 +1,91 @@
import sys
print 'running the test script with args', sys.argv
if len(sys.argv) != 2:
print 'need to pass in the test directory location'
sys.exit(1)
# the velocity is [y*t, 0, 0] and the time step length is 0.018
# the beginning x-location for the seeds is 1
# the y location for the seeds are [1, 11.5, 22, 32.5, 43, 53.5, 64]
# the z location for the seeds is 30
# the analytical locations of the initially injected seeds are 1+y*time*time/2
# the seeds are reinjected at time step 70 (time 1.26) and their
# analytical locations are 1+y*(time*time-1.26*1.26)/2
# in parallel when seeds are migrated to different processes there
# is a slight loss of accuracy due to using a first order time
# integration method instead of vtkRungeKutta4.cxx.
from paraview.simple import *
r = XMLPartitionedPolydataReader(FileName=sys.argv[1]+'/particles_40.pvtp')
r.UpdatePipeline()
bounds = r.GetDataInformation().DataInformation.GetBounds()
if bounds[0] < 1.25 or bounds[0] > 1.27 or \
bounds[1] < 17.5 or bounds[1] > 17.7 or \
bounds[2] < .9 or bounds[2] > 1.1 or \
bounds[3] < 63.9 or bounds[3] > 64.1 or \
bounds[4] < 29.9 or bounds[4] > 30.1 or \
bounds[5] < 29.9 or bounds[5] > 30.1:
print 'Time step 40: wrong particle bounds', bounds
sys.exit(1)
g = Glyph()
g.GlyphMode = 'All Points'
g.GlyphType = '2D Glyph'
g.GlyphType.GlyphType = 'Vertex'
t = Threshold()
t.Scalars = ['POINTS', 'ParticleAge']
t.ThresholdRange = [0.71, 0.73]
t.UpdatePipeline()
grid = servermanager.Fetch(t)
if grid.GetNumberOfPoints() != 7:
print 'Time step 40: wrong number of points', grid.GetNumberOfPoints()
sys.exit(1)
r.FileName = sys.argv[1]+'/particles_80.pvtp'
# threshold to get the seeds that were originally injected only
t.ThresholdRange = [1.43, 1.45]
t.UpdatePipeline()
bounds = t.GetDataInformation().DataInformation.GetBounds()
if bounds[0] < 2. or bounds[0] > 2.1 or \
bounds[1] < 67.3 or bounds[1] > 67.4 or \
bounds[2] < .9 or bounds[2] > 1.1 or \
bounds[3] < 63.9 or bounds[3] > 64.1 or \
bounds[4] < 29.9 or bounds[4] > 30.1 or \
bounds[5] < 29.9 or bounds[5] > 30.1:
print 'Time step 80: wrong particle bounds for initial injected particles', bounds
sys.exit(1)
grid = servermanager.Fetch(t)
if grid.GetNumberOfPoints() != 7:
print 'Time step 80: wrong number of points for initial injected particles', grid.GetNumberOfPoints()
sys.exit(1)
# threshold to get the seeds that were injected at time step 70
t.Scalars = ['POINTS', 'InjectionStepId']
t.ThresholdRange = [69, 71]
t.UpdatePipeline()
bounds = t.GetDataInformation().DataInformation.GetBounds()
if bounds[0] < 1.23 or bounds[0] > 1.25 or \
bounds[1] < 16.5 or bounds[1] > 16.7 or \
bounds[2] < .9 or bounds[2] > 1.1 or \
bounds[3] < 63.9 or bounds[3] > 64.1 or \
bounds[4] < 29.9 or bounds[4] > 30.1 or \
bounds[5] < 29.9 or bounds[5] > 30.1:
print 'Time step 80: wrong particle bounds for reinjected particles', bounds
sys.exit(1)
grid = servermanager.Fetch(t)
if grid.GetNumberOfPoints() != 7:
print 'Time step 80: wrong number of points for reinjected particles', grid.GetNumberOfPoints()
sys.exit(1)
print 'test passed'