28 #include <vtkCPDataDescription.h>
29 #include <vtkCPInputDataDescription.h>
30 #include <vtkCPProcessor.h>
31 #include <vtkCPPythonScriptPipeline.h>
32 #include <vtkDoubleArray.h>
33 #include <vtkFieldData.h>
34 #include <vtkIdTypeArray.h>
35 #include <vtkImageData.h>
36 #include <vtkImageDataStreamer.h>
37 #include <vtkIntArray.h>
39 #include <vtkPointData.h>
40 #include <vtkPoints.h>
41 #include <vtkStringArray.h>
42 #include <vtkUnstructuredGrid.h>
43 #include <vtkXMLImageDataWriter.h>
44 #include <vtkXMLPImageDataWriter.h>
45 #include <vtkXMLPUnstructuredGridWriter.h>
46 #include <vtkXMLUnstructuredGridWriter.h>
54 std::unordered_map<std::string, VtkDiffusionGrid*>
vtk_dgrids_;
64 impl_ = std::unique_ptr<ParaviewAdaptor::ParaviewImpl>(
75 impl_->g_processor_->RemoveAllPipelines();
76 impl_->g_processor_->Finalize();
77 impl_->g_processor_->Delete();
78 impl_->g_processor_ =
nullptr;
80 if (param->export_visualization &&
81 param->visualization_export_generate_pvsm) {
86 if (
impl_->data_description_ !=
nullptr) {
87 impl_->data_description_->Delete();
89 for (
auto& el :
impl_->vtk_agents_) {
92 for (
auto& el :
impl_->vtk_dgrids_) {
106 auto* param = sim->GetParam();
107 uint64_t total_steps = sim->GetScheduler()->GetSimulatedSteps();
108 if (total_steps % param->visualization_interval != 0) {
112 real_t time = param->simulation_time_step * total_steps;
113 impl_->data_description_->SetTimeData(time, total_steps);
117 if (param->insitu_visualization) {
120 if (param->export_visualization) {
128 auto* param = sim->GetParam();
130 if (param->insitu_visualization &&
impl_->g_processor_ ==
nullptr) {
133 "Insitu visualization is currently not supported on MacOS. "
134 "Please use export visualization.");
136 impl_->g_processor_ = vtkCPProcessor::New();
137 impl_->g_processor_->Initialize();
140 if (param->insitu_visualization) {
141 const std::string& script =
145 std::string final_python_script_name =
146 Concat(sim->GetOutputDir(),
"/insitu_pipeline.py");
147 ofs.open(final_python_script_name);
150 vtkNew<vtkCPPythonScriptPipeline> pipeline;
151 pipeline->Initialize(final_python_script_name.c_str());
152 impl_->g_processor_->AddPipeline(pipeline.GetPointer());
155 if (
impl_->data_description_ ==
nullptr) {
156 impl_->data_description_ = vtkCPDataDescription::New();
158 impl_->data_description_->Delete();
159 impl_->data_description_ = vtkCPDataDescription::New();
161 impl_->data_description_->SetTimeData(0, 0);
163 for (
auto& pair : param->visualize_agents) {
164 impl_->vtk_agents_[pair.first.c_str()] =
167 for (
auto& entry : param->visualize_diffusion) {
168 impl_->vtk_dgrids_[entry.name] =
175 #ifdef BDM_PV_EXPERIMENTAL
176 vtkCommand::kOpenGLCacheEnable =
true;
177 vtkCommand::kOpenGLCacheIndex = 0;
179 impl_->g_processor_->RequestDataDescription(
impl_->data_description_);
180 impl_->data_description_->ForceOutputOn();
181 impl_->g_processor_->CoProcess(
impl_->data_description_);
188 auto step =
impl_->data_description_->GetTimeStep();
190 for (
auto& el :
impl_->vtk_agents_) {
191 el.second->WriteToFile(step);
194 for (
auto& el :
impl_->vtk_dgrids_) {
195 el.second->WriteToFile(step);
203 if (
impl_->data_description_->GetUserData() ==
nullptr) {
204 vtkNew<vtkStringArray> json;
205 json->SetName(
"metadata");
206 json->InsertNextValue(
208 vtkNew<vtkFieldData> field;
209 field->AddArray(json);
210 impl_->data_description_->SetUserData(field);
217 for (
auto& pair :
impl_->vtk_agents_) {
219 pair.second->Update(&agents);
229 if (it !=
impl_->vtk_dgrids_.end()) {
230 it->second->Update(grid);
241 ofstr.open(
Concat(sim->GetOutputDir(),
"/", kSimulationInfoJson));
254 std::stringstream python_cmd;
255 std::string pv_dir = std::getenv(
"ParaView_DIR");
256 std::string bdmsys = std::getenv(
"BDMSYS");
258 python_cmd << pv_dir <<
"/bin/pvbatch --force-offscreen-rendering " << bdmsys
259 <<
"/include/core/visualization/paraview/generate_pv_state.py "
260 << sim->GetOutputDir() <<
"/" << kSimulationInfoJson;
261 int ret_code = system(python_cmd.str().c_str());
270 Concat(sim->GetOutputDir(),
"/", sim->GetUniqueName(),
".pvsm");
273 "pvbatch exited with code ", ret_code,
274 " but wrote a ParaView state file. It may be incomplete: "
275 "the animation time range is the most likely omission.\n",
276 "Command\n", python_cmd.str());
278 Log::Fatal(
"ParaviewAdaptor::GenerateParaviewState",
279 "Error during generation of ParaView state. pvbatch exited "
281 ret_code,
" and wrote no state file to ", state_file,
"\n",
282 "Command\n", python_cmd.str());
289 const std::string& python_script) {
290 std::stringstream script;
293 ifs.open(python_script, std::ifstream::in);
294 if (!ifs.is_open()) {
295 Log::Fatal(
"ParaviewAdaptor::BuildPythonScriptString",
296 Concat(
"Python script (", python_script,
297 ") was not found or could not be opened."));
299 script << ifs.rdbuf();
302 std::string default_python_script =
303 std::string(std::getenv(
"BDMSYS")) +
305 "/include/core/visualization/paraview/default_insitu_pipeline.py");
307 std::ifstream ifs_default;
308 ifs_default.open(default_python_script, std::ifstream::in);
309 if (!ifs_default.is_open()) {
310 Log::Fatal(
"ParaviewAdaptor::BuildPythonScriptString",
311 Concat(
"Python script (", default_python_script,
312 ") was not found or could not be opened."));
314 script << std::endl << ifs_default.rdbuf();
338 const std::string& python_script) {}
const std::string & GetContinuumName() const
Returns the name of the continuum.
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
static void Warning(const std::string &location, const Args &... parts)
Prints warning message.
void BuildAgentsVTKStructures()
Create the required vtk objects to visualize agents.
void WriteSimulationInfoJsonFile()
void CreateVtkObjects()
Creates the VTK objects that represent the agents in ParaView.
void Visualize() override
Visualize one timestep based on the configuration in Param
static std::atomic< uint64_t > counter_
void BuildDiffusionGridVTKStructures()
Create the required vtk objects to visualize diffusion grids.
static void GenerateParaviewState()
static std::string BuildPythonScriptString(const std::string &python_script)
~ParaviewAdaptor() override
bool initialized_
only needed for insitu visualization
void InsituVisualization()
Execute the insitu pipelines that were defined in Initialize
bool simulation_info_json_generated_
std::unique_ptr< ParaviewImpl > impl_
void ExportVisualization()
const TypeIndex * GetTypeIndex() const
void ForEachDiffusionGrid(TFunctor &&f) const
ResourceManager * GetResourceManager()
Returns the ResourceManager instance.
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
const Param * GetParam() const
Returns the simulation parameters.
const std::vector< Agent * > & GetType(TClass *tclass) const
std::string Concat(const Args &... parts)
Concatenates all arguments into a string. Equivalent to streaming all arguments into a stringstream a...
bool FileExists(const std::string &file_name)
std::string GenerateSimulationInfoJson(const std::unordered_map< std::string, VtkAgents * > &vtk_agents, const std::unordered_map< std::string, VtkDiffusionGrid * > &vtk_dgrids)
void WriteToFile(const std::string &filename, const std::string &content)
vtkCPProcessor * g_processor_
vtkCPDataDescription * data_description_
std::unordered_map< std::string, VtkDiffusionGrid * > vtk_dgrids_
std::unordered_map< std::string, VtkAgents * > vtk_agents_