Microflow 3D  v1.0
MF::Database::AutoThreading Class Reference

The AutoThreading class is responsible for automatic partitioning of grid nodes into MFThreads. More...

#include <AutoThreading.h>

Public Member Functions

 AutoThreading ()=default
 
 ~AutoThreading ()=default
 

Static Public Member Functions

static void GridThreading (const openvdb::Int64Grid::Ptr &VDBGrid_Ptr, std::shared_ptr< MF::Database::ThreadArray > &ThreadArray_Ptr)
 Grid partitioning into MFThreads. More...
 
static void ThreadPartitioning (const openvdb::Int64Grid::Ptr &VDBGrid_Ptr, const std::shared_ptr< MF::Database::ConfigData > &ConfigData_Ptr)
 MFThreads partitioning. More...
 

Detailed Description

The AutoThreading class is responsible for automatic partitioning of grid nodes into MFThreads.

The AutoThreading class creates the VDB grid of pointers to active (not solid) nodes. It is also responsible for the proper linking of nodes between threads for standard fluid node propagation and propagation of periodic boundary nodes. Linkages are realized by an array of pointers that are stored in PropagationTable and SecondHalfPropagationTable_Ptr.

Parameters
VDBGrid_PtrShared pointer to VDB geometry grid containing nodeIDs (node type + uid-threadNr+1 + ThreadCount).
ThreadArray_PtrShared pointer to array of shared pointers to MFThreads.
Note
Each computational Node has to belong to exactly one MFThread.

Definition at line 38 of file AutoThreading.h.

Constructor & Destructor Documentation

◆ AutoThreading()

MF::Database::AutoThreading::AutoThreading ( )
default

◆ ~AutoThreading()

MF::Database::AutoThreading::~AutoThreading ( )
default

Member Function Documentation

◆ GridThreading()

void MF::Database::AutoThreading::GridThreading ( const openvdb::Int64Grid::Ptr &  VDBGrid_Ptr,
std::shared_ptr< MF::Database::ThreadArray > &  ThreadArray_Ptr 
)
static

Grid partitioning into MFThreads.

Definition at line 13 of file AutoThreading.cpp.

References MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cx, MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cy, MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cz, MFQ19_H, MF::GB::NodeID::Node, MF::GB::NodeID::node_id, MF::GB::NodeID::NodeID, and MF::GU::LatticeParametersD3Q19::SwapDirections.

Referenced by main().

