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 2182 : MFEMEigenproblem::validParams() 20 : { 21 2182 : InputParameters params = MFEMProblem::validParams(); 22 4364 : params.addClassDescription("Problem type for building and solving a finite element eigenproblem " 23 : "using the MFEM finite element library."); 24 8728 : params.addParam<int>("num_modes", 1, "Set the number of lowest eigenmodes to compute."); 25 6546 : 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 2182 : 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 26 : validateVariableNumericType(var_type, var_name); 47 : 48 : // Reject names that would collide with the mode-suffix convention or with any 49 : // already-registered eigenmode storage entry. 50 52 : const auto num_modes = getParam<int>("num_modes"); 51 26 : const auto & sep = getProblemData().mode_separator; 52 26 : if (getProblemData().gridfunctions.Has(var_name)) 53 0 : mooseError("MFEM variable '", 54 : var_name, 55 : "' clashes with an existing gridfunction (likely an eigenmode entry from another " 56 : "variable). Choose a different variable name or set 'mode_separator' to a string " 57 : "that avoids the clash."); 58 : 59 156 : for (int i = 0; i < num_modes; ++i) 60 : { 61 130 : const auto mode_name = var_name + sep + std::to_string(i); 62 130 : if (getProblemData().gridfunctions.Has(mode_name)) 63 0 : mooseError("Eigenmode storage name '", 64 : mode_name, 65 : "' for variable '", 66 : var_name, 67 : "' clashes with an already-registered variable. Set 'mode_separator' to a " 68 : "string that avoids the clash, or rename the conflicting variable."); 69 130 : } 70 : 71 26 : addGridFunction(var_type, var_name, parameters); 72 : 73 156 : for (int i = 0; i < num_modes; ++i) 74 130 : addGridFunction(var_type, var_name + sep + std::to_string(i), parameters); 75 26 : } 76 : 77 : void 78 26 : MFEMEigenproblem::resolveMFEMSolvers() 79 : { 80 26 : MFEMProblem::resolveMFEMSolvers(); 81 : 82 26 : if (getProblemData().nonlinear_solver) 83 0 : mooseError("MFEMEigenproblem does not support nonlinear solver '", 84 0 : getProblemData().nonlinear_solver->name(), 85 : "'."); 86 : 87 78 : if (getProblemData().jacobian_solver && 88 78 : !std::dynamic_pointer_cast<Moose::MFEM::EigensolverBase>(getProblemData().jacobian_solver)) 89 0 : mooseError("The selected solver '", 90 0 : getProblemData().jacobian_solver->name(), 91 : "' is not an eigensolver, but the problem is marked as an eigenproblem."); 92 26 : } 93 : 94 : #endif