Beispiel #1
0
void
Transient::solveStep(Real input_dt)
{
  _dt_old = _dt;

  if (input_dt == -1.0)
    _dt = computeConstrainedDT();
  else
    _dt = input_dt;

  Real current_dt = _dt;

  _problem.onTimestepBegin();

  // Increment time
  _time = _time_old + _dt;

  _problem.execTransfers(EXEC_TIMESTEP_BEGIN);
  _problem.execMultiApps(EXEC_TIMESTEP_BEGIN, _picard_max_its == 1);

  preSolve();
  _time_stepper->preSolve();

  _problem.timestepSetup();

  // Compute Pre-Aux User Objects (Timestep begin)
  _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::PRE_AUX);

  // Compute TimestepBegin AuxKernels
  _problem.computeAuxiliaryKernels(EXEC_TIMESTEP_BEGIN);

  // Compute Post-Aux User Objects (Timestep begin)
  _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::POST_AUX);

  // Perform output for timestep begin
  _problem.outputStep(EXEC_TIMESTEP_BEGIN);

  if (_picard_max_its > 1)
  {
    Real current_norm = _problem.computeResidualL2Norm();
    if (_picard_it == 0) // First Picard iteration - need to save off the initial nonlinear residual
    {
      _picard_initial_norm = current_norm;
      _console << "Initial Picard Norm: " << _picard_initial_norm << '\n';
    }
    else
      _console << "Current Picard Norm: " << current_norm << '\n';

    Real relative_drop = current_norm / _picard_initial_norm;

    if (current_norm < _picard_abs_tol || relative_drop < _picard_rel_tol)
    {
      _console << "Picard converged!" << std::endl;

      _picard_converged = true;
      _time_stepper->acceptStep();
      return;
    }
  }

  _time_stepper->step();

  // We know whether or not the nonlinear solver thinks it converged, but we need to see if the executioner concurs
  if (lastSolveConverged())
  {
    _console << COLOR_GREEN << " Solve Converged!" << COLOR_DEFAULT << std::endl;

    if (_picard_max_its <= 1)
      _time_stepper->acceptStep();

    _solution_change_norm = _problem.solutionChangeNorm();

    _problem.computeUserObjects(EXEC_TIMESTEP_END, UserObjectWarehouse::PRE_AUX);
#if 0
    // User definable callback
    if (_estimate_error)
      estimateTimeError();
#endif

    _problem.onTimestepEnd();

    _problem.computeAuxiliaryKernels(EXEC_TIMESTEP_END);
    _problem.computeUserObjects(EXEC_TIMESTEP_END, UserObjectWarehouse::POST_AUX);
    _problem.execTransfers(EXEC_TIMESTEP_END);
    _problem.execMultiApps(EXEC_TIMESTEP_END, _picard_max_its == 1);
  }
  else
  {
    _console << COLOR_RED << " Solve Did NOT Converge!" << COLOR_DEFAULT << std::endl;

    // Perform the output of the current, failed time step (this only occurs if desired)
    _problem.outputStep(EXEC_FAILED);
  }

  postSolve();
  _time_stepper->postSolve();
  _dt = current_dt; // _dt might be smaller than this at this point for multistep methods
  _time = _time_old;
}
Beispiel #2
0
void
Transient::takeStep(Real input_dt)
{
  _problem.out().setOutput(false);

  _dt_old = _dt;

  if (input_dt == -1.0)
    _dt = computeConstrainedDT();
  else
    _dt = input_dt;

  _problem.onTimestepBegin();
  if (lastSolveConverged())
    _problem.updateMaterials();             // Update backward material data structures

  // Increment time
  _time = _time_old + _dt;

  _problem.execTransfers(EXEC_TIMESTEP_BEGIN);
  _problem.execMultiApps(EXEC_TIMESTEP_BEGIN);

  // Only print this if the 'Output' block exists
  /// \todo{Remove when old output system is removed}
  if (_app.hasLegacyOutput())
  {
    Moose::out << "\nTime Step ";
    {
      std::ostringstream out;

      out << std::setw(2)
          << _t_step
          << ", time = "
          << std::setw(9)
          << std::setprecision(6)
          << std::setfill('0')
          << std::showpoint
          << std::left
          << _time;
      Moose::out << out.str() << std::endl;
    }

    {
      std::ostringstream tstepstr;
      tstepstr << _t_step;
      unsigned int tsteplen = tstepstr.str().size();
      if (tsteplen < 2)
        tsteplen = 2;

      std::ostringstream out;

      if (_verbose)
      {
        out << std::setw(tsteplen)
            << "          old time = "
            << std::setw(9)
            << std::setprecision(6)
            << std::setfill('0')
            << std::showpoint
            << std::left
            << _time_old
            << std::endl;
      }

      out << std::setw(tsteplen)
          <<"                dt = "
          << std::setw(9)
          << std::setprecision(6)
          << std::setfill('0')
          << std::showpoint
          << std::left
          << _dt;

      Moose::out << out.str() << std::endl;
    }
  }

  preSolve();
  _time_stepper->preSolve();

  _problem.timestepSetup();

  // Compute Pre-Aux User Objects (Timestep begin)
  _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::PRE_AUX);

  // Compute TimestepBegin AuxKernels
  _problem.computeAuxiliaryKernels(EXEC_TIMESTEP_BEGIN);

  // Compute Post-Aux User Objects (Timestep begin)
  _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::POST_AUX);

  _time_stepper->step();

  // We know whether or not the nonlinear solver thinks it converged, but we need to see if the executioner concurs
  if (lastSolveConverged())
  {
    Moose::out << "Solve Converged!" << std::endl;

    _time_stepper->acceptStep();

    _solution_change_norm = _problem.solutionChangeNorm();

    _problem.computeUserObjects(EXEC_TIMESTEP, UserObjectWarehouse::PRE_AUX);
#if 0
    // User definable callback
    if (_estimate_error)
    {
      estimateTimeError();
    }
#endif

    _problem.onTimestepEnd();

    _problem.computeAuxiliaryKernels(EXEC_TIMESTEP);
    _problem.computeUserObjects(EXEC_TIMESTEP, UserObjectWarehouse::POST_AUX);
    _problem.execTransfers(EXEC_TIMESTEP);
    _problem.execMultiApps(EXEC_TIMESTEP);
  }
  else
    Moose::out << "Solve Did NOT Converge!" << std::endl;

  postSolve();
  _time_stepper->postSolve();
}
Beispiel #3
0
void
AutoRBTransient::solveStep(Real input_dt)
{

  _dt_old = _dt;

  if (input_dt == -1.0)
    _dt = computeConstrainedDT();
  else
    _dt = input_dt;

  Real current_dt = _dt;

  _problem.onTimestepBegin();

  // Increment time
  _time = _time_old + _dt;

  // You could evaluate/store _his_initial_norm_old  here
  
  _problem.execTransfers(EXEC_TIMESTEP_BEGIN);
  _multiapps_converged = _problem.execMultiApps(EXEC_TIMESTEP_BEGIN, _picard_max_its == 1);

  if (!_multiapps_converged)
    return;

  preSolve();
  _time_stepper->preSolve();

  _problem.timestepSetup();
  
  _problem.execute(EXEC_TIMESTEP_BEGIN);

  // Perform output for timestep begin
  _problem.outputStep(EXEC_TIMESTEP_BEGIN);

  // Update warehouse active objects
  _problem.updateActiveObjects();

  _my_current_norm = _problem.computeResidualL2Norm(); // the norm from this app only
  _his_initial_norm_old = _his_initial_norm;
  _his_initial_norm = getPostprocessorValue("InitialResidual");
    //for sub-app@timestep_begin: his_initial_norm should be zero at each timestep
  
  // if this is sub app and its the initial_residual wasn't updated 
      // or use his_initial_norm_old
  //  On the first iteration Old should not match _his_initial if sub-app comes
  //    second (timestep_end).
  //if (_picard_max_its==1 && _his_initial_norm == getPostprocessorValueOld("InitialResidual"))
  if (_picard_max_its==1 && _his_initial_norm == _his_initial_norm_old)
     _his_initial_norm = 0;
  
  _his_final_norm = getPostprocessorValue("FinalResidual");
  if (_picard_max_its > 1)
  {    
      // is there a way to get his_final_norm without a postprocessor transfer?
      //std::vector<MultiApp *> multi_apps = _problem._multi_apps(EXEC_TIMESTEP_END)[0].all();
          // unfortunately _multi_apps is protected
      //Real his_last_norm = multi_apps[i]._subproblem.finalNonlinearResidual();
      //_console << "Multi-app end residual" << his_final_norm << std::endl; // did it work?

    if (_picard_it == 0) // First Picard iteration - need to save off the initial nonlinear residual
    {
      _current_norm = _my_current_norm;  
      //his_initial_norm_old) //EXEC_TIMESTEP_END
      //if (_his_initial_norm == getPostprocessorValueOld("InitialResidual")) 
      if (_his_initial_norm == _his_initial_norm_old) 
        _his_initial_norm = 0; 
      // set his_initial_norm to 0 so that we can start a new timestep properly
      
      _picard_initial_norm = _current_norm + _his_initial_norm; 
      //_console << "Initial Picard Norm: " << _picard_initial_norm << '\n';
      if (_his_initial_norm == 0)
        _adjust_initial_norm = true;
      _spectral_radius = pow(_new_tol_mult, 0.5);//*#*//
    }
    else
    {
      _current_norm_old = _current_norm;
      _current_norm = _my_current_norm + _his_final_norm; 
      //@^&// These changes smooth out the change in _spectral_radius
      //@^&//_spectral_radius = _current_norm / _current_norm_old;
      //@^&//_spectral_radius = 0.5 * (_current_norm / _current_norm_old + _spectral_radius);
      _spectral_radius = pow(_current_norm / _current_norm_old * _spectral_radius, 0.5);
      _console << "Current Picard Norm: " << _current_norm << '\n';
    }

    if (_picard_it == 1 && _adjust_initial_norm == true)
    {
      _picard_initial_norm = _picard_initial_norm + _his_initial_norm;
      _console << "Adjusted Initial Picard Norm: " << _picard_initial_norm << '\n';
      //@^&//_spectral_radius = _current_norm / _picard_initial_norm;
      //@^&//_spectral_radius = 0.5 * (_current_norm / _picard_initial_norm + _spectral_radius);
      _spectral_radius = pow(_current_norm / _picard_initial_norm * _spectral_radius, 0.5);
    }

    Real _relative_drop = _current_norm / _picard_initial_norm;

    if (_current_norm < _picard_abs_tol || _relative_drop < _picard_rel_tol)
    {
      _console << "Picard converged!" << std::endl;

      _picard_converged = true;
      _time_stepper->acceptStep();

      // Accumulator Postprocessor goes now, at the actual timestep_end, but
      //   only if _picard_max_its>1: 
      //_problem.computeUserObjects(EXEC_CUSTOM, UserObjectWarehouse::POST_AUX);
      _problem.execute(EXEC_CUSTOM); // new method
      return;
    }
  }
  else // this is the sub-app
  {
      // If this is the first Picard iteration of the timestep
      //   Second condition ensures proper treatment the very first time
      if ( _his_initial_norm == 0 || _current_norm_old == 0 )
      {
        _spectral_radius = pow(_new_tol_mult, 0.5);//*#*//
        _current_norm = _his_final_norm + _my_current_norm;
      }
      else
      {
        _current_norm_old = _current_norm;
        _current_norm = _his_final_norm + _my_current_norm;
        //@^&//_spectral_radius = _current_norm / _current_norm_old;
        //@^&//_spectral_radius = 0.5 * (_current_norm / _current_norm_old + _spectral_radius);
        _spectral_radius = pow(_current_norm / _current_norm_old * _spectral_radius, 0.5);
      }
  }
  
  // For multiple sub-apps you'll need an aggregate PP to collect residuals in
  //    or some way to keep the number of PPs low.
  
  if (_his_initial_norm == 0)
    _his_initial_norm = _my_current_norm; 
  //assume the other residual is comparable to this one

  //_new_tol = std::min(_his_initial_norm*_new_tol_mult, 0.95*_my_current_norm);
  _new_tol = std::min(_his_initial_norm*_spectral_radius*_spectral_radius, 0.95*_my_current_norm);
  // you may want 0.95 to be a parameter for the user to (not) change
  if (_new_tol < _min_abs_tol)
    _new_tol = _min_abs_tol;
  _console << "New Abs_Tol = " << _new_tol << std::endl;
  _problem.es().parameters.set<Real> ("nonlinear solver absolute residual tolerance") = _new_tol;


  _time_stepper->step();

  // We know whether or not the nonlinear solver thinks it converged, but we need to see if the executioner concurs
  if (lastSolveConverged())
  {
    _console << COLOR_GREEN << " Solve Converged!" << COLOR_DEFAULT << std::endl;

    if (_picard_max_its <= 1 )
      _time_stepper->acceptStep();

    _solution_change_norm = _problem.relativeSolutionDifferenceNorm();
    
    _problem.onTimestepEnd();
    _problem.execute(EXEC_TIMESTEP_END);

    _problem.execTransfers(EXEC_TIMESTEP_END);
    _multiapps_converged = _problem.execMultiApps(EXEC_TIMESTEP_END, _picard_max_its == 1);

    if (!_multiapps_converged)
      return;

  }
  else
  {
    _console << COLOR_RED << " Solve Did NOT Converge!" << COLOR_DEFAULT << std::endl;

    // Perform the output of the current, failed time step (this only occurs if desired)
    _problem.outputStep(EXEC_FAILED);
  }

  postSolve();
  _time_stepper->postSolve();
  _dt = current_dt; // _dt might be smaller than this at this point for multistep methods
  _time = _time_old;
}
Beispiel #4
0
void
Transient::solveStep(Real input_dt)
{
  _dt_old = _dt;

  if (input_dt == -1.0)
    _dt = computeConstrainedDT();
  else
    _dt = input_dt;

  Real current_dt = _dt;

  _problem.onTimestepBegin();

  // Increment time
  _time = _time_old + _dt;

  _problem.execTransfers(EXEC_TIMESTEP_BEGIN);
  _multiapps_converged = _problem.execMultiApps(EXEC_TIMESTEP_BEGIN, _picard_max_its == 1);

  if (!_multiapps_converged)
    return;

  preSolve();
  _time_stepper->preSolve();

  _problem.timestepSetup();

  _problem.execute(EXEC_TIMESTEP_BEGIN);

  if (_picard_max_its > 1)
  {
    _picard_timestep_begin_norm = _problem.computeResidualL2Norm();

    _console << "Picard Norm after TIMESTEP_BEGIN MultiApps: " << _picard_timestep_begin_norm << '\n';
  }

  // Perform output for timestep begin
  _problem.outputStep(EXEC_TIMESTEP_BEGIN);

  // Update warehouse active objects
  _problem.updateActiveObjects();

  _time_stepper->step();

  // We know whether or not the nonlinear solver thinks it converged, but we need to see if the executioner concurs
  if (lastSolveConverged())
  {
    _console << COLOR_GREEN << " Solve Converged!" << COLOR_DEFAULT << std::endl;

    if (_picard_max_its <= 1)
      _time_stepper->acceptStep();

    _solution_change_norm = _problem.solutionChangeNorm();

    _problem.onTimestepEnd();
    _problem.execute(EXEC_TIMESTEP_END);

    _problem.execTransfers(EXEC_TIMESTEP_END);
    _multiapps_converged = _problem.execMultiApps(EXEC_TIMESTEP_END, _picard_max_its == 1);

    if (!_multiapps_converged)
      return;
  }
  else
  {
    _console << COLOR_RED << " Solve Did NOT Converge!" << COLOR_DEFAULT << std::endl;

    // Perform the output of the current, failed time step (this only occurs if desired)
    _problem.outputStep(EXEC_FAILED);
  }

  postSolve();
  _time_stepper->postSolve();
  _dt = current_dt; // _dt might be smaller than this at this point for multistep methods
  _time = _time_old;
}
Beispiel #5
0
void
AdaptiveTransient::takeStep(Real input_dt)
{
  if (_converged)
    _problem.copyOldSolutions();
  else
    _problem.restoreSolutions();

  _dt_old = _dt;
  if (input_dt == -1.0)
    _dt = computeConstrainedDT();
  else
    _dt = input_dt;

  _problem.onTimestepBegin();
  if (_converged)
  {
    // Update backward material data structures
    _problem.updateMaterials();
  }

  // Increment time
  _time = _time_old + _dt;

  // Compute TimestepBegin AuxKernels
  _problem.computeAuxiliaryKernels(EXEC_TIMESTEP_BEGIN);

  // Compute TimestepBegin Postprocessors
  _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN);

  Moose::out << "Solving time step ";
  {
    std::ostringstream out;

    out << std::setw(2)
        << _t_step
        << ", old time="
        << std::setw(9)
        << std::setprecision(6)
        << std::setfill('0')
        << std::showpoint
        << std::left
        << _time_old
        << ", time="
        << std::setw(9)
        << std::setprecision(6)
        << std::setfill('0')
        << std::showpoint
        << std::left
        << _time
        << ", dt="
        << std::setw(9)
        << std::setprecision(6)
        << std::setfill('0')
        << std::showpoint
        << std::left
        << _dt;
    Moose::out << out.str() << std::endl;
  }

  preSolve();

  _problem.timestepSetup();

  try
  {
    // Compute Pre-Aux User Objects (Timestep begin)
    _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::PRE_AUX);

    // Compute TimestepBegin AuxKernels
    _problem.computeAuxiliaryKernels(EXEC_TIMESTEP_BEGIN);

    // Compute Post-Aux User Objects (Timestep begin)
    _problem.computeUserObjects(EXEC_TIMESTEP_BEGIN, UserObjectWarehouse::POST_AUX);

    _problem.solve();
    _converged = _problem.converged();
  }
  catch (MooseException &e)
  {
    _caught_exception = true;
    _converged = false;
  }

  if (!_caught_exception)
  {
    // We know whether or not the nonlinear solver thinks it converged, but we need to see if the executioner concurs
    bool last_solve_converged = lastSolveConverged();

    if (last_solve_converged)
      _problem.computeUserObjects(EXEC_TIMESTEP, UserObjectWarehouse::PRE_AUX);

    postSolve();

    _problem.onTimestepEnd();

    // We know whether or not the nonlinear solver thinks it converged, but we need to see if the executioner concurs
    if (last_solve_converged)
    {
      _problem.computeAuxiliaryKernels(EXEC_TIMESTEP);
      _problem.computeUserObjects();
    }

    Moose::out << std::endl;
  }
}