13  {
14 
15  struct nodeForAutoThreading {
16  uint64_t NodeEncodedID = 1;
17  uint32_t NodeNumber = 0;
18  };
19 
20  nodeForAutoThreading newNode;
21  auto NodeArray_Ptr = std::make_unique<std::vector<nodeForAutoThreading>>(1);
22  uint64_t nodeEID; // nodeForAutoThreading NodeID + uid-thread number+1 + ThreadCount + ComponentNr + PhaseNr.
23  unsigned char mark;
24 
25  //auto accessor = VDBGrid_Ptr->getAccessor();
26  openvdb::Coord xyz;
27  int32_t &i = xyz[0], &j = xyz[1], &h = xyz[2];
28 
29  // Counts nodes with the same nodeID
30  for (auto iter = VDBGrid_Ptr->beginValueOn(); iter; ++iter) {
31  mark = 0;
32  nodeEID = iter.getValue();
33  for (auto & it : *NodeArray_Ptr) {
34  if (it.NodeEncodedID == nodeEID) {
35  it.NodeNumber++;
36  mark++;
37  }
38  }
39  if (mark == 0) {
40  newNode.NodeNumber = 1;
41  newNode.NodeEncodedID = nodeEID;
42  NodeArray_Ptr->push_back(newNode);
43  }
44  else if (mark > 1) {
45  std::cout << "AutoThreading Error" << std::endl;
46  exit(EXIT_FAILURE);
47  }
48  }
49 
50  // Add new thread to threads array
51  for (auto & it : *NodeArray_Ptr) {
52  ThreadArray_Ptr->NewThread(it.NodeEncodedID,it.NodeNumber);
53  }
54 
55  // Add nodes coordinates to threads
56  for (auto & thread1 : *ThreadArray_Ptr->m_ThreadsTable_Ptr){
57  MF::GB::NodeID nodeTMP;
58  nodeTMP.node_id.Node.nodeType = thread1->m_NodeType;
59  nodeTMP.node_id.Node.uidThreadNr = thread1->m_uidThreadNr;
60  nodeTMP.node_id.Node.ThreadCount = thread1->m_ThreadCount;
61  nodeTMP.node_id.Node.ComponentNr = thread1->m_ComponentNr;
62  nodeTMP.node_id.Node.PhaseNr = thread1->m_PhaseNr;
63  auto iter2 = VDBGrid_Ptr->beginValueOn();
64  for (size_t node = 0; node < thread1->m_NodeArray_Ptr->size(); node++) {
65  for (auto iter = iter2; iter; ++iter) {
66  if (iter.getValue() == nodeTMP.node_id.NodeID) {
67  xyz = iter.getCoord();
68  thread1->setNodeCoordX(node, i);
69  thread1->setNodeCoordY(node, j);
70  thread1->setNodeCoordZ(node, h);
71  iter2 = iter;
72  ++iter2;
73  break;
74  }
75  }
76  }
77  }
78 
79  NodeArray_Ptr.reset();
80 
81  // Create VDB grid of pointers
82  using PointersTree = openvdb::tree::Tree4<uintptr_t, 5, 4, 3 >::Type;
83  using PointersGrid = openvdb::Grid<PointersTree>;
84 
85  // Create an empty grid with background nodeForAutoThreading 0.
86  auto PointersGrid_Ptr = PointersGrid::create(0);
87  auto accessor2 = PointersGrid_Ptr->getAccessor();
88 
89  // Set pointers in VDB grid to thread nodes
90  for (auto & thread2 : *ThreadArray_Ptr->m_ThreadsTable_Ptr){
91  for (size_t node = 0; node < thread2->m_NodeArray_Ptr->size(); node++) {
92  i = thread2->getNodeCoordX(node);
93  j = thread2->getNodeCoordY(node);
94  h = thread2->getNodeCoordZ(node);
95  auto address1 = reinterpret_cast<uintptr_t>(thread2->getNodePointer(node));
96  accessor2.setValue(xyz,address1);
97  }
98  }
99  // Propagation pointers arrangement
100  openvdb::CoordBBox its_bbox;
101  VDBGrid_Ptr->treePtr()->evalActiveVoxelBoundingBox(its_bbox);
102  auto Nx = its_bbox.dim().x();
103  auto Ny = its_bbox.dim().y();
104  auto Nz = its_bbox.dim().z();
105  auto minX = its_bbox.min().x();
106  auto maxX = its_bbox.max().x();
107  auto minY = its_bbox.min().y();
108  auto maxY = its_bbox.max().y();
109  auto minZ = its_bbox.min().z();
110  auto maxZ = its_bbox.max().z();
111 
112  // Set nodeForAutoThreading propagation pointers.
113  for (auto & thread : *ThreadArray_Ptr->m_ThreadsTable_Ptr) {
114  for (size_t node = 0; node < thread->m_NodeArray_Ptr->size(); node++) {
115  thread->getNodeRef(node).pMyThread_Ptr = &thread; // Thread pointer initialization
116  for (uint8_t ik = 0; ik < MFQ19_H ; ik++) {
117  auto direction = MF::GU::LatticeParametersD3Q19::SwapDirections[ik][0];
118  i = thread->getNodeCoordX(node) + MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cx[direction];
119  j = thread->getNodeCoordY(node) + MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cy[direction];
120  h = thread->getNodeCoordZ(node) + MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cz[direction];
121  auto value = accessor2.getValue(xyz);
122  if (value != 0) {
123  thread->setNodePtrInPropTable(node,ik, reinterpret_cast<Node *>(accessor2.getValue(xyz))); //Fluid nodeForAutoThreading pointer.
124  }
125  else if (thread->m_NodeType != 4 && thread->m_NodeType != 5) { //For nodes outside te boundary
126  thread->setNodePtrInPropTable(node,ik, nullptr);
127  }
128  else { //Propagation for periodic boundary nodes
129  if (i < minX)
130  i = i + Nx;
131  else if (i > maxX)
132  i = i - Nx;
133  if (j < minY)
134  j = j + Ny;
135  else if (j > maxY)
136  j = j - Ny;
137  if (h < minZ)
138  h = h + Nz;
139  else if (h > maxZ)
140  h = h - Nz;
141  value = accessor2.getValue(xyz);
142  if (value != 0) {
143  thread->setNodePtrInPropTable(node,ik, reinterpret_cast<Node *>(accessor2.getValue(xyz))); // Periodic nodeForAutoThreading pointer.
144  }
145  else {
146  std::cout << "Lack of consistence of periodic boundary " << thread->m_NodeType << " nodeForAutoThreading: " << " (" << i << "," << j << "," << h << ") " << std::endl;
147  exit(EXIT_FAILURE);
148  }
149  }
150  }
151  }
152  }
153  // Set second half nodeForAutoThreading propagation pointers.
154  for (auto & thread : *ThreadArray_Ptr->m_ThreadsTable_Ptr) {
155  for (size_t node = 0; node < thread->m_NodeArray_Ptr->size(); node++) {
156  for (uint8_t ik = 0; ik < MFQ19_H ; ik++) {
157  auto direction = MF::GU::LatticeParametersD3Q19::SwapDirections[ik][1];
158  i = thread->getNodeCoordX(node) + MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cx[direction];
159  j = thread->getNodeCoordY(node) + MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cy[direction];
160  h = thread->getNodeCoordZ(node) + MF::GU::LatticeParametersD3Q19::DirectionVectorComponent_Cz[direction];
161  auto value = accessor2.getValue(xyz);
162  if (value != 0) {
163  thread->setNodePtrInSecondPropTable(node,ik, reinterpret_cast<Node *>(accessor2.getValue(xyz))); //Fluid nodeForAutoThreading pointer.
164  }
165  else if (thread->m_NodeType != 4 && thread->m_NodeType != 5) { //For nodes outside te boundary
166  thread->setNodePtrInSecondPropTable(node, ik,nullptr);
167  }
168  else { //Propagation for periodic boundary nodes
169  if (i < minX)
170  i = i + Nx;
171  else if (i > maxX)
172  i = i - Nx;
173  if (j < minY)
174  j = j + Ny;
175  else if (j > maxY)
176  j = j - Ny;
177  if (h < minZ)
178  h = h + Nz;
179  else if (h > maxZ)
180  h = h - Nz;
181  value = accessor2.getValue(xyz);
182  if (value != 0) {
183  thread->setNodePtrInSecondPropTable(node,ik, reinterpret_cast<Node *>(accessor2.getValue(xyz))); // Periodic nodeForAutoThreading pointer.
184  }
185  else {
186  std::cout << "Lack of consistence of periodic boundary " << thread->m_NodeType << " nodeForAutoThreading: " << " (" << i << "," << j << "," << h << ") " << std::endl;
187  exit(EXIT_FAILURE);
188  }
189  }
190  }
191  }
192  }
193 }
struct MF::GB::NodeID::@0::@1 Node
A class that allows to determine the proper NodeID from combined nodeType, uidThreadNr, ThreadCount, ComponentNr and PhaseNr.
Definition: NodeID.h:18
static constexpr int8_t DirectionVectorComponent_Cx[MFQ27]
The x direction vector component of all D3Q19 lattice directions plus additional nodes of the Q27 lat...
static constexpr int8_t DirectionVectorComponent_Cy[MFQ27]
The y direction vector component of all D3Q19 lattice directions plus additional nodes of the Q27 lat...
static constexpr int8_t DirectionVectorComponent_Cz[MFQ27]
The z direction vector component of all D3Q19 lattice directions plus additional nodes of the Q27 lat...
uint64_t NodeID
Definition: NodeID.h:29
union MF::GB::NodeID::@0 node_id
#define MFQ19_H
Number of elements (linked directions) in propagation table for one node.
static constexpr uint8_t SwapDirections[MFQ19_H][2]
Indexes of swap directions of f(i) in D3Q19.

