Commit 039f2281 authored by Burlen Loring's avatar Burlen Loring

support multiple meshes

Adds mesh name (string) parameter to data access methods in the data
adaptor data API. Adds methods to query number of meshes and mesh names
by index to data adaptor metadata API. Updates data adptors, analysis
adaptors, and mini-apps too use the new API.
Co-Authored-By: default avatarBrad Whitlock <bjw.ilight@gmail.com>
parent d80a0f86
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
set enabled="1" on analyses you wish to enable --> set enabled="1" on analyses you wish to enable -->
<sensei> <sensei>
<!-- Custom Analyses --> <!-- Custom Analyses -->
<analysis type="histogram" array="pressure" association="cell" bins="10" enabled="1" /> <analysis type="histogram" mesh="mesh" array="pressure" association="cell" bins="10" enabled="1" />
<analysis type="histogram" array="density" association="cell" bins="10" enabled="1" /> <analysis type="histogram" mesh="mesh" array="density" association="cell" bins="10" enabled="1" />
<analysis type="histogram" array="temperature" association="cell" bins="10" enabled="1" /> <analysis type="histogram" mesh="mesh" array="temperature" association="cell" bins="10" enabled="1" />
<!-- ADIOS Analyses --> <!-- ADIOS Analyses -->
<analysis type="adios" filename="3D_Grid.bp" method="MPI" enabled ="0"/> <analysis type="adios" filename="3D_Grid.bp" method="MPI" enabled ="0"/>
......
...@@ -2,8 +2,3 @@ if(ENABLE_ADIOS) ...@@ -2,8 +2,3 @@ if(ENABLE_ADIOS)
add_executable(ADIOSAnalysisEndPoint ADIOSAnalysisEndPoint.cxx) add_executable(ADIOSAnalysisEndPoint ADIOSAnalysisEndPoint.cxx)
target_link_libraries(ADIOSAnalysisEndPoint PRIVATE opts mpi adios sensei timer) target_link_libraries(ADIOSAnalysisEndPoint PRIVATE opts mpi adios sensei timer)
endif() endif()
if(ENABLE_ADIOS AND ENABLE_VTK_XMLP AND NOT ENABLE_LIBSIM)
add_executable(PosthocIOEndPoint PosthocIOEndPoint.cxx)
target_link_libraries(PosthocIOEndPoint PRIVATE opts mpi adios sensei timer)
endif()
#include "dataadaptor.h" #include "dataadaptor.h"
#include "Error.h"
#include <vtkInformation.h> #include <vtkInformation.h>
#include <vtkFloatArray.h> #include <vtkFloatArray.h>
...@@ -24,7 +25,8 @@ struct DataAdaptor::DInternals ...@@ -24,7 +25,8 @@ struct DataAdaptor::DInternals
inline bool areBoundsValid(const diy::DiscreteBounds& bds) inline bool areBoundsValid(const diy::DiscreteBounds& bds)
{ {
return (bds.min[0] <= bds.max[0] && bds.min[1] <= bds.max[1] && bds.min[2] <= bds.max[2]); return ((bds.min[0] <= bds.max[0]) && (bds.min[1] <= bds.max[1])
&& (bds.min[2] <= bds.max[2]));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -80,8 +82,8 @@ void DataAdaptor::SetBlockExtent(int gid, ...@@ -80,8 +82,8 @@ void DataAdaptor::SetBlockExtent(int gid,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void DataAdaptor::SetDataExtent(int ext[6]) void DataAdaptor::SetDataExtent(int ext[6])
{ {
// TODO -- this key holds a int**, it should copy the data
this->Internals->DataExtent.assign(ext, ext+6); this->Internals->DataExtent.assign(ext, ext+6);
this->GetInformation()->Set(vtkDataObject::DATA_EXTENT(), this->GetInformation()->Set(vtkDataObject::DATA_EXTENT(),
this->Internals->DataExtent.data(), 6); this->Internals->DataExtent.data(), 6);
} }
...@@ -94,9 +96,20 @@ void DataAdaptor::SetBlockData(int gid, float* data) ...@@ -94,9 +96,20 @@ void DataAdaptor::SetBlockData(int gid, float* data)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
vtkDataObject* DataAdaptor::GetMesh(bool vtkNotUsed(structure_only)) int DataAdaptor::GetMesh(const std::string &meshName, bool structureOnly,
vtkDataObject *&mesh)
{ {
(void)structureOnly;
if (meshName != "mesh")
{
SENSEI_ERROR("the miniapp provides a mesh named \"mesh\""
" you requested \"" << meshName << "\"")
return -1;
}
DInternals& internals = (*this->Internals); DInternals& internals = (*this->Internals);
if (!internals.Mesh) if (!internals.Mesh)
{ {
internals.Mesh = vtkSmartPointer<vtkMultiBlockDataSet>::New(); internals.Mesh = vtkSmartPointer<vtkMultiBlockDataSet>::New();
...@@ -106,9 +119,10 @@ vtkDataObject* DataAdaptor::GetMesh(bool vtkNotUsed(structure_only)) ...@@ -106,9 +119,10 @@ vtkDataObject* DataAdaptor::GetMesh(bool vtkNotUsed(structure_only))
internals.Mesh->SetBlock(static_cast<unsigned int>(cc), this->GetBlockMesh(cc)); internals.Mesh->SetBlock(static_cast<unsigned int>(cc), this->GetBlockMesh(cc));
} }
} }
this->AddArray(internals.Mesh,
vtkDataObject::FIELD_ASSOCIATION_CELLS, "data"); mesh = internals.Mesh;
return internals.Mesh;
return 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -129,19 +143,23 @@ vtkDataObject* DataAdaptor::GetBlockMesh(int gid) ...@@ -129,19 +143,23 @@ vtkDataObject* DataAdaptor::GetBlockMesh(int gid)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool DataAdaptor::AddArray(vtkDataObject* mesh, int association, int DataAdaptor::AddArray(vtkDataObject* mesh, const std::string &meshName,
const std::string& arrayname) int association, const std::string &arrayName)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if (association != vtkDataObject::FIELD_ASSOCIATION_CELLS || if ((association != vtkDataObject::FIELD_ASSOCIATION_CELLS) ||
arrayname != "data") (arrayName != "data") || (meshName != "mesh"))
{ {
return false; SENSEI_ERROR("the miniapp provides a cell centered array named \"data\" "
" on a mesh named \"mesh\"")
return 1;
} }
#else #else
(void)meshName;
(void)association; (void)association;
(void)arrayName;
#endif #endif
bool retVal = false; int retVal = 1;
DInternals& internals = (*this->Internals); DInternals& internals = (*this->Internals);
vtkMultiBlockDataSet* md = vtkMultiBlockDataSet::SafeDownCast(mesh); vtkMultiBlockDataSet* md = vtkMultiBlockDataSet::SafeDownCast(mesh);
for (unsigned int cc=0, max=md->GetNumberOfBlocks(); cc < max; ++cc) for (unsigned int cc=0, max=md->GetNumberOfBlocks(); cc < max; ++cc)
...@@ -153,23 +171,70 @@ bool DataAdaptor::AddArray(vtkDataObject* mesh, int association, ...@@ -153,23 +171,70 @@ bool DataAdaptor::AddArray(vtkDataObject* mesh, int association,
vtkSmartPointer<vtkImageData>& blockMesh = internals.BlockMesh[cc]; vtkSmartPointer<vtkImageData>& blockMesh = internals.BlockMesh[cc];
if (vtkCellData* cd = (blockMesh? blockMesh->GetCellData(): NULL)) if (vtkCellData* cd = (blockMesh? blockMesh->GetCellData(): NULL))
{ {
if (cd->GetArray(arrayname.c_str()) == NULL) if (cd->GetArray(arrayName.c_str()) == NULL)
{ {
vtkFloatArray* fa = vtkFloatArray::New(); vtkFloatArray* fa = vtkFloatArray::New();
fa->SetName(arrayname.c_str()); fa->SetName(arrayName.c_str());
fa->SetArray(internals.Data[cc], blockMesh->GetNumberOfCells(), 1); fa->SetArray(internals.Data[cc], blockMesh->GetNumberOfCells(), 1);
cd->SetScalars(fa); cd->SetScalars(fa);
cd->SetActiveScalars("data"); cd->SetActiveScalars("data");
fa->FastDelete(); fa->FastDelete();
} }
retVal = true; retVal = 0;
} }
} }
return retVal; return retVal;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void DataAdaptor::ReleaseData() int DataAdaptor::GetNumberOfMeshes(unsigned int &numMeshes)
{
numMeshes = 1;
return 0;
}
//-----------------------------------------------------------------------------
int DataAdaptor::GetMeshName(unsigned int id, std::string &meshName)
{
if (id == 0)
{
meshName = "mesh";
return 0;
}
SENSEI_ERROR("Failed to get mesh name")
return -1;
}
//-----------------------------------------------------------------------------
int DataAdaptor::GetNumberOfArrays(const std::string &meshName, int association,
unsigned int &numberOfArrays)
{
if ((meshName == "mesh") && (association == vtkDataObject::CELL))
{
numberOfArrays = 1;
return 0;
}
return 0;
}
//-----------------------------------------------------------------------------
int DataAdaptor::GetArrayName(const std::string &meshName, int association,
unsigned int index, std::string &arrayName)
{
if ((meshName == "mesh") &&
(association == vtkDataObject::CELL) && (index == 0))
{
arrayName = "data";
return 0;
}
SENSEI_ERROR("Failed to get array name")
return -1;
}
//-----------------------------------------------------------------------------
int DataAdaptor::ReleaseData()
{ {
DInternals& internals = (*this->Internals); DInternals& internals = (*this->Internals);
internals.Mesh = NULL; internals.Mesh = NULL;
...@@ -183,6 +248,7 @@ void DataAdaptor::ReleaseData() ...@@ -183,6 +248,7 @@ void DataAdaptor::ReleaseData()
internals.Data[cc] = NULL; internals.Data[cc] = NULL;
internals.BlockMesh[cc] = NULL; internals.BlockMesh[cc] = NULL;
} }
return 0;
} }
} }
...@@ -28,12 +28,24 @@ public: ...@@ -28,12 +28,24 @@ public:
/// Set data for a specific block. /// Set data for a specific block.
void SetBlockData(int gid, float* data); void SetBlockData(int gid, float* data);
vtkDataObject* GetMesh(bool structure_only=false) override; // SENSEI API
bool AddArray(vtkDataObject* mesh, int association, const std::string& arrayname) override; int GetNumberOfMeshes(unsigned int &numMeshes) override;
unsigned int GetNumberOfArrays(int) override { return 1; }
std::string GetArrayName(int, unsigned int index) override int GetMeshName(unsigned int id, std::string &meshName) override;
{ return index==0? "data" : std::string(); }
void ReleaseData() override; int GetMesh(const std::string &meshName, bool structureOnly,
vtkDataObject *&mesh) override;
int AddArray(vtkDataObject* mesh, const std::string &meshName,
int association, const std::string &arrayName) override;
int GetNumberOfArrays(const std::string &meshName, int association,
unsigned int &numberOfArrays) override;
int GetArrayName(const std::string &meshName, int association,
unsigned int index, std::string &arrayName) override;
int ReleaseData() override;
protected: protected:
DataAdaptor(); DataAdaptor();
......
#include "DataAdaptor.h" #include "DataAdaptor.h"
#include "Error.h"
#include "vtkCellData.h" #include <vtkCellData.h>
#include "vtkDataObject.h" #include <vtkDataObject.h>
#include "vtkDoubleArray.h" #include <vtkDoubleArray.h>
#include "vtkImageData.h" #include <vtkImageData.h>
#include "vtkInformation.h" #include <vtkInformation.h>
#include "vtkObjectFactory.h" #include <vtkObjectFactory.h>
#include <limits>
namespace parallel3d namespace parallel3d
{ {
...@@ -15,6 +18,19 @@ senseiNewMacro(DataAdaptor); ...@@ -15,6 +18,19 @@ senseiNewMacro(DataAdaptor);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
DataAdaptor::DataAdaptor() DataAdaptor::DataAdaptor()
{ {
this->CellExtent[0] = std::numeric_limits<int>::max();
this->CellExtent[1] = std::numeric_limits<int>::min();
this->CellExtent[2] = std::numeric_limits<int>::max();
this->CellExtent[3] = std::numeric_limits<int>::min();
this->CellExtent[4] = std::numeric_limits<int>::max();
this->CellExtent[5] = std::numeric_limits<int>::min();
this->WholeExtent[0] = std::numeric_limits<int>::max();
this->WholeExtent[1] = std::numeric_limits<int>::min();
this->WholeExtent[2] = std::numeric_limits<int>::max();
this->WholeExtent[3] = std::numeric_limits<int>::min();
this->WholeExtent[4] = std::numeric_limits<int>::max();
this->WholeExtent[5] = std::numeric_limits<int>::min();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -23,12 +39,10 @@ DataAdaptor::~DataAdaptor() ...@@ -23,12 +39,10 @@ DataAdaptor::~DataAdaptor()
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void DataAdaptor::Initialize( void DataAdaptor::Initialize(int g_x, int g_y, int g_z, int l_x, int l_y, int l_z,
int g_x, int g_y, int g_z,
int l_x, int l_y, int l_z,
uint64_t start_extents_x, uint64_t start_extents_y, uint64_t start_extents_z, uint64_t start_extents_x, uint64_t start_extents_y, uint64_t start_extents_z,
int tot_blocks_x, int tot_blocks_y, int tot_blocks_z, int tot_blocks_x, int tot_blocks_y, int tot_blocks_z, int block_id_x,
int block_id_x, int block_id_y, int block_id_z) int block_id_y, int block_id_z)
{ {
(void)tot_blocks_x; (void)tot_blocks_x;
(void)tot_blocks_y; (void)tot_blocks_y;
...@@ -36,6 +50,7 @@ void DataAdaptor::Initialize( ...@@ -36,6 +50,7 @@ void DataAdaptor::Initialize(
(void)block_id_x; (void)block_id_x;
(void)block_id_y; (void)block_id_y;
(void)block_id_z; (void)block_id_z;
// we only really need to save the local extents for our current example. So // we only really need to save the local extents for our current example. So
// we'll just save that. // we'll just save that.
this->CellExtent[0] = start_extents_x; this->CellExtent[0] = start_extents_x;
...@@ -52,6 +67,7 @@ void DataAdaptor::Initialize( ...@@ -52,6 +67,7 @@ void DataAdaptor::Initialize(
this->WholeExtent[3] = g_y; this->WholeExtent[3] = g_y;
this->WholeExtent[4] = 0; this->WholeExtent[4] = 0;
this->WholeExtent[5] = g_z; this->WholeExtent[5] = g_z;
this->GetInformation()->Set(vtkDataObject::DATA_EXTENT(), this->GetInformation()->Set(vtkDataObject::DATA_EXTENT(),
this->WholeExtent, 6); this->WholeExtent, 6);
} }
...@@ -74,85 +90,156 @@ void DataAdaptor::ClearArrays() ...@@ -74,85 +90,156 @@ void DataAdaptor::ClearArrays()
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
vtkDataObject* DataAdaptor::GetMesh(bool vtkNotUsed(structure_only)) int DataAdaptor::GetNumberOfArrays(const std::string &meshName,
int association, unsigned int &numberOfArrays)
{ {
if (!this->Mesh) numberOfArrays = 0;
if (meshName != "mesh")
{ {
this->Mesh = vtkSmartPointer<vtkImageData>::New(); SENSEI_ERROR("No mesh \"" << meshName << "\"")
this->Mesh->SetExtent( return -1;
this->CellExtent[0], this->CellExtent[1] + 1, }
this->CellExtent[2], this->CellExtent[3] + 1,
this->CellExtent[4], this->CellExtent[5] + 1); if (association == vtkDataObject::FIELD_ASSOCIATION_CELLS)
{
numberOfArrays = this->Variables.size();
} }
return this->Mesh;
return 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool DataAdaptor::AddArray(vtkDataObject* mesh, int association, const std::string& name) int DataAdaptor::GetArrayName(const std::string &meshName, int association,
unsigned int index, std::string &arrayName)
{ {
if (association != vtkDataObject::FIELD_ASSOCIATION_CELLS || name.empty()) arrayName = "";
if (meshName != "mesh")
{ {
return false; SENSEI_ERROR("No mesh \"" << meshName << "\"")
return -1;
} }
VariablesType::iterator iterV = this->Variables.find(name); if (association != vtkDataObject::FIELD_ASSOCIATION_CELLS)
if (iterV == this->Variables.end())
{ {
return false; SENSEI_ERROR("No point data on mesh")
return -1;
}
if (index >= this->Variables.size())
{
SENSEI_ERROR("Index out of bounds")
return -1;
} }
#ifndef NDEBUG
vtkImageData* image = vtkImageData::SafeDownCast(mesh);
#endif
assert(image != NULL);
ArraysType::iterator iterA = this->Arrays.find(iterV->first); unsigned int count = 0;
if (iterA == this->Arrays.end()) VariablesType::iterator end = this->Variables.end();
VariablesType::iterator iter = this->Variables.begin();
for (; iter != end; ++iter, ++count)
{ {
vtkSmartPointer<vtkDoubleArray>& vtkarray = this->Arrays[iterV->first]; if (count == index)
vtkarray = vtkSmartPointer<vtkDoubleArray>::New(); {
vtkarray->SetName(name.c_str()); arrayName = iter->first;
const vtkIdType size = (this->CellExtent[1] - this->CellExtent[0] + 1) * return 0;
(this->CellExtent[3] - this->CellExtent[2] + 1) * }
(this->CellExtent[5] - this->CellExtent[4] + 1);
assert(size == image->GetNumberOfCells());
vtkarray->SetArray(iterV->second, size, 1);
vtkImageData::SafeDownCast(mesh)->GetCellData()->AddArray(vtkarray);
return true;
} }
return true;
return 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
unsigned int DataAdaptor::GetNumberOfArrays(int association) int DataAdaptor::GetNumberOfMeshes(unsigned int &numMeshes)
{ {
return (association == vtkDataObject::FIELD_ASSOCIATION_CELLS)? numMeshes = 1;
static_cast<unsigned int>(this->Variables.size()): 0; return 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::string DataAdaptor::GetArrayName(int association, unsigned int index) int DataAdaptor::GetMeshName(unsigned int id, std::string &meshName)
{
if (id != 0)
{
SENSEI_ERROR("Mesh id is out of range. 1 mesh available.")
return -1;
}
meshName = "mesh";
return 0;
}
//-----------------------------------------------------------------------------
int DataAdaptor::GetMesh(const std::string &meshName, bool structureOnly,
vtkDataObject *&mesh)
{ {
(void)structureOnly;
if (meshName != "mesh")
{
SENSEI_ERROR("No mesh \"" << meshName << "\"")
return -1;
}
if (!this->Mesh)
{
this->Mesh = vtkSmartPointer<vtkImageData>::New();
this->Mesh->SetExtent(
this->CellExtent[0], this->CellExtent[1] + 1,
this->CellExtent[2], this->CellExtent[3] + 1,
this->CellExtent[4], this->CellExtent[5] + 1);
}
mesh = this->Mesh;
return 0;
}
//-----------------------------------------------------------------------------
int DataAdaptor::AddArray(vtkDataObject* mesh, const std::string &meshName,
int association, const std::string& arrayName)
{
if (meshName != "mesh")
{
SENSEI_ERROR("No mesh \"" << meshName << "\"")
return -1;
}
if (association != vtkDataObject::FIELD_ASSOCIATION_CELLS) if (association != vtkDataObject::FIELD_ASSOCIATION_CELLS)
{ {
return std::string(); SENSEI_ERROR("No point data on mesh")
return -1;
} }
unsigned int count = 0;
for (VariablesType::iterator iter=this->Variables.begin(), max=this->Variables.end(); VariablesType::iterator iterV = this->Variables.find(arrayName);
iter != max; ++iter, ++count)
if (iterV == this->Variables.end())
{ {
if (count==index) SENSEI_ERROR("no array named \"" << arrayName << "\"")
{ return -1;
return iter->first;
}
} }
return std::string();
vtkDoubleArrayPtr vtkarray = vtkDoubleArrayPtr::New();
vtkarray->SetName(arrayName.c_str());
const vtkIdType size =
(this->CellExtent[1] - this->CellExtent[0] + 1) *
(this->CellExtent[3] - this->CellExtent[2] + 1) *
(this->CellExtent[5] - this->CellExtent[4] + 1);
vtkarray->SetArray(iterV->second, size, 1);
vtkImageData* image = vtkImageData::SafeDownCast(mesh);
image->GetCellData()->AddArray(vtkarray);
assert(image);
assert(size == image->GetNumberOfCells());
return 0;