OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
126template<typename Sys_eqs, typename grid_type>
128{
129public:
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
137private:
138
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>
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
212 {
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
285
290 size_t s_pnt;
291
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
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 {
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 {
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
805public:
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
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
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
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_ */
This class represent an N-dimensional box.
Definition Box.hpp:61
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition Box.hpp:556
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition Box.hpp:567
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition Box.hpp:544
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition Box.hpp:533
Finite Differences.
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.
size_t row_b
row on b
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.
size_t s_pnt
Class that contain Padding information on each direction positive and Negative direction.
Definition Ghost.hpp:127
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.
Definition VCluster.hpp:59
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
Definition grid_key.hpp:19
void zero()
Set to zero the key.
Definition grid_key.hpp:170
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition grid_key.hpp:516
std::string to_string() const
convert the information into a string
Definition grid_key.hpp:444
Declaration grid_sm.
Definition grid_sm.hpp:167
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition grid_sm.hpp:760
__device__ __host__ size_t size() const
Return the size of the grid.
Definition grid_sm.hpp:657
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
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
size_t eq
equation id
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.
Definition comb.hpp:35
void mone()
Set all the elements to -1.
Definition comb.hpp:95
void zero()
Set all the elements to zero.
Definition comb.hpp:83
signed char c[dim]
Array that store the combination.
Definition comb.hpp:37
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...
Definition common.hpp:45
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.