13#include "Matrix/SparseMatrix.hpp"
14#include "Vector/Vector.hpp"
15#include "Grid/grid_dist_id.hpp"
16#include "Grid/Iterators/grid_dist_id_iterator_sub.hpp"
17#include "NN/CellList/CellDecomposer.hpp"
18#include "Grid/staggered_dist_grid_util.hpp"
19#include "Grid/grid_dist_id.hpp"
20#include "Vector/Vector_util.hpp"
21#include "Grid/staggered_dist_grid.hpp"
22#include "util/eq_solve_common.hpp"
126template<
typename Sys_eqs,
typename gr
id_type>
169 inline bool isConstant()
176 template<
unsigned int prp_
id>
201 return grid.template getProp<prp_id>(key);
204 inline bool isConstant()
214 typename Sys_eqs::stype* spacing;
215 const std::function<double(
double,
double)> &f;
223 :
grid(
grid), spacing(spacing), f(f), c_where(c_where)
229 double hx = spacing[0];
230 double hy = spacing[1];
231 double x = hx * (key.
getKeyRef().value(0) +
grid.getLocalGridsInfo().get(key.
getSub()).origin[0]);
232 double y = hy * (key.
getKeyRef().value(1) +
grid.getLocalGridsInfo().get(key.
getSub()).origin[1]);
235 x -= (-1-c_where[0])*(hx/2.0);
236 y -= (-1-c_where[1])*(hy/2.0);
241 inline bool isConstant()
254 typedef typename Sys_eqs::SparseMatrix_type::triplet_type
triplet;
257 typename Sys_eqs::Vector_type
b;
263 typename Sys_eqs::stype
spacing[Sys_eqs::dims];
318 size_t row_low =
g_map.template get<0>(it.get());
320 if (
row >= row_low * Sys_eqs::nvar &&
row < row_low * Sys_eqs::nvar + Sys_eqs::nvar)
322 ke.
eq =
row - row_low * Sys_eqs::nvar;
329 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" the row does not map to any position" <<
"\n";
344 std::vector<size_t> g_sz_pad(Sys_eqs::dims);
346 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
361 std::cerr <<
"Error " << __FILE__ <<
":" << __LINE__ <<
"the term B and the Matrix A for Ax=B must contain the same number of rows\n";
365 nz_rows.resize(
row_b);
367 for (
size_t i = 0 ; i < trpl.
size() ; i++)
368 nz_rows.get(trpl.get(i).row() -
s_pnt*Sys_eqs::nvar) =
true;
377 nz_cols.resize(
row_b);
379 for (
size_t i = 0 ; i < trpl.
size() ; i++)
380 nz_cols.get(trpl.get(i).col()) =
true;
383 for (
size_t i = 0 ; i < nz_rows.
size() ; i++)
385 if (nz_rows.get(i) ==
false)
388 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" Ill posed matrix row " << i <<
" is not filled, position " << ke.
key.
to_string() <<
" equation: " << ke.
eq <<
"\n";
393 for (
size_t i = 0 ; i < nz_cols.
size() ; i++)
395 if (nz_cols.get(i) ==
false)
396 std::cerr <<
"Error: " << __FILE__ <<
":" << __LINE__ <<
" Ill posed matrix colum " << i <<
" is not filled\n";
411 template<
typename Vct,
typename Grid_dst ,
unsigned int ... pos>
void copy_staggered(Vct & v, Grid_dst & g_dst)
414 if (g_dst.is_staggered() ==
false)
415 std::cerr << __FILE__ <<
":" << __LINE__ <<
" The destination grid must be staggered " << std::endl;
420 std::cerr << __FILE__ <<
":" << __LINE__ <<
" The staggered and destination grid in size does not match " << std::endl;
427 auto g_dst_it = g_dst.getDomainIterator();
429 while (g_map_it.isNext() ==
true)
432 typedef boost::mpl::size<vid> v_size;
434 auto key_src = g_map_it.get();
435 size_t lin_id =
g_map.template get<0>(key_src);
438 auto key_dst = g_dst_it.get();
444 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
461 template<
typename Vct,
typename Grid_dst ,
unsigned int ... pos>
void copy_normal(Vct & v, Grid_dst & g_dst)
464 if (g_dst.is_staggered() ==
true)
465 std::cerr << __FILE__ <<
":" << __LINE__ <<
" The destination grid must be normal " << std::endl;
470 for (
size_t i = 0 ; i < Grid_dst::dims ; i++)
480 auto g_dst_it = g_dst.getDomainIterator();
482 while (g_dst_it.isNext() ==
true)
485 typedef boost::mpl::size<vid> v_size;
487 auto key_src = g_map_it.get();
488 size_t lin_id =
g_map.template get<0>(key_src);
491 auto key_dst = g_dst_it.get();
497 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
517 template<
typename bop,
typename iterator>
520 const iterator & it_d)
532 b(
g_map.template get<0>(key)*Sys_eqs::nvar +
id) = num.get(key);
544 template<
typename T,
typename col,
typename trp,
typename iterator,
typename cmb,
typename Key>
void impose_git_it(
const T & op ,
548 const iterator &it_d,
552 op.template value_nz<Sys_eqs>(
g_map,key,
gs,
spacing,cols,1.0,0,c_where);
553 key.getKeyRef() -=
shift;
556 bool is_diag =
false;
559 for (
auto it = cols.begin(); it != cols.end(); ++it )
562 trpl.last().row() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
563 trpl.last().col() = it->first;
564 trpl.last().value() = it->second;
566 if (trpl.last().row() == trpl.last().col())
573 if (is_diag ==
false)
576 trpl.last().row() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
577 trpl.last().col() =
g_map.template get<0>(key)*Sys_eqs::nvar + id;
578 trpl.last().value() = 0.0;
598 template<
typename T,
typename bop,
typename iterator>
void impose_git(
const T & op ,
601 const iterator & it_d,
608 for (
int i = 0 ; i < Sys_eqs::dims ; i++)
617 iterator it(it_d,
false);
620 std::unordered_map<long int,typename Sys_eqs::stype> cols;
625 if (num.isConstant() ==
false)
627 auto it_num =
grid.getSubDomainIterator(it.getStart(),it.getStop());
633 auto key_num=it_num.get();
635 impose_git_it(op,cols,trpl,
id,it,c_where,key,
shift);
637 b(
g_map.template get<0>(key)*Sys_eqs::nvar +
id) = num.get(key_num);
660 impose_git_it(op,cols,trpl,
id,it,c_where,key,
shift);
662 b(
g_map.template get<0>(key)*Sys_eqs::nvar +
id) = num.get(key);
699 b.resize(Sys_eqs::nvar *
g_map.
size(),Sys_eqs::nvar * sz);
720 g_map.template ghost_get<0>();
734 size_t sz_g[Sys_eqs::dims];
735 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
737 if (Sys_eqs::boundary[i] == NON_PERIODIC)
743 CellDecomposer_sm<Sys_eqs::dims,typename Sys_eqs::stype> cd(domain,sz_g,0);
745 for (
size_t i = 0 ; i < Sys_eqs::dims ; i++)
746 spacing[i] = cd.getCellBox().getHigh(i);
756 template<
typename solType,
typename expr_type>
757 void copy_impl(solType & x, expr_type exp,
unsigned int comp)
761 auto &
grid = exp.getGrid();
763 auto it =
grid.getDomainIterator();
767 for (
int i = 0 ; i < Sys_eqs::dims ; i++)
777 auto gp = it_map.get();
779 size_t pn =
g_map.template get<0>(gp);
780 exp.value_ref(p,c_where) = x(pn*Sys_eqs::nvar + comp);
787 template<
typename solType,
typename exp1,
typename ... othersExp>
788 void copy_nested(solType & x,
unsigned int & comp, exp1 exp, othersExp ... exps)
793 copy_nested(x,comp,exps ...);
797 template<
typename solType,
typename exp1>
798 void copy_nested(solType & x,
unsigned int & comp, exp1 exp)
814 for (
size_t i = 0 ; i < Sys_eqs::nvar ; i++)
827 typedef typename Sys_eqs::b_grid::value_type prp_type;
833 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,prp_type::max_prop> >(ssp);
869 options_solver
opt = options_solver::STANDARD)
870 :
grid(b_g),
pd({0,0,0},{0,0,0}),
gs(b_g.getGridInfoVoid()),
g_map(b_g,stencil,
pd),
row(0),
row_b(0),
opt(
opt)
888 options_solver
opt = options_solver::STANDARD)
911 template<
typename T>
void impose(
const T & op,
914 typename Sys_eqs::stype num,
942 template<
typename T,
unsigned int prp_
id>
void impose(
const T & op,
971 template<
typename T>
void impose(
const T & op,
974 const std::function<
double(
double,
double)> &f,
1003 template<
typename T>
void impose(
const T & op,
1006 typename Sys_eqs::stype num,
1008 bool skip_first =
false)
1012 bool increment =
false;
1013 if (skip_first ==
true)
1017 if (it.isNext() ==
true)
1023 if (increment ==
true)
1049 template<
typename T,
unsigned int prp_
id>
void impose(
const T & op,
1054 bool skip_first =
false)
1058 bool increment =
false;
1059 if (skip_first ==
true)
1064 if (it.isNext() ==
true)
1070 if (increment ==
true)
1096 template<typename T, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type>
1099 const RHS_type &rhs,
1101 bool skip_first =
false)
1105 bool increment =
false;
1106 if (skip_first ==
true)
1111 if (it.isNext() ==
true)
1117 if (increment ==
true)
1141 template<
typename T>
void impose(
const T & op,
1144 const std::function<
double(
double,
double)> &f,
1146 bool skip_first =
false)
1150 bool increment =
false;
1151 if (skip_first ==
true)
1156 if (it.isNext() ==
true)
1162 if (increment ==
true)
1186 typename Sys_eqs::SparseMatrix_type
A;
1193 typename Sys_eqs::SparseMatrix_type &
getA(options_solver
opt = options_solver::STANDARD)
1198 if (
opt == options_solver::STANDARD) {
1199 A.resize(
tot * Sys_eqs::nvar,
tot * Sys_eqs::nvar,
1204 auto & v_cl = create_vcluster();
1207 if (v_cl.rank() == v_cl.size() - 1)
1209 A.resize(
tot * Sys_eqs::nvar + 1,
tot * Sys_eqs::nvar + 1,
1213 for (
int i = 0 ; i <
tot * Sys_eqs::nvar ; i++)
1217 t1.row() =
tot * Sys_eqs::nvar;
1228 t2.row() = i +
s_pnt*Sys_eqs::nvar;
1229 t2.col() =
tot * Sys_eqs::nvar;
1237 t3.col() =
tot * Sys_eqs::nvar;
1238 t3.row() =
tot * Sys_eqs::nvar;
1247 A.resize(
tot * Sys_eqs::nvar + 1,
tot * Sys_eqs::nvar + 1,
1255 t2.row() = i +
s_pnt*Sys_eqs::nvar;
1256 t2.col() =
tot * Sys_eqs::nvar;
1275 typename Sys_eqs::Vector_type &
getB(options_solver
opt = options_solver::STANDARD)
1280 if (
opt == options_solver::LAGRANGE_MULTIPLIER)
1282 auto & v_cl = create_vcluster();
1283 if (v_cl.rank() == v_cl.size() - 1) {
1285 b(
tot * Sys_eqs::nvar) = 0;
1308 template<
unsigned int ... pos,
typename Vct,
typename Grid_dst>
void copy(Vct & v,
const long int (& start)[Sys_eqs_typ::dims],
const long int (& stop)[Sys_eqs_typ::dims], Grid_dst & g_dst)
1312 if (g_dst.is_staggered() ==
true)
1322 for (
size_t i = 0 ; i < Grid_dst::dims ; i++)
1333 stg.template ghost_get<pos...>();
1334 stg.template to_normal<Grid_dst,pos...>(g_dst,this->
getPadding(),start,stop);
1350 template<
typename ... expr_type>
1353 if (
sizeof...(exps) != Sys_eqs::nvar)
1354 {std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error the number of properties you gave does not match the solution in\
1355 dimensionality, I am expecting " << Sys_eqs::nvar <<
1356 " properties " << std::endl;};
1357 typename Sys_eqs::solver_type solver;
1361 unsigned int comp = 0;
1362 copy_nested(x,comp,exps ...);
1372 template<
typename SolverType,
typename ... expr_type>
1377 if (
sizeof...(exps) != Sys_eqs::nvar)
1378 {std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error the number of properties you gave does not match the solution in\
1379 dimensionality, I am expecting " << Sys_eqs::nvar <<
1380 " properties " << std::endl;};
1384 unsigned int comp = 0;
1385 copy_nested(x,comp,exps ...);
1388 template<
typename SolverType,
typename ... expr_type>
1389 void solve_with_constant_nullspace_solver(SolverType & solver, expr_type ... exps)
1393 if (
sizeof...(exps) != Sys_eqs::nvar)
1394 {std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error the number of properties you gave does not match the solution in\
1395 dimensionality, I am expecting " << Sys_eqs::nvar <<
1396 " properties " << std::endl;};
1398 auto x = solver.with_constant_nullspace_solve(
getA(
opt),
getB(
opt));
1400 unsigned int comp = 0;
1401 copy_nested(x,comp,exps ...);
1411 template<
typename SolverType,
typename ... expr_type>
1414 if (
sizeof...(exps) != Sys_eqs::nvar)
1415 {std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error the number of properties you gave does not match the solution in\
1416 dimensionality, I am expecting " << Sys_eqs::nvar <<
1417 " properties " << std::endl;};
1421 unsigned int comp = 0;
1422 copy_nested(x,comp,exps ...);
1438 template<
unsigned int ... pos,
typename Vct,
typename Grid_dst>
void copy(Vct & v, Grid_dst & g_dst)
1440 long int start[Sys_eqs_typ::dims];
1441 long int stop[Sys_eqs_typ::dims];
1443 for (
size_t i = 0 ; i < Sys_eqs_typ::dims ; i++)
1446 stop[i] = g_dst.size(i);
1449 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
FD_scheme(const Ghost< Sys_eqs::dims, long int > &stencil, grid_type &b_g, options_solver opt=options_solver::STANDARD)
Constructor.
void copy_normal(Vct &v, Grid_dst &g_dst)
Copy a given solution vector in a normal grid.
Sys_eqs::stype spacing[Sys_eqs::dims]
Get the grid spacing.
void copy_impl(solType &x, expr_type exp, unsigned int comp)
Solve an equation.
void consistency()
Check if the Matrix is consistent.
void Initialize(const Box< Sys_eqs::dims, typename Sys_eqs::stype > &domain)
void impose_dit_b(bop num, long int id, const iterator &it_d)
Impose an operator.
void computeStag()
compute the staggered position for each property
grid_type & grid
our base grid
void impose_git(const T &op, bop num, long int id, const iterator &it_d, comb< Sys_eqs::dims > c_where)
Impose an operator.
void new_A()
In case we want to impose a new A re-using FD_scheme we have to call This function.
Sys_eqs::SparseMatrix_type & getA(options_solver opt=options_solver::STANDARD)
produce the Matrix
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, const std::function< double(double, double)> &f, eq_id id=eq_id(), bool skip_first=false)
Impose an operator.
FD_scheme(Padding< Sys_eqs::dims > &pd, const Ghost< Sys_eqs::dims, long int > &stencil, grid_type &b_g, options_solver opt=options_solver::STANDARD)
Constructor.
grid_dist_id< Sys_eqs::dims, typename Sys_eqs::stype, aggregate< size_t >, typename grid_type::decomposition::extended_type > g_map_type
Distributed grid map.
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, typename Sys_eqs::stype num, eq_id id, comb< Sys_eqs::dims > c_where)
Impose an operator.
void setStagPos(comb< Sys_eqs::dims >(&sp)[Sys_eqs::nvar])
set the staggered position for each property
void try_solve_with_solver(SolverType &solver, expr_type ... exps)
Solve an equation.
void solve(expr_type ... exps)
Solve an equation.
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, typename Sys_eqs::stype num, eq_id id=eq_id(), bool skip_first=false)
Impose an operator.
openfpm::vector< size_t > pnt
Grid points that has each processor.
options_solver opt
solver options
const g_map_type & getMap()
Return the map between the grid index position and the position in the distributed vector.
Sys_eqs::Vector_type b
Vector b.
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.
void solve_with_solver(SolverType &solver, expr_type ... exps)
Solve an equation.
const Padding< Sys_eqs::dims > & getPadding()
Get the specified padding.
void new_b()
In case we want to impose a new b re-using FD_scheme we have to call This function.
key_and_eq from_row_to_key(size_t row)
From the row Matrix position to the spatial position.
void copy(Vct &v, Grid_dst &g_dst)
Copy the vector into the grid.
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, prop_id< prp_id > num, eq_id id=eq_id(), bool skip_first=false)
Impose an operator.
size_t tot
Total number of points.
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, const RHS_type &rhs, eq_id id=eq_id(), bool skip_first=false)
Impose an operator.
void copy_staggered(Vct &v, Grid_dst &g_dst)
Copy a given solution vector in a staggered grid.
Padding< Sys_eqs::dims > pd
Padding.
void construct_gmap()
Construct the gmap structure.
comb< Sys_eqs::dims > s_pos[Sys_eqs::nvar]
Staggered position for each property.
Sys_eqs::Vector_type & getB(options_solver opt=options_solver::STANDARD)
produce the B vector
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, prop_id< prp_id > num, eq_id id, comb< Sys_eqs::dims > c_where)
Impose an operator.
Sys_eqs Sys_eqs_typ
Type that specify the properties of the system of equations.
void impose(const T &op, const grid_key_dx< Sys_eqs::dims > start_k, const grid_key_dx< Sys_eqs::dims > stop_k, const std::function< double(double, double)> &f, eq_id id, comb< Sys_eqs::dims > c_where)
Impose an operator.
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
Sys_eqs::SparseMatrix_type A
type of the sparse matrix
size_t row
row of the matrix
g_map_type g_map
mapping grid
const grid_sm< Sys_eqs::dims, void > & gs
Domain Grid informations.
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)
Box< dim, size_t > getDomain(size_t i)
Given a local sub-domain i with a local grid Domain + ghost return the part of the local grid that is...
Grid key for a distributed grid.
size_t getSub() const
Get the local grid.
base_key & getKeyRef()
Get the reference key.
grid_key_dx is the key to access any element in the grid
void zero()
Set to zero the key.
__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.
__device__ __host__ size_t size() const
Return the size of the grid.
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 scal
scalar
Sys_eqs::stype get(grid_dist_key_dx< Sys_eqs::dims > &key)
Get the b term on a grid point.
constant_b(typename Sys_eqs::stype scal)
Constrictor from a scalar.
Encapsulation of the b term as a function.
function_b(g_map_type &grid, typename Sys_eqs::stype *spacing, const std::function< double(double, double)> &f, comb< Sys_eqs::dims > c_where=comb< 2 >({0, 0}))
Constrictor from a function.
Equation id + space position.
grid_key_dx< Sys_eqs::dims > key
space position
Encapsulation of the b term as constant.
variable_b(grid_type &grid)
Constrictor from a scalar.
Sys_eqs::stype get(grid_dist_key_dx< Sys_eqs::dims > &key)
Get the b term on a grid point.
Position of the element of dimension d in the hyper-cube of dimension dim.
void mone()
Set all the elements to -1.
void zero()
Set all the elements to zero.
signed char c[dim]
Array that store the combination.
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...
It model an expression expr1 * expr2.
static void value(const grid_dist_id< Sys_eqs::dims, typename Sys_eqs::stype, aggregate< size_t >, typename Sys_eqs::b_grid::decomposition::extended_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.
It store the non zero elements of the matrix.