Skip to content

Commit 2250110

Browse files
author
Martin D. Weinberg
committed
Two main changes: (1) eliminate the 'weight' field since the 'density' field sufficies'; (2) fix a shadowing error in the density file construction that did not set the class version of 'rmin' and 'rmax' from the file resulting in a poor basis construction if 'rmin' and 'rmax' were *not* set in the configuration file as well.
1 parent 8261ff8 commit 2250110

1 file changed

Lines changed: 48 additions & 34 deletions

File tree

expui/FieldBasis.cc

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)