◆ ThreadPartitioning()

void MF::Database::AutoThreading::ThreadPartitioning ( const openvdb::Int64Grid::Ptr &  VDBGrid_Ptr,
const std::shared_ptr< MF::Database::ConfigData > &  ConfigData_Ptr 
)
static

MFThreads partitioning.

Definition at line 195 of file AutoThreading.cpp.

References MF::GB::NodeID::Node, MF::GB::NodeID::node_id, and MF::GB::NodeID::NodeID.

Referenced by main().

195  {
196 
197  uint32_t ThreadMaxSize {std::numeric_limits<uint32_t>::max()};
198  if (ConfigData_Ptr->getCaseIntParam("ThreadParams.MFThreadMaxSize") < std::numeric_limits<uint32_t>::max()
199  && ConfigData_Ptr->getCaseIntParam("ThreadParams.MFThreadMaxSize") != 0) {
200  ThreadMaxSize = ConfigData_Ptr->getCaseIntParam("ThreadParams.MFThreadMaxSize");
201  }
202 
203  struct nodeForAutoThreading {
204  uint64_t NodeEncodedID = 1;
205  uint64_t NodeNumber = 0;
206  };
207 
208  nodeForAutoThreading newNode;
209  auto NodeArray_Ptr = std::make_unique<std::vector<nodeForAutoThreading>>(1);
210  uint64_t nodeEID; // nodeForAutoThreading NodeID + uid-thread number+1 + ThreadCount + ComponentNr + PhaseNr.
211  MF::GB::NodeID nodeTMP;
212  unsigned char mark;
213 
214  //auto accessor = VDBGrid_Ptr->getAccessor();
215  openvdb::Coord xyz;
216  int32_t &i = xyz[0], &j = xyz[1], &h = xyz[2];
217  for (auto iter = VDBGrid_Ptr->beginValueOn(); iter; ++iter) {
218  mark = 0;
219  nodeEID = iter.getValue();
220  for (auto &it : *NodeArray_Ptr) {
221  if (it.NodeEncodedID == nodeEID) {
222  it.NodeNumber++;
223  mark++;
224  if (it.NodeNumber >= ThreadMaxSize && (uint32_t)(it.NodeNumber / ThreadMaxSize) < std::numeric_limits<uint16_t>::max()) {
225  nodeTMP.node_id.NodeID = nodeEID;
226  nodeTMP.node_id.Node.ThreadCount = (uint32_t)(it.NodeNumber / ThreadMaxSize);
227  iter.setValue(nodeTMP.node_id.NodeID);
228  } else if ((uint32_t)(it.NodeNumber / ThreadMaxSize) >= std::numeric_limits<uint16_t>::max()){ // Only 65535 MFThreads of the same type are allowed.
229  std::cout << "AutoThreading Error. Too many parts of MFThread: " << nodeEID << std::endl;
230  exit(EXIT_FAILURE);
231  }
232  }
233  }
234  if (mark == 0) {
235  newNode.NodeNumber = 1;
236  newNode.NodeEncodedID = nodeEID;
237  NodeArray_Ptr->push_back(newNode);
238 
239  } else if (mark > 1) {
240  std::cout << "AutoThreading Error" << std::endl;
241  exit(EXIT_FAILURE);
242  }
243  }
244  NodeArray_Ptr.reset();
245 }
struct MF::GB::NodeID::@0::@1 Node
A class that allows to determine the proper NodeID from combined nodeType, uidThreadNr, ThreadCount, ComponentNr and PhaseNr.
Definition: NodeID.h:18
uint64_t NodeID
Definition: NodeID.h:29
union MF::GB::NodeID::@0 node_id

The documentation for this class was generated from the following files: