Line data Source code
1 : /********************************************************************/ 2 : /* SOFTWARE COPYRIGHT NOTIFICATION */ 3 : /* Cardinal */ 4 : /* */ 5 : /* (c) 2021 UChicago Argonne, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /* */ 8 : /* Prepared by UChicago Argonne, LLC */ 9 : /* Under Contract No. DE-AC02-06CH11357 */ 10 : /* With the U. S. Department of Energy */ 11 : /* */ 12 : /* Prepared by Battelle Energy Alliance, LLC */ 13 : /* Under Contract No. DE-AC07-05ID14517 */ 14 : /* With the U. S. Department of Energy */ 15 : /* */ 16 : /* See LICENSE for full restrictions */ 17 : /********************************************************************/ 18 : 19 : #ifdef ENABLE_OPENMC_COUPLING 20 : 21 : #include "OpenMCInitAction.h" 22 : #include "CreateProblemAction.h" 23 : #include "AddMeshGeneratorAction.h" 24 : 25 : registerMooseAction("CardinalApp", OpenMCInitAction, "openmc_init"); 26 : 27 : InputParameters 28 3221 : OpenMCInitAction::validParams() 29 : { 30 3221 : InputParameters params = Action::validParams(); 31 3221 : params.addClassDescription("Initializes OpenMC when an OpenMCCellAverageProblem or an " 32 : "OpenMCMeshGenerator is present in the input."); 33 3221 : return params; 34 0 : } 35 : 36 3221 : OpenMCInitAction::OpenMCInitAction(const InputParameters & parameters) : Action(parameters) {} 37 : 38 : void 39 3221 : OpenMCInitAction::act() 40 : { 41 : // Check whether OpenMCCellAverageProblem is requested in the input file 42 : std::string xml_directory_problem; 43 : Real scaling_problem; 44 : bool openmc_problem_requested = 45 3221 : isOpenMCCellAverageProblemRequested(xml_directory_problem, scaling_problem); 46 : 47 : // Check whether OpenMCMeshGenerator is requested in the input file 48 : std::string xml_directory_generator; 49 : Real scaling_generator; 50 : bool openmc_mesh_generator_requested = 51 3221 : isOpenMCMeshGeneratorRequested(xml_directory_generator, scaling_generator); 52 : 53 : // if there is no need to initialize OpenMC, return 54 3217 : if (!openmc_problem_requested && !openmc_mesh_generator_requested) 55 : return; 56 : 57 : // If both OpenMC problem and mesh generator are present 58 2442 : if (openmc_problem_requested && openmc_mesh_generator_requested) 59 : { 60 : // Check for xml_directory consistency 61 30 : if (xml_directory_problem != xml_directory_generator) 62 2 : mooseError("Inconsistent 'xml_directory' for OpenMC in the mesh generator and problem " 63 : "declarations. Make sure the same value is used throughout the [Mesh] and " 64 : "[Problem] blocks."); 65 : 66 : // Check for scaling consistency 67 28 : if (scaling_problem != scaling_generator) 68 2 : mooseError("Inconsistent 'scaling' factors for OpenMC in the mesh generator and problem " 69 : "declarations. Make sure the same value is used throughout the [Mesh] and " 70 : "[Problem] blocks."); 71 : } 72 : 73 : // Select xml_directory 74 : std::string xml_directory = 75 2446 : (openmc_problem_requested) ? xml_directory_problem : xml_directory_generator; 76 : 77 : // Initialize OpenMC 78 2438 : initOpenMC(xml_directory); 79 : } 80 : 81 : bool 82 3221 : OpenMCInitAction::isOpenMCCellAverageProblemRequested(std::string & xml_directory, 83 : Real & scaling) const 84 : { 85 : // Retrieve all CreateProblemAction actions 86 3221 : const auto & problem_actions = _awh.getActions<CreateProblemAction>(); 87 : 88 : // Search for an OpenMCCellAverageProblem 89 3455 : for (const auto * action : problem_actions) 90 : { 91 5336 : if (action->getParam<std::string>("type") == "OpenMCCellAverageProblem") 92 : { 93 4868 : xml_directory = action->getObjectParams().get<FileName>("xml_directory"); 94 2434 : scaling = action->getObjectParams().get<Real>("scaling"); 95 : return true; 96 : } 97 : } 98 : return false; 99 3221 : } 100 : 101 : bool 102 3221 : OpenMCInitAction::isOpenMCMeshGeneratorRequested(std::string & xml_directory, Real & scaling) const 103 : { 104 : // Retrieve all AddMeshGeneratorAction actions 105 3221 : const auto & mesh_gen_actions = _awh.getActions<AddMeshGeneratorAction>(); 106 : 107 : // Search for OpenMCMeshGenerators and verify parameters consistency 108 : bool found = false; 109 11816 : for (const auto * action : mesh_gen_actions) 110 : { 111 8599 : if (action->getMooseObjectType() == "OpenMCMeshGenerator") 112 : { 113 54 : std::string xml_directory_temp = action->getObjectParams().get<FileName>("xml_directory"); 114 54 : Real scaling_temp = action->getObjectParams().get<Real>("scaling"); 115 54 : if (found) 116 : { 117 : // Check for xml_directory consistency 118 12 : if (xml_directory_temp != xml_directory) 119 2 : mooseError("Inconsistent 'xml_directory' values found in the declared " 120 : "OpenMCMeshGenerators; the same choice for 'xml_directory' must be used " 121 : "across all OpenMCMeshGenerator objects"); 122 : 123 : // Check for scaling consistency 124 10 : if (scaling_temp != scaling) 125 2 : mooseError( 126 : "Inconsistent 'scaling' factors for OpenMC in the declared OpenMCMeshGenerators; the " 127 : "same choice for 'scaling' must be used across all OpenMCMeshGenerator objects"); 128 : } 129 : else 130 : { 131 : xml_directory = xml_directory_temp; 132 42 : scaling = scaling_temp; 133 : found = true; 134 : } 135 : } 136 : } 137 3217 : return found; 138 3217 : } 139 : 140 : void 141 2438 : OpenMCInitAction::initOpenMC(const std::string & xml_directory) 142 : { 143 : // Suppress OpenMC output when the language server is active by 144 : // decreasing the verbosity to level 1 (the lowest). 145 2438 : std::vector<std::string> argv_vec = {"openmc"}; 146 9752 : if (_app.isParamValid("language_server") && _app.getParam<bool>("language_server")) 147 : { 148 0 : argv_vec.push_back("-q"); 149 0 : argv_vec.push_back("1"); 150 : } 151 : 152 : // Add xml_directory 153 2438 : argv_vec.push_back(xml_directory); 154 : 155 : std::vector<char *> argv; 156 7314 : for (const auto & arg : argv_vec) 157 : { 158 4876 : argv.push_back(const_cast<char *>(arg.data())); 159 : } 160 : 161 : // Add terminating nullptr 162 2438 : argv.push_back(nullptr); 163 : 164 : // Initialize OpenMC 165 2438 : openmc_init(argv.size() - 1, argv.data(), &_communicator.get()); 166 2438 : } 167 : 168 : #endif