CellModules
DiffusionGrid.hpp
Go to the documentation of this file.
1#ifndef ONKO3D_3_0_DIFFUSIONGRID_HPP
2#define ONKO3D_3_0_DIFFUSIONGRID_HPP
10#include <vector>
11#include <typeindex>
12#include <typeinfo>
13#include <unordered_map>
15
16
17
21namespace Diffusion2D {
25 struct Molecule {
30 Molecule(double dc, double dq, double de)
32 {}
33 };
34
35
36
40 struct GridCell {
48 inline GridCell() = default;
49
55 int size = m.size();
56 quantities.resize(size);
58 consumptions.assign(size, 0.);
59 for (int i = 0; i < size; ++i) {
60 quantities[i] = m[i].defaultQuantity;
61 prevQuantities[i] = m[i].defaultQuantity;
62 }
63 }
64 };
65
71 private:
75 bool toreX = true;
76 bool toreY = true;
78 int height = 10;
79 int width = 10;
80
84 void preStep() {
85 for (int i = 0; i < grid.size(); ++i) {
86 for (int j = 0; j < grid.size(); ++j) {
87 for(int m = 0; m < molecules.size(); ++m){
88 grid[i][j].prevQuantities[m] = grid[i][j].quantities[m];
89 grid[i][j].quantities[m] = 0.;
90 grid[i][j].consumptions[m] = 0.;
91 }
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
159 void computeStep() {
160 for (int i = 0; i < grid.size(); ++i) {
161 for (int j = 0; j < grid.size(); ++j) { //for each cell in the grid
162 diffuse(i,j);
163 }
164 }
165 }
166
173 template<typename world_t>
174 void updateConsumptions(world_t *w){
175 for(auto cell : w->cells){
176 int x = cell->getBody().get2DPosition().x();
177 int y = cell->getBody().get2DPosition().y();
178 for(int m = 0; m < molecules.size(); ++m){
179 grid[x][y].consumptions[m] += cell->getBody().getConsumptions()[m];
180 }
181 }
182 }
183
184 public:
185
186 unordered_map<int,int> moleculesDict;
187
188 DiffusionGrid() = default;
189
195 inline void setToreX(bool b) { toreX = b; }
196
202 inline void setToreY(bool b) { toreY = b; }
203
204
211 inline void setTore(bool x, bool y) {toreX = x; toreY = y;}
212
220 inline double getMolecule(int x, int y, int m) {return(grid[x][y].quantities[moleculesDict[m]]);}
221
226 inline int getWidth() const { return width; };
227
232 inline int getHeight() const { return height; };
233
238 inline vector<vector<GridCell>> &getGrid() { return grid; }
239
244 inline vector<Molecule> getMolecules() const { return molecules; }
245
251 void addMolecule(int n, Molecule m) {
252 moleculesDict[n] = (int) molecules.size();
253 molecules.push_back(m);
254 }
255
262 void initGrid(int w, int h){
263 grid.resize(w);
264 for(int i = 0; i < w; ++i){
265 grid[i].resize(h);
266 for(int j = 0; j < h; ++j){
267 grid[i][j] = GridCell(molecules);
268 }
269 }
270 height = h;
271 width = w;
272 }
273
279 void initGrid(int size) { initGrid(size, size); }
280
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
molecules grid based class
void initGrid(int size)
square grid initializer
void initGrid(int w, int h)
grid initializer
vector< Molecule > molecules
double getMolecule(int x, int y, int m)
molecule quantity getter
unordered_map< int, int > moleculesDict
int getWidth() const
grid's width getter
void setToreX(bool b)
toreX setter
void addMolecule(int n, Molecule m)
molecule adder
int getHeight() const
grid's height getter
vector< Molecule > getMolecules() const
molecules getter
void diffuse(int x, int y)
apply diffusion to the molecule m at position (x,y)
vector< vector< GridCell > > & getGrid()
grid getter
void updateConsumptions(world_t *w)
consumptions updater
void setToreY(bool b)
toreY setter
void preStep()
next step cells initializer
void computeStep()
molecules updater
void setTore(bool x, bool y)
tore setter
void computeMolecules(world_t *w)
molecules quantities updater
vector< vector< GridCell > > grid
void resize(size_t newSize)
Resizes the vector to contain the specified number of elements.
Definition: std.hpp:363
size_t size() const
Returns the number of elements in the vector.
Definition: std.hpp:320
GridCell(vector< Molecule > m)
constructor
vector< double > consumptions
vector< double > prevQuantities
GridCell()=default
default constructor
vector< double > quantities
Molecule(double dc, double dq, double de)