CellModules
DiffusionGrid.hpp
Go to the documentation of this file.
1#ifndef ONKO3D_3_0_DIFFUSIONGRID_HPP
2#define ONKO3D_3_0_DIFFUSIONGRID_HPP
3
11#include <vector>
12#include <typeindex>
13#include <typeinfo>
14#include <unordered_map>
16
21namespace Diffusion2D {
22
27 struct Molecule {
32 Molecule(double dc, double dq, double de)
34 {}
35 };
36
41 struct GridCell {
49 inline GridCell() = default;
50
56 int size = m.size();
57 quantities.resize(size);
59 consumptions.assign(size, 0.);
60 for (int i = 0; i < size; ++i) {
61 quantities[i] = m[i].defaultQuantity;
62 prevQuantities[i] = m[i].defaultQuantity;
63 }
64 }
65 };
66
72 private:
76 bool toreX = true;
77 bool toreY = true;
79 int height = 10;
80 int width = 10;
81
85 void preStep() {
86 for (int i = 0; i < grid.size(); ++i) {
87 for (int j = 0; j < grid.size(); ++j) {
88 for(int m = 0; m < molecules.size(); ++m){
89 grid[i][j].prevQuantities[m] = grid[i][j].quantities[m];
90 grid[i][j].quantities[m] = 0.;
91 grid[i][j].consumptions[m] = 0.;
92 }
93 }
94 }
95 }
96
103 void diffuse(int x, int y){
104 GridCell &gc = grid[x][y];
105 int nbNeighbors = 8;
106 for (int i = -1; i <= 1; ++i) {
107 for (int j = -1; j <= 1; ++j) {
108 if(i != 0 || j != 0){
109 int xi = x + i;
110 int yj = y + j;
111 if (toreX && toreY) {
112 if(xi < 0) xi = width -1;
113 if(xi >= width) xi = 0;
114 if(yj < 0) yj = height -1;
115 if(yj >= height) yj = 0;
116 for(int m = 0; m < molecules.size(); ++m){
117 gc.quantities[m] += 1./8. * molecules[m].diffusionCoef * grid[xi][yj].prevQuantities[m];
118 }
119 }else if(toreX){
120 if(xi < 0) xi = width -1;
121 if(xi >= width) xi = 0;
122 if(yj >= 0 && yj < height){
123 for(int m = 0; m < molecules.size(); ++m){
124 gc.quantities[m] += 1./8. * molecules[m].diffusionCoef * grid[xi][yj].prevQuantities[m];
125 }
126 }else nbNeighbors --;
127 }else if(toreY){
128 if(yj < 0) yj = height -1;
129 if(yj >= height) yj = 0;
130 if(xi >= 0 && xi < width){
131 for(int m = 0; m < molecules.size(); ++m){
132 gc.quantities[m] += 1./8. * molecules[m].diffusionCoef * grid[xi][yj].prevQuantities[m];
133 }
134 }else nbNeighbors --;
135 }else{
136 if(xi >= 0 && xi < width && yj >= 0 && yj < height){
137 for(int m = 0; m < molecules.size(); ++m){
138 gc.quantities[m] += 1./8. * molecules[m].diffusionCoef * grid[xi][yj].prevQuantities[m];
139 }
140 }
141 else nbNeighbors --;
142 }
143 }
144 }
145 }
146 for(int m = 0; m < molecules.size(); ++m){
147 gc.quantities[m] += gc.prevQuantities[m] * (1. - molecules[m].diffusionCoef) + (8-nbNeighbors)/8. *molecules[m].diffusionCoef*gc.prevQuantities[m] - molecules[m].defaultEvaporation - gc.consumptions[m];
148 if (gc.quantities[m] < 0.) { //can't have a negative amount of molecule
149 gc.quantities[m] = 0.;
150 }
151 }
152 }
153
157 void computeStep() {
158 for (int i = 0; i < width; ++i) {
159 for (int j = 0; j < height; ++j) { //for each cell in the grid
160 diffuse(i,j);
161 }
162 }
163 }
164
171 template<typename world_t>
172 void updateConsumptions(world_t *w){
173 for(auto cell : w->cells){
174 int x = cell->getBody().get2DPosition().x();
175 int y = cell->getBody().get2DPosition().y();
176 for(int m = 0; m < molecules.size(); ++m){
177 grid[x][y].consumptions[m] += cell->getBody().getConsumptions()[m];
178 }
179 }
180 }
181
182 public:
183
184 std::unordered_map<int,int> moleculesDict;
185
186 DiffusionGrid() = default;
187
193 inline void setToreX(bool b) { toreX = b; }
194
200 inline void setToreY(bool b) { toreY = b; }
201
208 inline void setTore(bool x, bool y) { toreX = x; toreY = y; }
209
218 inline double getMolecule(int x, int y, int m) { return(grid[x][y].quantities[moleculesDict[m]]); }
219
224 inline int getWidth() const { return width; }
225
230 inline int getHeight() const { return height; }
231
237
243
250 void addMolecule(int id, Molecule m) {
251 moleculesDict[id] = (int) molecules.size();
252 molecules.push_back(m);
253 }
254
261 void initGrid(int w, int h){
262 grid.resize(w);
263 for(int i = 0; i < w; ++i){
264 grid[i].resize(h);
265 for(int j = 0; j < h; ++j){
266 grid[i][j] = GridCell(molecules);
267 }
268 }
269 height = h;
270 width = w;
271 }
272
278 void initGrid(int size) { initGrid(size, size); }
279
286 template<typename world_t>
287 void computeMolecules(world_t *w) {
288 preStep();
290 computeStep();
291 }
292 };
293}
294
295#endif //ONKO3D_3_0_DIFFUSIONGRID_HPP
Manages a grid of molecules for diffusion.
std::vector< std::vector< GridCell > > & getGrid()
Gets the grid.
std::vector< Molecule > getMolecules() const
Gets the molecules in the grid.
void initGrid(int size)
Initializes the square grid.
void initGrid(int w, int h)
Initializes the grid with dimensions.
double getMolecule(int x, int y, int m)
Gets the quantity of a molecule at a specific position.
int getWidth() const
Gets the width of the grid.
void setToreX(bool b)
Sets the toroidal property on the x-axis.
int getHeight() const
Gets the height of the grid.
std::unordered_map< int, int > moleculesDict
void diffuse(int x, int y)
Applies diffusion to the molecule at position (x, y).
std::vector< std::vector< GridCell > > grid
void updateConsumptions(world_t *w)
Updates the consumptions for each cell.
void setToreY(bool b)
Sets the toroidal property on the y-axis.
void preStep()
Initializes cells for the next step.
std::vector< Molecule > molecules
void computeStep()
Updates the quantity of molecules for each cell.
void setTore(bool x, bool y)
Sets the toroidal properties on both axes.
void addMolecule(int id, Molecule m)
Adds a molecule to the grid.
void computeMolecules(world_t *w)
Computes the quantities of molecules in the grid.
void resize(size_t newSize)
Resizes the vector to contain the specified number of elements.
Definition: std.hpp:397
size_t size() const
Returns the number of elements in the vector.
Definition: std.hpp:354
Namespace for 2D diffusion-related classes and functions.
Represents a cell in the diffusion grid.
GridCell(std::vector< Molecule > m)
Constructor with existing molecules.
std::vector< double > quantities
std::vector< double > prevQuantities
GridCell()=default
Default constructor.
std::vector< double > consumptions
Represents a molecule with diffusion properties.
Molecule(double dc, double dq, double de)