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