8#ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FDSCHEME_HPP_
9#define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FDSCHEME_HPP_
11#include "Matrix/SparseMatrix.hpp"
12#include "Vector/Vector.hpp"
13#include "Grid/grid_dist_id.hpp"
14#include "Grid/Iterators/grid_dist_id_iterator_sub.hpp"
16#include "NN/CellList/CellDecomposer.hpp"
17#include "Grid/staggered_dist_grid_util.hpp"
18#include "Grid/grid_dist_id.hpp"
19#include "Vector/Vector_util.hpp"
20#include "Grid/staggered_dist_grid.hpp"
125template<
typename Sys_eqs>
168 template<
typename gr
id,
unsigned int prp>
192 return gr.template get<prp>(key);
202 typedef typename Sys_eqs::SparseMatrix_type::triplet_type
triplet;
205 typename Sys_eqs::Vector_type
b;
211 typename Sys_eqs::stype
spacing[Sys_eqs::dims];
260 size_t row_low =
g_map.template get<0>(it.get());
262 if (
row >= row_low * Sys_eqs::nvar &&
row < row_low * Sys_eqs::nvar + Sys_eqs::nvar)
264 ke.
eq =
row - row_low * Sys_eqs::nvar;
271 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" the row does not map to any position" <<
"\n";
286 std::vector<size_t> g_sz_pad(Sys_eqs::dims);
288 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
303 std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
"the term B and the Matrix A for Ax=B must contain the same number of rows\n";
307 nz_rows.resize(
row_b);
309 for (
size_t i = 0 ; i < trpl.
size() ; i++)
310 nz_rows.get(trpl.get(i).row() -
s_pnt*Sys_eqs::nvar) =
true;
319 nz_cols.resize(
row_b);
321 for (
size_t i = 0 ; i < trpl.
size() ; i++)
322 nz_cols.get(trpl.get(i).col()) =
true;
325 for (
size_t i = 0 ; i < nz_rows.
size() ; i++)
327 if (nz_rows.get(i) ==
false)
330 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" Ill posed matrix row " << i <<
" is not filled, position " << ke.
key.
to_string() <<
" equation: " << ke.
eq <<
"\n";
335 for (
size_t i = 0 ; i < nz_cols.
size() ; i++)
337 if (nz_cols.get(i) ==
false)
338 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" Ill posed matrix colum " << i <<
" is not filled\n";
356 if (g_dst.is_staggered() ==
false)
357 std::cerr << __FILE__ <<
":" << __LINE__ <<
" The destination grid must be staggered " << std::endl;
363 auto g_dst_it = g_dst.getSubDomainIterator(start_d,stop_d);
365 while (g_map_it.isNext() ==
true)
368 typedef boost::mpl::size<vid> v_size;
370 auto key_src = g_map_it.get();
371 size_t lin_id =
g_map.template get<0>(key_src);
374 auto key_dst = g_dst_it.get();
380 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
397 template<
typename Vct,
typename Grid_dst ,
unsigned int ... pos>
void copy_normal(Vct & v, Grid_dst & g_dst)
400 if (g_dst.is_staggered() ==
true)
401 std::cerr << __FILE__ <<
":" << __LINE__ <<
" The destination grid must be normal " << std::endl;
406 for (
size_t i = 0 ; i < Grid_dst::dims ; i++)
416 auto g_dst_it = g_dst.getDomainIterator();
418 while (g_dst_it.isNext() ==
true)
421 typedef boost::mpl::size<vid> v_size;
423 auto key_src = g_map_it.get();
424 size_t lin_id =
g_map.template get<0>(key_src);
427 auto key_dst = g_dst_it.get();
433 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
453 template<
typename bop,
typename iterator>
456 const iterator & it_d)
468 b(
g_map.template get<0>(key)*Sys_eqs::nvar +
id) = num.get(key);
495 template<
typename T,
typename bop,
typename iterator>
void impose_dit(
const T & op,
498 const iterator & it_d)
505 std::unordered_map<long int,typename Sys_eqs::stype> cols;
514 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
515 key.getKeyRef().set_d(i,key.getKeyRef().get(i) +
pd.
getLow(i));
521 bool is_diag =
false;
524 for (
auto it = cols.begin(); it != cols.end(); ++it )
527 trpl.last().row() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
528 trpl.last().col() = it->first;
529 trpl.last().value() = it->second;
531 if (trpl.last().row() == trpl.last().col())
537 if (is_diag ==
false)
540 trpl.last().row() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
541 trpl.last().col() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
542 trpl.last().value() = 0.0;
545 b(
g_map.template get<0>(key)*Sys_eqs::nvar +
id) = num.get(key);
582 b.resize(Sys_eqs::nvar *
g_map.
size(),Sys_eqs::nvar * sz);
603 g_map.template ghost_get<0>();
617 size_t sz_g[Sys_eqs::dims];
618 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
620 if (Sys_eqs::boundary[i] == NON_PERIODIC)
626 CellDecomposer_sm<Sys_eqs::dims,typename Sys_eqs::stype> cd(domain,sz_g,0);
628 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
629 spacing[i] = cd.getCellBox().getHigh(i);
641 for (
size_t i = 0 ; i < Sys_eqs::nvar ; i++)
654 typedef typename Sys_eqs::b_grid::value_type prp_type;
660 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,prp_type::max_prop> >(ssp);
696 const typename Sys_eqs::b_grid & b_g)
697 :
pd({0,0,0},{0,0,0}),
gs(b_g.getGridInfoVoid()),
g_map(b_g,stencil,
pd),
row(0),
row_b(0)
715 const typename Sys_eqs::b_grid & b_g)
738 template<
typename T>
void impose(
const T & op,
739 typename Sys_eqs::stype num,
741 const long int (& start)[Sys_eqs::dims],
742 const long int (& stop)[Sys_eqs::dims],
743 bool skip_first =
false)
748 bool increment =
false;
749 if (skip_first ==
true)
756 if (it.isNext() ==
true)
766 if (increment ==
true)
803 template<
unsigned int prp,
typename b_term,
typename iterator>
805 const iterator & it_d,
829 typename Sys_eqs::stype num,
853 template<
typename T,
typename bop,
typename iterator>
void impose_git_gmap(
const T & op ,
862 std::unordered_map<long int,float> cols;
874 bool is_diag =
false;
877 for (
auto it = cols.begin(); it != cols.end(); ++it )
880 trpl.last().row() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
881 trpl.last().col() = it->first;
882 trpl.last().value() = it->second;
884 if (trpl.last().row() == trpl.last().col())
891 if (is_diag ==
false)
894 trpl.last().row() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
895 trpl.last().col() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
896 trpl.last().value() = 0.0;
899 b(
g_map.template get<0>(key)*Sys_eqs::nvar +
id) = num.get(key);
929 template<
typename T,
typename bop,
typename iterator>
void impose_git(
const T & op ,
932 const iterator & it_d,
933 bool skip_first =
false)
937 auto start = it_d.getStart();
938 auto stop = it_d.getStop();
944 if (skip_first ==
true)
949 std::unordered_map<long int,float> cols;
956 auto keyg = itg.get();
962 bool is_diag =
false;
965 for (
auto it = cols.begin(); it != cols.end(); ++it )
968 trpl.last().row() =
g_map.template get<0>(keyg)*Sys_eqs::nvar + id;
969 trpl.last().col() = it->first;
970 trpl.last().value() = it->second;
972 if (trpl.last().row() == trpl.last().col())
979 if (is_diag ==
false)
982 trpl.last().row() =
g_map.template get<0>(keyg)*Sys_eqs::nvar + id;
983 trpl.last().col() =
g_map.template get<0>(keyg)*Sys_eqs::nvar + id;
984 trpl.last().value() = 0.0;
987 b(
g_map.template get<0>(keyg)*Sys_eqs::nvar +
id) = num.get(key);
1018 template<
unsigned int prp,
typename T,
typename b_term,
typename iterator>
void impose_dit(
const T & op ,
1020 const iterator & it_d,
1029 typename Sys_eqs::SparseMatrix_type
A;
1036 typename Sys_eqs::SparseMatrix_type &
getA()
1054 typename Sys_eqs::Vector_type &
getB()
1078 template<
unsigned int ... pos,
typename Vct,
typename Grid_dst>
1079 void copy(Vct & v,
const long int (& start)[Sys_eqs_typ::dims],
const long int (& stop)[Sys_eqs_typ::dims], Grid_dst & g_dst)
1083 if (g_dst.is_staggered() ==
true)
1097 for (
size_t i = 0 ; i < Grid_dst::dims ; i++)
1109 for (
int i = 0 ; i < Grid_dst::dims ; i++)
1112 st.
set_d(i,stop[i]);
1118 stg.template ghost_get<pos...>();
1119 stg.template to_normal<Grid_dst,pos...>(g_dst,this->
getPadding(),start,stop);
1141 template<
unsigned int ... pos,
typename Vct,
typename Grid_dst>
void copy(Vct & v, Grid_dst & g_dst)
1143 long int start[Sys_eqs_typ::dims];
1144 long int stop[Sys_eqs_typ::dims];
1146 for (
size_t i = 0 ; i < Sys_eqs_typ::dims ; i++)
1149 stop[i] = g_dst.size(i);
1152 this->
copy<pos...>(v,start,stop,g_dst);
This class represent an N-dimensional box.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
__device__ __host__ T getHigh(int i) const
get the high interval of the box
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
void impose_dit(const T &op, bop num, long int id, const iterator &it_d)
Impose an operator.
void construct_gmap()
Construct the gmap structure.
const std::vector< size_t > padding(const size_t(&sz)[Sys_eqs::dims], Padding< Sys_eqs::dims > &pd)
calculate the mapping grid size with padding
void consistency()
Check if the Matrix is consistent.
Padding< Sys_eqs::dims > pd
Padding.
const grid_sm< Sys_eqs::dims, void > & gs
Domain Grid informations.
void impose_git_gmap(const T &op, bop num, long int id, iterator &it)
Impose an operator.
void impose_git(const T &op, bop num, long int id, const iterator &it_d, bool skip_first=false)
Impose an operator.
void setStagPos(comb< Sys_eqs::dims >(&sp)[Sys_eqs::nvar])
set the staggered position for each property
void impose_dit(const T &op, b_term &b_t, const iterator &it_d, long int id=0)
Impose an operator.
const g_map_type & getMap()
Return the map between the grid index position and the position in the distributed vector.
void copy_normal(Vct &v, Grid_dst &g_dst)
Copy a given solution vector in a normal grid.
Sys_eqs::Vector_type b
Vector b.
Sys_eqs::Vector_type & getB()
produce the B vector
Sys_eqs Sys_eqs_typ
Type that specify the properties of the system of equations.
void copy(Vct &v, const long int(&start)[Sys_eqs_typ::dims], const long int(&stop)[Sys_eqs_typ::dims], Grid_dst &g_dst)
Copy the vector into the grid.
Sys_eqs::SparseMatrix_type & getA()
produce the Matrix
openfpm::vector< size_t > pnt
Grid points that has each processor.
void new_A()
In case we want to impose a new A re-using FDScheme we have to call This function.
void copy_staggered(Vct &v, Grid_dst &g_dst, grid_key_dx< Grid_dst::dims > &start_d, grid_key_dx< Grid_dst::dims > &stop_d)
Copy a given solution vector in a staggered grid.
void impose_dit_b(b_term &b_t, const iterator &it_d, long int id=0)
Impose an operator.
FDScheme(Padding< Sys_eqs::dims > &pd, const Ghost< Sys_eqs::dims, long int > &stencil, const Box< Sys_eqs::dims, typename Sys_eqs::stype > &domain, const typename Sys_eqs::b_grid &b_g)
Constructor.
comb< Sys_eqs::dims > s_pos[Sys_eqs::nvar]
Staggered position for each property.
void impose_dit(const T &op, typename Sys_eqs::stype num, long int id, grid_dist_iterator_sub< Sys_eqs::dims, typename g_map_type::d_grid > it_d)
Impose an operator.
void copy(Vct &v, Grid_dst &g_dst)
Copy the vector into the grid.
void new_b()
In case we want to impose a new b re-using FDScheme we have to call This function.
FDScheme(const Ghost< Sys_eqs::dims, long int > &stencil, const Box< Sys_eqs::dims, typename Sys_eqs::stype > &domain, const typename Sys_eqs::b_grid &b_g)
Constructor.
g_map_type g_map
mapping grid
Sys_eqs::stype spacing[Sys_eqs::dims]
Get the grid spacing.
void impose_dit_b(bop num, long int id, const iterator &it_d)
Impose an operator.
key_and_eq from_row_to_key(size_t row)
From the row Matrix position to the spatial position.
void Initialize(const Box< Sys_eqs::dims, typename Sys_eqs::stype > &domain)
Sys_eqs::SparseMatrix_type A
type of the sparse matrix
grid_dist_id< Sys_eqs::dims, typename Sys_eqs::stype, aggregate< size_t >, typename Sys_eqs::b_grid::decomposition::extended_type > g_map_type
Distributed grid map.
size_t row
row of the matrix
const Padding< Sys_eqs::dims > & getPadding()
Get the specified padding.
void computeStag()
compute the staggered position for each property
void impose(const T &op, typename Sys_eqs::stype num, long int id, const long int(&start)[Sys_eqs::dims], const long int(&stop)[Sys_eqs::dims], bool skip_first=false)
Impose an operator.
Sys_eqs::SparseMatrix_type::triplet_type triplet
Sparse matrix triplet type.
Class that contain Padding information on each direction positive and Negative direction.
void execute()
Execute all the requests.
size_t getProcessUnitID()
Get the process unit id.
size_t getProcessingUnits()
Get the total number of processors.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
Implementation of VCluster class.
This is a distributed grid.
const grid_sm< dim, void > & getGridInfoVoid() const
Get an object containing the grid informations without type.
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
size_t getLocalDomainSize() const
Get the total number of grid points for the calling processor.
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &k) const
Convert a g_dist_key_dx into a global key.
grid_dist_iterator_sub< dim, device_grid > getSubDomainIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop) const
It return an iterator that span the grid domain only in the specified part.
size_t size() const
Return the total number of points in the grid.
St spacing(size_t i) const
Get the spacing of the grid in direction i.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
Distributed grid iterator.
Grid key for a distributed grid.
grid_key_dx is the key to access any element in the grid
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
std::string to_string() const
convert the information into a string
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Implementation of 1-D std::vector like structure.
this class is a functor for "for_each" algorithm
Implementation of the staggered grid.
void setDefaultStagPosition()
It set all the properties defined to be staggered on the default location.
Encapsulation of the b term as constant.
Sys_eqs::stype get(grid_dist_key_dx< Sys_eqs::dims > &key)
Get the b term on a grid point.
Sys_eqs::stype scal
scalar
constant_b(typename Sys_eqs::stype scal)
Constrictor from a scalar.
Encapsulation of the b term as grid.
grid & gr
b term fo the grid
grid_b(grid &gr)
gr grid that encapsulate
auto get(grid_dist_key_dx< Sys_eqs::dims > &key) -> decltype(gr.template get< prp >(key))
Get the value of the b term on a grid point.
Equation id + space position.
grid_key_dx< Sys_eqs::dims > key
space position
Position of the element of dimension d in the hyper-cube of dimension dim.
this class is a functor for "for_each" algorithm
is_grid_staggered analyse T if it has a property grid_type defined and indicate that the grid is stag...