OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
FD_simple.hpp
1 //
2 // Created by jstark on 17.05.21.
3 //
4 #ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FD_SIMPLE_HPP
5 #define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FD_SIMPLE_HPP
6 
7 // Include OpenFPM header files
8 #include "Grid/grid_dist_id.hpp"
9 
20 template <size_t Field, typename gridtype, typename keytype>
21 auto FD_forward(gridtype & grid, keytype & key, size_t d)
22 {
23  return (grid.template get<Field> (key.move(d, 1)) - grid.template get<Field> (key)) / grid.getSpacing()[d];
24 }
35 template <size_t Field, typename gridtype, typename keytype>
36 auto FD_backward(gridtype & grid, keytype & key, size_t d)
37 {
38  return (grid.template get<Field> (key) - grid.template get<Field> (key.move(d, -1))) / grid.getSpacing()[d];
39 }
40 
41 
52 template <size_t Field, typename gridtype, typename keytype>
53 auto FD_central(gridtype & grid, keytype & key, size_t d)
54 {
55  return (grid.template get<Field>(key.move(d, 1))
56  - grid.template get<Field>(key.move(d, -1)))
57  / (2 * grid.getSpacing()[d]);
58 }
59 
69 template <size_t Field, size_t Gradient, typename gridtype>
70 void get_central_FD_grid(gridtype & grid, const bool one_sided_BC)
71 {
72  grid.template ghost_get<Field>(KEEP_PROPERTIES);
73  auto dom = grid.getDomainIterator();
74  if (one_sided_BC)
75  {
76  while (dom.isNext())
77  {
78  auto key = dom.get();
79  auto key_g = grid.getGKey(key);
80  for(size_t d = 0; d < gridtype::dims; d++)
81  {
82  // Grid nodes inside and distance from boundary > stencil-width
83  if (key_g.get(d) > 0 && key_g.get(d) < grid.size(d) - 1) // if point lays with min. 1 nodes distance to
84  // boundary
85  {
86  grid.template get<Gradient> (key) [d] = FD_central<Field>(grid, key, d);
87  }
88  else if (key_g.get(d) == 0) // if point lays at left boundary, use right sided kernel
89  {
90  grid.template get<Gradient> (key) [d] = FD_forward<Field>(grid, key, d);
91  }
92  else if (key_g.get(d) >= grid.size(d) - 1) // if point lays at right boundary, use left sided kernel
93  {
94  grid.template get<Gradient> (key) [d] = FD_backward<Field>(grid, key, d);
95  }
96  }
97  ++dom;
98  }
99  }
100  else
101  {
102  while (dom.isNext())
103  {
104  auto key = dom.get();
105  for(size_t d = 0; d < gridtype::dims; d++)
106  {
107  grid.template get<Gradient> (key) [d] = FD_central<Field>(grid, key, d);
108  }
109  ++dom;
110  }
111  }
112 }
113 
114 
115 #endif //OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FD_SIMPLE_HPP
116