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; }
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]; } } }
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]; } } }