OpenFPM  5.2.0
Project that contain the implementation of distributed structures
DiffusionSpace_sparseGrid.hpp
1 //
2 // Created by jstark on 28.09.21.
3 //
4 
5 #ifndef SPARSEGRID_DIFFUSIONSPACE_SPARSEGRID_HPP
6 #define SPARSEGRID_DIFFUSIONSPACE_SPARSEGRID_HPP
7 
8 #include "math.h"
9 
10 template <typename T>
11 static bool is_diffusionSpace(const T & phi_sdf, const T & lower_bound, const T & upper_bound)
12 {
13  const T EPSILON = std::numeric_limits<T>::epsilon();
14  const T _b_low = lower_bound + EPSILON;
15  const T _b_up = upper_bound - EPSILON;
16  return (phi_sdf > _b_low && phi_sdf < _b_up);
17 }
18 
19 template <size_t PHI_SDF_ECS_FULL, size_t PHI_SDF_ECS_SPARSE, typename grid_type, typename sparse_in_type, typename T>
20 void get_diffusion_domain_sparse_grid(grid_type & grid,
21  sparse_in_type & sparse_grid,
22  const T b_low,
23  const T b_up)
24 {
25  auto dom = grid.getDomainIterator();
26  while(dom.isNext())
27  {
28  auto key = dom.get();
29  if(is_diffusionSpace(grid.template get<PHI_SDF_ECS_FULL>(key), b_low, b_up))
30  {
31  sparse_grid.template insertFlush<PHI_SDF_ECS_SPARSE>(key) = grid.template get<PHI_SDF_ECS_FULL>(key);
32  }
33  ++dom;
34  }
35  // Mapping?
36  // Load Balancing?
37 }
38 
39 #if 0
40 template <size_t PHI_SDF_ECS_FULL, size_t PHI_SDF_ECS_SPARSE, typename grid_type, typename grid_type_upscale, typename sparse_in_type, typename T>
41 void get_diffusion_domain_sparse_grid_upscale(grid_type & grid,
42  grid_type_upscale & grid_upscale,
43  sparse_in_type & sparse_grid,
44  const int upscale_factor, // total upscale factor that is product all dimensions, e.g. 2^3 = 8
45  const T b_low,
46  const T b_up)
47 {
48  auto dom = grid.getDomainIterator();
49  auto dom_upscale = grid_upscale.getDomainIterator();
50  while(dom.isNext())
51  {
52  auto key = dom.get();
53  auto key_upscale = dom_upscale.get();
54 
55  for(int i = 0, i < upscale_factor, ++i) // Place upscale number of points for each key
56  {
57  if(is_diffusionSpace(grid.template get<PHI_SDF_ECS_FULL>(key), b_low, b_up))
58  {
59  sparse_grid.template insertFlush<PHI_SDF_ECS_SPARSE>(key_upscale) = grid.template get<PHI_SDF_ECS_FULL>(key);
60  }
61  ++dom_upscale
62  }
63 
64 
65  ++dom;
66  }
67 
68 }
69 #endif
70 
71 template <
72 size_t PHI_SDF_ECS_FULL,
73 size_t PHI_SDF_SHELL_FULL,
74 size_t PHI_SDF_ECS_SPARSE,
75 size_t PHI_SDF_SHELL_SPARSE,
76 typename grid_type,
77 typename sparse_in_type,
78 typename T>
79 void get_diffusion_domain_sparse_grid_with_shell(grid_type & grid_ecs,
80  grid_type & grid_shell,
81  sparse_in_type & sparse_grid,
82  const T b_low,
83  const T b_up)
84 {
85  auto dom = grid_ecs.getDomainIterator();
86  while(dom.isNext())
87  {
88  auto key = dom.get();
89  if(is_diffusionSpace(grid_ecs.template get<PHI_SDF_ECS_FULL>(key), b_low, b_up))
90  {
91  sparse_grid.template insertFlush<PHI_SDF_ECS_SPARSE>(key) = grid_ecs.template get<PHI_SDF_ECS_FULL>(key);
92  sparse_grid.template insertFlush<PHI_SDF_SHELL_SPARSE>(key) = grid_shell.template get<PHI_SDF_SHELL_FULL>(key);
93  }
94  ++dom;
95  }
96 }
97 
98 
99 #if 0
100 // Init c0
101  auto dom = g_sparse.getDomainIterator();
102  while(dom.isNext())
103  {
104  auto key = dom.get();
105  if (g_sparse.template getProp<PHI_SDF>(key) < 4 * g_sparse.spacing(x))
106  {
107  g_sparse.template getProp<CONC_N>(key) =
108  (1 - 0.25 * g_sparse.template getProp<PHI_SDF>(key)) / g_sparse.spacing(x);
109  }
110  ++dom;
111  }
112  if(v_cl.rank() == 0) std::cout << "Initialized grid with smoothed c0 at the boundary." << std::endl;
113  g_sparse.write(path_output + "g_init", FORMAT_BINARY);
114 #endif
115 
116 
117 
118 
119 template <typename point_type, typename y_margin_type>
120 auto distance_from_margin(point_type & coord, y_margin_type y_margin)
121 {
122  return(coord.get(1) - y_margin);
123 }
124 
125 template <typename point_type, typename y_margin_type, typename width_type>
126 bool is_source(point_type & coord, y_margin_type y_margin, width_type width_source)
127 {
128  return (coord.get(1) >= y_margin
129  && distance_from_margin(coord, y_margin) <= width_source);
130 }
131 
132 template <typename T>
133 static bool is_inner_surface(const T & phi_sdf, const T & lower_bound)
134 {
135  const T EPSILON = std::numeric_limits<T>::epsilon();
136  const T _b_low = lower_bound + EPSILON;
137  return (phi_sdf > _b_low);
138 }
139 
140 template <size_t PHI_SDF, size_t K_SOURCE, size_t K_SINK, typename grid_type, typename y_margin_type, typename width_type, typename k_type>
141 void init_reactionTerms(grid_type & grid,
142  width_type width_source,
143  y_margin_type y_margin,
144  k_type k_source,
145  k_type k_sink,
146  int no_membrane_points=4)
147 {
148  /*
149  * Setting the reaction terms according to their distance from the margin of the blastoderm along the dorsal-ventral axis
150  *
151  * */
152 
153  auto dom = grid.getDomainIterator();
154  while(dom.isNext())
155  {
156  auto key = dom.get();
157  Point<grid_type::dims, y_margin_type> coord = grid.getPos(key);
158 
159  if(grid.template get<PHI_SDF>(key) < no_membrane_points * grid.spacing(0)) // If point lies close to the cell surface
160  {
161  if(is_source(coord, y_margin, width_source)) // If point lies within width_source distance from the margin, set k_source
162  {
163  grid.template insertFlush<K_SOURCE>(key) = k_source;
164  }
165  else
166  {
167  grid.template insertFlush<K_SOURCE>(key) = 0.0; // If membrane point not in source, emission is zero
168  }
169  grid.template insertFlush<K_SINK>(key) = k_sink; // Have sink at all membranes
170 
171  }
172 
173  else // For the nodes that are further away from the membrane, set both reaction terms to zero
174  {
175  grid.template insertFlush<K_SOURCE>(key) = 0.0;
176  grid.template insertFlush<K_SINK>(key) = 0.0;
177  }
178  ++dom;
179  }
180 }
181 
182 template <
183 size_t PHI_SDF_ECS_SPARSE,
184 size_t PHI_SDF_SHELL_SPARSE,
185 size_t K_SOURCE,
186 size_t K_SINK,
187 typename grid_type,
188 typename y_margin_type,
189 typename width_type,
190 typename k_type,
191 typename boundary_type>
192 void init_reactionTerms_with_shell(grid_type & grid,
193  width_type width_source,
194  y_margin_type y_margin,
195  k_type k_source,
196  k_type k_sink,
197  boundary_type b_low_shell,
198  int no_membrane_points=4)
199 {
200  /*
201  * Setting the reaction terms according to their distance from the margin of the blastoderm along the dorsal-ventral axis
202  *
203  * */
204 
205  auto dom = grid.getDomainIterator();
206  while(dom.isNext())
207  {
208  auto key = dom.get();
209  Point<grid_type::dims, y_margin_type> coord = grid.getPos(key);
210 
211  if(
212  grid.template get<PHI_SDF_ECS_SPARSE>(key) < no_membrane_points * grid.spacing(0) // If point is a surface point
213  && is_inner_surface(grid.template get<PHI_SDF_SHELL_SPARSE>(key), b_low_shell) // and this surface is not towards the yolk or EVL
214  )
215  {
216  if(is_source(coord, y_margin, width_source)) // If point lies within width_source distance from the margin, set k_source
217  {
218  grid.template insertFlush<K_SOURCE>(key) = k_source;
219  }
220  else
221  {
222  grid.template insertFlush<K_SOURCE>(key) = 0.0; // If membrane point not in source, emission is zero
223  }
224  grid.template insertFlush<K_SINK>(key) = k_sink; // Have sink at all membranes
225 
226  }
227 
228  else // For the nodes that are further away from the membrane or belong to the outer surface, set both reaction terms to zero
229  {
230  grid.template insertFlush<K_SOURCE>(key) = 0.0;
231  grid.template insertFlush<K_SINK>(key) = 0.0;
232  }
233  ++dom;
234  }
235 }
236 
237 
238 template <size_t PHI_SDF, size_t K_SOURCE, size_t K_SINK, typename grid_type, typename coord_type, typename k_type>
239 void init_reactionTerms_smoothed(grid_type & grid,
240  coord_type y_start,
241  coord_type y_peak,
242  coord_type y_stop,
243  k_type k_source,
244  k_type k_sink,
245  coord_type no_membrane_points=4,
246  coord_type smoothing=0.25)
247 {
248  /*
249  * Setting the reaction terms according to the position along the animal-vegetal axis = y-axis
250  *
251  * */
252  const int x = 0;
253  const int y = 1;
254  const int z = 2;
255 
256  auto dom = grid.getDomainIterator();
257  while(dom.isNext())
258  {
259  auto key = dom.get();
260  Point<grid_type::dims, coord_type> coord = grid.getPos(key);
261 // k_type sdf_based_smoothing = (1 - smoothing * grid.template getProp<PHI_SDF>(key)) / grid.spacing(x);
262  k_type sdf_based_smoothing = 1.0;
263  if(grid.template get<PHI_SDF>(key) < no_membrane_points * grid.spacing(0)) // If grid node lies close to the
264  // membrane
265  {
266  // If membrane on animal side of the peak, emission strength increases with y
267  if (coord[y] > y_start
268  && coord[y] < y_peak + std::numeric_limits<coord_type>::epsilon())
269  {
270  grid.template insertFlush<K_SOURCE>(key) = k_source * (coord[y] - y_start) * sdf_based_smoothing;
271  }
272  // Else if membrane on vegetal side of the peak, emission strength decreases with y as moving towards the
273  // boundary to the yolk
274  else if (coord[y] >= y_peak - std::numeric_limits<coord_type>::epsilon()
275  && coord[y] < y_stop - std::numeric_limits<coord_type>::epsilon())
276  {
277  grid.template insertFlush<K_SOURCE>(key) = k_source * (y_stop - coord[y]) * sdf_based_smoothing;
278  }
279  // Else source is zero
280  else grid.template insertFlush<K_SOURCE>(key) = 0.0;
281  grid.template insertFlush<K_SINK>(key) = k_sink; // Have sink at all membranes
282  }
283 
284  else // For the nodes that are further away from the membrane, set the reaction terms to zero
285  {
286  grid.template insertFlush<K_SOURCE>(key) = 0.0;
287  grid.template insertFlush<K_SINK>(key) = 0.0;
288  }
289  ++dom;
290  }
291 }
292 
293 
294 
295 #endif //SPARSEGRID_DIFFUSIONSPACE_SPARSEGRID_HPP
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
This is a distributed grid.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)