1 #include "SparseLinearSolver.hpp"
2 #include <complex>
3
4 template<class I,class R> typename TheFFSolver<I,R>::MAPSF TheFFSolver<I,R>::ffsolver;
5
setptrstring(string * & ds,const string & s)6 void setptrstring( string * & ds, const string & s)
7 {
8 if(ds) delete ds;
9 ds = new string(s);
10 }
11 template<class R>
Init_sym_positive_var(int syma)12 void Data_Sparse_Solver::Init_sym_positive_var(int syma)
13 {
14 // put the solver name in UPPER CASE
15 std::transform(solver.begin(), solver.end(), solver.begin(), static_cast<int(*)(int)>(std::toupper));
16 auto i= TheFFSolver<int,R>::ffsolver.find(solver);
17 if ( i != TheFFSolver<int,R>::ffsolver.end())
18 {
19 // sym = 0:unsym, sym = 1:herm, sym = 2:sym
20 // 1 unsym , 2 herm, 4 sym, 8 pos , 16 nopos, 32 seq, 64 ompi, 128 mpi ,
21 int ts = i->second->orTypeSol ;
22 sym = syma;
23 // first verification: is the solver compatible with previous syma value ?
24 if ((syma == 0) && ((ts & 1) != 1)) // unsym
25 sym = -1;
26 else if ((syma == 1) && ((ts & 2) != 2)) // herm
27 sym = -1;
28 else if ((syma == 2) && ((ts & 4) != 4)) // sym
29 sym = -1;
30 // if not, choose default value:
31 if (sym == -1) {
32 if ((ts & 1) == 1)
33 sym = 0;
34 else if ((ts & 2) == 2) {
35 sym = 1;
36 }
37 else if ((ts & 4) == 4) {
38 sym = 2;
39 }
40 else {
41 cerr << " bug in orTypeSol for solver " << solver << endl;
42 ffassert(0);
43 }
44 }
45 positive = (ts & (8+16)) == 8;
46 if(verbosity>4)
47 cout << " The solver "<< solver << " need sym "<< sym << " and positif def "
48 << positive << " matrix ( prev sym"<< syma <<" ts " << ts << " ) \n";
49 }
50 else
51 {
52 if( solver == "CHOLESKY") {sym = 1; positive = true;}
53 if( solver == "CROUT") {sym = 1;}
54 if( solver == "CG") {sym = 1;positive=true;}
55 if( solver == "SPARSESOLVERSYM") {sym=1;}
56 if( solver == "CHOLMOD") {sym=1;}
57 }
58 }
59
60 template<class Z,class K>
TypeOfMat(Data_Sparse_Solver & ds)61 int TypeOfMat( Data_Sparse_Solver & ds)
62 {
63 string sn = ds.solver;
64 typedef VirtualMatrix<Z,K> VM;
65 auto i= TheFFSolver<Z,K>::ffsolver.find(sn);
66 int sym=ds.sym, pos = ds.positive;
67 if( sn == "CHOLESKY") {sym = true; pos = true;}
68 if( sn == "CROUT") {sym = true;}
69 if( sn == "CG") {sym = true;pos=true;}
70 if( sn == "SPARSESOLVERSYM") {sym=true;}
71 return sym + pos*2;
72 }
73
74 template<class Z,class K>
Find(HashMatrix<Z,K> & A,const Data_Sparse_Solver & ds,Stack stack)75 typename VirtualMatrix<Z,K>::VSolver * TheFFSolver<Z,K>::Find(HashMatrix<Z,K> &A, const Data_Sparse_Solver & ds,Stack stack )
76 {
77 // 1 unsym , 2 herm, 4 sym, 8 pos , 16 nopos, 32 seq, 64 ompi, 128 mpi
78 // static const int TS_unsym=1, TS_herm=2, TS_sym=4, TS_def_positif=8, TS_not_def_positif=16, TS_sequental = 32, TS_mpi = 64;
79 typedef VirtualMatrix<Z,K> VM;
80 int sym=ds.sym, pos = ds.positive;
81 if(verbosity>3) cout << " ** Search solver "<< ds.solver << " sym = " << sym << " pos. " << pos << " half "<< A.half <<endl;
82
83 string sn = ds.solver;
84 std::transform(sn.begin(), sn.end(), sn.begin(), static_cast<int(*)(int)>(std::toupper));
85
86 int typesolve = (sym ? VM::TS_sym: VM::TS_unsym ) + (pos ? VM::TS_def_positif : VM::TS_not_def_positif );
87 auto i= ffsolver.find(sn);
88 auto ii=i;
89 int pp=-1;
90 if( i == ffsolver.end()) // choose the best ???
91 for ( auto j = ffsolver.begin() ; j != ffsolver.end() ; ++j)
92 {
93 int ts=j->second->orTypeSol;
94 int p=j->second->p;
95 if( (ts & typesolve) == typesolve ) // compiatile
96 {
97
98 if( pp < p)
99 {
100 i=j; // the last ???
101 pp=p;
102 if(verbosity>9)
103 cout << " find solver " << i->first << " "<< p << " / " << typesolve << " in "<< ts << endl;
104 }
105
106 }
107 else
108 if(verbosity>9)
109 cout << " not find solver " << i->first << " "<< p << " / " << typesolve << " in "<< ts << endl;
110
111
112 }
113
114 if( i != ffsolver.end())
115 {
116 if(verbosity>2) cout << " ** Find solver "<< i->first << " ts: "<< i->second->orTypeSol
117 << " sym = " << sym << " pos. " << pos << " half "<< A.half <<endl;
118
119 return i->second->create(A,ds,stack);
120 }
121 else
122 {
123 cerr << " TheFFSolver<Z,K>::FATAL ERROR impossible to find solver \n"
124 << " want "<< ds.solver << " type " << typesolve << endl;
125 cerr << " dispo \n";
126 for ( auto j = ffsolver.begin() ; j != ffsolver.end() ; ++j)
127 {
128 cerr << j->first << " orTypeSol: " << j->second->orTypeSol <<endl;
129 }
130 ExecError(" No Solver ????");
131 return 0;
132 }
133
134 }
135
136
137 template<class R>
SetSolver(Stack stack,bool VF,VirtualMatrix<int,R> & A,const Data_Sparse_Solver & ds)138 void SetSolver(Stack stack,bool VF,VirtualMatrix<int,R> & A,const Data_Sparse_Solver & ds)
139 {
140 using namespace Fem2D;
141 typename VirtualMatrix<int,R>::VSolver * solver=0;
142 HashMatrix<int,R> * AH(dynamic_cast<HashMatrix<int,R> *>(&A));
143 ffassert(AH);
144 solver = NewVSolver<int,R>(*AH,ds,stack);
145 if(solver)
146 {
147 A.SetSolver(solver,true);
148 if(ds.factorize)
149 {
150 solver->factorize(ds.factorize);// full factorization mars 2019 FH/PHT
151 }
152 }
153 else
154 CompileError("SetSolver: type resolution unknown");
155
156 }
157
158
159 template<class R>
DefSolver(Stack stack,VirtualMatrix<int,R> & A,const Data_Sparse_Solver & ds)160 void DefSolver(Stack stack, VirtualMatrix<int,R> & A,const Data_Sparse_Solver & ds)
161 {
162 typename VirtualMatrix<int,R>::VSolver * solver=0;
163 HashMatrix<int,R>* AH(dynamic_cast<HashMatrix<int,R> *>(&A));
164 ffassert(AH);
165
166 solver = NewVSolver<int,R>(*AH,ds,stack);
167
168 if(solver)
169 A.SetSolver(solver,true);
170 else
171 CompileError("SetSolver: type resolution unknown");
172
173
174 }
175
176 typedef double R;
177 typedef complex<double> C;
178
179 // explicit instentition of solver ...
180 std::map<std::string,int> * Data_Sparse_Solver::mds = Data_Sparse_Solver::Set_mds();
181
init_SparseLinearSolver()182 void init_SparseLinearSolver()
183 {
184 InitSolver<int,R>();
185 InitSolver<int,C>();
186 }
187
188 template class SparseLinearSolver<int,R>;
189 template class SparseLinearSolver<int,C>;
190
191 template class TheFFSolver<int,R>;
192 template class TheFFSolver<int,C>;
193
194 template int TypeOfMat<int,R>( Data_Sparse_Solver & ds);
195 template int TypeOfMat<int,C>( Data_Sparse_Solver & ds);
196
197 template void Data_Sparse_Solver::Init_sym_positive_var<R>(int );
198 template void Data_Sparse_Solver::Init_sym_positive_var<C>(int );
199
200 template void SetSolver(Stack stack,bool VF,VirtualMatrix<int,R> & A, const Data_Sparse_Solver & ds);
201 template void SetSolver(Stack stack,bool VF,VirtualMatrix<int,C> & A, const Data_Sparse_Solver & ds);
202
203 template void DefSolver(Stack stack, VirtualMatrix<int,R> & A,const Data_Sparse_Solver & ds);
204 template void DefSolver(Stack stack, VirtualMatrix<int,C> & A,const Data_Sparse_Solver & ds);
205