NonlinearEigenSystem::NonlinearEigenSystem(EigenProblem & eigen_problem, const std::string & name) : NonlinearSystemBase( eigen_problem, eigen_problem.es().add_system<TransientEigenSystem>(name), name), _transient_sys(eigen_problem.es().get_system<TransientEigenSystem>(name)), _n_eigen_pairs_required(eigen_problem.getNEigenPairsRequired()) { sys().attach_assemble_function(Moose::assemble_matrix); }
void assemble_matrix(EquationSystems & es, const std::string & system_name) { EigenProblem * p = es.parameters.get<EigenProblem *>("_eigen_problem"); EigenSystem & eigen_system = es.get_system<EigenSystem>(system_name); p->computeJacobian( *eigen_system.current_local_solution.get(), *eigen_system.matrix_A, Moose::KT_NONEIGEN); if (eigen_system.generalized()) { if (eigen_system.matrix_B) p->computeJacobian( *eigen_system.current_local_solution.get(), *eigen_system.matrix_B, Moose::KT_EIGEN); else mooseError("It is a generalized eigenvalue problem but matrix B is empty\n"); } }
void assemble_matrix(EquationSystems & es, const std::string & system_name) { EigenProblem * p = es.parameters.get<EigenProblem *>("_eigen_problem"); EigenSystem & eigen_system = es.get_system<EigenSystem>(system_name); if (!p->isNonlinearEigenvalueSolver()) { p->computeJacobian( *eigen_system.current_local_solution.get(), *eigen_system.matrix_A, Moose::KT_NONEIGEN); } else { Mat petsc_mat_A = static_cast<PetscMatrix<Number> &>(*eigen_system.matrix_A).mat(); PetscObjectComposeFunction((PetscObject)petsc_mat_A, "formJacobian", Moose::SlepcSupport::mooseSlepcEigenFormJacobianA); PetscObjectComposeFunction((PetscObject)petsc_mat_A, "formFunction", Moose::SlepcSupport::mooseSlepcEigenFormFunctionA); PetscContainer container; PetscContainerCreate(eigen_system.comm().get(), &container); PetscContainerSetPointer(container, p); PetscObjectCompose((PetscObject)petsc_mat_A, "formJacobianCtx", nullptr); PetscObjectCompose((PetscObject)petsc_mat_A, "formJacobianCtx", (PetscObject)container); PetscObjectCompose((PetscObject)petsc_mat_A, "formFunctionCtx", nullptr); PetscObjectCompose((PetscObject)petsc_mat_A, "formFunctionCtx", (PetscObject)container); PetscContainerDestroy(&container); // Let libmesh do not close matrices before solve eigen_system.eigen_solver->set_close_matrix_before_solve(false); } if (eigen_system.generalized()) { if (eigen_system.matrix_B) { if (!p->isNonlinearEigenvalueSolver()) { p->computeJacobian( *eigen_system.current_local_solution.get(), *eigen_system.matrix_B, Moose::KT_EIGEN); } else { Mat petsc_mat_B = static_cast<PetscMatrix<Number> &>(*eigen_system.matrix_B).mat(); PetscObjectComposeFunction((PetscObject)petsc_mat_B, "formJacobian", Moose::SlepcSupport::mooseSlepcEigenFormJacobianB); PetscObjectComposeFunction((PetscObject)petsc_mat_B, "formFunction", Moose::SlepcSupport::mooseSlepcEigenFormFunctionB); PetscContainer container; PetscContainerCreate(eigen_system.comm().get(), &container); PetscContainerSetPointer(container, p); PetscObjectCompose((PetscObject)petsc_mat_B, "formFunctionCtx", nullptr); PetscObjectCompose((PetscObject)petsc_mat_B, "formFunctionCtx", (PetscObject)container); PetscObjectCompose((PetscObject)petsc_mat_B, "formJacobianCtx", nullptr); PetscObjectCompose((PetscObject)petsc_mat_B, "formJacobianCtx", (PetscObject)container); PetscContainerDestroy(&container); } } else mooseError("It is a generalized eigenvalue problem but matrix B is empty\n"); } }