Skip to content

Commit 81d1f8c

Browse files
authored
Custom Initialization of LOBPCG solver in parametric case (#299)
* Add boundary condition switch * Output eigenvalue absolute error * Make eigenfunction sign in FOM and ROM consistent * Clean up problems * Change Gaussian radius * Change calculation of Gaussian width * Slight changes in example command lines * Change filenames * Remove TODO * Astyle * Change filenames. Change calculation of Gaussian width * Slight changes to filenames * Consistent sign over parameters and eigenvector ordering * Astyle * Fix visualization signs * Fix stream names * Reset stream name * Reorganize reference mode sign logic * Clean up * Change variable names * Warning meesages * Astyle * Normalize * Adjust Gaussian * Rename variables * Remove verbose * Update example in header * Fix failing CI * Updates * Fix verbose * Minor changes to verbose * Astyle * Clean up * Make muber of LOBPCG iterations an option * Set up the Gaussians for the Li2 example * Add variables * Add GTH potential * Slight modification * Slight updates * superposing gaussians * Minor changes to parameters * Minor changes * Add loading * Use HypreParVector I/O instead of libROM I/O for this task * Astyle * Add option to compare initialization * Minor change to example * Abort if no files found * Minor change * Make tolerences user-defined options
1 parent 6218f38 commit 81d1f8c

1 file changed

Lines changed: 41 additions & 11 deletions

File tree

‎examples/prom/elliptic_eigenproblem_global_rom.cpp‎

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,14 @@ int main(int argc, char *argv[])
9494
int order = 1;
9595
int nev = 4;
9696
int seed = 75;
97+
bool prescribe_init = false;
9798
int lobpcg_niter = 200;
99+
double lobpcg_tol = 1e-8;
100+
double eig_tol = 1e-6;
98101
bool slu_solver = false;
99102
bool sp_solver = false;
100103
bool cpardiso_solver = false;
104+
int verbose_level = 0;
101105

102106
bool visualization = true;
103107
bool visit = false;
@@ -110,7 +114,6 @@ int main(int argc, char *argv[])
110114
int nsets = 0;
111115
double ef = 1.0;
112116
int rdim = -1;
113-
int verbose_level = 0;
114117

115118
int precision = 8;
116119
cout.precision(precision);
@@ -163,8 +166,14 @@ int main(int argc, char *argv[])
163166
"Reduced dimension.");
164167
args.AddOption(&verbose_level, "-v", "--verbose",
165168
"Set the verbosity level of the LOBPCG solver and preconditioner. 0 is off.");
169+
args.AddOption(&prescribe_init, "-init", "--init", "-no-init", "--no-init",
170+
"Prescribe custom Initialization of LOBPCG.");
166171
args.AddOption(&lobpcg_niter, "-fi", "--fom-iter",
167172
"Number of iterations for the LOBPCG solver.");
173+
args.AddOption(&lobpcg_tol, "-tol", "--fom-tol",
174+
"Tolerance for the LOBPCG solver.");
175+
args.AddOption(&eig_tol, "-tol", "--fom-tol",
176+
"Tolerance for eigenvalues to be considered equal.");
168177
#ifdef MFEM_USE_SUPERLU
169178
args.AddOption(&slu_solver, "-slu", "--superlu", "-no-slu",
170179
"--no-superlu", "Use the SuperLU Solver.");
@@ -451,13 +460,29 @@ int main(int argc, char *argv[])
451460
lobpcg->SetNumModes(nev);
452461
lobpcg->SetRandomSeed(seed);
453462
lobpcg->SetPreconditioner(*precond);
454-
lobpcg->SetMaxIter(200);
455-
lobpcg->SetTol(1e-8);
463+
lobpcg->SetMaxIter(lobpcg_niter);
464+
lobpcg->SetTol(lobpcg_tol);
456465
lobpcg->SetPrecondUsageMode(1);
457466
lobpcg->SetPrintLevel(verbose_level);
458467
lobpcg->SetMassMatrix(*M);
459468
lobpcg->SetOperator(*A);
460469

