OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
Derivative.hpp
1 /*
2  * Derivative.hpp
3  *
4  * Created on: Oct 5, 2015
5  * Author: Pietro Incardona
6  */
7 
8 #ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_DERIVATIVE_HPP_
9 #define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_DERIVATIVE_HPP_
10 
11 
12 #include "util/mathutil.hpp"
13 #include "Vector/map_vector.hpp"
14 #include "Grid/comb.hpp"
15 #include "FiniteDifference/util/common.hpp"
16 #include "util/util_num.hpp"
17 #include <unordered_map>
18 #include "FD_util_include.hpp"
19 
27 template<unsigned int d, typename Field, typename Sys_eqs, unsigned int impl=CENTRAL>
28 class D
29 {
42  inline static void value(const grid_key_dx<Sys_eqs::dims> & pos, const grid_sm<Sys_eqs::dims,void> & gs, std::unordered_map<long int,typename Sys_eqs::stype > & cols, typename Sys_eqs::stype coeff)
43  {
44  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " only CENTRAL, FORWARD, BACKWARD derivative are defined";
45  }
46 
60  const grid_sm<Sys_eqs::dims,void> & gs,
61  const comb<Sys_eqs::dims> (& s_pos)[Sys_eqs::nvar])
62  {
63  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " only CENTRAL, FORWARD, BACKWARD derivative are defined";
64 
65  return pos;
66  }
67 };
68 
79 template<unsigned int d, typename arg, typename Sys_eqs>
80 class D<d,arg,Sys_eqs,CENTRAL>
81 {
82  public:
83 
100  const grid_sm<Sys_eqs::dims,void> & gs,
101  typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
102  std::unordered_map<long int,typename Sys_eqs::stype > & cols,
103  typename Sys_eqs::stype coeff)
104  {
105  // if the system is staggered the CENTRAL derivative is equivalent to a forward derivative
107  {
108  D<d,arg,Sys_eqs,BACKWARD>::value(g_map,kmap,gs,spacing,cols,coeff);
109  return;
110  }
111 
112  long int old_val = kmap.getKeyRef().get(d);
113  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) + 1);
114  arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]/2.0 );
115  kmap.getKeyRef().set_d(d,old_val);
116 
117 
118  old_val = kmap.getKeyRef().get(d);
119  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) - 1);
120  arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]/2.0 );
121  kmap.getKeyRef().set_d(d,old_val);
122  }
123 
124 
162  const grid_sm<Sys_eqs::dims,void> & gs,
163  const comb<Sys_eqs::dims> (& s_pos)[Sys_eqs::nvar])
164  {
165  auto arg_pos = arg::position(pos,gs,s_pos);
167  {
168  if (arg_pos.get(d) == -1)
169  {
170  arg_pos.set_d(d,0);
171  return arg_pos;
172  }
173  else
174  {
175  arg_pos.set_d(d,-1);
176  return arg_pos;
177  }
178  }
179 
180  return arg_pos;
181  }
182 };
183 
184 
205 template<unsigned int d, typename arg, typename Sys_eqs>
206 class D<d,arg,Sys_eqs,CENTRAL_B_ONE_SIDE>
207 {
208 public:
209 
226  const grid_sm<Sys_eqs::dims,void> & gs,
227  typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
228  std::unordered_map<long int,typename Sys_eqs::stype > & cols,
229  typename Sys_eqs::stype coeff)
230  {
231 #ifdef SE_CLASS1
232  if (Sys_eqs::boundary[d] == PERIODIC)
233  std::cerr << __FILE__ << ":" << __LINE__ << " error, it make no sense use one sided derivation with periodic boundary, please use CENTRAL\n";
234 #endif
235 
236  grid_key_dx<Sys_eqs::dims> pos = g_map.getGKey(kmap);
237 
238  if (pos.get(d) == (long int)gs.size(d)-1 )
239  {
240  arg::value(g_map,kmap,gs,spacing,cols,1.5*coeff/spacing[d]);
241 
242  long int old_val = kmap.getKeyRef().get(d);
243  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) - 1);
244  arg::value(g_map,kmap,gs,spacing,cols,-2.0*coeff/spacing[d]);
245  kmap.getKeyRef().set_d(d,old_val);
246 
247  old_val = kmap.getKeyRef().get(d);
248  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) - 2);
249  arg::value(g_map,kmap,gs,spacing,cols,0.5*coeff/spacing[d]);
250  kmap.getKeyRef().set_d(d,old_val);
251  }
252  else if (pos.get(d) == 0)
253  {
254  arg::value(g_map,kmap,gs,spacing,cols,-1.5*coeff/spacing[d]);
255 
256  long int old_val = kmap.getKeyRef().get(d);
257  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) + 1);
258  arg::value(g_map,kmap,gs,spacing,cols,2.0*coeff/spacing[d]);
259  kmap.getKeyRef().set_d(d,old_val);
260 
261  old_val = kmap.getKeyRef().get(d);
262  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) + 2);
263  arg::value(g_map,kmap,gs,spacing,cols,-0.5*coeff/spacing[d]);
264  kmap.getKeyRef().set_d(d,old_val);
265  }
266  else
267  {
268  long int old_val = kmap.getKeyRef().get(d);
269  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) + 1);
270  arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]);
271  kmap.getKeyRef().set_d(d,old_val);
272 
273  old_val = kmap.getKeyRef().get(d);
274  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) - 1);
275  arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]);
276  kmap.getKeyRef().set_d(d,old_val);
277  }
278  }
279 
311  {
312  return arg::position(pos,gs,s_pos);
313  }
314 };
315 
316 
327 template<unsigned int d, typename arg, typename Sys_eqs>
328 class D<d,arg,Sys_eqs,FORWARD>
329 {
330  public:
331 
348  const grid_sm<Sys_eqs::dims,void> & gs,
349  typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
350  std::unordered_map<long int,typename Sys_eqs::stype > & cols,
351  typename Sys_eqs::stype coeff)
352  {
353 
354  long int old_val = kmap.getKeyRef().get(d);
355  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) + 1);
356  arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]);
357  kmap.getKeyRef().set_d(d,old_val);
358 
359  // backward
360  arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]);
361  }
362 
363 
377  const grid_sm<Sys_eqs::dims,void> & gs,
378  const comb<Sys_eqs::dims> (& s_pos)[Sys_eqs::nvar])
379  {
380  return arg::position(pos,gs,s_pos);
381  }
382 };
383 
394 template<unsigned int d, typename arg, typename Sys_eqs>
395 class D<d,arg,Sys_eqs,BACKWARD>
396 {
397  public:
398 
415  const grid_sm<Sys_eqs::dims,void> & gs,
416  typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
417  std::unordered_map<long int,typename Sys_eqs::stype > & cols,
418  typename Sys_eqs::stype coeff)
419  {
420 
421  long int old_val = kmap.getKeyRef().get(d);
422  kmap.getKeyRef().set_d(d, kmap.getKeyRef().get(d) - 1);
423  arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]);
424  kmap.getKeyRef().set_d(d,old_val);
425 
426  // forward
427  arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]);
428  }
429 
430 
444  {
445  return arg::position(pos,gs,s_pos);
446  }
447 };
448 
449 #endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_DERIVATIVE_HPP_ */
Derivative second order on h (spacing)
Definition: Derivative.hpp:28
grid_key_dx< dim > & getKeyRef()
Get the reference key.
static void value(const typename stub_or_real< Sys_eqs, Sys_eqs::dims, typename Sys_eqs::stype, typename Sys_eqs::b_grid::decomposition::extended_type >::type &g_map, grid_dist_key_dx< Sys_eqs::dims > &kmap, const grid_sm< Sys_eqs::dims, void > &gs, typename Sys_eqs::stype(&spacing)[Sys_eqs::dims], std::unordered_map< long int, typename Sys_eqs::stype > &cols, typename Sys_eqs::stype coeff)
Calculate which colums of the Matrix are non zero.
Definition: Derivative.hpp:346
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
Grid key for a distributed grid.
static grid_key_dx< Sys_eqs::dims > position(grid_key_dx< Sys_eqs::dims > &pos, const grid_sm< Sys_eqs::dims, void > &gs, const comb< Sys_eqs::dims >(&s_pos)[Sys_eqs::nvar])
Calculate the position where the derivative is calculated.
Definition: Derivative.hpp:310
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
static grid_key_dx< Sys_eqs::dims > position(grid_key_dx< Sys_eqs::dims > &pos, const grid_sm< Sys_eqs::dims, void > &gs, const comb< Sys_eqs::dims >(&s_pos)[Sys_eqs::nvar])
Calculate the position where the derivative is calculated.
Definition: Derivative.hpp:59
static grid_key_dx< Sys_eqs::dims > position(grid_key_dx< Sys_eqs::dims > &pos, const grid_sm< Sys_eqs::dims, void > &gs, const comb< Sys_eqs::dims >(&s_pos)[Sys_eqs::nvar])
Calculate the position where the derivative is calculated.
Definition: Derivative.hpp:376
static void value(const typename stub_or_real< Sys_eqs, Sys_eqs::dims, typename Sys_eqs::stype, typename Sys_eqs::b_grid::decomposition::extended_type >::type &g_map, grid_dist_key_dx< Sys_eqs::dims > &kmap, const grid_sm< Sys_eqs::dims, void > &gs, typename Sys_eqs::stype(&spacing)[Sys_eqs::dims], std::unordered_map< long int, typename Sys_eqs::stype > &cols, typename Sys_eqs::stype coeff)
Calculate which colums of the Matrix are non zero.
Definition: Derivative.hpp:413
is_grid_staggered analyse T if it has a property grid_type defined and indicate that the grid is stag...
Definition: common.hpp:42
static void value(const typename stub_or_real< Sys_eqs, Sys_eqs::dims, typename Sys_eqs::stype, typename Sys_eqs::b_grid::decomposition::extended_type >::type &g_map, grid_dist_key_dx< Sys_eqs::dims > &kmap, const grid_sm< Sys_eqs::dims, void > &gs, typename Sys_eqs::stype(&spacing)[Sys_eqs::dims], std::unordered_map< long int, typename Sys_eqs::stype > &cols, typename Sys_eqs::stype coeff)
Calculate which colums of the Matrix are non zero.
Definition: Derivative.hpp:224
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &key) const
Return the global key.
static void value(const grid_key_dx< Sys_eqs::dims > &pos, const grid_sm< Sys_eqs::dims, void > &gs, std::unordered_map< long int, typename Sys_eqs::stype > &cols, typename Sys_eqs::stype coeff)
Calculate which colums of the Matrix are non zero.
Definition: Derivative.hpp:42
static void value(const typename stub_or_real< Sys_eqs, Sys_eqs::dims, typename Sys_eqs::stype, typename Sys_eqs::b_grid::decomposition::extended_type >::type &g_map, grid_dist_key_dx< Sys_eqs::dims > &kmap, const grid_sm< Sys_eqs::dims, void > &gs, typename Sys_eqs::stype(&spacing)[Sys_eqs::dims], std::unordered_map< long int, typename Sys_eqs::stype > &cols, typename Sys_eqs::stype coeff)
Calculate which colums of the Matrix are non zero.
Definition: Derivative.hpp:98
static grid_key_dx< Sys_eqs::dims > position(grid_key_dx< Sys_eqs::dims > &pos, const grid_sm< Sys_eqs::dims, void > &gs, const comb< Sys_eqs::dims >(&s_pos)[Sys_eqs::nvar])
Calculate the position where the derivative is calculated.
Definition: Derivative.hpp:443
static grid_key_dx< Sys_eqs::dims > position(grid_key_dx< Sys_eqs::dims > &pos, const grid_sm< Sys_eqs::dims, void > &gs, const comb< Sys_eqs::dims >(&s_pos)[Sys_eqs::nvar])
Calculate the position where the derivative is calculated.
Definition: Derivative.hpp:161