OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
27template<unsigned int d, typename Field, typename Sys_eqs, unsigned int impl=CENTRAL>
28class 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
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
79template<unsigned int d, typename arg, typename Sys_eqs>
80class D<d,arg,Sys_eqs,CENTRAL>
81{
82 public:
83
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
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
205template<unsigned int d, typename arg, typename Sys_eqs>
206class D<d,arg,Sys_eqs,CENTRAL_B_ONE_SIDE>
207{
208public:
209
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
327template<unsigned int d, typename arg, typename Sys_eqs>
328class D<d,arg,Sys_eqs,FORWARD>
329{
330 public:
331
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
378 const comb<Sys_eqs::dims> (& s_pos)[Sys_eqs::nvar])
379 {
380 return arg::position(pos,gs,s_pos);
381 }
382};
383
394template<unsigned int d, typename arg, typename Sys_eqs>
395class D<d,arg,Sys_eqs,BACKWARD>
396{
397 public:
398
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_ */
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.
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.
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.
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.
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.
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.
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.
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.
Derivative second order on h (spacing)
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.
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.
Grid key for a distributed grid.
base_key & getKeyRef()
Get the reference key.
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &key) const
Return the global key.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition grid_key.hpp:503
Declaration grid_sm.
Definition grid_sm.hpp:167
__device__ __host__ size_t size() const
Return the size of the grid.
Definition grid_sm.hpp:657
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition comb.hpp:35
is_grid_staggered analyse T if it has a property grid_type defined and indicate that the grid is stag...
Definition common.hpp:45