1 //
2 //  Gradsolvmat.cpp
3 //  pbsam_xcode
4 //
5 //  Created by David Brookes on 6/20/16.
6 //  Copyright © 2016 David Brookes. All rights reserved.
7 //
8 
9 #include "Gradsolvmat.h"
10 
11 
reset_mat()12 void GradCmplxMolMat::reset_mat()
13 {
14   for (int k = 0; k < mat_.size(); k++)
15   {
16     for (int i = 0; i < mat_[k].get_nrows(); i++)
17     {
18       for (int j = 0; j < mat_[k].get_ncols(); j++)
19       {
20         mat_[k].set_val(i, j, Ptx());
21       }
22     }
23   }
24 }
25 
26 
reset_mat(int k)27 void GradNumericalMat::reset_mat(int k)
28 {
29   for (int i = 0; i < mat_cmplx_[k].get_nrows(); i++)
30   {
31     for (int j = 0; j < mat_cmplx_[k].get_ncols(); j++)
32     {
33       mat_cmplx_[k].set_val(i, j, cmplx(0, 0));
34     }
35   }
36 
37 }
38 
GradWFMatrix(int I,int wrt,int ns,int p,double eps_in,double eps_out,double kappa)39 GradWFMatrix::GradWFMatrix(int I, int wrt, int ns, int p,
40                            double eps_in, double eps_out,
41                            double kappa)
42 :GradCmplxMolMat(I, wrt, ns, p), eps_(eps_in/eps_out), kappa_(kappa)
43 {
44 }
45 
46 
47 
calc_all_vals(shared_ptr<BaseMolecule> mol,shared_ptr<BesselCalc> bcalc,shared_ptr<GradHMatrix> dH,shared_ptr<GradFMatrix> dF,shared_ptr<GradLHMatrix> dLH,shared_ptr<GradLHNMatrix> dLHN,shared_ptr<GradLFMatrix> dLF)48 void GradWFMatrix::calc_all_vals(shared_ptr<BaseMolecule> mol,
49                                  shared_ptr<BesselCalc> bcalc,
50                                  shared_ptr<GradHMatrix> dH,
51                                  shared_ptr<GradFMatrix> dF,
52                                  shared_ptr<GradLHMatrix> dLH,
53                                  shared_ptr<GradLHNMatrix> dLHN,
54                                  shared_ptr<GradLFMatrix> dLF)
55 {
56   vector<double> besseli, besselk;
57   for (int k = 0; k < get_ns(); k++)
58   {
59     besseli = bcalc->calc_mbfI(p_+1, kappa_*mol->get_ak(k));
60     besselk = bcalc->calc_mbfK(p_+1, kappa_*mol->get_ak(k));
61     calc_val_k(k, mol, besseli, besselk, dH, dF, dLH, dLHN, dLF);
62   }
63 }
64 
calc_val_k(int k,shared_ptr<BaseMolecule> mol,vector<double> besseli,vector<double> besselk,shared_ptr<GradHMatrix> dH,shared_ptr<GradFMatrix> dF,shared_ptr<GradLHMatrix> dLH,shared_ptr<GradLHNMatrix> dLHN,shared_ptr<GradLFMatrix> dLF)65 void GradWFMatrix::calc_val_k(int k, shared_ptr<BaseMolecule> mol,
66                               vector<double> besseli,
67                               vector<double> besselk,
68                               shared_ptr<GradHMatrix> dH,
69                               shared_ptr<GradFMatrix> dF,
70                               shared_ptr<GradLHMatrix> dLH,
71                               shared_ptr<GradLHNMatrix> dLHN,
72                               shared_ptr<GradLFMatrix> dLF)
73 {
74   double ak = mol->get_ak(k);
75   double exp_ka = exp(-kappa_*ak);
76   double bin, bin1, bkn, bkn1;
77   Ptx tot, val1, val2, val3, val4;
78   double inner;
79   for (int n = 0; n < p_; n++)
80   {
81     bin = besseli[n];
82     bin1 = besseli[n+1];
83     bkn = besselk[n];
84     bkn1 = besselk[n+1];
85     for (int m = -n; m < n+1; m++)
86     {
87       val1=dH->get_mat_knm(k,n,m)*exp_ka*(n*bkn-(2*n+1)*bkn1);
88       val2=dF->get_mat_knm(k,n,m)*(2*n+1-n*eps_);
89       val3=dLF->get_mat_knm(k, n, m)*n*eps_*ak;
90       inner=(n*bin)+((bin1*pow(kappa_*ak,2))/(double)(2*n+3));
91       val4 = (dLH->get_mat_knm(k,n,m)+dLHN->get_mat_knm(k,n,m)) * inner * ak;
92       set_mat_knm(k, n, m, val1+val2-val3+val4);
93     }
94   }
95 }
96 
97 
GradWHMatrix(int I,int wrt,int ns,int p,double kappa)98 GradWHMatrix::GradWHMatrix(int I, int wrt,
99                            int ns, int p, double kappa)
100 :GradCmplxMolMat(I, wrt, ns, p), kappa_(kappa)
101 {
102 }
103 
104 
calc_all_vals(shared_ptr<BaseMolecule> mol,shared_ptr<BesselCalc> bcalc,shared_ptr<GradHMatrix> dH,shared_ptr<GradFMatrix> dF,shared_ptr<GradLHMatrix> dLH,shared_ptr<GradLHNMatrix> dLHN,shared_ptr<GradLFMatrix> dLF)105 void GradWHMatrix::calc_all_vals(shared_ptr<BaseMolecule> mol,
106                              shared_ptr<BesselCalc> bcalc,
107                              shared_ptr<GradHMatrix> dH,
108                              shared_ptr<GradFMatrix> dF,
109                              shared_ptr<GradLHMatrix> dLH,
110                              shared_ptr<GradLHNMatrix> dLHN,
111                              shared_ptr<GradLFMatrix> dLF)
112 {
113   vector<double> besseli, besselk;
114   for (int k = 0; k < get_ns(); k++)
115   {
116     besseli = bcalc->calc_mbfI(p_+1, kappa_*mol->get_ak(k));
117     besselk = bcalc->calc_mbfK(p_+1, kappa_*mol->get_ak(k));
118     calc_val_k(k, mol, besseli, besselk, dH, dF, dLH, dLHN, dLF);
119   }
120 }
121 
122 
calc_val_k(int k,shared_ptr<BaseMolecule> mol,vector<double> besseli,vector<double> besselk,shared_ptr<GradHMatrix> dH,shared_ptr<GradFMatrix> dF,shared_ptr<GradLHMatrix> dLH,shared_ptr<GradLHNMatrix> dLHN,shared_ptr<GradLFMatrix> dLF)123 void GradWHMatrix::calc_val_k(int k, shared_ptr<BaseMolecule> mol,
124                               vector<double> besseli,
125                               vector<double> besselk,
126                               shared_ptr<GradHMatrix> dH,
127                               shared_ptr<GradFMatrix> dF,
128                               shared_ptr<GradLHMatrix> dLH,
129                               shared_ptr<GradLHNMatrix> dLHN,
130                               shared_ptr<GradLFMatrix> dLF)
131 {
132   double ak = mol->get_ak(k);
133   double exp_ka = exp(-kappa_*ak);
134   double bin, bkn, inner;
135   Ptx tot, val1, val2, val3, val4;
136 
137   for (int n = 0; n < p_; n++)
138   {
139     bin = besseli[n];
140     bkn = besselk[n];
141     for (int m = -n; m < n+1; m++)
142     {
143       inner = ((2.0*n+1.0) / bin) - (exp_ka * bkn);
144       val1 = dH->get_mat_knm(k, n, m) * inner;
145       val2 = dF->get_mat_knm(k, n, m);
146       val3 = dLF->get_mat_knm(k, n, m) * ak;
147       val4 = (dLH->get_mat_knm(k,n,m)+dLHN->get_mat_knm(k,n,m))*ak*bin;
148       tot = val1+val2+val3-val4;
149       set_mat_knm(k, n, m, tot);
150     }
151   }
152 }
153 
GradFMatrix(int I,int wrt,int ns,int p)154 GradFMatrix::GradFMatrix(int I, int wrt, int ns, int p)
155 :GradCmplxMolMat(I, wrt, ns, p)
156 {
157 }
158 
calc_all_vals(shared_ptr<IEMatrix> IE,shared_ptr<GradWFMatrix> dWF)159 void GradFMatrix::calc_all_vals(shared_ptr<IEMatrix> IE,
160                             shared_ptr<GradWFMatrix> dWF)
161 {
162   for (int k = 0; k < get_ns(); k++)
163     calc_val_k(k, IE, dWF);
164 }
165 
calc_val_k(int k,shared_ptr<IEMatrix> IE,shared_ptr<GradWFMatrix> dWF)166 void GradFMatrix::calc_val_k(int k, shared_ptr<IEMatrix> IE,
167                              shared_ptr<GradWFMatrix> dWF)
168 {
169   int ct(0), dim(3), p2(p_*p_);
170   double dfRe, dfIm;
171   double df_in[p_*p_*dim], df_out[p_*p_*dim];
172 
173   for (int d = 0; d < dim; d++)  // 3 dimensions
174   {
175     for (int l = 0; l < p_; l++)  // rows in old matrix
176     {
177       for (int s = 0; s < l+1; s++)  //columns in old matrix
178       {
179         df_in[ct] = dWF->get_mat_knm_d(k, l, s, d).real();
180         ct++;
181         if ( s > 0 )
182         {
183           df_in[ct] = dWF->get_mat_knm_d(k, l, s, d).imag();
184           ct++;
185         }
186       }
187     }
188   }
189 
190 #ifdef __LAU
191   applyMMat(&IE->get_IE_k_org(k)[0],&df_in[0],&df_out[0],1.0,0.0,p2,dim,p2);
192 #else
193   vector<MyMatrix<double> > df_out1(3, MyMatrix<double> (p2, 1));
194   for (int d = 0; d < dim; d++)  // 3 dimensions
195   {
196     MyMatrix<double> df_in1(p2, 1, &df_in[d*p2]);
197     df_out1[d] = IE->get_IE_k(k) * df_in1;  // Matrix vector multiplication
198   }
199 
200   for (int o = 0; o<p2; o++)
201 
202 #endif
203 
204   ct = 0;
205   for (int d = 0; d < 3; d++)  // 3 dimensions
206   {
207 #ifndef __LAU
208     ct = 0;
209 #endif
210     for (int n = 0; n < p_; n++)  // rows in new matrix
211     {
212       double scl = 1.0 / (double)(2.0*n+1.0);
213       for (int m = 0; m < n+1; m++)  // columns in new matrix
214       {
215 #ifdef __LAU
216         dfRe = df_out[ct];
217 #else
218         dfRe = df_out1[d](ct,0);
219 #endif
220         ct++;
221 
222         if ( m > 0 )
223         {
224 #ifdef __LAU
225           dfIm = df_out[ct];
226 #else
227           dfIm = df_out1[d](ct,0);
228 #endif
229           ct++;
230         } else
231           dfIm = 0.0;
232 
233         set_mat_knm_d(k,n,m,d, scl*complex<double> (dfRe,dfIm));
234         if ( m > 0 ) set_mat_knm_d(k,n,-m,d,scl*complex<double> (dfRe,-dfIm));
235       }
236     }
237   }
238 }
239 
calc_df_P(Pt P,int k,shared_ptr<SHCalc> shcalc)240 Ptx GradFMatrix::calc_df_P(Pt P, int k, shared_ptr<SHCalc> shcalc)
241 {
242   shcalc->calc_sh(P.theta(), P.phi());
243   Ptx df = Ptx();
244   Ptx in;
245   for (int n = 0; n < p_; n++)
246   {
247     for (int m = -n; m < n+1; m++)
248     {
249       in = get_mat_knm(k,n,m)*shcalc->get_result(n,m)*((2*n+1)/(4*M_PI));
250       df += in;
251     }
252   }
253   return df;
254 }
255 
256 
GradHMatrix(int I,int wrt,int ns,int p,double kappa)257 GradHMatrix::GradHMatrix(int I, int wrt, int ns, int p, double kappa)
258 :GradCmplxMolMat(I, wrt, ns, p), kappa_(kappa)
259 {
260 }
261 
calc_all_vals(shared_ptr<BaseMolecule> mol,shared_ptr<BesselCalc> bcalc,shared_ptr<IEMatrix> IE,shared_ptr<GradWHMatrix> dWH)262 void GradHMatrix::calc_all_vals(shared_ptr<BaseMolecule> mol,
263                                 shared_ptr<BesselCalc> bcalc,
264                                 shared_ptr<IEMatrix> IE,
265                                 shared_ptr<GradWHMatrix> dWH)
266 {
267   vector<double> besseli;
268   for (int k = 0; k < get_ns(); k++)
269   {
270     besseli = bcalc->calc_mbfI(p_, kappa_*mol->get_ak(k));
271     calc_val_k(k, besseli, IE, dWH);
272   }
273 }
274 
calc_val_k(int k,vector<double> besseli,shared_ptr<IEMatrix> IE,shared_ptr<GradWHMatrix> dWH)275 void GradHMatrix::calc_val_k(int k, vector<double> besseli,
276                              shared_ptr<IEMatrix> IE,
277                              shared_ptr<GradWHMatrix> dWH)
278 {
279   int ct(0), d, l, s, n, m, dim(3), p2(p_*p_);
280   double dhR, dhI;
281   double dh_in[p_*p_*dim], dh_out[p_*p_*dim];
282 
283   for (d = 0; d < dim; d++)  // 3 dimensions
284   {
285     for (l = 0; l < p_; l++)  // rows in old matrix
286     {
287       for (s = 0; s < l+1; s++)  //columns in old matrix
288       {
289         dh_in[ct] = dWH->get_mat_knm_d(k, l, s, d).real();
290         ct++;
291         if ( s > 0 )
292         {
293           dh_in[ct] = dWH->get_mat_knm_d(k, l, s, d).imag();
294           ct++;
295         }
296       }
297     }
298   }
299 
300 #ifdef __LAU
301   applyMMat(&IE->get_IE_k_org(k)[0],&dh_in[0],&dh_out[0],1.0,0.0,p2,dim,p2);
302 #else
303   vector<MyMatrix<double> > dh_out1(3, MyMatrix<double> (p2, 1));
304   for (int d = 0; d < dim; d++)  // 3 dimensions
305   {
306     MyMatrix<double> dh_in1(p2, 1, &dh_in[d*p2]);
307     dh_out1[d] = IE->get_IE_k(k) * dh_in1;  // Matrix vector multiplication
308   }
309 #endif
310 
311   ct = 0;
312   for (d = 0; d < 3; d++)  // 3 dimensions
313   {
314 #ifndef __LAU
315     ct = 0;
316 #endif
317     for (n = 0; n < p_; n++)  // rows in new matrix
318     {
319       double scl = besseli[n] / (double)(2.0*n+1.0);
320       for (m = 0; m < n+1; m++)  // columns in new matrix
321       {
322 #ifdef __LAU
323         dhR = dh_out[ct];
324 #else
325         dhR = dh_out1[d](ct,0);
326 #endif
327         ct++;
328 
329         if ( m > 0 )
330         {
331 #ifdef __LAU
332           dhI = dh_out[ct];
333 #else
334           dhI = dh_out1[d](ct,0);
335 #endif
336           ct++;
337         } else
338           dhI = 0.0;
339 
340         set_mat_knm_d(k,n,m,d,scl*complex<double> (dhR,dhI));
341         if ( m > 0 ) set_mat_knm_d(k,n,-m,d,scl*complex<double> (dhR,-dhI));
342       }
343     }
344   }
345 }
346 
GradLFMatrix(int I,int wrt,int ns,int p)347 GradLFMatrix::GradLFMatrix(int I, int wrt, int ns, int p)
348 :GradNumericalMat(I, wrt, ns, p)
349 {
350 }
351 
init_k(int k,shared_ptr<BaseMolecule> mol,shared_ptr<GradFMatrix> dF,shared_ptr<SHCalc> shcalc,shared_ptr<PreCalcSH> pre_sh,shared_ptr<ExpansionConstants> _expconst,bool no_pre_sh)352 void GradLFMatrix::init_k(int k, shared_ptr<BaseMolecule> mol,
353                           shared_ptr<GradFMatrix> dF,
354                           shared_ptr<SHCalc> shcalc,
355                           shared_ptr<PreCalcSH> pre_sh,
356                           shared_ptr<ExpansionConstants> _expconst,
357                           bool no_pre_sh)
358 {
359   double rl, im;
360   cmplx sh;
361   for (int k=0; k< mol->get_ns(); k++)
362   {
363     vector <int> exp_pts = mol->get_gdpt_expj(k);
364     mat_[k].resize( (int) exp_pts.size() );
365     double dA = 4 * M_PI / (double) mol->get_gridj(k).size();
366 
367     for (int h = 0; h < exp_pts.size(); h++)
368     {
369       vector<double> val(3, 0.0);
370       Pt q = mol->get_gridjh(k, exp_pts[h]);
371       if (no_pre_sh) pre_sh->calc_and_add(q, shcalc);
372 
373       for (int d = 0; d < 3; d++)
374       {
375         for (int n=0; n<p_; n++)
376         {
377           for (int m = -n; m <= n; m++)
378           {
379             sh = pre_sh->get_sh(q, n, m);
380             rl = (sh.real()*dF->get_mat_knm_d(k,n,m,d).real());
381             im = (sh.imag()*dF->get_mat_knm_d(k,n,m,d).imag());
382             val[d] += dA*_expconst->get_const1_l(n) * ( rl + im );
383           }
384         }
385       }
386       set_mat_kh(k, h, Pt(val[0], val[1], val[2]));
387     }
388   }
389 }
390 
calc_all_vals(shared_ptr<BaseMolecule> mol,vector<int> interpol,shared_ptr<TMatrix> T,shared_ptr<GradFMatrix> dF,shared_ptr<PreCalcSH> pre_sh,bool no_pre_sh)391 void GradLFMatrix::calc_all_vals(shared_ptr<BaseMolecule> mol,
392                                  vector<int> interpol,
393                                  shared_ptr<TMatrix> T,
394                                  shared_ptr<GradFMatrix> dF,
395                                  shared_ptr<PreCalcSH> pre_sh,
396                                  bool no_pre_sh)
397 {
398   for (int k = 0; k < get_ns(); k++)
399     calc_val_k(k, mol, interpol, T, dF, pre_sh, no_pre_sh);
400 }
401 
calc_val_k(int k,shared_ptr<BaseMolecule> mol,vector<int> interpol,shared_ptr<TMatrix> T,shared_ptr<GradFMatrix> dF,shared_ptr<PreCalcSH> pre_sh,bool no_pre_sh)402 void GradLFMatrix::calc_val_k(int k, shared_ptr<BaseMolecule> mol,
403                               vector<int> interpol,
404                               shared_ptr<TMatrix> T,
405                               shared_ptr<GradFMatrix> dF,
406                               shared_ptr<PreCalcSH> pre_sh,
407                               bool no_pre_sh)
408 {
409   MyMatrix<Ptx> reex, inner(p_, 2*p_+1);
410 
411   for (int j = 0; j < get_ns(); j++)
412   {
413     if (j == k) continue;
414     if ((interpol[k] != 0) || (interpol[j] != 0)) continue;
415 
416     if (T->is_analytic(I_, k, I_, j))
417     {
418       reex = T->re_expand_gradX(dF->get_mat_k(j), I_, k, I_, j, true);
419     }
420     else
421     {
422       // From (I,j) -> (I,k) is re_exp_numeric( , I, k, I, j)
423       reex = T->re_expandgradX_numeric(get_mat(), I_, k, I_, j, 0.0, pre_sh,
424                                        no_pre_sh);
425     }
426 
427     inner += reex;
428   }
429   mat_cmplx_[k] = inner;
430 }
431 
432 
GradLHMatrix(int I,int wrt,int ns,int p,double kappa)433 GradLHMatrix::GradLHMatrix(int I, int wrt, int ns, int p, double kappa)
434 :GradNumericalMat(I, wrt, ns, p), kappa_(kappa)
435 {
436 }
437 
init_k(int k,shared_ptr<BaseMolecule> mol,shared_ptr<GradHMatrix> dH,shared_ptr<SHCalc> shcalc,shared_ptr<BesselCalc> bcalc,shared_ptr<PreCalcSH> pre_sh,shared_ptr<ExpansionConstants> _expconst,bool no_pre_sh)438 void GradLHMatrix::init_k(int k, shared_ptr<BaseMolecule> mol,
439                           shared_ptr<GradHMatrix> dH,
440                           shared_ptr<SHCalc> shcalc,
441                           shared_ptr<BesselCalc> bcalc,
442                           shared_ptr<PreCalcSH> pre_sh,
443                           shared_ptr<ExpansionConstants> _expconst,
444                           bool no_pre_sh)
445 {
446   double rl, im;
447   cmplx sh;
448   vector <int> exp_pts = mol->get_gdpt_expj(k);
449   mat_[k].resize( (int) exp_pts.size() );
450   double dA = 4 * M_PI / (double) mol->get_gridj(k).size();
451 
452   for (int h = 0; h < exp_pts.size(); h++)
453   {
454     vector<double> val(3, 0.0);
455     Pt q = mol->get_gridjh(k, exp_pts[h]);
456     if (no_pre_sh) pre_sh->calc_and_add(q, shcalc);
457     vector<double> bessI = bcalc->calc_mbfI(p_+1, kappa_*q.r());
458 
459     for (int d = 0; d < 3; d++)
460     {
461       for (int n=0; n<p_; n++)
462       {
463         for (int m = -n; m <= n; m++)
464         {
465           sh = pre_sh->get_sh(q, n, m);
466           rl = (sh.real()*dH->get_mat_knm_d(k,n,m,d).real());
467           im = (sh.imag()*dH->get_mat_knm_d(k,n,m,d).imag());
468           val[d] += dA*_expconst->get_const1_l(n) * ( rl + im )/bessI[n];
469         }
470       }
471     }
472     set_mat_kh(k, h, Pt(val[0], val[1], val[2]));
473   }
474 }
475 
calc_all_vals(shared_ptr<BaseMolecule> mol,vector<int> interpol,shared_ptr<TMatrix> T,shared_ptr<GradHMatrix> dH,shared_ptr<PreCalcSH> pre_sh,bool no_pre_sh)476 void GradLHMatrix::calc_all_vals(shared_ptr<BaseMolecule> mol, vector<int> interpol,
477                                  shared_ptr<TMatrix> T,
478                                  shared_ptr<GradHMatrix> dH,
479                                  shared_ptr<PreCalcSH> pre_sh,
480                                  bool no_pre_sh)
481 {
482   for (int k = 0; k < get_ns(); k++)
483     calc_val_k(k, mol, interpol, T, dH, pre_sh, no_pre_sh);
484 }
485 
calc_val_k(int k,shared_ptr<BaseMolecule> mol,vector<int> interpol,shared_ptr<TMatrix> T,shared_ptr<GradHMatrix> dH,shared_ptr<PreCalcSH> pre_sh,bool no_pre_sh)486 void GradLHMatrix::calc_val_k(int k, shared_ptr<BaseMolecule> mol,
487                               vector<int> interpol,
488                               shared_ptr<TMatrix> T,
489                               shared_ptr<GradHMatrix> dH,
490                               shared_ptr<PreCalcSH> pre_sh,
491                               bool no_pre_sh)
492 {
493   MyMatrix<Ptx> reex, inner(p_, 2*p_+1);
494 
495   for (int j = 0; j < get_ns(); j++)
496   {
497     if (j == k) continue;
498     if ((interpol[k] != 0) || (interpol[j] != 0)) continue;
499 
500     if (T->is_analytic(I_, k, I_, j))
501     {
502       reex = T->re_expand_gradX(dH->get_mat_k(j), I_, k, I_, j);
503     }
504     else
505     {
506       reex = T->re_expandgradX_numeric(get_mat(), I_, k, I_, j, kappa_, pre_sh,
507                                        no_pre_sh);
508     }
509     inner += reex;
510   }
511   mat_cmplx_[k] = inner;
512 }
513 
514 
calc_dh_P(Pt P,int k,vector<double> besseli,shared_ptr<SHCalc> shcalc)515 Ptx GradHMatrix::calc_dh_P(Pt P, int k,
516                             vector<double> besseli,
517                             shared_ptr<SHCalc> shcalc)
518 {
519   shcalc->calc_sh(P.theta(), P.phi());
520   Ptx dh = Ptx();
521   Ptx in;
522   for (int n = 0; n < p_; n++)
523   {
524     for (int m = -n; m < n+1; m++)
525     {
526       in = get_mat_knm(k,n,m)*shcalc->get_result(n,m)*((2*n+1)/(4*M_PI));
527       in *= 1/besseli[n];
528       dh += in;
529     }
530   }
531   return dh;
532 }
533 
534 
GradLHNMatrix(int I,int wrt,int ns,int p)535 GradLHNMatrix::GradLHNMatrix(int I, int wrt, int ns, int p)
536 :GradCmplxMolMat(I, wrt, ns, p)
537 {
538 }
539 
calc_all_vals(shared_ptr<SystemSAM> sys,shared_ptr<TMatrix> T,vector<shared_ptr<GradCmplxMolMat>> gradT_A,vector<shared_ptr<GradHMatrix>> dH)540 void GradLHNMatrix::calc_all_vals(shared_ptr<SystemSAM> sys,
541                                   shared_ptr<TMatrix> T,
542                                   vector<shared_ptr<GradCmplxMolMat> > gradT_A,
543                                   vector<shared_ptr<GradHMatrix> > dH)
544 {
545   MyMatrix<Ptx> lhn_k, inner;
546   for (int k = 0; k < get_ns(); k++)
547     calc_val_k(k, sys, T, gradT_A, dH);
548 }
549 
calc_val_k(int k,shared_ptr<SystemSAM> sys,shared_ptr<TMatrix> T,vector<shared_ptr<GradCmplxMolMat>> gradT_A,vector<shared_ptr<GradHMatrix>> dH,double dist_cut)550 void GradLHNMatrix::calc_val_k(int k, shared_ptr<SystemSAM> sys,
551                                shared_ptr<TMatrix> T,
552                                vector<shared_ptr<GradCmplxMolMat> > gradT_A,
553                                vector<shared_ptr<GradHMatrix> > dH,
554                                double dist_cut)
555 {
556   Pt Ik, Mm;
557   double aIk, aMm, interPolcut = dist_cut;
558   MyMatrix<Ptx> lhn_k(p_, 2*p_+1), inner;
559   lhn_k = gradT_A[I_]->get_mat_k(k);
560 
561   Ik = sys->get_centerik(I_, k);
562   aIk = sys->get_aik(I_, k);
563 
564   for (int M=0; M < sys->get_n(); M++)
565   {
566     if (M == I_) continue;
567     for (int m=0; m < sys->get_Ns_i(M); m++)
568     {
569       Mm = sys->get_centerik(M, m);
570       aMm = sys->get_aik(M, m);
571 
572       if ( sys->get_pbc_dist_vec_base(Ik, Mm).norm() < (interPolcut+aIk+aMm))
573       {
574         inner = T->re_expand_gradX(dH[M]->get_mat_k(m), I_, k, M, m);
575         lhn_k += inner;
576       }
577     }
578     mat_[k] = lhn_k;
579   }
580 }
581