OpenFPM  5.2.0
Project that contain the implementation of distributed structures
DCPSE_Solver.hpp
1 //
2 // Created by Abhinav Singh on 20.01.20.
3 //
4 
5 #ifndef OPENFPM_PDATA_DCPSE_SOLVER_HPP
6 #define OPENFPM_PDATA_DCPSE_SOLVER_HPP
7 #ifdef HAVE_EIGEN
8 
9 
10 #include "DCPSE_op.hpp"
11 #include "Matrix/SparseMatrix.hpp"
12 #include "Vector/Vector.hpp"
13 #include "NN/CellList/CellDecomposer.hpp"
14 #include "Vector/Vector_util.hpp"
15 #include "Vector/vector_dist.hpp"
16 #include "Solvers/umfpack_solver.hpp"
17 #include "Solvers/petsc_solver.hpp"
18 #include "util/eq_solve_common.hpp"
19 
20 /*enum eq_struct
21 {
22  VECTOR,
23  SCALAR
24 };*/
25 
26 //template<unsigned int prp_id> using prop_id = boost::mpl::int_<prp_id>;
38 template<typename Sys_eqs,
39  typename particles_type,
40  typename Memory = typename Sys_eqs::b_part::Memory_type,
41  template<typename> class layout_base = memory_traits_lin>
42 class DCPSE_scheme {
43 
45  typename Sys_eqs::SparseMatrix_type A;
46 
48  typename Sys_eqs::Vector_type b;
49 
51  typename Sys_eqs::Vector_type x_ig;
52 
54  typedef typename Sys_eqs::SparseMatrix_type::triplet_type triplet;
55 
57  typedef vector_dist< Sys_eqs::dims,
58  typename Sys_eqs::stype, aggregate<size_t>,
59  typename Sys_eqs::b_part::Decomposition_type,
60  typename Sys_eqs::b_part::Memory_type,
61  layout_base> p_map_type;
62 
64  p_map_type p_map;
65 
68 
70  particles_type &parts;
71 
73  //int col_sm[Sys_eqs::nvar];
74 
79  size_t s_pnt;
80 
82  size_t row;
83 
85  size_t row_b;
86 
88  size_t row_x_ig;
89 
91  size_t tot;
92 
94  options_solver opt;
95 
96  size_t offset;
97 
98 template<typename options>
102  void construct_pmap(options opt = options_solver::STANDARD) {
103  Vcluster<> &v_cl = create_vcluster();
104 
105  // Calculate the size of the local domain
106  size_t sz = p_map.size_local();
107 
108  // Get the total size of the local grids on each processors
109  v_cl.allGather(sz, pnt);
110  v_cl.execute();
111  s_pnt = 0;
112 
113  // calculate the starting point for this processor
114  for (size_t i = 0; i < v_cl.getProcessUnitID(); i++)
115  s_pnt += pnt.get(i);
116 
117  tot = sz;
118  v_cl.sum(tot);
119  v_cl.execute();
120 
121  // resize b if needed
122  if (opt == options_solver::STANDARD) {
123  b.resize(Sys_eqs::nvar * tot, Sys_eqs::nvar * sz);
124  x_ig.resize(Sys_eqs::nvar * tot, Sys_eqs::nvar * sz);
125 
126  } else if (opt == options_solver::LAGRANGE_MULTIPLIER) {
127  if (v_cl.rank() == v_cl.size() - 1) {
128  b.resize(Sys_eqs::nvar * (tot + 1), Sys_eqs::nvar * (sz + 1));
129  x_ig.resize(Sys_eqs::nvar * (tot + 1), Sys_eqs::nvar * (sz + 1));
130  } else {
131  b.resize(Sys_eqs::nvar * (tot + 1), Sys_eqs::nvar * sz);
132  x_ig.resize(Sys_eqs::nvar * (tot + 1), Sys_eqs::nvar * sz);
133  }
134  }
135  //Use Custom number of constraints using opt as an integer
136  else {
137  if (v_cl.rank() == v_cl.size() - 1) {
138  b.resize(Sys_eqs::nvar * tot - offset, Sys_eqs::nvar * sz - offset);
139  x_ig.resize(Sys_eqs::nvar * tot - offset, Sys_eqs::nvar * sz - offset);
140  } else {
141  b.resize(Sys_eqs::nvar * tot - offset, Sys_eqs::nvar * sz);
142  x_ig.resize(Sys_eqs::nvar * tot - offset, Sys_eqs::nvar * sz);
143  }
144  }
145 
146  // Calculate the starting point
147 
148  // Counter
149  size_t cnt = 0;
150 
151  // Create the re-mapping grid
152  auto it = p_map.getDomainIterator();
153 
154  while (it.isNext()) {
155  auto key = it.get();
156 
157  for (int i = 0; i < particles_type::dims; i++) {
158  p_map.getPos(key)[i] = parts.getPos(key)[i];
159  }
160 
161  p_map.template getProp<0>(key) = cnt + s_pnt;
162 
163  ++cnt;
164  ++it;
165  }
166 
167  // sync the ghost
168  p_map.template ghost_get<0>();
169  }
170 
172  struct constant_b {
174  typename Sys_eqs::stype scal;
175 
181  constant_b(typename Sys_eqs::stype scal) {
182  this->scal = scal;
183  }
184 
194  typename Sys_eqs::stype get(size_t key) {
195  return scal;
196  }
197  };
198 
200  template<unsigned int prp_id>
201  struct variable_b {
203  typename Sys_eqs::stype scal;
204 
205  particles_type &parts;
206 
212  variable_b(particles_type &parts)
213  : parts(parts) {}
214 
224  inline typename Sys_eqs::stype get(size_t key) {
225  return parts.template getProp<prp_id>(key);
226  }
227  };
228 
229 
233  void consistency(options_solver opt)
234  {
235  openfpm::vector<triplet> &trpl = A.getMatrixTriplets();
236  Vcluster<> &v_cl = create_vcluster();
237 
238  // A and B must have the same rows
239  if (row != row_b) {
240  std::cerr << "Error " << __FILE__ << ":" << __LINE__
241  << " the term B and the Matrix A for Ax=B must contain the same number of rows " << row
242  << "!=" << row_b << "\n";
243  return;
244  }
245 
246  if (row_b != p_map.size_local() * Sys_eqs::nvar) {
247  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " your system is underdetermined you set "
248  << row_b << " conditions " << " but i am expecting " << p_map.size_local() * Sys_eqs::nvar
249  << std::endl;
250  return;
251  }
252  // Indicate all the non zero rows
254 
255 
256  if (v_cl.rank() == v_cl.size()-1 && opt == options_solver::LAGRANGE_MULTIPLIER) {
257  nz_rows.resize(row_b+Sys_eqs::nvar);
258  }
259  else{
260  nz_rows.resize(row_b);
261  };
262 
263  for (size_t i = 0; i < trpl.size(); i++) {
264  if (trpl.get(i).row() - s_pnt * Sys_eqs::nvar >= nz_rows.size()) {
265  std::cerr << "Error " << __FILE__ << ":" << __LINE__
266  << " It seems that you are setting colums that does not exist \n";
267  }
268  if (trpl.get(i).value() != 0) { nz_rows.get(trpl.get(i).row() - s_pnt * Sys_eqs::nvar) = true; }
269  }
270 
271  // Indicate all the non zero colums
272  // This check can be done only on single processor
273 
274  if (v_cl.getProcessingUnits() == 1) {
276  if (v_cl.rank() == v_cl.size()-1 && opt == options_solver::LAGRANGE_MULTIPLIER) {
277  nz_cols.resize(row_b+Sys_eqs::nvar);
278  }
279  else{
280  nz_cols.resize(row_b);
281  };
282 
283  for (size_t i = 0; i < trpl.size(); i++) {
284  if (trpl.get(i).value() != 0) { nz_cols.get(trpl.get(i).col()) = true; }
285  }
286 
287  // all the rows must have a non zero element
288  for (size_t i = 0; i < nz_rows.size(); i++) {
289  if (nz_rows.get(i) == false) {
290  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i
291  << " is not filled " << " equation: " << "\n";
292  }
293  }
294 
295  // all the colums must have a non zero element
296  for (size_t i = 0; i < nz_cols.size(); i++) {
297  if (nz_cols.get(i) == false)
298  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix colum " << i
299  << " is not filled\n";
300  }
301  }
302  }
303 
311  template<typename solType, typename expr_type>
312  void copy_impl(solType & x, expr_type exp, unsigned int comp)
313  {
314  auto & parts = exp.getVector();
315 
316  auto it = parts.getDomainIterator();
317 
318  while (it.isNext()) {
319  auto p = it.get();
320  exp.value(p) = x(p.getKey() * Sys_eqs::nvar + comp + s_pnt * Sys_eqs::nvar);
321  ++it;
322  }
323  }
324 
325  template<typename solType, typename exp1, typename ... othersExp>
326  void copy_nested(solType &x, unsigned int &comp, exp1 exp, othersExp ... exps) {
327  copy_impl(x, exp, comp);
328  comp++;
329 
330  copy_nested(x, comp, exps ...);
331  }
332 
333 
334  template<typename solType, typename exp1>
335  void copy_nested(solType &x, unsigned int &comp, exp1 exp) {
336  copy_impl(x, exp, comp);
337  comp++;
338  }
339 
340 public:
341 
351 /* void setEquationStructure(std::initializer_list<eq_struct> l)
352  {
353  int i = 0;
354  for (eq_struct e : l)
355  {
356  if (e == eq_struct::VECTOR)
357  {
358  for (int j = 0 ; j < Sys_eqs::dims ; j++)
359  {
360  col_sm[i+j] = i;
361  }
362  i += Sys_eqs::dims;
363  }
364  else
365  {
366  col_sm[i] = i;
367  }
368  }
369  }*/
370 
371 
379  template<typename ... expr_type>
380  void solve(expr_type ... exps) {
381  if (sizeof...(exps) != Sys_eqs::nvar) {
382  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
383  dimensionality, I am expecting " << Sys_eqs::nvar <<
384  " properties " << std::endl;
385  };
386  typename Sys_eqs::solver_type solver;
387 // umfpack_solver<double> solver;
388  auto x = solver.solve(getA(opt), getB(opt));
389 
390  unsigned int comp = 0;
391  copy_nested(x, comp, exps ...);
392  }
393 
402  template<typename SolverType, typename ... expr_type>
403  void solve_with_solver(SolverType &solver, expr_type ... exps) {
404 #ifdef SE_CLASS1
405 
406  if (sizeof...(exps) != Sys_eqs::nvar) {
407  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
408  dimensionality, I am expecting " << Sys_eqs::nvar <<
409  " properties " << std::endl;
410  };
411 #endif
412  auto x = solver.solve(getA(opt), getB(opt));
413 
414  unsigned int comp = 0;
415  copy_nested(x, comp, exps ...);
416  }
417 
426  template<typename SolverType, typename ... expr_type>
427  void solve_with_solver_ig(SolverType &solver,expr_type ... exps) {
428 #ifdef SE_CLASS1
429 
430  if (sizeof...(exps) != Sys_eqs::nvar) {
431  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
432  dimensionality, I am expecting " << Sys_eqs::nvar <<
433  " properties " << std::endl;
434  };
435 #endif
436  auto x = solver.solve(getA(opt),get_x_ig(opt),getB(opt));
437 
438  unsigned int comp = 0;
439  copy_nested(x, comp, exps ...);
440  }
441 
450  template<typename SolverType, typename ... expr_type>
451  void solve_with_solver_successive(SolverType &solver,expr_type ... exps) {
452 #ifdef SE_CLASS1
453 
454  if (sizeof...(exps) != Sys_eqs::nvar) {
455  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
456  dimensionality, I am expecting " << Sys_eqs::nvar <<
457  " properties " << std::endl;
458  };
459 #endif
460  auto x = solver.solve_successive(getB(opt));
461 
462  unsigned int comp = 0;
463  copy_nested(x, comp, exps ...);
464  }
465 
474  template<typename SolverType, typename ... expr_type>
475  void solve_with_solver_ig_successive(SolverType &solver,expr_type ... exps) {
476 #ifdef SE_CLASS1
477 
478  if (sizeof...(exps) != Sys_eqs::nvar) {
479  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
480  dimensionality, I am expecting " << Sys_eqs::nvar <<
481  " properties " << std::endl;
482  };
483 #endif
484  auto x = solver.solve_successive(get_x_ig(opt),getB(opt));
485 
486  unsigned int comp = 0;
487  copy_nested(x, comp, exps ...);
488  }
489 
498 /* template<typename NullspaceType, typename SolverType, typename ... expr_type>
499  void solve_with_nullspace_solver(NullspaceType &nullspace,SolverType &solver, expr_type ... exps) {
500 #ifdef SE_CLASS1
501 
502  if (sizeof...(exps) != Sys_eqs::nvar) {
503  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
504  dimensionality, I am expecting " << Sys_eqs::nvar <<
505  " properties " << std::endl;
506  };
507 #endif
508  auto x = solver.nullspace_solve(nullspace,getA(opt), getB(opt));
509 
510  unsigned int comp = 0;
511  copy_nested(x, comp, exps ...);
512  }*/
513 
522  template<typename SolverType, typename ... expr_type>
523  void solve_with_default_nullspace_solver(SolverType &solver, expr_type ... exps) {
524 #ifdef SE_CLASS1
525 
526  if (sizeof...(exps) != Sys_eqs::nvar) {
527  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
528  dimensionality, I am expecting " << Sys_eqs::nvar <<
529  " properties " << std::endl;
530  };
531 #endif
532  auto x = solver.with_nullspace_solve(getA(opt), getB(opt));
533 
534  unsigned int comp = 0;
535  copy_nested(x, comp, exps ...);
536  }
537 
545  template<typename SolverType, typename ... expr_type>
546  void try_solve_with_solver(SolverType &solver, expr_type ... exps) {
547  if (sizeof...(exps) != Sys_eqs::nvar) {
548  std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\
549  dimensionality, I am expecting " << Sys_eqs::nvar <<
550  " properties " << std::endl;
551  };
552 
553  auto x = solver.try_solve(getA(opt), getB(opt));
554 
555  unsigned int comp = 0;
556  copy_nested(x, comp, exps ...);
557  }
558 
559  void reset_b()
560  {
561  row_b = 0;
562  }
563  void reset_x_ig()
564  {
565  row_x_ig = 0;
566  }
567 
568  void reset(particles_type &part, options_solver opt = options_solver::STANDARD)
569  {
570  row = 0;
571  row_b = 0;
572  row_x_ig = 0;
573 
574 
575  p_map.clear();
576  p_map.resize(part.size_local());
577 
578  A.getMatrixTriplets().clear();
579 
580  construct_pmap(opt);
581  }
582 
583  void reset_nodec()
584  {
585  row = 0;
586  row_b = 0;
587  row_x_ig = 0;
588 
589  A.getMatrixTriplets().clear();
590  }
591 
599  DCPSE_scheme(particles_type &part, options_solver opt = options_solver::STANDARD)
600  : parts(part), p_map(part.getDecomposition(), 0), row(0), row_b(0), opt(opt) {
601  p_map.resize(part.size_local());
602 
603  construct_pmap(opt);
604  }
605 
606  /*DCPSE_scheme(particles_type &part, int option_num)
607  : parts(part), p_map(part.getDecomposition(), 0), row(0), row_b(0),opt(options_solver::CUSTOM),offset(option_num) {
608  p_map.resize(part.size_local());
609  construct_pmap(option_num);
610  }*/
611 
612 
626  template<typename T, typename index_type, unsigned int prp_id>
627  void impose(const T &op, openfpm::vector<index_type> &subset,
628  const prop_id<prp_id> &num,
629  eq_id id = eq_id()) {
630  auto itd = subset.template getIteratorElements<0>();
631 
632  variable_b<prp_id> vb(parts);
633 
634  impose_git(op, vb, id.getId(), itd);
635  }
636 
647  template<typename index_type, unsigned int prp_id>
648  void impose_b(openfpm::vector<index_type> &subset,
649  const prop_id<prp_id> &num,
650  eq_id id = eq_id()) {
651  auto itd = subset.template getIteratorElements<0>();
652 
653  variable_b<prp_id> vb(parts);
654 
655  impose_git_b(vb, id.getId(), itd);
656  }
657 
668  template<typename index_type, unsigned int prp_id>
669  void impose_x_ig(openfpm::vector<index_type> &subset,
670  const prop_id<prp_id> &num,
671  eq_id id = eq_id()) {
672  auto itd = subset.template getIteratorElements<0>();
673 
674  variable_b<prp_id> vx(parts);
675 
676  impose_git_x(vx, id.getId(), itd);
677  }
678 
692  template<typename T, typename index_type, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type>
693  void impose(const T &op, openfpm::vector<index_type> &subset,
694  const RHS_type &rhs,
695  eq_id id = eq_id()) {
696  auto itd = subset.template getIteratorElements<0>();
697 
698  impose_git(op, rhs, id.getId(), itd);
699  }
711  template<typename index_type, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type>
712  void impose_b(openfpm::vector<index_type> &subset,
713  const RHS_type &rhs,
714  eq_id id = eq_id()) {
715  auto itd = subset.template getIteratorElements<0>();
716  impose_git_b(rhs, id.getId(), itd);
717  }
727  template<typename index_type, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type>
728  void impose_x_ig(openfpm::vector<index_type> &subset,
729  const RHS_type &rhs,
730  eq_id id = eq_id()) {
731  auto itd = subset.template getIteratorElements<0>();
732  impose_git_x(rhs, id.getId(), itd);
733  }
734 
748  template<typename T, typename index_type>
749  void impose(const T &op,
751  const typename Sys_eqs::stype num,
752  eq_id id = eq_id()) {
753  auto itd = subset.template getIteratorElements<0>();
754 
755  constant_b b(num);
756 
757  impose_git(op, b, id.getId(), itd);
758  }
770  template< typename index_type>
771  void impose_b(openfpm::vector<index_type> &subset,
772  const typename Sys_eqs::stype num,
773  eq_id id = eq_id()) {
774  auto itd = subset.template getIteratorElements<0>();
775 
776  constant_b b(num);
777 
778  impose_git_b(b, id.getId(), itd);
779  }
780 
792  template< typename index_type>
793  void impose_x_ig(openfpm::vector<index_type> &subset,
794  const typename Sys_eqs::stype num,
795  eq_id id = eq_id()) {
796  auto itd = subset.template getIteratorElements<0>();
797 
798  constant_b x_ig(num);
799 
800  impose_git_x(x_ig, id.getId(), itd);
801  }
802 
808  template<typename options>
809  typename Sys_eqs::SparseMatrix_type &getA(options opt) {
810  if (A.isMatrixFilled()) return A;
811  if (opt == options_solver::STANDARD) {
812  A.resize(tot * Sys_eqs::nvar, tot * Sys_eqs::nvar,
813  p_map.size_local() * Sys_eqs::nvar,
814  p_map.size_local() * Sys_eqs::nvar);
815  }
816  else if (opt == options_solver::LAGRANGE_MULTIPLIER) {
817  auto &v_cl = create_vcluster();
818  openfpm::vector<triplet> &trpl = A.getMatrixTriplets();
819 
820  if (v_cl.rank() == v_cl.size() - 1) {
821  A.resize(Sys_eqs::nvar * (tot + 1), Sys_eqs::nvar * (tot + 1),
822  Sys_eqs::nvar * (p_map.size_local() + 1),
823  Sys_eqs::nvar * (p_map.size_local() + 1));
824 
825  for (int j = 0; j < Sys_eqs::nvar; j++) {
826  for (int i = 0; i < tot; i++) {
827  triplet t1;
828  t1.row() = tot * Sys_eqs::nvar + j;
829  t1.col() = i * Sys_eqs::nvar + j;
830  t1.value() = 1;
831  trpl.add(t1);
832  }
833  for (int i = 0; i < p_map.size_local(); i++) {
834  triplet t2;
835  t2.row() = s_pnt * Sys_eqs::nvar + i * Sys_eqs::nvar + j;
836  t2.col() = tot * Sys_eqs::nvar + j;
837  t2.value() = 1;
838  trpl.add(t2);
839  }
840  triplet t3;
841  t3.col() = tot * Sys_eqs::nvar + j;
842  t3.row() = tot * Sys_eqs::nvar + j;
843  t3.value() = 0;
844  trpl.add(t3);
845  }
846  } else {
847  A.resize(Sys_eqs::nvar * (tot + 1), Sys_eqs::nvar * (tot + 1),
848  p_map.size_local() * Sys_eqs::nvar,
849  p_map.size_local() * Sys_eqs::nvar);
850  for (int j = 0; j < Sys_eqs::nvar; j++) {
851  for (int i = 0; i < p_map.size_local(); i++) {
852  triplet t2;
853  t2.row() = s_pnt * Sys_eqs::nvar + i * Sys_eqs::nvar + j;
854  t2.col() = tot * Sys_eqs::nvar + j;
855  t2.value() = 1;
856  trpl.add(t2);
857  }
858  }
859  }
860  }
861  else{
862  auto &v_cl = create_vcluster();
863  if (v_cl.rank() == v_cl.size() - 1) {
864  A.resize(tot * Sys_eqs::nvar - offset, tot * Sys_eqs::nvar - offset,
865  p_map.size_local() * Sys_eqs::nvar - offset,
866  p_map.size_local() * Sys_eqs::nvar - offset);
867  }
868  else {
869  A.resize(tot * Sys_eqs::nvar - offset, tot * Sys_eqs::nvar - offset,
870  p_map.size_local() * Sys_eqs::nvar,
871  p_map.size_local() * Sys_eqs::nvar);
872  }
873  }
874 #ifdef SE_CLASS1
875  consistency(opt);
876 #endif
877  return A;
878 
879  }
880 
886  typename Sys_eqs::Vector_type &getB(options_solver opt = options_solver::STANDARD) {
887 /*#ifdef SE_CLASS1
888  consistency(opt);
889 #endif*/
890  if (opt == options_solver::LAGRANGE_MULTIPLIER) {
891  auto &v_cl = create_vcluster();
892  if (v_cl.rank() == v_cl.size() - 1) {
893  for(int j=0;j<Sys_eqs::nvar;j++)
894  {b(tot * Sys_eqs::nvar+j) = 0;}
895  }
896  }
897  return b;
898  }
899 
905  typename Sys_eqs::Vector_type &get_x_ig(options_solver opt = options_solver::STANDARD) {
906 /*#ifdef SE_CLASS1
907  consistency(opt);
908 #endif*/
909  if (opt == options_solver::LAGRANGE_MULTIPLIER) {
910  auto &v_cl = create_vcluster();
911  if (v_cl.rank() == v_cl.size() - 1) {
912  for(int j=0;j<Sys_eqs::nvar;j++)
913  {x_ig(tot * Sys_eqs::nvar+j) = 0;}
914  }
915  }
916  return x_ig;
917  }
918 
919 
920  template<typename bop, typename iterator>
921  void impose_git_b(bop num,
922  long int id,
923  const iterator &it_d) {
924  auto it = it_d;
925  // iterate all particles points
926  while (it.isNext()) {
927  // get the particle
928  auto key = it.get();
929  // Calculate the non-zero colums
930  b(p_map.template getProp<0>(key) * Sys_eqs::nvar + id) = num.get(key);
931 // std::cout << "b=(" << p_map.template getProp<0>(key)*Sys_eqs::nvar + id << "," << num.get(key)<<")" <<"\n";
932 
933  // if SE_CLASS1 is defined check the position
934 #ifdef SE_CLASS1
935  // T::position(key,gs,s_pos);
936 #endif
937  ++row_b;
938  ++it;
939  }
940  }
941 
942  template<typename xop, typename iterator>
943  void impose_git_x(xop num,
944  long int id,
945  const iterator &it_d) {
946  auto it = it_d;
947  // iterate all particles points
948  while (it.isNext()) {
949  // get the particle
950  auto key = it.get();
951  // Calculate the non-zero colums
952  x_ig(p_map.template getProp<0>(key) * Sys_eqs::nvar + id) = num.get(key);
953 // std::cout << "b=(" << p_map.template getProp<0>(key)*Sys_eqs::nvar + id << "," << num.get(key)<<")" <<"\n";
954 
955  // if SE_CLASS1 is defined check the position
956 #ifdef SE_CLASS1
957  // T::position(key,gs,s_pos);
958 #endif
959  ++row_x_ig;
960  ++it;
961  }
962  }
963 
964 
980  template<typename T, typename bop, typename iterator>
981  void impose_git(const T &op,
982  bop num,
983  long int id,
984  const iterator &it_d) {
985  openfpm::vector<triplet> &trpl = A.getMatrixTriplets();
986 
987  auto it = it_d;
988 
989  //std::unordered_map<long int, typename particles_type::stype> cols;
990 
992 
993  // iterate all particles points
994  while (it.isNext()) {
995  // get the particle
996  auto key = it.get();
997 
998  // Calculate the non-zero colums
999  typename Sys_eqs::stype coeff = 1.0;
1000  op.template value_nz<Sys_eqs>(p_map, key, cols, coeff, 0);
1001 
1002  // indicate if the diagonal has been set
1003  bool is_diag = false;
1004 
1005  // create the triplet
1006  for (auto it2 = cols.begin(); it2 != cols.end(); ++it2) {
1007  trpl.add();
1008  trpl.last().row() = p_map.template getProp<0>(key) * Sys_eqs::nvar + id;
1009  trpl.last().col() = it2->first;
1010  trpl.last().value() = it2->second;
1011  if (trpl.last().row() == trpl.last().col())
1012  {is_diag = true;}
1013  }
1014 
1015  // If does not have a diagonal entry put it to zero
1016  if (is_diag == false)
1017  {
1018  trpl.add();
1019  trpl.last().row() = p_map.template getProp<0>(key) * Sys_eqs::nvar + id;
1020  trpl.last().col() = p_map.template getProp<0>(key) * Sys_eqs::nvar + id;
1021  trpl.last().value() = 0.0;
1022  }
1023  b(p_map.template getProp<0>(key) * Sys_eqs::nvar + id) = num.get(key);
1024  cols.clear();
1025 
1026  // if SE_CLASS1 is defined check the position
1027 #ifdef SE_CLASS1
1028  // T::position(key,gs,s_pos);
1029 #endif
1030 
1031  ++row;
1032  ++row_b;
1033  ++row_x_ig;
1034  ++it;
1035  }
1036  }
1037 
1038 };
1039 
1040 template<typename Sys_eqs, typename particles_type> using DCPSE_scheme_gpu = DCPSE_scheme<Sys_eqs,particles_type,CudaMemory,memory_traits_inte>;
1041 
1042 #include "DCPSE/DCPSE_op/EqnsStruct.hpp"
1043 #endif //Eigen
1044 #endif //OPENFPM_PDATA_DCPSE_SOLVER_HPP
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
size_t size()
Get the total number of processors.
void sum(T &num)
Sum the numbers across all processors and get the result.
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.
Definition: VCluster.hpp:59
size_t size()
Stub size.
Definition: map_vector.hpp:212
Distributed vector.
size_t size_local() const
return the local size of the vector
void resize(size_t rs)
Resize the vector (locally)
static const unsigned int dims
template parameters typedefs
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:221
Transform the boost::fusion::vector into memory specification (memory_traits)
It store the non zero elements of the matrix.