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_NEK_COUPLING 20 : 21 : #include "NekTimeStepper.h" 22 : #include "MooseApp.h" 23 : #include "Transient.h" 24 : #include "NekInterface.h" 25 : 26 : registerMooseObject("CardinalApp", NekTimeStepper); 27 : 28 : InputParameters 29 1467 : NekTimeStepper::validParams() 30 : { 31 1467 : InputParameters params = TimeStepper::validParams(); 32 2934 : params.addParam<Real>("min_dt", 1e-9, "Minimum time step size to allow MOOSE to set in nekRS"); 33 1467 : params.addClassDescription("Select time step size based on NekRS time stepping schemes"); 34 1467 : return params; 35 0 : } 36 : 37 711 : NekTimeStepper::NekTimeStepper(const InputParameters & parameters) 38 1422 : : TimeStepper(parameters), _min_dt(getParam<Real>("min_dt")) 39 : { 40 : // Set a higher value for the timestep tolerance with which time steps are 41 : // compared between nekRS and other MOOSE apps in a multiapp hierarchy. For some reason, 42 : // it seems that floating point round-off accumulation is significant in nekRS, such 43 : // that with subcycling, I frequently see that MOOSE wants nekRS to take a time step 44 : // on the order of 5e-14 in order to "catch up" to a synchronization point. 45 711 : _executioner.setTimestepTolerance(_min_dt); 46 : 47 : // nekRS can end a simulation based on (1) a number of time steps, (2) an 48 : // end time, or (3) a total elapsed wall time. Because this wall timer would 49 : // keep incrementing while other applications are running in this multiphysics 50 : // environment, we don't want to base when to finish nekRS on this. Even if 51 : // Nek is the ultimate master app, we still probably don't want to use a wall 52 : // time to determine when to end the simulation, because other objects in the 53 : // MOOSE input file would consume that wall time. 54 711 : if (nekrs::endControlElapsedTime()) 55 0 : mooseError( 56 : "A wall time cannot be used to control the end of the nekRS simulation " 57 : "when other applications (i.e. MOOSE) are consuming the same wall time.\n\nPlease set " 58 : "'stopAt' to either 'numSteps' or 'endTime' in your .par file."); 59 : 60 : // The NekTimeStepper will take the end simulation control from the nekRS .par file. 61 : // If the Nek app is a sub-app, then the higher-up master app will automatically take 62 : // control of when the overall simulation ends. 63 711 : if (nekrs::endControlTime()) 64 20 : _end_time = nekrs::endTime(); 65 : 66 711 : if (nekrs::endControlNumSteps()) 67 691 : forceNumSteps(nekrs::numSteps()); 68 : 69 : // If running in JIT build mode, we don't want to do any time steps 70 711 : if (nekrs::buildOnly()) 71 0 : forceNumSteps(0); 72 : 73 : // When using this time stepper, the user should not try to set any constantDT-type 74 : // time stepping parameters with the Transient executioner. These could potentially 75 : // interfere with what nekRS is trying to use. 76 711 : std::vector<std::string> invalid_params = {"end_time", "dt", "dtmin", "dtmax", "num_steps"}; 77 4266 : for (const auto & s : invalid_params) 78 3555 : if (_executioner.parameters().isParamSetByUser(s)) 79 0 : mooseError("Parameter '" + s + "' is unused by the Executioner because it is " + 80 : "already specified by 'NekTimeStepper'!"); 81 : 82 : // at this point, this is non-dimensional dt 83 711 : auto [dtSubStep, dt] = nekrs::dt(1); 84 711 : _nek_dt = dt; 85 711 : } 86 : 87 : Real 88 1390 : NekTimeStepper::computeInitialDT() 89 : { 90 1390 : return _nek_dt * nekrs::referenceTime(); 91 : } 92 : 93 : Real 94 20384 : NekTimeStepper::computeDT() 95 : { 96 20384 : auto [dtSubStep, _dt] = nekrs::dt(_t_step); 97 20384 : Real dt = nekrs::hasVariableDt() ? _dt : _nek_dt; 98 20384 : return dt * nekrs::referenceTime(); 99 : } 100 : 101 : Real 102 21084 : NekTimeStepper::minDT() const 103 : { 104 21084 : return _min_dt; 105 : } 106 : 107 : Real 108 141669 : NekTimeStepper::nondimensionalDT(const Real & dimensional_dt) const 109 : { 110 141669 : return dimensional_dt / nekrs::referenceTime(); 111 : } 112 : 113 : #endif