8#ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_DERIVATIVE_HPP_ 
    9#define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_DERIVATIVE_HPP_ 
   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" 
   27template<
unsigned int d, 
typename Field, 
typename Sys_eqs, 
unsigned int impl=CENTRAL>
 
   44        std::cerr << 
"Error " << __FILE__ << 
":" << __LINE__ << 
" only CENTRAL, FORWARD, BACKWARD derivative are defined";
 
   63        std::cerr << 
"Error " << __FILE__ << 
":" << __LINE__ << 
" only CENTRAL, FORWARD, BACKWARD derivative are defined";
 
   79template<
unsigned int d, 
typename arg, 
typename Sys_eqs>
 
   80class D<d,arg,Sys_eqs,CENTRAL>
 
  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)
 
  112        long int old_val = kmap.
getKeyRef().get(d);
 
  114        arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]/2.0 );
 
  120        arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]/2.0 );
 
  165        auto arg_pos = arg::position(pos,gs,s_pos);
 
  168            if (arg_pos.get(d) == -1)
 
  205template<
unsigned int d, 
typename arg, 
typename Sys_eqs>
 
  206class D<d,arg,Sys_eqs,CENTRAL_B_ONE_SIDE>
 
  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)
 
  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";
 
  238        if (pos.
get(d) == (
long int)gs.
size(d)-1 )
 
  240            arg::value(g_map,kmap,gs,spacing,cols,1.5*coeff/spacing[d]);
 
  242            long int old_val = kmap.
getKeyRef().get(d);
 
  244            arg::value(g_map,kmap,gs,spacing,cols,-2.0*coeff/spacing[d]);
 
  249            arg::value(g_map,kmap,gs,spacing,cols,0.5*coeff/spacing[d]);
 
  252        else if (pos.
get(d) == 0)
 
  254            arg::value(g_map,kmap,gs,spacing,cols,-1.5*coeff/spacing[d]);
 
  256            long int old_val = kmap.
getKeyRef().get(d);
 
  258            arg::value(g_map,kmap,gs,spacing,cols,2.0*coeff/spacing[d]);
 
  263            arg::value(g_map,kmap,gs,spacing,cols,-0.5*coeff/spacing[d]);
 
  268            long int old_val = kmap.
getKeyRef().get(d);
 
  270            arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]);
 
  275            arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]);
 
  312        return arg::position(pos,gs,s_pos);
 
  327template<
unsigned int d, 
typename arg, 
typename Sys_eqs>
 
  328class D<d,arg,Sys_eqs,FORWARD>
 
  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)
 
  354        long int old_val = kmap.
getKeyRef().get(d);
 
  356        arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]);
 
  360        arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]);
 
  380        return arg::position(pos,gs,s_pos);
 
  394template<
unsigned int d, 
typename arg, 
typename Sys_eqs>
 
  395class D<d,arg,Sys_eqs,BACKWARD>
 
  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)
 
  421        long int old_val = kmap.
getKeyRef().get(d);
 
  423        arg::value(g_map,kmap,gs,spacing,cols,-coeff/spacing[d]);
 
  427        arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[d]);
 
  445        return arg::position(pos,gs,s_pos);
 
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
__device__ __host__ index_type get(index_type i) const
Get the i index.
__device__ __host__ size_t size() const
Return the size of the grid.
Position of the element of dimension d in the hyper-cube of dimension dim.
is_grid_staggered analyse T if it has a property grid_type defined and indicate that the grid is stag...