BioDynaMo  v1.05.119-a4ff3934
vtk_agents.cc
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
16 // std
17 #include <algorithm>
18 #include <set>
19 #include <vector>
20 // ParaView
21 #include <vtkCPDataDescription.h>
22 #include <vtkCPInputDataDescription.h>
23 #include <vtkNew.h>
24 #include <vtkPointData.h>
25 #include <vtkPoints.h>
26 // ROOT
27 #include <TClass.h>
28 #include <TClassTable.h>
29 #include <TDataMember.h>
30 // BioDynaMo
31 #include "core/agent/agent.h"
32 #include "core/param/param.h"
33 #include "core/shape.h"
34 #include "core/simulation.h"
35 #include "core/util/jit.h"
38 
39 #include "core/agent/cell.h"
40 
41 namespace bdm {
42 
43 // -----------------------------------------------------------------------------
44 VtkAgents::VtkAgents(const char* type_name,
45  vtkCPDataDescription* data_description) {
46  auto* param = Simulation::GetActive()->GetParam();
47  auto* tinfo = ThreadInfo::GetInstance();
48  if (param->export_visualization) {
49  data_.resize(tinfo->GetMaxThreads());
50  } else {
51  data_.resize(1);
52  }
53 #pragma omp parallel for schedule(static, 1)
54  for (uint64_t i = 0; i < data_.size(); ++i) {
55  data_[i] = vtkUnstructuredGrid::New();
56  }
57  name_ = type_name;
58 
59  if (!param->export_visualization) {
60  data_description->AddInput(type_name);
61  data_description->GetInputDescriptionByName(type_name)->SetGrid(data_[0]);
62  }
63 
64  tclass_ = FindTClass();
65  auto* tmp_instance = static_cast<Agent*>(tclass_->New());
66  shape_ = tmp_instance->GetShape();
67  std::vector<std::string> data_members;
68  InitializeDataMembers(tmp_instance, &data_members);
69 
71  tclass_, data_members, "CreateVtkDataArrays",
72  [](const std::string& functor_name,
73  const std::vector<TDataMember*>& tdata_members) {
74  std::stringstream sstr;
75  sstr << "namespace bdm {\n\n"
76  << "struct R__CLING_PTRCHECK(off) " << functor_name
77  << " : public Functor<void, VtkAgents*, int> {\n"
78  << " void operator()(VtkAgents* agent_grid, int tid) {\n";
79 
80  for (auto* tdm : tdata_members) {
81  // example:
82  // { CreateVtkDataArray<Cell, Real3> f; f(tid, "position_", 123,
83  // agent_grid); }
84  sstr << "{ CreateVtkDataArray<" << tdm->GetClass()->GetName() << ", "
85  << tdm->GetTypeName() << ">f; f("
86  << "tid, \"" << tdm->GetName() << "\", " << tdm->GetOffset()
87  << ", agent_grid); }\n";
88  }
89 
90  sstr << " }\n";
91  sstr << "};\n\n";
92  sstr << "} // namespace bdm\n";
93 
94  return sstr.str();
95  });
96  jitcreate.Compile();
97  auto* create_functor = jitcreate.New<Functor<void, VtkAgents*, int>>();
98  for (uint64_t i = 0; i < data_.size(); ++i) {
99  (*create_functor)(this, i);
100  }
101  delete create_functor;
102 }
103 
104 // -----------------------------------------------------------------------------
106  name_ = "";
107  for (auto& el : data_) {
108  el->Delete();
109  }
110  data_.clear();
111 }
112 
113 // -----------------------------------------------------------------------------
114 vtkUnstructuredGrid* VtkAgents::GetData(uint64_t idx) { return data_[idx]; }
115 
116 // -----------------------------------------------------------------------------
117 Shape VtkAgents::GetShape() const { return shape_; }
118 
119 // -----------------------------------------------------------------------------
120 TClass* VtkAgents::GetTClass() { return tclass_; }
121 
122 // -----------------------------------------------------------------------------
123 void VtkAgents::Update(const std::vector<Agent*>* agents) {
124  auto* param = Simulation::GetActive()->GetParam();
125  if (param->export_visualization) {
126 #pragma omp parallel
127  {
128  auto* tinfo = ThreadInfo::GetInstance();
129  auto tid = tinfo->GetMyThreadId();
130  auto max_threads = tinfo->GetMaxThreads();
131 
132  // use static scheduling for now
133  auto correction = agents->size() % max_threads == 0 ? 0 : 1;
134  auto chunk = agents->size() / max_threads + correction;
135  auto start = tid * chunk;
136  auto end = std::min(agents->size(), start + chunk);
137 
138  UpdateMappedDataArrays(tid, agents, start, end);
139  }
140  } else {
141  UpdateMappedDataArrays(0, agents, 0, agents->size());
142  }
143 }
144 
145 // -----------------------------------------------------------------------------
146 void VtkAgents::WriteToFile(uint64_t step) const {
147  auto* sim = Simulation::GetActive();
148  auto filename_prefix = Concat(name_, "-", step);
149 
150  ParallelVtuWriter writer;
151  writer(sim->GetOutputDir(), filename_prefix, data_);
152 }
153 
154 // -----------------------------------------------------------------------------
156  const std::vector<Agent*>* agents,
157  uint64_t start, uint64_t end) {
158  auto* parray = dynamic_cast<MappedDataArrayInterface*>(
159  data_[tid]->GetPoints()->GetData());
160  parray->Update(agents, start, end);
161  auto* point_data = data_[tid]->GetPointData();
162  for (int i = 0; i < point_data->GetNumberOfArrays(); i++) {
163  auto* array =
164  dynamic_cast<MappedDataArrayInterface*>(point_data->GetArray(i));
165  array->Update(agents, start, end);
166  }
167 }
168 
169 // -----------------------------------------------------------------------------
171  const auto& tclass_vector = FindClassSlow(name_);
172  if (tclass_vector.size() == 0) {
173  Log::Fatal("VtkAgents::VtkAgents",
174  Concat("Could not find class: ", name_).c_str());
175  } else if (tclass_vector.size() == 0) {
176  std::stringstream str;
177  for (auto& tc : tclass_vector) {
178  str << tc->GetName() << std::endl;
179  }
180  Log::Fatal("VtkAgents::VtkAgents",
181  Concat("Found multiple classes with name : ", name_,
182  ". See list below. Fix this issue by adding a namespace "
183  "modifier.\n'",
184  str.str())
185  .c_str());
186  }
187  return tclass_vector[0];
188 }
189 
190 // -----------------------------------------------------------------------------
192  const Agent* agent, std::vector<std::string>* data_members) const {
193  std::set<std::string> dm_set = agent->GetRequiredVisDataMembers();
194  auto* param = Simulation::GetActive()->GetParam();
195  for (auto& dm : param->visualize_agents.at(name_)) {
196  dm_set.insert(dm);
197  }
198  data_members->resize(dm_set.size());
199  std::copy(dm_set.begin(), dm_set.end(), data_members->begin());
200 }
201 
202 } // namespace bdm
bdm::MappedDataArrayInterface::Update
virtual void Update(const std::vector< Agent * > *agents, uint64_t start, uint64_t end)=0
shape.h
bdm::Agent::GetRequiredVisDataMembers
virtual std::set< std::string > GetRequiredVisDataMembers() const
Definition: agent.h:140
bdm::Shape
Shape
Definition: shape.h:20
parallel_vtu_writer.h
vtk_agents.h
bdm::VtkAgents::data_
std::vector< vtkUnstructuredGrid * > data_
Definition: vtk_agents.h:51
bdm::VtkAgents::shape_
Shape shape_
Definition: vtk_agents.h:52
bdm::VtkAgents::GetData
vtkUnstructuredGrid * GetData(uint64_t idx)
Definition: vtk_agents.cc:114
bdm::ThreadInfo::GetInstance
static ThreadInfo * GetInstance()
Definition: thread_info.cc:21
bdm
Definition: agent.cc:39
bdm::MappedDataArrayInterface
Definition: mapped_data_array.h:119
bdm::VtkAgents::GetShape
Shape GetShape() const
Definition: vtk_agents.cc:117
jit_helper.h
bdm::VtkAgents::tclass_
TClass * tclass_
Definition: vtk_agents.h:50
bdm::Agent
Contains code required by all agents.
Definition: agent.h:79
jit.h
bdm::Functor
Definition: functor.h:24
bdm::VtkAgents::name_
std::string name_
Definition: vtk_agents.h:49
bdm::FindClassSlow
std::vector< TClass * > FindClassSlow(const std::string &class_name)
Definition: jit.cc:31
bdm::JitForEachDataMemberFunctor::Compile
void Compile() const
Definition: jit.cc:129
bdm::VtkAgents::UpdateMappedDataArrays
void UpdateMappedDataArrays(uint64_t tid, const std::vector< Agent * > *agents, uint64_t start, uint64_t end)
Definition: vtk_agents.cc:155
bdm::Concat
std::string Concat(const Args &... parts)
Concatenates all arguments into a string. Equivalent to streaming all arguments into a stringstream a...
Definition: string.h:70
agent.h
bdm::JitForEachDataMemberFunctor
Definition: jit.h:49
bdm::Log::Fatal
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
Definition: log.h:115
bdm::VtkAgents::WriteToFile
void WriteToFile(uint64_t step) const
Definition: vtk_agents.cc:146
bdm::ParallelVtuWriter
Definition: parallel_vtu_writer.h:26
bdm::VtkAgents::~VtkAgents
~VtkAgents()
Definition: vtk_agents.cc:105
bdm::VtkAgents::FindTClass
TClass * FindTClass()
Definition: vtk_agents.cc:170
bdm::VtkAgents::GetTClass
TClass * GetTClass()
Definition: vtk_agents.cc:120
simulation.h
bdm::Simulation::GetParam
const Param * GetParam() const
Returns the simulation parameters.
Definition: simulation.cc:254
bdm::VtkAgents::Update
void Update(const std::vector< Agent * > *agents)
Definition: vtk_agents.cc:123
bdm::VtkAgents::InitializeDataMembers
void InitializeDataMembers(const Agent *agent, std::vector< std::string > *data_members) const
Definition: vtk_agents.cc:191
param.h
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68
cell.h
bdm::VtkAgents::VtkAgents
VtkAgents(const char *type_name, vtkCPDataDescription *data_description)
Definition: vtk_agents.cc:44