diff --git a/framework/src/problems/EigenProblem.C b/framework/src/problems/EigenProblem.C index d4b6073e3ef0..02c2e3c9793e 100644 --- a/framework/src/problems/EigenProblem.C +++ b/framework/src/problems/EigenProblem.C @@ -19,6 +19,7 @@ #include "OutputWarehouse.h" #include "Function.h" #include "MooseVariableScalar.h" +#include "UserObject.h" // libMesh includes #include "libmesh/system.h" @@ -493,6 +494,16 @@ EigenProblem::checkProblemIntegrity() { FEProblemBase::checkProblemIntegrity(); _nl_eigen->checkIntegrity(); + if (_bx_norm_name) + { + if (!isNonlinearEigenvalueSolver()) + paramWarning("bx_norm", "This parameter is only used for nonlinear solve types"); + else if (auto & pp = getUserObjectBase(_bx_norm_name.value()); + !pp.getExecuteOnEnum().contains(EXEC_LINEAR)) + pp.paramError("execute_on", + "If providing the Bx norm, this postprocessor must execute on linear e.g. " + "during residual evaluations"); + } } void diff --git a/framework/src/utils/SlepcSupport.C b/framework/src/utils/SlepcSupport.C index bd9e0cda1a2d..3b7c82119d1b 100644 --- a/framework/src/utils/SlepcSupport.C +++ b/framework/src/utils/SlepcSupport.C @@ -951,6 +951,13 @@ mooseSlepcEigenFormFunctionB(SNES snes, Vec x, Vec r, void * ctx) ierr = MatMult(B, x, r); CHKERRQ(ierr); + + if (eigen_problem->bxNormProvided()) + { + // User has provided a postprocessor. We need it updated + updateCurrentLocalSolution(eigen_nl.sys(), x); + eigen_problem->execute(EXEC_LINEAR); + } } else moosePetscSNESFormFunction(snes, x, r, ctx, eigen_nl.eigenVectorTag()); @@ -1006,6 +1013,13 @@ mooseSlepcEigenFormFunctionAB(SNES /*snes*/, Vec x, Vec Ax, Vec Bx, void * ctx) CHKERRQ(ierr); } + if (eigen_problem->bxNormProvided()) + { + // User has provided a postprocessor. We need it updated + updateCurrentLocalSolution(sys, x); + eigen_problem->execute(EXEC_LINEAR); + } + PetscFunctionReturn(PETSC_SUCCESS); } diff --git a/test/tests/problems/eigen_problem/jfnk_mo/ne_coupled_mo.i b/test/tests/problems/eigen_problem/jfnk_mo/ne_coupled_mo.i index 49c050270a83..b29d122959e6 100644 --- a/test/tests/problems/eigen_problem/jfnk_mo/ne_coupled_mo.i +++ b/test/tests/problems/eigen_problem/jfnk_mo/ne_coupled_mo.i @@ -79,6 +79,20 @@ type = Eigenvalue solve_type = PJFNKMO nl_rel_tol = 1e-6 + nl_abs_tol = 1e-14 +[] + +[Problem] + type = EigenProblem +[] + +[Postprocessors] + [uint] + type = ElementIntegralVariablePostprocessor + variable = u + execute_on = 'initial linear nonlinear' + outputs = 'console' + [] [] [VectorPostprocessors] diff --git a/test/tests/problems/eigen_problem/jfnk_mo/tests b/test/tests/problems/eigen_problem/jfnk_mo/tests index 13ba015af496..66fccbf57158 100644 --- a/test/tests/problems/eigen_problem/jfnk_mo/tests +++ b/test/tests/problems/eigen_problem/jfnk_mo/tests @@ -54,19 +54,41 @@ [] [ne_coupled_mo] - type = 'CSVDiff' - input = 'ne_coupled_mo.i' - csvdiff = 'ne_coupled_eigenvalues_0001.csv' - slepc = true - slepc_version = '>=3.11.0' - requirement = "The system shall support use of matrix-vector multiplication as residual evaluation for coupled eigenvalue problems" + requirement = "The system shall support use of matrix-vector multiplication as residual evaluation for coupled eigenvalue problems with the bx norm" + issues = "#18493 #21056 #28993" + [l2_bx] + type = 'CSVDiff' + input = 'ne_coupled_mo.i' + csvdiff = 'ne_coupled_eigenvalues_0001.csv' + slepc = true + slepc_version = '>=3.11.0' + detail = 'computed as the L2 norm of the bx vector, or' + [] + [custom_bx] + type = 'CSVDiff' + input = 'ne_coupled_mo.i' + csvdiff = 'ne_coupled_eigenvalues_0001.csv' + cli_args = 'Problem/bx_norm=uint' + slepc = true + slepc_version = '>=3.11.0' + detail = 'computed by a user provided postprocessor.' + prereq = 'ne_coupled_mo/l2_bx' + [] + [] + [missing_bx_norm_exec_linear] + type = RunException + issues = '#28993' + input = ne_coupled_mo.i + cli_args = "Problem/bx_norm=uint Postprocessors/uint/execute_on='initial nonlinear'" + requirement = 'The system shall error if the user wants the Bx norm provided by a postprocessor but the postprocessor is not executed during residual evaluations.' + expect_err = "If providing the Bx norm, this postprocessor must execute on linear" [] [ne_coupled_mo_full] type = 'CSVDiff' input = 'ne_coupled_mo.i' csvdiff = 'ne_coupled_eigenvalues_0001.csv' - prereq = 'ne_coupled_mo' + prereq = 'ne_coupled_mo/custom_bx' cli_args = 'Preconditioning/active=''' slepc = true slepc_version = '>=3.11.0'