Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #ifdef MOOSE_MFEM_ENABLED 11 : 12 : #include "MFEMEigenproblem.h" 13 : #include "MFEMVariable.h" 14 : #include "MFEMEigensolverBase.h" 15 : 16 : registerMooseObject("MooseApp", MFEMEigenproblem); 17 : 18 : InputParameters 19 2178 : MFEMEigenproblem::validParams() 20 : { 21 2178 : InputParameters params = MFEMProblem::validParams(); 22 4356 : params.addClassDescription("Problem type for building and solving a finite element eigenproblem " 23 : "using the MFEM finite element library."); 24 8712 : params.addParam<int>("num_modes", 1, "Set the number of lowest eigenmodes to compute."); 25 6534 : params.addParam<std::string>( 26 : "mode_separator", 27 : "_", 28 : "Separator string inserted between a variable name and its eigenmode index when " 29 : "registering the gridfunction that stores the corresponding eigenvector."); 30 : 31 2178 : return params; 32 0 : } 33 : 34 26 : MFEMEigenproblem::MFEMEigenproblem(const InputParameters & params) : MFEMProblem(params) 35 : { 36 52 : getProblemData().mode_separator = getParam<std::string>("mode_separator"); 37 26 : if (_num_type == NumericType::COMPLEX) 38 0 : mooseError("Complex numbers are not currently supported for eigenproblems."); 39 26 : } 40 : 41 : void 42 26 : MFEMEigenproblem::addVariable(const std::string & var_type, 43 : const std::string & var_name, 44 : InputParameters & parameters) 45 : { 46 : // Reject names that would collide with the mode-suffix convention or with any 47 : // already-registered eigenmode storage entry. 48 52 : const auto num_modes = getParam<int>("num_modes"); 49 26 : const auto & sep = getProblemData().mode_separator; 50 26 : if (getProblemData().gridfunctions.Has(var_name)) 51 0 : mooseError("MFEM variable '", 52 : var_name, 53 : "' clashes with an existing gridfunction (likely an eigenmode entry from another " 54 : "variable). Choose a different variable name or set 'mode_separator' to a string " 55 : "that avoids the clash."); 56 : 57 156 : for (int i = 0; i < num_modes; ++i) 58 : { 59 130 : const auto mode_name = var_name + sep + std::to_string(i); 60 130 : if (getProblemData().gridfunctions.Has(mode_name)) 61 0 : mooseError("Eigenmode storage name '", 62 : mode_name, 63 : "' for variable '", 64 : var_name, 65 : "' clashes with an already-registered variable. Set 'mode_separator' to a " 66 : "string that avoids the clash, or rename the conflicting variable."); 67 130 : } 68 : 69 26 : addGridFunction(var_type, var_name, parameters); 70 : 71 156 : for (int i = 0; i < num_modes; ++i) 72 130 : addGridFunction(var_type, var_name + sep + std::to_string(i), parameters); 73 26 : } 74 : 75 : void 76 26 : MFEMEigenproblem::resolveMFEMSolvers() 77 : { 78 26 : MFEMProblem::resolveMFEMSolvers(); 79 : 80 26 : if (getProblemData().nonlinear_solver) 81 0 : mooseError("MFEMEigenproblem does not support nonlinear solver '", 82 0 : getProblemData().nonlinear_solver->name(), 83 : "'."); 84 : 85 78 : if (getProblemData().jacobian_solver && 86 78 : !std::dynamic_pointer_cast<Moose::MFEM::EigensolverBase>(getProblemData().jacobian_solver)) 87 0 : mooseError("The selected solver '", 88 0 : getProblemData().jacobian_solver->name(), 89 : "' is not an eigensolver, but the problem is marked as an eigenproblem."); 90 26 : } 91 : 92 : #endif