Line data Source code
1 : /**********************************************************************/ 2 : /* DO NOT MODIFY THIS HEADER */ 3 : /* Swift, a Fourier spectral solver for MOOSE */ 4 : /* */ 5 : /* Copyright 2024 Battelle Energy Alliance, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /**********************************************************************/ 8 : 9 : #include "Moose.h" 10 : #include "TensorOutput.h" 11 : #include "MooseError.h" 12 : #include "SwiftTypes.h" 13 : #include "TensorProblem.h" 14 : #include "DomainAction.h" 15 : 16 : InputParameters 17 22 : TensorOutput::validParams() 18 : { 19 22 : InputParameters params = MooseObject::validParams(); 20 44 : params.addRequiredParam<std::vector<TensorInputBufferName>>("buffer", "The buffers to output"); 21 44 : params.addParam<std::string>( 22 : "file_base", 23 : "The desired solution output name without an extension. If not provided, MOOSE sets it " 24 : "with Outputs/file_base when available. Otherwise, MOOSE uses input file name and this " 25 : "object name for a master input or uses master file_base, the subapp name and this object " 26 : "name for a subapp input to set it."); 27 22 : params.registerBase("TensorOutput"); 28 22 : params.addPrivateParam<TensorProblem *>("_tensor_problem", nullptr); 29 22 : params.addPrivateParam<const DomainAction *>("_domain", nullptr); 30 : 31 : // Add the 'execute_on' input parameter for users to set 32 22 : ExecFlagEnum exec_enum; 33 22 : exec_enum.addAvailableFlags(EXEC_INITIAL); 34 22 : exec_enum.addAvailableFlags(EXEC_TIMESTEP_END); 35 88 : exec_enum = {EXEC_INITIAL, EXEC_TIMESTEP_END}; 36 44 : params.addParam<ExecFlagEnum>("execute_on", exec_enum, exec_enum.getDocString()); 37 : 38 44 : params.addClassDescription("TensorOutput object."); 39 22 : return params; 40 22 : } 41 : 42 12 : TensorOutput::TensorOutput(const InputParameters & parameters) 43 : : MooseObject(parameters), 44 24 : _tensor_problem(*getCheckedPointerParam<TensorProblem *>("_tensor_problem")), 45 24 : _domain(*getCheckedPointerParam<const DomainAction *>("_domain")), 46 : /* Outputs run in a dedicated thread. We must be careful not to access data from the problem 47 : class that might be updated while the output is running, which would lead to race conditions 48 : resulting in unreproducible outputs. Time is such a quantity, which is why we provide a 49 : dedicated output time that is not changed while the asynchronous output is running.*/ 50 12 : _time(_tensor_problem.outputTime()), 51 36 : _file_base(isParamValid("file_base") ? getParam<std::string>("file_base") 52 12 : : _app.getOutputFileBase(true)), 53 36 : _execute_on(getParam<ExecFlagEnum>("execute_on")) 54 : { 55 : const TensorBufferBase & getBufferBase(const std::string & buffer_name); 56 : 57 54 : for (const auto & name : getParam<std::vector<TensorInputBufferName>>("buffer")) 58 30 : _out_buffers[name] = &_tensor_problem.getBufferBase(name).getRawCPUTensor(); 59 12 : } 60 : 61 : bool 62 88 : TensorOutput::shouldRun(const ExecFlagType & execute_flag) const 63 : { 64 88 : return _execute_on.isValueSet(execute_flag); 65 : } 66 : 67 : void 68 88 : TensorOutput::startOutput() 69 : { 70 88 : if (_output_thread.joinable()) 71 0 : mooseError("Output thread is already running. Must call waitForCompletion() first. This is a " 72 : "code error."); 73 88 : _output_thread = std::move(std::thread(&TensorOutput::output, this)); 74 88 : } 75 : 76 : void 77 96 : TensorOutput::waitForCompletion() 78 : { 79 96 : if (_output_thread.joinable()) 80 88 : _output_thread.join(); 81 96 : }