Skip to content

Commit 812331b

Browse files
committed
correct power method loop
1 parent b40e595 commit 812331b

File tree

1 file changed

+56
-75
lines changed

1 file changed

+56
-75
lines changed

SU2_CFD/src/drivers/CSinglezoneDriver.cpp

Lines changed: 56 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ void CSinglezoneDriver::SeedAllDerivatives(const su2matrix<passivedouble>& deriv
351351
// WORKS WHEN RUNNING SU2_CFD_DIRECTDIFF, when SU2_CFD is run gives "Got= 0"
352352
if (iPoint < 5 && iVar == 0 && rank == MASTER_NODE) {
353353
std::cout << "Point " << iPoint << ", Var " << iVar << ": Set=" << derivative_value
354-
<< ", Got=" << extracted_derivative << ", Value=" << original_value << std::endl;
354+
<< ", Got=" << extracted_derivative << ", Value=" << original_value << endl;
355355
}
356356
}
357357
}
@@ -395,7 +395,7 @@ void CSinglezoneDriver::GetAllDerivatives(su2matrix<passivedouble>& derivatives,
395395

396396
// Debug: check if derivatives are being extracted correctly
397397
if (iPoint == 0 && iVar == 0 && rank == MASTER_NODE) {
398-
std::cout << "extracted derivative for solver " << iSol << ", point 0, var 0: " << derivative_value << std::endl;
398+
std::cout << "extracted derivative for solver " << iSol << ", point 0, var 0: " << derivative_value << endl;
399399
}
400400
}
401401
}
@@ -433,13 +433,13 @@ void CSinglezoneDriver::PreRunSpectralRadius() {
433433
norm += v_estimate(iPoint, iVar) * v_estimate(iPoint, iVar);
434434
}
435435
}
436-
437-
// norm calculation
436+
// Calculate the global norm
437+
passivedouble local_norm = norm;
438438
passivedouble global_norm;
439-
SU2_MPI::Allreduce(&norm, &global_norm, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm());
440-
global_norm = sqrt(global_norm);
441-
442-
// normalize the matrix
439+
SU2_MPI::Allreduce(&local_norm, &global_norm, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm());
440+
global_norm = sqrt(local_norm);
441+
442+
// normalize matrix
443443
for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) {
444444
for (unsigned short iVar = 0; iVar < nVarTotal; iVar++) {
445445
v_estimate(iPoint, iVar) /= global_norm;
@@ -454,90 +454,71 @@ void CSinglezoneDriver::PreRunSpectralRadius() {
454454

455455
void CSinglezoneDriver::PostRunSpectralRadius() {
456456
if (!config_container[ZONE_0]->GetSpectralRadius_Analysis()) return;
457-
458-
if (rank == MASTER_NODE) {
457+
if (rank == MASTER_NODE) {
459458
std::cout << "Running PostRunSpectralRadius" << endl;
460459
}
461460

462461
CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0];
463462

464-
// get total number of variables and points
465-
unsigned long nVarTotal = 0;
466463
unsigned long nPoint = geometry->GetnPointDomain();
464+
unsigned short nVarTotal = 0;
467465
for (auto iSol = 0u; iSol < MAX_SOLS; ++iSol) {
468466
CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][iSol];
469467
if (solver) nVarTotal += solver->GetnVar();
470468
}
471-
472-
if (rank == MASTER_NODE) {
469+
470+
if (rank == MASTER_NODE) {
473471
std::cout << "total var: " << nVarTotal << ", total points: " << nPoint << endl;
474472
}
475473

476-
// extract derivatives from all solvers
477-
su2matrix<passivedouble> w(nPoint, nVarTotal);
478-
479-
if (rank == MASTER_NODE) {
480-
std::cout << "matrix w initialized with size: " << w.rows() << " x " << w.cols() << endl;
481-
}
482-
483-
GetAllDerivatives(w, geometry);
484-
485-
if (rank == MASTER_NODE) {
486-
std::cout << "derivatives extracted" << endl;
487-
}
474+
su2matrix<passivedouble> w_k(nPoint, nVarTotal);
475+
if (rank == MASTER_NODE) {std::cout << "matrix w initialized with size: " << w_k.rows() << " x " << w_k.cols() << endl;}
488476

489-
// compute norm
490-
passivedouble rho_new = 0.0;
491-
for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) {
492-
for (unsigned short iVar = 0; iVar < nVarTotal; iVar++) {
493-
rho_new += w(iPoint, iVar) * w(iPoint, iVar);
494-
}
495-
}
496-
497-
passivedouble global_rho_new;
498-
SU2_MPI::Allreduce(&rho_new, &global_rho_new, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm());
499-
global_rho_new = sqrt(global_rho_new);
500-
501-
if (rank == MASTER_NODE) {
502-
std::cout << "Global rho_new: " << global_rho_new << endl;
503-
}
477+
passivedouble rho_old = 0.0;
478+
int max_iter = config_container[ZONE_0]->GetnPowerMethodIter();
479+
su2double tol = config_container[ZONE_0]->GetPowerMethodTolerance();
480+
int k = 0;
504481

505-
// update eigenvector estimate
506-
for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) {
507-
for (unsigned short iVar = 0; iVar < nVarTotal; iVar++) {
508-
v_estimate(iPoint, iVar) = w(iPoint, iVar) / global_rho_new;
482+
while (k < max_iter) {
483+
GetAllDerivatives(w_k, geometry);
484+
485+
// compute local squared norm
486+
passivedouble rho_local = 0.0;
487+
for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) {
488+
for (unsigned short iVar = 0; iVar < nVarTotal; iVar++) {
489+
rho_local += w_k(iPoint, iVar) * w_k(iPoint, iVar);
490+
}
509491
}
510-
}
511492

512-
// check convergence
513-
static passivedouble rho_old = 0.0;
514-
static int iter = 0;
515-
516-
int max_iter = config_container[ZONE_0]->GetnPowerMethodIter();
517-
su2double tol = config_container[ZONE_0]->GetPowerMethodTolerance();
518-
519-
if (rank == MASTER_NODE) {
520-
std::cout << "Power Iterations requested = " << max_iter << endl;
521-
std::cout << "Power tolerance requested = " << tol << endl;
522-
std::cout << "Current iteration = " << iter << endl;
523-
std::cout << "Current rho_old = " << rho_old << endl;
524-
std::cout << "Current global_rho_new = " << global_rho_new << endl;
525-
}
526-
527-
if (abs(global_rho_new - rho_old) < tol || iter >= max_iter) {
493+
// global reduction
494+
passivedouble rho_global = 0.0;
495+
SU2_MPI::Allreduce(&rho_local, &rho_global, 1, MPI_DOUBLE, MPI_MAX, SU2_MPI::GetComm());
496+
passivedouble rho_k = sqrt(rho_local);
497+
528498
if (rank == MASTER_NODE) {
529-
std::cout << "Spectral Radius Estimate: " << global_rho_new << " after " << iter << " iterations." << std::endl;
499+
std::cout << "Spectral Radius Estimate for Iteration " << k << " is " << rho_k << endl;
530500
}
531-
// Reset
532-
rho_old = 0.0;
533-
iter = 0;
534-
v_estimate.resize(0, 0);
535-
} else {
536-
rho_old = global_rho_new;
537-
iter++;
538-
539-
if (rank == MASTER_NODE) {
540-
std::cout << "Continuing to iteration " << iter << " with rho_old = " << rho_old << endl;
501+
502+
// convergence check
503+
if (abs(rho_k - rho_old) < tol) {
504+
if (rank == MASTER_NODE) {
505+
std::cout << "Converged Eigenvalue after " << k << " iterations is " << rho_k << endl;
506+
}
507+
break;
541508
}
542-
}
543-
}
509+
510+
// normalize w_k to form next seed w_{k+1}
511+
for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) {
512+
for (unsigned short iVar = 0; iVar < nVarTotal; ++iVar) {
513+
w_k(iPoint, iVar) /= rho_k;
514+
}
515+
}
516+
517+
SeedAllDerivatives(w_k, geometry);
518+
rho_old = rho_k;
519+
k++;
520+
521+
} //while
522+
523+
w_k.resize(0, 0);
524+
}

0 commit comments

Comments
 (0)