OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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>;
38template<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>
42class 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
98template<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
340public:
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
1040template<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
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
vect_dist_key_dx get()
Get the actual key.
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(v_pos.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...
Transform the boost::fusion::vector into memory specification (memory_traits)
It model an expression expr1 * expr2.
Definition mul.hpp:120
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
It store the non zero elements of the matrix.