OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
FD_Solver.hpp
1 /*
2  * FD_Solver.hpp
3  *
4  * Created on: Jun 5, 2020
5  * Author: i-bird
6  */
7 
8 #ifndef FDSOLVER_HPP_
9 #define FDSOLVER_HPP_
10 
11 #include <functional>
12 
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"
23 
126 template<typename Sys_eqs, typename grid_type>
128 {
129 public:
130 
132  typedef grid_dist_id<Sys_eqs::dims,typename Sys_eqs::stype,aggregate<size_t>,typename grid_type::decomposition::extended_type> g_map_type;
133 
135  typedef Sys_eqs Sys_eqs_typ;
136 
137 private:
138 
140  struct constant_b
141  {
143  typename Sys_eqs::stype scal;
144 
150  constant_b(typename Sys_eqs::stype scal)
151  {
152  this->scal = scal;
153  }
154 
164  typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
165  {
166  return scal;
167  }
168 
169  inline bool isConstant()
170  {
171  return true;
172  }
173  };
174 
176  template<unsigned int prp_id>
177  struct variable_b
178  {
179  grid_type & grid;
180 
187  :grid(grid)
188  {}
189 
199  inline typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
200  {
201  return grid.template getProp<prp_id>(key);
202  }
203 
204  inline bool isConstant()
205  {
206  return false;
207  }
208  };
209 
211  struct function_b
212  {
213  g_map_type & grid;
214  typename Sys_eqs::stype* spacing;
215  const std::function<double(double,double)> &f;
216  comb<Sys_eqs::dims> c_where;
222  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}))
223  :grid(grid), spacing(spacing), f(f), c_where(c_where)
224  {}
225 
226  inline typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
227  {
228 
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]);
233 
234  // shift x, y according to the staggered location
235  x -= (-1-c_where[0])*(hx/2.0);
236  y -= (-1-c_where[1])*(hy/2.0);
237 
238  return f(x,y);
239  }
240 
241  inline bool isConstant()
242  {
243  return true;
244  }
245  };
246 
249 
252 
254  typedef typename Sys_eqs::SparseMatrix_type::triplet_type triplet;
255 
257  typename Sys_eqs::Vector_type b;
258 
261 
263  typename Sys_eqs::stype spacing[Sys_eqs::dims];
264 
267 
269  size_t row;
270 
272  size_t row_b;
273 
275  options_solver opt;
276 
278  size_t tot;
279 
282 
284  comb<Sys_eqs::dims> s_pos[Sys_eqs::nvar];
285 
290  size_t s_pnt;
291 
295  struct key_and_eq
296  {
299 
301  size_t eq;
302  };
303 
312  {
313  key_and_eq ke;
314  auto it = g_map.getDomainIterator();
315 
316  while (it.isNext())
317  {
318  size_t row_low = g_map.template get<0>(it.get());
319 
320  if (row >= row_low * Sys_eqs::nvar && row < row_low * Sys_eqs::nvar + Sys_eqs::nvar)
321  {
322  ke.eq = row - row_low * Sys_eqs::nvar;
323  ke.key = g_map.getGKey(it.get());
324  return ke;
325  }
326 
327  ++it;
328  }
329  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " the row does not map to any position" << "\n";
330 
331  return ke;
332  }
333 
342  inline const std::vector<size_t> padding( const size_t (& sz)[Sys_eqs::dims], Padding<Sys_eqs::dims> & pd)
343  {
344  std::vector<size_t> g_sz_pad(Sys_eqs::dims);
345 
346  for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
347  g_sz_pad[i] = sz[i] + pd.getLow(i) + pd.getHigh(i);
348 
349  return g_sz_pad;
350  }
351 
355  void consistency()
356  {
357  openfpm::vector<triplet> & trpl = A.getMatrixTriplets();
358 
359  // A and B must have the same rows
360  if (row != row_b)
361  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << "the term B and the Matrix A for Ax=B must contain the same number of rows\n";
362 
363  // Indicate all the non zero rows
365  nz_rows.resize(row_b);
366 
367  for (size_t i = 0 ; i < trpl.size() ; i++)
368  nz_rows.get(trpl.get(i).row() - s_pnt*Sys_eqs::nvar) = true;
369 
370  // Indicate all the non zero colums
371  // This check can be done only on single processor
372 
373  Vcluster<> & v_cl = create_vcluster();
374  if (v_cl.getProcessingUnits() == 1)
375  {
377  nz_cols.resize(row_b);
378 
379  for (size_t i = 0 ; i < trpl.size() ; i++)
380  nz_cols.get(trpl.get(i).col()) = true;
381 
382  // all the rows must have a non zero element
383  for (size_t i = 0 ; i < nz_rows.size() ; i++)
384  {
385  if (nz_rows.get(i) == false)
386  {
387  key_and_eq ke = from_row_to_key(i);
388  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i << " is not filled, position " << ke.key.to_string() << " equation: " << ke.eq << "\n";
389  }
390  }
391 
392  // all the colums must have a non zero element
393  for (size_t i = 0 ; i < nz_cols.size() ; i++)
394  {
395  if (nz_cols.get(i) == false)
396  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix colum " << i << " is not filled\n";
397  }
398  }
399  }
400 
411  template<typename Vct, typename Grid_dst ,unsigned int ... pos> void copy_staggered(Vct & v, Grid_dst & g_dst)
412  {
413  // check that g_dst is staggered
414  if (g_dst.is_staggered() == false)
415  std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be staggered " << std::endl;
416 
417 #ifdef SE_CLASS1
418 
419  if (g_map.getLocalDomainSize() != g_dst.getLocalDomainSize())
420  std::cerr << __FILE__ << ":" << __LINE__ << " The staggered and destination grid in size does not match " << std::endl;
421 #endif
422 
423  // sub-grid iterator over the grid map
424  auto g_map_it = g_map.getDomainIterator();
425 
426  // Iterator over the destination grid
427  auto g_dst_it = g_dst.getDomainIterator();
428 
429  while (g_map_it.isNext() == true)
430  {
431  typedef typename to_boost_vmpl<pos...>::type vid;
432  typedef boost::mpl::size<vid> v_size;
433 
434  auto key_src = g_map_it.get();
435  size_t lin_id = g_map.template get<0>(key_src);
436 
437  // destination point
438  auto key_dst = g_dst_it.get();
439 
440  // Transform this id into an id for the Eigen vector
441 
442  copy_ele<Sys_eqs_typ, Grid_dst,Vct> cp(key_dst,g_dst,v,lin_id,g_map.size());
443 
444  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
445 
446  ++g_map_it;
447  ++g_dst_it;
448  }
449  }
450 
461  template<typename Vct, typename Grid_dst ,unsigned int ... pos> void copy_normal(Vct & v, Grid_dst & g_dst)
462  {
463  // check that g_dst is staggered
464  if (g_dst.is_staggered() == true)
465  std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be normal " << std::endl;
466 
469 
470  for (size_t i = 0 ; i < Grid_dst::dims ; i++)
471  {
472  start.set_d(i,pd.getLow(i));
473  stop.set_d(i,g_map.size(i) - pd.getHigh(i));
474  }
475 
476  // sub-grid iterator over the grid map
477  auto g_map_it = g_map.getSubDomainIterator(start,stop);
478 
479  // Iterator over the destination grid
480  auto g_dst_it = g_dst.getDomainIterator();
481 
482  while (g_dst_it.isNext() == true)
483  {
484  typedef typename to_boost_vmpl<pos...>::type vid;
485  typedef boost::mpl::size<vid> v_size;
486 
487  auto key_src = g_map_it.get();
488  size_t lin_id = g_map.template get<0>(key_src);
489 
490  // destination point
491  auto key_dst = g_dst_it.get();
492 
493  // Transform this id into an id for the vector
494 
495  copy_ele<Sys_eqs_typ, Grid_dst,Vct> cp(key_dst,g_dst,v,lin_id,g_map.size());
496 
497  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
498 
499  ++g_map_it;
500  ++g_dst_it;
501  }
502  }
503 
517  template<typename bop, typename iterator>
518  void impose_dit_b(bop num,
519  long int id ,
520  const iterator & it_d)
521  {
522 
523  auto it = it_d;
525 
526  // iterate all the grid points
527  while (it.isNext())
528  {
529  // get the position
530  auto key = it.get();
531 
532  b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num.get(key);
533 
534  // if SE_CLASS1 is defined check the position
535 #ifdef SE_CLASS1
536 // T::position(key,gs,s_pos);
537 #endif
538 
539  ++row_b;
540  ++it;
541  }
542  }
543 
544  template<typename T,typename col, typename trp,typename iterator,typename cmb, typename Key> void impose_git_it(const T & op ,
545  col &cols,
546  trp &trpl,
547  long int &id,
548  const iterator &it_d,
549  cmb &c_where, Key &key, grid_key_dx<Sys_eqs::dims> &shift)
550  { // Calculate the non-zero colums
551  key.getKeyRef() += shift;
552  op.template value_nz<Sys_eqs>(g_map,key,gs,spacing,cols,1.0,0,c_where);
553  key.getKeyRef() -= shift;
554 
555  // indicate if the diagonal has been set
556  bool is_diag = false;
557 
558  // create the triplet
559  for ( auto it = cols.begin(); it != cols.end(); ++it )
560  {
561  trpl.add();
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;
565 
566  if (trpl.last().row() == trpl.last().col())
567  is_diag = true;
568 
569  //std::cout << "(" << trpl.last().row() << "," << trpl.last().col() << "," << trpl.last().value() << ")" << "\n";
570  }
571 
572  // If does not have a diagonal entry put it to zero
573  if (is_diag == false)
574  {
575  trpl.add();
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;
579  }
580 
581  }
582 
598  template<typename T, typename bop, typename iterator> void impose_git(const T & op ,
599  bop num,
600  long int id ,
601  const iterator & it_d,
602  comb<Sys_eqs::dims> c_where)
603  {
604  openfpm::vector<triplet> & trpl = A.getMatrixTriplets();
605 
607  shift.zero();
608  for (int i = 0 ; i < Sys_eqs::dims ; i++)
609  {
610  if (c_where[i] == 1)
611  {
612  shift.set_d(i,1);
613  c_where.c[i] = -1;
614  }
615  }
616 
617  iterator it(it_d,false);
619 
620  std::unordered_map<long int,typename Sys_eqs::stype> cols;
621 
623  zero.zero();
624 
625  if (num.isConstant() == false)
626  {
627  auto it_num = grid.getSubDomainIterator(it.getStart(),it.getStop());
628  // iterate all the grid points
629  while (it.isNext())
630  {
631  // get the position
632  auto key = it.get();
633  auto key_num=it_num.get();
634 
635  impose_git_it(op,cols,trpl,id,it,c_where,key,shift);
636 
637  b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num.get(key_num);
638 
639  cols.clear();
640 
641  // if SE_CLASS1 is defined check the position
642  #ifdef SE_CLASS1
643  // T::position(key,gs,s_pos);
644  #endif
645 
646  ++row;
647  ++row_b;
648  ++it;
649  ++it_num;
650  }
651  }
652  else
653  {
654  // iterate all the grid points
655  while (it.isNext())
656  {
657  // get the position
658  auto key = it.get();
659  // iterate all the grid points
660  impose_git_it(op,cols,trpl,id,it,c_where,key,shift);
661 
662  b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num.get(key);
663 
664  cols.clear();
665 
666  // if SE_CLASS1 is defined check the position
667  #ifdef SE_CLASS1
668  // T::position(key,gs,s_pos);
669  #endif
670  ++row;
671  ++row_b;
672  ++it;
673  }
674  }
675  }
676 
681  {
683 
684  Vcluster<> & v_cl = create_vcluster();
685 
686  // Calculate the size of the local domain
687  size_t sz = g_map.getLocalDomainSize();
688 
689  // Get the total size of the local grids on each processors
690  v_cl.allGather(sz,pnt);
691  v_cl.execute();
692  s_pnt = 0;
693 
694  // calculate the starting point for this processor
695  for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
696  s_pnt += pnt.get(i);
697 
698  // resize b if needed
699  b.resize(Sys_eqs::nvar * g_map.size(),Sys_eqs::nvar * sz);
700 
701  // Calculate the starting point
702 
703  // Counter
704  size_t cnt = 0;
705 
706  // Create the re-mapping grid
707  auto it = g_map.getDomainIterator();
708 
709  while (it.isNext())
710  {
711  auto key = it.get();
712 
713  g_map.template get<0>(key) = cnt + s_pnt;
714 
715  ++cnt;
716  ++it;
717  }
718 
719  // sync the ghost
720  g_map.template ghost_get<0>();
721  }
722 
729  {
730  construct_gmap();
731 
732  // Create a CellDecomposer and calculate the spacing
733 
734  size_t sz_g[Sys_eqs::dims];
735  for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
736  {
737  if (Sys_eqs::boundary[i] == NON_PERIODIC)
738  sz_g[i] = gs.getSize()[i] - 1;
739  else
740  sz_g[i] = gs.getSize()[i];
741  }
742 
743  CellDecomposer_sm<Sys_eqs::dims,typename Sys_eqs::stype> cd(domain,sz_g,0);
744 
745  for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
746  spacing[i] = cd.getCellBox().getHigh(i);
747  }
748 
756  template<typename solType, typename expr_type>
757  void copy_impl(solType & x, expr_type exp, unsigned int comp)
758  {
759  comb<Sys_eqs::dims> c_where;
760  c_where.mone();
761  auto & grid = exp.getGrid();
762 
763  auto it = grid.getDomainIterator();
766 
767  for (int i = 0 ; i < Sys_eqs::dims ; i++)
768  {
769  start.set_d(i,0);
770  stop.set_d(i,grid.size(i)-1);
771  }
772  auto it_map = g_map.getSubDomainIterator(start,stop);
773 
774  while (it.isNext())
775  {
776  auto p = it.get();
777  auto gp = it_map.get();
778 
779  size_t pn = g_map.template get<0>(gp);
780  exp.value_ref(p,c_where) = x(pn*Sys_eqs::nvar + comp);
781 
782  ++it;
783  ++it_map;
784  }
785  }
786 
787  template<typename solType, typename exp1, typename ... othersExp>
788  void copy_nested(solType & x, unsigned int & comp, exp1 exp, othersExp ... exps)
789  {
790  copy_impl(x,exp,comp);
791  comp++;
792 
793  copy_nested(x,comp,exps ...);
794  }
795 
796 
797  template<typename solType, typename exp1>
798  void copy_nested(solType & x, unsigned int & comp, exp1 exp)
799  {
800  copy_impl(x,exp,comp);
801  comp++;
802  }
803 
804 
805 public:
806 
812  void setStagPos(comb<Sys_eqs::dims> (& sp)[Sys_eqs::nvar])
813  {
814  for (size_t i = 0 ; i < Sys_eqs::nvar ; i++)
815  s_pos[i] = sp[i];
816  }
817 
825  void computeStag()
826  {
827  typedef typename Sys_eqs::b_grid::value_type prp_type;
828 
829  openfpm::vector<comb<Sys_eqs::dims>> c_prp[prp_type::max_prop];
830 
832 
833  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,prp_type::max_prop> >(ssp);
834  }
835 
842  {
843  return pd;
844  }
845 
853  const g_map_type & getMap()
854  {
855  return g_map;
856  }
857 
868  grid_type & b_g,
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)
871  {
872  Initialize(b_g.getDomain());
873  }
874 
886  const Ghost<Sys_eqs::dims,long int> & stencil,
887  grid_type & b_g,
888  options_solver opt = options_solver::STANDARD)
889  :grid(b_g),pd(pd),gs(b_g.getGridInfoVoid()),g_map(b_g,stencil,pd),row(0),row_b(0),opt(opt)
890  {
891  Initialize(b_g.getDomain());
892  }
893 
911  template<typename T> void impose(const T & op,
912  const grid_key_dx<Sys_eqs::dims> start_k,
913  const grid_key_dx<Sys_eqs::dims> stop_k,
914  typename Sys_eqs::stype num,
915  eq_id id,
916  comb<Sys_eqs::dims> c_where)
917  {
918  auto it = g_map.getSubDomainIterator(start_k,stop_k);
919 
920  constant_b b(num);
921 
922  impose_git(op,b,id.getId(),it,c_where);
923  }
924 
942  template<typename T,unsigned int prp_id> void impose(const T & op,
943  const grid_key_dx<Sys_eqs::dims> start_k,
944  const grid_key_dx<Sys_eqs::dims> stop_k,
945  prop_id<prp_id> num,
946  eq_id id,
947  comb<Sys_eqs::dims> c_where)
948  {
949  auto it = g_map.getSubDomainIterator(start_k,stop_k);
950 
952 
953  impose_git(op,b,id.getId(),it,c_where);
954  }
955 
971  template<typename T> void impose(const T & op,
972  const grid_key_dx<Sys_eqs::dims> start_k,
973  const grid_key_dx<Sys_eqs::dims> stop_k,
974  const std::function<double(double,double)> &f,
975  eq_id id,
976  comb<Sys_eqs::dims> c_where)
977  {
978  auto it = g_map.getSubDomainIterator(start_k,stop_k);
979 
980  function_b b(g_map, spacing, f, c_where);
981 
982  impose_git(op,b,id.getId(),it,c_where);
983  }
984 
985 
1003  template<typename T> void impose(const T & op,
1004  const grid_key_dx<Sys_eqs::dims> start_k,
1005  const grid_key_dx<Sys_eqs::dims> stop_k,
1006  typename Sys_eqs::stype num,
1007  eq_id id = eq_id(),
1008  bool skip_first = false)
1009  {
1010  comb<Sys_eqs::dims> c_zero;
1011  c_zero.zero();
1012  bool increment = false;
1013  if (skip_first == true)
1014  {
1015  auto it = g_map.getSubDomainIterator(start_k,start_k);
1016 
1017  if (it.isNext() == true)
1018  increment = true;
1019  }
1020 
1021  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1022 
1023  if (increment == true)
1024  ++it;
1025 
1026  constant_b b(num);
1027 
1028  impose_git(op,b,id.getId(),it,c_zero);
1029 
1030  }
1031 
1049  template<typename T, unsigned int prp_id> void impose(const T & op,
1050  const grid_key_dx<Sys_eqs::dims> start_k,
1051  const grid_key_dx<Sys_eqs::dims> stop_k,
1052  prop_id<prp_id> num,
1053  eq_id id = eq_id(),
1054  bool skip_first = false)
1055  {
1056  comb<Sys_eqs::dims> c_zero;
1057  c_zero.zero();
1058  bool increment = false;
1059  if (skip_first == true)
1060  {
1061 
1062  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1063 
1064  if (it.isNext() == true)
1065  increment = true;
1066  }
1067 
1068  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1069 
1070  if (increment == true)
1071  ++it;
1072 
1074 
1075  impose_git(op,b,id.getId(),it,c_zero);
1076 
1077  }
1078 
1096  template<typename T, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type>
1097  void impose(const T & op,const grid_key_dx<Sys_eqs::dims> start_k,
1098  const grid_key_dx<Sys_eqs::dims> stop_k,
1099  const RHS_type &rhs,
1100  eq_id id = eq_id(),
1101  bool skip_first = false)
1102  {
1103  comb<Sys_eqs::dims> c_zero;
1104  c_zero.zero();
1105  bool increment = false;
1106  if (skip_first == true)
1107  {
1108 
1109  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1110 
1111  if (it.isNext() == true)
1112  increment = true;
1113  }
1114 
1115  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1116 
1117  if (increment == true)
1118  ++it;
1119 
1120  //variable_b<prp_id> b(grid);
1121 
1122  impose_git(op,rhs,id.getId(),it,c_zero);
1123 
1124  }
1125 
1141  template<typename T> void impose(const T & op,
1142  const grid_key_dx<Sys_eqs::dims> start_k,
1143  const grid_key_dx<Sys_eqs::dims> stop_k,
1144  const std::function<double(double,double)> &f,
1145  eq_id id = eq_id(),
1146  bool skip_first = false)
1147  {
1148  comb<Sys_eqs::dims> c_zero;
1149  c_zero.zero();
1150  bool increment = false;
1151  if (skip_first == true)
1152  {
1153 
1154  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1155 
1156  if (it.isNext() == true)
1157  increment = true;
1158  }
1159 
1160  auto it = g_map.getSubDomainIterator(start_k,stop_k);
1161 
1162  if (increment == true)
1163  ++it;
1164 
1165  function_b b(grid, spacing, f);
1166 
1167  impose_git(op,b,id.getId(),it,c_zero);
1168 
1169  }
1170 
1174  void new_b()
1175  {row_b = 0;}
1176 
1181  void new_A()
1182  {row = 0;}
1183 
1184 
1186  typename Sys_eqs::SparseMatrix_type A;
1187 
1193  typename Sys_eqs::SparseMatrix_type & getA(options_solver opt = options_solver::STANDARD)
1194  {
1195 #ifdef SE_CLASS1
1196  consistency();
1197 #endif
1198  if (opt == options_solver::STANDARD) {
1199  A.resize(tot * Sys_eqs::nvar, tot * Sys_eqs::nvar,
1200  g_map.getLocalDomainSize() * Sys_eqs::nvar,
1201  g_map.getLocalDomainSize() * Sys_eqs::nvar);
1202  } else
1203  {
1204  auto & v_cl = create_vcluster();
1205  openfpm::vector<triplet> & trpl = A.getMatrixTriplets();
1206 
1207  if (v_cl.rank() == v_cl.size() - 1)
1208  {
1209  A.resize(tot * Sys_eqs::nvar + 1, tot * Sys_eqs::nvar + 1,
1210  g_map.getLocalDomainSize() * Sys_eqs::nvar + 1,
1211  g_map.getLocalDomainSize() * Sys_eqs::nvar + 1);
1212 
1213  for (int i = 0 ; i < tot * Sys_eqs::nvar ; i++)
1214  {
1215  triplet t1;
1216 
1217  t1.row() = tot * Sys_eqs::nvar;
1218  t1.col() = i;
1219  t1.value() = 1;
1220 
1221  trpl.add(t1);
1222  }
1223 
1224  for (int i = 0 ; i < g_map.getLocalDomainSize() * Sys_eqs::nvar ; i++)
1225  {
1226  triplet t2;
1227 
1228  t2.row() = i + s_pnt*Sys_eqs::nvar;
1229  t2.col() = tot * Sys_eqs::nvar;
1230  t2.value() = 1;
1231 
1232  trpl.add(t2);
1233  }
1234 
1235  triplet t3;
1236 
1237  t3.col() = tot * Sys_eqs::nvar;
1238  t3.row() = tot * Sys_eqs::nvar;
1239  t3.value() = 0;
1240 
1241  trpl.add(t3);
1242 
1243  row_b++;
1244  row++;
1245  }
1246  else {
1247  A.resize(tot * Sys_eqs::nvar + 1, tot * Sys_eqs::nvar + 1,
1248  g_map.getLocalDomainSize() * Sys_eqs::nvar,
1249  g_map.getLocalDomainSize() * Sys_eqs::nvar);
1250 
1251  for (int i = 0 ; i < g_map.getLocalDomainSize() * Sys_eqs::nvar ; i++)
1252  {
1253  triplet t2;
1254 
1255  t2.row() = i + s_pnt*Sys_eqs::nvar;
1256  t2.col() = tot * Sys_eqs::nvar;
1257  t2.value() = 1;
1258 
1259  trpl.add(t2);
1260  }
1261  }
1262 
1263 
1264  }
1265 
1266  return A;
1267 
1268  }
1269 
1275  typename Sys_eqs::Vector_type & getB(options_solver opt = options_solver::STANDARD)
1276  {
1277 #ifdef SE_CLASS1
1278  //consistency();
1279 #endif
1280  if (opt == options_solver::LAGRANGE_MULTIPLIER)
1281  {
1282  auto & v_cl = create_vcluster();
1283  if (v_cl.rank() == v_cl.size() - 1) {
1284 
1285  b(tot * Sys_eqs::nvar) = 0;
1286  }
1287  }
1288 
1289 
1290  return b;
1291  }
1292 
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)
1309  {
1311  {
1312  if (g_dst.is_staggered() == true)
1313  copy_staggered<Vct,Grid_dst,pos...>(v,g_dst);
1314  else
1315  {
1316  // Create a temporal staggered grid and copy the data there
1317  auto & g_map = this->getMap();
1318 
1319  // Convert the ghost in grid units
1320 
1322  for (size_t i = 0 ; i < Grid_dst::dims ; i++)
1323  {
1324  g_int.setLow(i,g_map.getDecomposition().getGhost().getLow(i) / g_map.spacing(i));
1325  g_int.setHigh(i,g_map.getDecomposition().getGhost().getHigh(i) / g_map.spacing(i));
1326  }
1327 
1329  stg.setDefaultStagPosition();
1330  copy_staggered<Vct,decltype(stg),pos...>(v,stg);
1331 
1332  // sync the ghost and interpolate to the normal grid
1333  stg.template ghost_get<pos...>();
1334  stg.template to_normal<Grid_dst,pos...>(g_dst,this->getPadding(),start,stop);
1335  }
1336  }
1337  else
1338  {
1339  copy_normal<Vct,Grid_dst,pos...>(v,g_dst);
1340  }
1341  }
1342 
1350  template<typename ... expr_type>
1351  void solve(expr_type ... exps)
1352  {
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;
1358 // umfpack_solver<double> solver;
1359  auto x = solver.solve(getA(opt),getB(opt));
1360 
1361  unsigned int comp = 0;
1362  copy_nested(x,comp,exps ...);
1363  }
1364 
1372  template<typename SolverType, typename ... expr_type>
1373  void solve_with_solver(SolverType & solver, expr_type ... exps)
1374  {
1375 #ifdef SE_CLASS1
1376 
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;};
1381 #endif
1382  auto x = solver.solve(getA(opt),getB(opt));
1383 
1384  unsigned int comp = 0;
1385  copy_nested(x,comp,exps ...);
1386  }
1387 
1388  template<typename SolverType, typename ... expr_type>
1389  void solve_with_constant_nullspace_solver(SolverType & solver, expr_type ... exps)
1390  {
1391 #ifdef SE_CLASS1
1392 
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;};
1397 #endif
1398  auto x = solver.with_constant_nullspace_solve(getA(opt),getB(opt));
1399 
1400  unsigned int comp = 0;
1401  copy_nested(x,comp,exps ...);
1402  }
1403 
1411  template<typename SolverType, typename ... expr_type>
1412  void try_solve_with_solver(SolverType & solver, expr_type ... exps)
1413  {
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;};
1418 
1419  auto x = solver.try_solve(getA(opt),getB(opt));
1420 
1421  unsigned int comp = 0;
1422  copy_nested(x,comp,exps ...);
1423  }
1424 
1438  template<unsigned int ... pos, typename Vct, typename Grid_dst> void copy(Vct & v, Grid_dst & g_dst)
1439  {
1440  long int start[Sys_eqs_typ::dims];
1441  long int stop[Sys_eqs_typ::dims];
1442 
1443  for (size_t i = 0 ; i < Sys_eqs_typ::dims ; i++)
1444  {
1445  start[i] = 0;
1446  stop[i] = g_dst.size(i);
1447  }
1448 
1449  this->copy<pos...>(v,start,stop,g_dst);
1450  }
1451 };
1452 
1453 #define EQS_FIELDS 0
1454 #define EQS_SPACE 1
1455 
1456 
1457 
1458 #endif /* FDSCHEME_NEW_HPP_ */
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.
Definition: FD_Solver.hpp:1049
options_solver opt
solver options
Definition: FD_Solver.hpp:275
comb< Sys_eqs::dims > s_pos[Sys_eqs::nvar]
Staggered position for each property.
Definition: FD_Solver.hpp:284
Sys_eqs::SparseMatrix_type::triplet_type triplet
Sparse matrix triplet type.
Definition: FD_Solver.hpp:254
FD_scheme(const Ghost< Sys_eqs::dims, long int > &stencil, grid_type &b_g, options_solver opt=options_solver::STANDARD)
Constructor.
Definition: FD_Solver.hpp:867
void setDefaultStagPosition()
It set all the properties defined to be staggered on the default location.
base_key & getKeyRef()
Get the reference key.
const grid_sm< Sys_eqs::dims, void > & gs
Domain Grid informations.
Definition: FD_Solver.hpp:260
Finite Differences.
Definition: FD_Solver.hpp:127
openfpm::vector< size_t > pnt
Grid points that has each processor.
Definition: FD_Solver.hpp:281
void try_solve_with_solver(SolverType &solver, expr_type ... exps)
Solve an equation.
Definition: FD_Solver.hpp:1412
size_t getProcessUnitID()
Get the process unit id.
void copy_impl(solType &x, expr_type exp, unsigned int comp)
Solve an equation.
Definition: FD_Solver.hpp:757
const Padding< Sys_eqs::dims > & getPadding()
Get the specified padding.
Definition: FD_Solver.hpp:841
void copy_staggered(Vct &v, Grid_dst &g_dst)
Copy a given solution vector in a staggered grid.
Definition: FD_Solver.hpp:411
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.
Definition: FD_Solver.hpp:222
Sys_eqs::Vector_type b
Vector b.
Definition: FD_Solver.hpp:257
void impose_git(const T &op, bop num, long int id, const iterator &it_d, comb< Sys_eqs::dims > c_where)
Impose an operator.
Definition: FD_Solver.hpp:598
size_t size() const
Return the total number of points in the grid.
__device__ __host__ size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:637
Sys_eqs Sys_eqs_typ
Type that specify the properties of the system of equations.
Definition: FD_Solver.hpp:135
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
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.
Definition: FD_Solver.hpp:132
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.
Definition: FD_Solver.hpp:971
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &k) const
Convert a g_dist_key_dx into a global key.
It store the non zero elements of the matrix.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
size_t tot
Total number of points.
Definition: FD_Solver.hpp:278
const grid_sm< dim, void > & getGridInfoVoid() const
Get an object containing the grid informations without type.
key_and_eq from_row_to_key(size_t row)
From the row Matrix position to the spatial position.
Definition: FD_Solver.hpp:311
Grid key for a distributed grid.
size_t size()
Stub size.
Definition: map_vector.hpp:211
St spacing(size_t i) const
Get the spacing of the grid in direction i.
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.
Definition: FD_Solver.hpp:885
void solve(expr_type ... exps)
Solve an equation.
Definition: FD_Solver.hpp:1351
Definition: Ghost.hpp:39
Sys_eqs::stype get(grid_dist_key_dx< Sys_eqs::dims > &key)
Get the b term on a grid point.
Definition: FD_Solver.hpp:164
Implementation of VCluster class.
Definition: VCluster.hpp:58
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
void execute()
Execute all the requests.
Encapsulation of the b term as constant.
Definition: FD_Solver.hpp:177
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.
void new_A()
In case we want to impose a new A re-using FD_scheme we have to call This function.
Definition: FD_Solver.hpp:1181
It model an expression expr1 * expr2.
Definition: mul.hpp:119
const g_map_type & getMap()
Return the map between the grid index position and the position in the distributed vector.
Definition: FD_Solver.hpp:853
This is a distributed grid.
Implementation of the staggered grid.
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...
size_t eq
equation id
Definition: FD_Solver.hpp:301
void consistency()
Check if the Matrix is consistent.
Definition: FD_Solver.hpp:355
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.
Definition: FD_Solver.hpp:1003
this class is a functor for "for_each" algorithm
Sys_eqs::SparseMatrix_type & getA(options_solver opt=options_solver::STANDARD)
produce the Matrix
Definition: FD_Solver.hpp:1193
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:533
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:740
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.
Definition: mul.hpp:140
size_t row_b
row on b
Definition: FD_Solver.hpp:272
void copy(Vct &v, Grid_dst &g_dst)
Copy the vector into the grid.
Definition: FD_Solver.hpp:1438
void computeStag()
compute the staggered position for each property
Definition: FD_Solver.hpp:825
void solve_with_solver(SolverType &solver, expr_type ... exps)
Solve an equation.
Definition: FD_Solver.hpp:1373
is_grid_staggered analyse T if it has a property grid_type defined and indicate that the grid is stag...
Definition: common.hpp:44
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
Definition: FD_Solver.hpp:342
Sys_eqs::stype spacing[Sys_eqs::dims]
Get the grid spacing.
Definition: FD_Solver.hpp:263
Sys_eqs::stype scal
scalar
Definition: FD_Solver.hpp:143
size_t getProcessingUnits()
Get the total number of processors.
void mone()
Set all the elements to -1.
Definition: comb.hpp:95
Equation id + space position.
Definition: FD_Solver.hpp:295
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)
void zero()
Set all the elements to zero.
Definition: comb.hpp:83
This class represent an N-dimensional box.
Definition: Box.hpp:60
void setStagPos(comb< Sys_eqs::dims >(&sp)[Sys_eqs::nvar])
set the staggered position for each property
Definition: FD_Solver.hpp:812
size_t s_pnt
Definition: FD_Solver.hpp:290
Encapsulation of the b term as constant.
Definition: FD_Solver.hpp:140
void new_b()
In case we want to impose a new b re-using FD_scheme we have to call This function.
Definition: FD_Solver.hpp:1174
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.
Definition: FD_Solver.hpp:1097
void copy_normal(Vct &v, Grid_dst &g_dst)
Copy a given solution vector in a normal grid.
Definition: FD_Solver.hpp:461
void construct_gmap()
Construct the gmap structure.
Definition: FD_Solver.hpp:680
grid_key_dx< Sys_eqs::dims > key
space position
Definition: FD_Solver.hpp:298
void Initialize(const Box< Sys_eqs::dims, typename Sys_eqs::stype > &domain)
Definition: FD_Solver.hpp:728
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.
Definition: FD_Solver.hpp:911
size_t getLocalDomainSize() const
Get the total number of grid points for the calling processor.
Sys_eqs::stype get(grid_dist_key_dx< Sys_eqs::dims > &key)
Get the b term on a grid point.
Definition: FD_Solver.hpp:199
size_t getSub() const
Get the local grid.
Sys_eqs::SparseMatrix_type A
type of the sparse matrix
Definition: FD_Solver.hpp:1186
void zero()
Set to zero the key.
Definition: grid_key.hpp:170
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.
Definition: FD_Solver.hpp:1308
std::string to_string() const
convert the information into a string
Definition: grid_key.hpp:444
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.
Definition: FD_Solver.hpp:942
grid_type & grid
our base grid
Definition: FD_Solver.hpp:248
Encapsulation of the b term as a function.
Definition: FD_Solver.hpp:211
g_map_type g_map
mapping grid
Definition: FD_Solver.hpp:266
Padding< Sys_eqs::dims > pd
Padding.
Definition: FD_Solver.hpp:251
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
this class is a functor for "for_each" algorithm
Definition: Vector_util.hpp:91
constant_b(typename Sys_eqs::stype scal)
Constrictor from a scalar.
Definition: FD_Solver.hpp:150
Sys_eqs::Vector_type & getB(options_solver opt=options_solver::STANDARD)
produce the B vector
Definition: FD_Solver.hpp:1275
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
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.
Definition: FD_Solver.hpp:1141
size_t row
row of the matrix
Definition: FD_Solver.hpp:269
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
void impose_dit_b(bop num, long int id, const iterator &it_d)
Impose an operator.
Definition: FD_Solver.hpp:518
char c[dim]
Array that store the combination.
Definition: comb.hpp:37
variable_b(grid_type &grid)
Constrictor from a scalar.
Definition: FD_Solver.hpp:186