OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
10template <typename T>
11static 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
19template <size_t PHI_SDF_ECS_FULL, size_t PHI_SDF_ECS_SPARSE, typename grid_type, typename sparse_in_type, typename T>
20void 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
40template <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>
41void 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
71template <
72size_t PHI_SDF_ECS_FULL,
73size_t PHI_SDF_SHELL_FULL,
74size_t PHI_SDF_ECS_SPARSE,
75size_t PHI_SDF_SHELL_SPARSE,
76typename grid_type,
77typename sparse_in_type,
78typename T>
79void 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
119template <typename point_type, typename y_margin_type>
120auto distance_from_margin(point_type & coord, y_margin_type y_margin)
121{
122 return(coord.get(1) - y_margin);
123}
124
125template <typename point_type, typename y_margin_type, typename width_type>
126bool 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
132template <typename T>
133static 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
140template <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>
141void 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();
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
182template <
183size_t PHI_SDF_ECS_SPARSE,
184size_t PHI_SDF_SHELL_SPARSE,
185size_t K_SOURCE,
186size_t K_SINK,
187typename grid_type,
188typename y_margin_type,
189typename width_type,
190typename k_type,
191typename boundary_type>
192void 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();
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
238template <size_t PHI_SDF, size_t K_SOURCE, size_t K_SINK, typename grid_type, typename coord_type, typename k_type>
239void 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)