20 #ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_UPWIND_GRADIENT_HPP
21 #define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_UPWIND_GRADIENT_HPP
27 #include "Grid/grid_dist_id.hpp"
28 #include "FD_simple.hpp"
29 #include "Eno_Weno.hpp"
39 template <
typename field_type>
40 static field_type
upwinding(field_type dplus, field_type dminus,
int sign)
42 field_type grad_upwind = 0.0;
44 && (dminus + dplus) * sign < 0) grad_upwind = dplus;
46 else if (dminus * sign > 0
47 && (dminus + dplus) * sign > 0) grad_upwind = dminus;
49 else if (dminus * sign < 0
50 && dplus * sign > 0) grad_upwind = 0;
61 template <
typename velocity_type>
74 template <
typename velocity_type>
94 template <
size_t Field,
size_t Velocity,
typename gr
idtype,
typename keytype>
99 typedef typename std::decay_t<decltype(
grid.template get<Field>(key))> field_type;
100 field_type dplus = 0.0, dminus = 0.0;
108 dplus = FD_forward<Field>(
grid, key, d);
109 dminus = FD_backward<Field>(
grid, key, d);
112 dplus = ENO_3_Plus<Field>(
grid, key, d);
113 dminus = ENO_3_Minus<Field>(
grid, key, d);
116 dplus = WENO_5_Plus<Field>(
grid, key, d);
117 dminus = WENO_5_Minus<Field>(
grid, key, d);
120 auto &v_cl = create_vcluster();
121 if (v_cl.rank() == 0) std::cout <<
"Order of accuracy chosen not valid. Using default order 1." <<
123 dplus = FD_forward<Field>(
grid, key, d);
124 dminus = FD_backward<Field>(
grid, key, d);
128 return upwinding(dplus, dminus, sign_velocity);
148 template <
size_t Field,
size_t Velocity,
size_t Gradient,
typename gr
idtype>
151 grid.template ghost_get<Field>(KEEP_PROPERTIES);
152 grid.template ghost_get<Velocity>(KEEP_PROPERTIES);
154 auto dom =
grid.getDomainIterator();
160 auto key = dom.get();
161 auto key_g =
grid.getGKey(key);
163 for(
size_t d = 0; d < gridtype::dims; d++ )
166 if (key_g.get(d) > 2 && key_g.get(d) <
grid.size(d) - 3)
169 grid.template get<Gradient> (key) [d] = FD_upwind<Field, Velocity>(
grid, key, d, order);
173 else if (key_g.get(d) > 0 && key_g.get(d) <
grid.size(d) - 1)
175 grid.template get<Gradient> (key) [d] = FD_upwind<Field, Velocity>(
grid, key, d, 1);
178 else if (key_g.get(d) == 0)
180 grid.template get<Gradient> (key) [d] = FD_forward<Field>(
grid, key, d);
183 else if (key_g.get(d) >=
grid.size(d) - 1)
185 grid.template get<Gradient> (key) [d] = FD_backward<Field>(
grid, key, d);
196 auto key = dom.get();
197 for(
size_t d = 0; d < gridtype::dims; d++)
199 grid.template get<Gradient> (key) [d] = FD_upwind<Field, Velocity>(
grid, key, d, order);
213 template <
typename gr
idtype>
216 auto ghost =
grid.getDecomposition().getGhost();
217 int np_ghost[gridtype::dims];
219 for (
int d = 0 ; d < gridtype::dims ; d++)
221 np_ghost[d] = ghost.getHigh(d) /
grid.getSpacing()[d];
224 int min_width = np_ghost[0];
225 for (
int d = 0 ; d < gridtype::dims ; d++)
227 if(np_ghost[d] < min_width) min_width = np_ghost[d];
230 return (min_width >= required_width);
241 template <
size_t Field_in,
size_t Velocity,
size_t Gradient_out,
typename gr
idtype>
244 grid.template ghost_get<Field_in>();
245 grid.template ghost_get<Velocity>();
249 auto &v_cl = create_vcluster();
250 if (v_cl.rank() == 0)
253 size_t stencil_width;
254 (order > 1) ? stencil_width = 3 : stencil_width = 1;
257 std::cout <<
"Error: Ghost layer not big enough. Either run with one_sided_BC=true or create a ghost "
258 "layer that has a width of least " << stencil_width <<
" grid node(s)" << std::endl;
269 upwind_gradient<Field_in, Velocity, Gradient_out>(
grid, one_sided_BC, order);
272 auto &v_cl = create_vcluster();
273 if (v_cl.rank() == 0) std::cout <<
"Order of accuracy chosen not valid. Using default order 1." <<
275 upwind_gradient<Field_in, Velocity, Gradient_out>(
grid, one_sided_BC, 1);
283 #endif //OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_UPWIND_GRADIENT_HPP