Beispiel #1
0
ElementLoop& BoundaryTerm::access_element_loop( const std::string& type_name )
{
  // ensure that the fields are present

  link_fields();

  // get the element loop or create it if does not exist

  ElementLoop::Ptr loop;
  Common::Component::Ptr cloop = get_child_ptr( "LOOP" );
  if( is_null( cloop ) )
  {
    const std::string update_vars_type =
        physical_model().get_child( RDM::Tags::update_vars() )
                        .as_type<Physics::Variables>()
                        .type();

    loop = build_component_abstract_type_reduced< FaceLoop >( "FaceLoopT<" + type_name + "," + update_vars_type + ">" , "LOOP");
    add_component(loop);
  }
  else
    loop = cloop->as_ptr_checked<ElementLoop>();


  return *loop;
}
Beispiel #2
0
void UpdateSolution::execute()
{
  link_fields();

  Field& solution     = *m_solution;
  Field& residual     = *m_residual;
  Field& update_coeff = *m_update_coeff;
  Field& jacobian_determinant = *m_jacobian_determinant;

  for (Uint i=0; i<solution.size(); ++i)
  {
    for (Uint j=0; j<solution.row_size(); ++j)
    {
      solution[i][j] += update_coeff[i][0] * residual[i][j];
    }
  }
}
Beispiel #3
0
ElementLoop& BoundaryTerm::access_element_loop( const std::string& type_name )
{
    // ensure that the fields are present

    link_fields();

    // get the element loop or create it if does not exist

    Handle< ElementLoop > loop(get_child( "LOOP" ));
    if( is_null( loop ) )
    {
        const std::string update_vars_type =
            physical_model().get_child( RDM::Tags::update_vars() )
            ->handle<physics::Variables>()
            ->type();

        loop = create_component<FaceLoop>("LOOP", "FaceLoopT<" + type_name + "," + update_vars_type + ">");
    }

    return *loop;
}
void ComputeUpdateCoefficient::execute()
{
  link_fields();

  if (is_null(m_wave_speed))   throw SetupError(FromHere(), "WaveSpeed field was not set");
  if (is_null(m_update_coeff)) throw SetupError(FromHere(), "UpdateCoeff Field was not set");

  Field& wave_speed = *m_wave_speed;
  Field& update_coeff = *m_update_coeff;
  Real cfl = options().value<Real>("cfl");
  if (options().value<bool>("time_accurate")) // global time stepping
  {
    if (is_null(m_time))   throw SetupError(FromHere(), "Time component was not set");

    Time& time = *m_time;

    cf3_assert_desc("Fields not compatible: "+to_str(update_coeff.size())+"!="+to_str(wave_speed.size()),update_coeff.size() == wave_speed.size());

    /// compute time step
    //  -----------------
    /// - take user-defined time step
    Real dt = time.options().value<Real>("time_step");
    if (dt==0.) dt = math::Consts::real_max();

    /// - Make time step stricter through the CFL number
    Real min_dt = dt;
    Real max_dt = 0.;
    RealVector ws(wave_speed.row_size());
    for (Uint i=0; i<wave_speed.size(); ++i)
    {
      if (wave_speed[i][0] > 0)
      {
        dt = cfl/wave_speed[i][0];

        min_dt = std::min(min_dt,dt);
        max_dt = std::max(max_dt,dt);
      }
    }
    Real glb_min_dt;
    PE::Comm::instance().all_reduce(PE::min(), &min_dt, 1, &glb_min_dt);
    dt = glb_min_dt;

    /// - Make sure we reach milestones and final simulation time
    Real tf = limit_end_time(time.current_time(), time.options().value<Real>("end_time"));
    if( time.current_time() + dt + m_tolerance > tf )
      dt = tf - time.current_time();

    /// Calculate the update_coefficient
    //  --------------------------------
    /// For Forward Euler: update_coefficient = @f$ \Delta t @f$.
    /// @f[ Q^{n+1} = Q^n + \Delta t \ R @f]
    for (Uint i=0; i<update_coeff.size(); ++i)
    {
      update_coeff[i][0] = dt ;
    }

    // Update the new time step
    time.dt() = dt;

  }
  else // local time stepping
  {
    if (is_not_null(m_time))  m_time->dt() = 0.;

    // Calculate the update_coefficient = CFL/wave_speed
    RealVector ws(wave_speed.row_size());
    for (Uint i=0; i<wave_speed.size(); ++i)
    {
      if (wave_speed[i][0] > 0)
        update_coeff[i][0] = cfl/wave_speed[i][0];
    }
  }
}