@@ -33,6 +33,7 @@ namespace BasisClasses
3333 " ascl" ,
3434 " delta" ,
3535 " lmax" ,
36+ " mmax" ,
3637 " nmax" ,
3738 " model"
3839 };
@@ -54,7 +55,7 @@ namespace BasisClasses
5455
5556 // Allocate coefficient storage
5657 //
57- nfld = p.size () + 2 ;
58+ nfld = p.size () + 1 ;
5859 allocateStore ();
5960
6061 // Okay to register
@@ -67,7 +68,7 @@ namespace BasisClasses
6768 //
6869 void FieldBasis::configure ()
6970 {
70- nfld = 2 ; // Weight and density fields by default
71+ nfld = 1 ; // Density field by default
7172 lmax = 4 ;
7273 nmax = 10 ;
7374 rmin = 1.0e-4 ;
@@ -137,7 +138,8 @@ namespace BasisClasses
137138
138139 // Compute interpolation functionoid
139140 //
140- double rmin = r.front (), rmax = r.back ();
141+ rmin = r.front ();
142+ rmax = r.back ();
141143
142144 interp = std::make_shared<Linear1d>(r, d);
143145 densfunc = [this ](double r)
@@ -168,7 +170,6 @@ namespace BasisClasses
168170 // Initialize fieldlabels
169171 //
170172 fieldLabels.clear ();
171- fieldLabels.push_back (" weight" );
172173 fieldLabels.push_back (" density" );
173174
174175 // Debug
@@ -204,9 +205,11 @@ namespace BasisClasses
204205
205206 void FieldBasis::initialize ()
206207 {
207- // Remove matched keys
208+ // Check for unmatched keys
208209 //
209- // for (auto v : valid_keys) current_keys.erase(v);
210+ auto unmatched = YamlCheck (conf, valid_keys);
211+ if (unmatched.size ())
212+ throw YamlConfigError (" Basis::FieldBasis" , " parameter" , unmatched, __FILE__, __LINE__);
210213
211214 // Assign values from YAML
212215 //
@@ -215,6 +218,7 @@ namespace BasisClasses
215218 if (conf[" model" ]) model = conf[" model" ].as <std::string>();
216219 if (conf[" nfld" ]) nfld = conf[" nfld" ].as <int >();
217220 if (conf[" lmax" ]) lmax = conf[" lmax" ].as <int >();
221+ if (conf[" mmax" ]) lmax = conf[" mmax" ].as <int >();
218222 if (conf[" nmax" ]) nmax = conf[" nmax" ].as <int >();
219223 if (conf[" dof" ]) dof = conf[" dof" ].as <int >();
220224 if (conf[" rmin" ]) rmin = conf[" rmin" ].as <double >();
@@ -312,8 +316,7 @@ namespace BasisClasses
312316 double x, double y, double z,
313317 double u, double v, double w)
314318 {
315- constexpr std::complex <double > I (0 , 1 );
316- constexpr double fac0 = 0.25 *M_2_SQRTPI;
319+ constexpr double fac2 = 0.5 *M_2_SQRTPI/M_SQRT2; // 1/sqrt(2*pi)=0.3989422804
317320
318321 int tid = omp_get_thread_num ();
319322 PS3 pos{x, y, z}, vel{u, v, w};
@@ -337,45 +340,42 @@ namespace BasisClasses
337340
338341 auto p = (*ortho)(R);
339342
340- (*coefs[tid])(0 , 0 , 0 ) += mass*p (0 )*fac0;
341-
342343 for (int m=0 ; m<=lmax; m++) {
343344
344- std:: complex < double > P = std::exp (-I*( phi*m));
345+ auto P = std::exp (std:: complex < double >( 0 , - phi*m))*fac2 ;
345346
346347 for (int n=0 ; n<nmax; n++) {
347348
348- (*coefs[tid])(1 , m, n) += mass*P*p (n);
349+ (*coefs[tid])(0 , m, n) += mass*P*p (n);
349350
350351 for (int k=0 ; k<vec.size (); k++)
351- (*coefs[tid])(k+2 , m, n) += mass*P*p (n)*vec[k];
352+ (*coefs[tid])(k+1 , m, n) += mass*P*p (n)*vec[k];
352353 }
353354 }
354355
355356 } else {
356357
357358 auto p = (*ortho)(r);
358359
359- (*coefs[tid])(0 , 0 , 0 ) += mass*p (0 );
360-
361360 for (int l=0 , lm=0 ; l<=lmax; l++) {
362361
363362 double s = 1.0 ;
364363
365364 for (int m=0 ; m<=l; m++, lm++) {
366365
367366 // Spherical harmonic value
368- std::complex <double > P =
369- std::exp (-I*(phi*m))*Ylm (l, m)*plgndr (l, m, cth) * s;
370-
371- s *= -1.0 ; // Flip sign for next evaluation
367+ auto P = std::exp (std::complex <double >(0 , -phi*m)) *
368+ Ylm (l, m)*plgndr (l, m, cth) * s;
369+
370+ // Flip sign for next evaluation
371+ s *= -1.0 ;
372372
373373 for (int n=0 ; n<nmax; n++) {
374374
375- (*coefs[tid])(1 , lm, n) += mass*P*p (n);
375+ (*coefs[tid])(0 , lm, n) += mass*P*p (n);
376376
377377 for (int k=0 ; k<vec.size (); k++)
378- (*coefs[tid])(k+2 , lm, n) += mass*P*p (n)*vec[k];
378+ (*coefs[tid])(k+1 , lm, n) += mass*P*p (n)*vec[k];
379379 }
380380 }
381381 }
@@ -407,8 +407,10 @@ namespace BasisClasses
407407 //
408408 if (not coefret) {
409409 if (dof==2 ) coefret = std::make_shared<CoefClasses::CylFldStruct>();
410- else coefret = std::make_shared<CoefClasses::SphFldStruct >();
411- // Add the configuration data
410+ else coefret = std::make_shared<CoefClasses::SphFldStruct>();
411+
412+ // Add the configuration data
413+ //
412414 std::ostringstream sout; sout << node;
413415 coefret->buf = sout.str ();
414416 }
@@ -419,10 +421,14 @@ namespace BasisClasses
419421 //
420422 if (dof==2 ) {
421423 auto p = dynamic_pointer_cast<CoefClasses::CylFldStruct>(coefret);
422- p->assign (store[0 ], nfld, lmax, nmax);
424+ int rows = lmax + 1 ;
425+ int cols = nmax;
426+ p->assign (store[0 ], nfld, rows, cols);
423427 } else {
424428 auto p = dynamic_pointer_cast<CoefClasses::SphFldStruct>(coefret);
425- p->assign (store[0 ], nfld, lmax, nmax);
429+ int rows = (lmax+1 )*(lmax+2 )/2 ;
430+ int cols = nmax;
431+ p->assign (store[0 ], nfld, rows, cols);
426432 }
427433 }
428434
@@ -431,30 +437,37 @@ namespace BasisClasses
431437 {
432438 if (dof==2 ) {
433439 auto cstr = std::make_shared<CoefClasses::CylFldStruct>();
434- cstr->assign (store[0 ], nfld, lmax, nmax);
440+ int rows = lmax + 1 ;
441+ int cols = nmax;
442+ cstr->assign (store[0 ], nfld, rows, cols);
435443 return cstr;
436444 } else {
437445 auto cstr = std::make_shared<CoefClasses::SphFldStruct>();
438- cstr->assign (store[0 ], nfld, lmax, nmax);
446+ int rows = (lmax+1 )*(lmax+2 )/2 ;
447+ int cols = nmax;
448+ cstr->assign (store[0 ], nfld, rows, cols);
439449 return cstr;
440450 }
441451 }
442452
443453 std::vector<double >
444454 FieldBasis::sph_eval (double r, double costh, double phi)
445455 {
446- constexpr std:: complex < double > I ( 0 , 1 );
456+ constexpr double fac2 = 0.5 *M_2_SQRTPI/M_SQRT2; // 1/sqrt(2 pi)
447457
448458 if (dof==2 ) {
449459 std::vector<double > ret (nfld, 0 );
450- auto p = (*ortho)(r* sqrt ( fabs ( 1.0 - costh*costh)) );
460+ auto p = (*ortho)(r);
451461 for (int i=0 ; i<nfld; i++) {
452462 for (int m=0 ; m<=lmax; m++) {
453- double fac = m>0 ? 2.0 : 1.0 ;
463+ auto P = std::exp (std::complex <double >(0 , -phi*m));
464+
465+ std::complex <double > sum = 0.0 ;
454466 for (int n=0 ; n<nmax; n++) {
455- ret[i] += fac *
456- std::real ((*coefs[0 ])(i, m, n)*exp (I*(phi*m)))*p[n];
467+ sum += (*coefs[0 ])(i, m, n)*P * p (n) * fac2;
457468 }
469+
470+ ret[i] += std::real (sum);
458471 }
459472 }
460473 return ret;
@@ -478,9 +491,11 @@ namespace BasisClasses
478491 for (int i=0 ; i<nfld; i++) {
479492 for (int l=0 , L=0 ; l<=lmax; l++) {
480493 for (int m=0 ; m<=l; m++, L++) {
494+ auto P = std::exp (std::complex <double >(0 , -phi*m));
495+
481496 double fac = m>0 ? 2.0 : 1.0 ;
482497 for (int n=0 ; n<nmax; n++) {
483- ret[i] += std::real ((*coefs[0 ])(i, L, n)*exp (I*(phi*m)))*p[n] *
498+ ret[i] += std::real ((*coefs[0 ])(i, L, n)*P)* p (n) *
484499 Ylm (l, m)*plgndr (l, m, costh) * fac;
485500 }
486501 }
@@ -751,7 +766,6 @@ namespace BasisClasses
751766
752767 // Field labels (force field labels added below)
753768 //
754- fieldLabels.push_back (" weight" );
755769 fieldLabels.push_back (" density" );
756770
757771 if (coordinates == Coord::Cylindrical) {
0 commit comments