470+
if (prescribe_init && (fom || (offline && id > 0)))
471+
{
472+
HypreParVector** snapshot_vecs = new HypreParVector*[nev];
473+
for (int i = 0; i < nev; i++)
474+
{
475+
std::string snapshot_filename = baseName + "ref_snapshot_" + std::to_string(i);
476+
std::ifstream snapshot_infile(snapshot_filename + "." + std::to_string(myid));
477+
MFEM_VERIFY(snapshot_infile.good(), "Failed to load vector for initialization");
478+
snapshot_vecs[i] = new HypreParVector();
479+
snapshot_vecs[i]->Read(MPI_COMM_WORLD, snapshot_filename.c_str());
480+
if (myid == 0) std::cout << "Loaded " << snapshot_filename << std::endl;
481+
}
482+
lobpcg->SetInitialVectors(nev, snapshot_vecs);
483+
if (myid == 0) std::cout << "LOBPCG initial vectors set" << std::endl;
484+
}
485+
461486
// 13. Compute the eigenmodes and extract the array of eigenvalues. Define a
462487
// parallel grid function to represent each of the eigenmodes returned by
463488
// the solver.
@@ -478,6 +503,13 @@ int main(int argc, char *argv[])
478503
eigenfunction_i = lobpcg->GetEigenvector(i);
479504
eigenfunction_i /= sqrt(InnerProduct(eigenfunction_i, eigenfunction_i));
480505
generator->takeSample(eigenfunction_i.GetData());
506+
if (prescribe_init && id == 0)
507+
{
508+
std::string snapshot_filename = baseName + "ref_snapshot_" + std::to_string(i);
509+
const HypreParVector snapshot_vec = lobpcg->GetEigenvector(i);
510+
snapshot_vec.Print(snapshot_filename.c_str());
511+
if (myid == 0) std::cout << "Saved " << snapshot_filename << std::endl;
512+
}
481513
}
482514
}
483515

@@ -598,12 +630,12 @@ int main(int argc, char *argv[])
598630
eigenvector_i = 0.0;
599631
for (int j = 0; j < nev; j++)
600632
{
601-
if (myid == 0 && verbose_level > 0)
633+
if (myid == 0)
602634
{
603635
std::cout << "correlation_matrix(" << j+1 << "," << i+1 << ") = " <<
604636
InnerProduct(mode_fom, modes_rom[j]) << ";" << std::endl;
605637
}
606-
if (abs(eigenvalues_fom[j] - eigenvalues_fom[i]) < 1e-6)
638+
if (abs(eigenvalues_fom[j] - eigenvalues_fom[i]) < eig_tol)
607639
{
608640
eigenvector_i.Add(InnerProduct(mode_fom, modes_rom[j]), modes_rom[j]);
609641
}
@@ -908,8 +940,7 @@ double Potential(const Vector &x)
908940
if (potential_well_switch == 0 || potential_well_switch == 1)
909941
{
910942
// add well with first center
911-
center(0) = (23 * bb_min[0] + 13 * bb_max[0]) / 36 -
912-
0.5 * h_max * pseudo_time * (bb_min[0] + bb_max[0]);
943+
center(0) = (23 * bb_min[0] + 13 * bb_max[0]) / 36 - h_max * pseudo_time;
913944
d_sq = x.DistanceSquaredTo(center);
914945
radius_sq = pow(0.28 * L, 2.0);
915946
rho += -28.9 * std::exp(-d_sq / (2 * radius_sq));
@@ -919,8 +950,7 @@ double Potential(const Vector &x)
919950
if (potential_well_switch == 0 || potential_well_switch == 2)
920951
{
921952
// add well with second center
922-
center(0) = (13 * bb_min[0] + 23 * bb_max[0]) / 36 +
923-
0.5 * h_max * pseudo_time * (bb_min[0] + bb_max[0]);
953+
center(0) = (13 * bb_min[0] + 23 * bb_max[0]) / 36 + h_max * pseudo_time;
924954
d_sq = x.DistanceSquaredTo(center);
925955
radius_sq = pow(0.28 * L, 2.0);
926956
rho += -28.9 * std::exp(-d_sq / (2 * radius_sq));
@@ -945,7 +975,7 @@ double Potential(const Vector &x)
945975
if (potential_well_switch == 0 || potential_well_switch == 1)
946976
{
947977
// add well with first center
948-
center(0) = (23 * bb_min[0] + 13 * bb_max[0]) / 36 - pseudo_time * h_max;
978+
center(0) = (23 * bb_min[0] + 13 * bb_max[0]) / 36 - h_max * pseudo_time;
949979
d_sq = x.DistanceSquaredTo(center);
950980
alpha = d_sq / pow(L * rloc, 2.0);
951981
rho += exp(-0.5 * alpha) * (c1 + c2 * alpha + c3 * alpha * alpha + c4 * alpha *
@@ -962,7 +992,7 @@ double Potential(const Vector &x)
962992
if (potential_well_switch == 0 || potential_well_switch == 2)
963993
{
964994
// add well with second center
965-
center(0) = (13 * bb_min[0] + 23 * bb_max[0]) / 36 + pseudo_time * h_max;
995+
center(0) = (13 * bb_min[0] + 23 * bb_max[0]) / 36 + h_max * pseudo_time;
966996
d_sq = x.DistanceSquaredTo(center);
967997
alpha = d_sq / pow(L * rloc, 2.0);
968998
rho += exp(-0.5 * alpha) * (c1 + c2 * alpha + c3 * alpha * alpha + c4 * alpha *

0 commit comments

Comments
 (0)