Generate3DAMRDataSetWithPulse
VTKExamples/Cxx/CompositeData/Generate3DAMRDataSetWithPulse
Description¶
This utility code generates a simple 3D AMR dataset with a Gaussian pulse at the center. The resulting AMR dataset is written using the vtkXMLHierarchicalBoxDataSetWriter.
Note
The original source code for this example is here.
Code¶
Generate3DAMRDataSetWithPulse.cxx
// .NAME Generate3DAMRDataSetWithPulse.cxx -- Generated sample 3D AMR dataset // // .SECTION Description // This utility code generates a simple 3D AMR dataset with a gaussian // pulse at the center. The resulting AMR dataset is written using the // vtkXMLHierarchicalBoxDataSetWriter. #include <iostream> #include <cmath> #include <sstream> #include <vtkAMRUtilities.h> #include <vtkCell.h> #include <vtkCellData.h> #include <vtkDataArray.h> #include <vtkDoubleArray.h> #include <vtkOverlappingAMR.h> #include <vtkPointData.h> #include <vtkPoints.h> #include <vtkUniformGrid.h> #include <vtkAMRBox.h> #include <vtkCompositeDataWriter.h> #include <vtkHierarchicalBoxDataSet.h> #include <vtkMultiBlockDataSet.h> #include <vtkXMLHierarchicalBoxDataReader.h> #include <vtkXMLImageDataWriter.h> #include <vtkXMLMultiBlockDataWriter.h> namespace { namespace AMRCommon { void WriteUniformGrid( vtkUniformGrid *g, const std::string &prefix ); void WriteAMRData( vtkOverlappingAMR *amrData, const std::string &prefix ); vtkHierarchicalBoxDataSet* ReadAMRData( const std::string &file ); void WriteMultiBlockData( vtkMultiBlockDataSet *mbds, const std::string &prefix ); vtkUniformGrid* GetGrid( double* origin,double* h,int* ndim ); void ComputeCellCenter( vtkUniformGrid *grid, const int cellIdx, double c[3] ); } } namespace { static struct PulseAttributes { double origin[3]; // xyz for the center of the pulse double width[3]; // the width of the pulse double amplitude; // the amplitude of the pulse } Pulse; // // Function prototype declarations // // Description: // Sets the pulse attributes void SetPulse(); // Description: // Constructs the vtkHierarchicalBoxDataSet. vtkOverlappingAMR* GetAMRDataSet(); // Description: // Attaches the pulse to the given grid. void AttachPulseToGrid( vtkUniformGrid *grid ); } // // Program main // int main( int, char *[] ) { // STEP 0: Initialize gaussian pulse parameters SetPulse(); // STEP 1: Get the AMR dataset vtkOverlappingAMR *amrDataSet = GetAMRDataSet(); AMRCommon::WriteAMRData( amrDataSet, "Gaussian3D" ); amrDataSet->Delete(); return 0; } namespace { //============================================================================= // Function Prototype Implementation //============================================================================= void SetPulse() { Pulse.origin[0] = Pulse.origin[1] = Pulse.origin[2] = -1.0; Pulse.width[0] = Pulse.width[1] = Pulse.width[2] = 6.0; Pulse.amplitude = 0.0001; } //------------------------------------------------------------------------------ void AttachPulseToGrid( vtkUniformGrid *grid ) { vtkDoubleArray* xyz = vtkDoubleArray::New( ); xyz->SetName( "GaussianPulse" ); xyz->SetNumberOfComponents( 1 ); xyz->SetNumberOfTuples( grid->GetNumberOfCells() ); for(int cellIdx=0; cellIdx < grid->GetNumberOfCells(); ++cellIdx ) { double center[3]; AMRCommon::ComputeCellCenter( grid, cellIdx, center ); double r = 0.0; for( int i=0; i < 3; ++i ) { double dx = center[i]-Pulse.origin[i]; r += (dx*dx) / (Pulse.width[i]*Pulse.width[i]); } double f = Pulse.amplitude*std::exp( -r ); xyz->SetTuple1( cellIdx, f ); } // END for all cells grid->GetCellData()->AddArray( xyz ); xyz->Delete(); } //------------------------------------------------------------------------------ vtkOverlappingAMR* GetAMRDataSet() { vtkOverlappingAMR *data = vtkOverlappingAMR::New(); int blocksPerLevel[2] = {1,3}; double globalOrigin[3] = {-2.0,-2.0,-2.0}; data->Initialize(2,blocksPerLevel); data->SetOrigin(globalOrigin); data->SetGridDescription(VTK_XYZ_GRID); double origin[3]; double h[3]; int ndim[3]; // Root Block -- Block 0 ndim[0] = 6; ndim[1] = ndim[2] = 5; h[0] = h[1] = h[2] = 1.0; origin[0] = origin[1] = origin[2] = -2.0; int blockId = 0; int level = 0; vtkUniformGrid *root = AMRCommon::GetGrid(origin,h,ndim); vtkAMRBox box(origin,ndim,h,data->GetOrigin(), data->GetGridDescription()); AttachPulseToGrid( root ); data->SetAMRBox(level,blockId,box); data->SetDataSet( level, blockId,root); root->Delete(); // Block 1 ndim[0] = 3; ndim[1] = ndim[2] = 5; h[0] = h[1] = h[2] = 0.5; origin[0] = origin[1] = origin[2] = -2.0; blockId = 0; level = 1; vtkUniformGrid *grid1 = AMRCommon::GetGrid(origin,h,ndim); AttachPulseToGrid(grid1); vtkAMRBox box1(origin,ndim,h,data->GetOrigin(), data->GetGridDescription()); data->SetAMRBox(level,blockId,box1); data->SetDataSet(level, blockId,grid1); grid1->Delete(); // Block 2 ndim[0] = 3; ndim[1] = ndim[2] = 5; h[0] = h[1] = h[2] = 0.5; origin[0] = 0.0; origin[1] = origin[2] = -1.0; blockId = 1; level = 1; vtkUniformGrid *grid2 = AMRCommon::GetGrid(origin,h,ndim); AttachPulseToGrid(grid2); vtkAMRBox box2(origin,ndim,h,data->GetOrigin(), data->GetGridDescription()); data->SetAMRBox(level,blockId,box2); data->SetDataSet(level,blockId,grid2); grid2->Delete(); // Block 3 ndim[0] = 3; ndim[1] = ndim[2] = 7; h[0] = h[1] = h[2] = 0.5; origin[0] = 2.0; origin[1] = origin[2] = -1.0; blockId = 2; level = 1; vtkUniformGrid *grid3 = AMRCommon::GetGrid(origin,h,ndim); vtkAMRBox box3(origin,ndim,h,data->GetOrigin(), data->GetGridDescription()); AttachPulseToGrid(grid3); data->SetAMRBox(level,blockId,box3); data->SetDataSet( level, blockId,grid3); grid3->Delete(); vtkAMRUtilities::BlankCells(data); return( data ); } } namespace { namespace AMRCommon { //------------------------------------------------------------------------------ // Description: // Writes a uniform grid as a structure grid void WriteUniformGrid( vtkUniformGrid *g, const std::string &prefix ) { vtkXMLImageDataWriter *imgWriter = vtkXMLImageDataWriter::New(); std::ostringstream oss; oss << prefix << "." << imgWriter->GetDefaultFileExtension(); imgWriter->SetFileName( oss.str().c_str() ); imgWriter->SetInputData( g ); imgWriter->Write(); imgWriter->Delete(); } //------------------------------------------------------------------------------ // Description: // Writes the given AMR dataset to a *.vth file with the given prefix. void WriteAMRData( vtkOverlappingAMR *amrData, const std::string &prefix ) { vtkCompositeDataWriter *writer = vtkCompositeDataWriter::New(); std::ostringstream oss; oss << prefix << ".vthb"; writer->SetFileName(oss.str().c_str()); writer->SetInputData(amrData); writer->Write(); writer->Delete(); } //------------------------------------------------------------------------------ // Description: // Reads AMR data to the given data-structure from the prescribed file. vtkHierarchicalBoxDataSet* ReadAMRData( const std::string &file ) { vtkXMLHierarchicalBoxDataReader *myAMRReader= vtkXMLHierarchicalBoxDataReader::New(); std::ostringstream oss; oss.str(""); oss.clear(); oss << file << ".vthb"; std::cout << "Reading AMR Data from: " << oss.str() << std::endl; std::cout.flush(); myAMRReader->SetFileName( oss.str().c_str() ); myAMRReader->Update(); vtkHierarchicalBoxDataSet *amrData = vtkHierarchicalBoxDataSet::SafeDownCast( myAMRReader->GetOutput() ); return( amrData ); } //------------------------------------------------------------------------------ // Description: // Writes the given multi-block data to an XML file with the prescribed prefix void WriteMultiBlockData( vtkMultiBlockDataSet *mbds, const std::string &prefix ) { // Sanity check vtkXMLMultiBlockDataWriter *writer = vtkXMLMultiBlockDataWriter::New(); std::ostringstream oss; oss.str(""); oss.clear(); oss << prefix << "." << writer->GetDefaultFileExtension(); writer->SetFileName( oss.str( ).c_str( ) ); writer->SetInputData( mbds ); writer->Write(); writer->Delete(); } //------------------------------------------------------------------------------ // Constructs a uniform grid instance given the prescribed // origin, grid spacing and dimensions. vtkUniformGrid* GetGrid( double* origin,double* h,int* ndim ) { vtkUniformGrid *grd = vtkUniformGrid::New(); grd->Initialize(); grd->SetOrigin( origin ); grd->SetSpacing( h ); grd->SetDimensions( ndim ); return grd; } //------------------------------------------------------------------------------ // Computes the cell center for the cell corresponding to cellIdx w.r.t. // the given grid. The cell center is stored in the supplied buffer c. void ComputeCellCenter( vtkUniformGrid *grid, const int cellIdx, double c[3] ) { vtkCell *myCell = grid->GetCell( cellIdx ); double pCenter[3]; double *weights = new double[ myCell->GetNumberOfPoints() ]; int subId = myCell->GetParametricCenter( pCenter ); myCell->EvaluateLocation( subId,pCenter,c,weights ); delete [] weights; } } }
CMakeLists.txt¶
cmake_minimum_required(VERSION 2.8) PROJECT(Generate3DAMRDataSetWithPulse) find_package(VTK REQUIRED) include(${VTK_USE_FILE}) add_executable(Generate3DAMRDataSetWithPulse MACOSX_BUNDLE Generate3DAMRDataSetWithPulse.cxx ) target_link_libraries(Generate3DAMRDataSetWithPulse ${VTK_LIBRARIES})
Download and Build Generate3DAMRDataSetWithPulse¶
Click here to download Generate3DAMRDataSetWithPulse and its CMakeLists.txt file. Once the tarball Generate3DAMRDataSetWithPulse.tar has been downloaded and extracted,
cd Generate3DAMRDataSetWithPulse/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./Generate3DAMRDataSetWithPulse
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.