Beispiel #1
0
void RGFlow<Two_scale>::check_setup() const
{
   for (size_t m = 0; m < models.size(); ++m) {
      TModel* model = models[m];
      if (!model->model) {
         std::stringstream message;
         message << "RGFlow<Two_scale>::Error: model pointer ["
                 << m << "] is NULL";
         throw SetupError(message.str());
      }

      // check wether last model has a non-zero matching condition
      if (m + 1 == models.size()) {
         if (model->matching_condition)
            WARNING("the matching condition of the " << model->model->name()
                    << " is non-zero but will not be used");
      } else {
         if (model->matching_condition == NULL) {
            std::stringstream message;
            message << "RGFlow<Two_scale>::Error: matching condition "
                    << "of the " << model->model->name() << " to the "
                    << models[m + 1]->model->name() << " is NULL";
            throw SetupError(message.str());
         }
      }
   }

   if (!convergence_tester) {
      throw SetupError("RGFlow<Two_scale>::Error: convergence tester must "
                       "not be NULL");
   }
}
Beispiel #2
0
void TwoSstarImplementation::step()
{
  if ( is_null(m_pde) )          throw SetupError( FromHere(), "pde not configured" );
  if ( is_null(m_pde->time()) )  throw SetupError(FromHere(), "Time was not set");
  if ( is_null(m_pde->solution()) )  throw SetupError(FromHere(), "Solution was not set");
  if ( is_null(m_time_step_computer) ) throw SetupError(FromHere(), "Time step computer was not set");

  Time& time = *m_pde->time();

  m_time_step_computer->options().set("wave_speed",m_pde->wave_speed());
  m_time_step_computer->options().set("time_step",m_dt);

  Field& U  = *m_pde->solution();
  Field& R  = *m_pde->rhs();
  Field& H  = *m_dt;
  Field& U0 = *m_backup;
  const Real T0 = time.current_time();
  const Uint nb_eqs = m_pde->nb_eqs();
  
  Real dt = 0; 
  for (Uint stage=0; stage<m_coeffs->nb_stages(); ++stage)
  {
    // Set time and iteration for this stage
    time.dt() = dt;
    time.current_time() = T0 + m_coeffs->gamma(stage) * dt;


    // Set boundary condition
    m_pde->bc()->execute();
    // Compute right-hand-side
    m_pde->rhs_computer()->compute_rhs(*m_pde->rhs(),*m_pde->wave_speed());

    // Compute time step and backup solution
    if (stage == 0)
    {
      m_time_step_computer->execute();
      U0 = U;
      dt = time.dt();
    }

    // Do post-processing to the rhs
    if ( is_not_null( m_pre_update ) ) m_pre_update->execute();

    // Update solution
    const Real one_minus_alpha = 1. - m_coeffs->alpha(stage);    
    for (Uint pt=0; pt<U.size(); ++pt)
    {
      for (Uint eq=0; eq<nb_eqs; ++eq)
      {
        U[pt][eq] = one_minus_alpha*U0[pt][eq] + m_coeffs->alpha(stage)*U[pt][eq] + m_coeffs->beta(stage)*H[pt][0]*R[pt][eq];
      }
    }
    U.synchronize();
    
    // Do post-processing to the stage solution
    if ( is_not_null( m_post_update ) ) m_post_update->execute();
  }
  time.current_time() = T0;
}
Beispiel #3
0
Field& Dictionary::create_field(const std::string &name, math::VariablesDescriptor& variables_descriptor)
{
  CFinfo << "Creating field " << uri()/name << CFendl;
  if (m_dim == 0) throw SetupError(FromHere(), "dimension not configured");
  Handle<Field> field = create_component<Field>(name);
  field->set_dict(*this);
  field->set_descriptor(variables_descriptor);
  if (variables_descriptor.options().option(common::Tags::dimension()).value<Uint>() == 0)
  {
    field->descriptor().options().set(common::Tags::dimension(),m_dim);
  }
  field->set_row_size(field->descriptor().size());
  field->resize(size());

  update_structures();

  CFinfo << "Created field " << field->uri() << " with variables \n";
  for (Uint var=0; var<field->descriptor().nb_vars(); ++var)
  {
    CFinfo << "    - " << field->descriptor().user_variable_name(var) << " [" << field->descriptor().var_length(var) << "]\n";
  }
  CFinfo << CFflush;


  return *field;
}
void BinaryDataReader::read_data_block(char *data, const Uint count, const Uint block_idx)
{
  if(is_null(m_implementation.get()))
    throw SetupError(FromHere(), "No open file for BinaryDataReader at " + uri().path());
  
  m_implementation->read_data_block(data, count, block_idx);
}
  void read_data_block(char *data, const Uint count, const Uint block_idx)
  {
    static const std::string block_prefix("__CFDATA_BEGIN");
    
    XmlNode block_node = get_block_node(block_idx);
      
    const Uint block_begin = from_str<Uint>(block_node.attribute_value("begin"));
    const Uint block_end = from_str<Uint>(block_node.attribute_value("end"));
    const Uint compressed_size = block_end - block_begin - block_prefix.size();

    // Check the prefix
    binary_file.seekg(block_begin);
    std::vector<char> prefix_buf(block_prefix.size());
    binary_file.read(&prefix_buf[0], block_prefix.size());
    const std::string read_prefix(prefix_buf.begin(), prefix_buf.end());
    if(read_prefix != block_prefix)
      throw SetupError(FromHere(), "Bad block prefix for block " + to_str(block_idx));
   
    if(count != 0)
    {
      // Build a decompressing stream
      boost::iostreams::filtering_istream decompressing_stream;
      decompressing_stream.set_auto_close(false);
      decompressing_stream.push(boost::iostreams::zlib_decompressor());
      decompressing_stream.push(boost::iostreams::restrict(binary_file, 0, compressed_size));
      
      // Read the data
      decompressing_stream.read(data, count);
      decompressing_stream.pop();
    }
    
    cf3_assert(binary_file.tellg() == block_end);
  }
Beispiel #6
0
double SLHA_io::read_vector(const std::string& block_name, Eigen::MatrixBase<Derived>& vector) const
{
   if (vector.cols() != 1) throw SetupError("Vector has more than 1 column");

   auto block = data.find(data.cbegin(), data.cend(), block_name);

   const int rows = vector.rows();
   double scale = 0.;

   while (block != data.cend()) {
      for (const auto& line: *block) {
         if (!line.is_data_line()) {
            // read scale from block definition
            if (line.size() > 3 &&
                to_lower(line[0]) == "block" && line[2] == "Q=")
               scale = convert_to<double>(line[3]);
            continue;
         }

         if (line.size() >= 2) {
            const int i = convert_to<int>(line[0]) - 1;
            if (0 <= i && i < rows) {
               const double value = convert_to<double>(line[1]);
               vector(i,0) = value;
            }
         }
      }

      ++block;
      block = data.find(block, data.cend(), block_name);
   }

   return scale;
}
Beispiel #7
0
static bool OpenStatusWindow( const char *title )
/***********************************************/
{
    gui_text_metrics    metrics;
//    int                 i;
    gui_rect            rect;

//    for( i = STAT_BLANK; i < sizeof( Messages ) / sizeof( Messages[0] ); ++i ) {
//      Messages[i] = GetVariableStrVal( Messages[i] );
//    }
    GUIGetDlgTextMetrics( &metrics );
    CharSize.x = metrics.avg.x;
    CharSize.y = 5 * metrics.avg.y / 4;
    GUITruncToPixel( &CharSize );

    StatusInfo.parent = MainWnd;
    StatusInfo.title = GUIStrDup( title, NULL );
    StatusInfo.rect.width = STATUS_WIDTH * CharSize.x;
    StatusInfo.rect.height = STATUS_HEIGHT * CharSize.y;
    GUIGetClientRect( MainWnd, &rect );
    if( GUIIsGUI() ) {
        StatusInfo.rect.y = BitMapBottom;
    } else {
        StatusInfo.rect.y = (GUIScale.y - StatusInfo.rect.height) / 2;
    }
    if( StatusInfo.rect.y > rect.height - StatusInfo.rect.height ) {
        StatusInfo.rect.y = rect.height - StatusInfo.rect.height;
    }
    StatusInfo.rect.x = (GUIScale.x - StatusInfo.rect.width) / 2;

    StatusBarLen = 0;

    StatusWnd = GUICreateWindow( &StatusInfo );

    GUIGetClientRect( StatusWnd, &StatusRect );

    Cancel.parent = StatusWnd;
    Cancel.text = LIT( Cancel );
    Cancel.rect.height = 7 * CharSize.y / 4;
    Cancel.rect.width = (strlen( Cancel.text ) + 4) * CharSize.x;
    Cancel.rect.x = (StatusRect.width - Cancel.rect.width) / 2;
    Cancel.rect.y = CANNERY_ROW * CharSize.y;

    StatusBarRect.x = BAR_INDENT * CharSize.x;
    StatusBarRect.width = StatusRect.width - 2 * BAR_INDENT * CharSize.x;
    StatusBarRect.y = STATUS_ROW * CharSize.y;
    StatusBarRect.height = CharSize.y;
#ifndef _UI
    StatusBarRect.y -= CharSize.y / 2;
    StatusBarRect.height += CharSize.y;
#endif

    StatusBarLen = StatusBarRect.width / CharSize.x;

    if( !GUIAddControl( &Cancel, &ToolPlain, &ToolStandout ) ) {
        SetupError( "IDS_CONTROLERROR" );
        return( false );
    }
    return( true );
}
Beispiel #8
0
void CPlotXY::convergence_history( SignalArgs & args )
{
  if( is_not_null(m_data.get()) )
  {
    SignalFrame reply = args.create_reply( uri() );
    SignalFrame& options = reply.map( Protocol::Tags::key_options() );
//    std::vector<Real> data(8000);
    CTable<Real>& table = *m_data.get();
    std::vector<std::string> labels =
        list_of<std::string>("x")("y")("z")("u")("v")("w")("p")("t");

    add_multi_array_in(options.main_map, "Table", m_data->array(), ";", labels);

//    for(Uint row = 0 ; row < 1000 ; ++row)
//    {
//      for(Uint col = 0 ; col < 8 ; ++col)
//        data[ (row * 8) + col ] = table[row][col];
//    }

//    XmlNode node = options.add("Table", data, " ; ");

//    node.set_attribute("dimensions", "8");
  }
  else
    throw SetupError( FromHere(), "Data to plot not setup" );
}
Beispiel #9
0
CLink& CLink::link_to ( Component& lnkto )
{
  if (lnkto.is_link())
    throw SetupError(FromHere(), "Cannot link a CLink to another CLink");

  m_link_component = lnkto.self();
  return *this;
}
Beispiel #10
0
Link& Link::link_to ( Component& lnkto )
{
  if (is_not_null(lnkto.handle<Link>()))
    throw SetupError(FromHere(), "Cannot link a Link to another Link");

  m_link_component = lnkto.handle();
  return *this;
}
Beispiel #11
0
CLink& CLink::link_to ( Component const& lnkto )
{
  if (lnkto.is_link())
    throw SetupError(FromHere(), "Cannot link a CLink to another CLink");

  m_link_component = boost::const_pointer_cast<Component>(lnkto.self());
  return *this;
}
void BinaryDataReader::trigger_file()
{
  const URI file_uri = options().value<URI>("file");
  if(!boost::filesystem::exists(file_uri.path()))
  {
    throw SetupError(FromHere(), "Input file " + file_uri.path() + " does not exist");
  }
  m_implementation.reset(new Implementation(file_uri, options().value<Uint>("rank")));
}
void OutputIterationInfo::execute()
{
  if (m_residual.expired())     throw SetupError(FromHere(), "Residual field was not set");
  if (m_time.expired())         throw SetupError(FromHere(), "Time component was not set");

  // compute norm
  Real rhs_L2=0;
  boost_foreach(CTable<Real>::ConstRow rhs , m_residual.lock()->data().array())
    rhs_L2 += rhs[0]*rhs[0];
  rhs_L2 = sqrt(rhs_L2) / m_residual.lock()->data().size();

  // output convergence info
  CFinfo << "Iter [" << std::setw(4) << time().iter() << "]";
  CFinfo << "      Time [" << std::setprecision(4) << std::setiosflags(std::ios_base::scientific) << std::setw(10) << time().time() << "]";
  CFinfo << "      Time Step [" << std::setprecision(4) << std::setiosflags(std::ios_base::scientific) << std::setw(10) << time().dt() << "]";
  CFinfo << "      L2(rhs) [" << std::setprecision(4) << std::setiosflags(std::ios_base::scientific) << std::setw(10) << rhs_L2 << "]";
  CFinfo << CFendl;
}
void UpdateSolution::execute()
{
  if (m_solution.expired())     throw SetupError(FromHere(), "Solution field was not set");
  if (m_residual.expired())     throw SetupError(FromHere(), "Residual field was not set");
  if (m_update_coeff.expired()) throw SetupError(FromHere(), "UpdateCoeff Field was not set");

  CTable<Real>& solution = m_solution.lock()->data();
  CTable<Real>& residual = m_residual.lock()->data();
  CTable<Real>& update_coeff = m_update_coeff.lock()->data();

  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];
    }
  }
}
 XmlNode get_block_node(const Uint block_idx)
 {
   XmlNode block_node(my_node.content->first_node("block"));
   for(; block_node.is_valid(); block_node = XmlNode(block_node.content->next_sibling("block")))
   {
     if(from_str<Uint>(block_node.attribute_value("index")) == block_idx)
       return block_node;
   }
   
   throw SetupError(FromHere(), "Block with index " + to_str(block_idx) + " was not found");
 }
Beispiel #16
0
CLink& CLink::link_to ( Component::Ptr lnkto )
{
  if ( is_null(lnkto) )
    throw BadValue(FromHere(), "Cannot link to null component");

  if (lnkto->is_link())
    throw SetupError(FromHere(), "Cannot link a CLink to another CLink");

  m_link_component = lnkto;
  return *this;
}
Convergence_tester_DRbar<Model>::Convergence_tester_DRbar
(const Model* model_, double accuracy_goal_, const Scale_getter& sg)
   : Convergence_tester()
   , model(model_)
   , scale_getter(sg)
   , max_it(static_cast<int>(-log10(accuracy_goal_) * 10))
   , accuracy_goal(accuracy_goal_)
{
   if (!model)
      throw SetupError("Convergence_tester_DRbar<Model>: "
                       "model pointer must not be zero!");
}
Beispiel #18
0
void Comm::init(int argc, char** args)
{
  if ( is_finalized() )
    throw SetupError( FromHere(), "Should not call Comm::initialize() after Comm::finalize()" );

  if( !is_initialized() && !is_finalized() ) // then initialize
  {
    MPI_CHECK_RESULT(MPI_Init,(&argc,&args));
    //  CFinfo << "MPI (version " <<  version() << ") -- initiated" << CFendl;
  }

  m_comm = MPI_COMM_WORLD;
}
Beispiel #19
0
static gui_control_class ControlClass( int id, a_dialog_header *curr_dialog )
/***************************************************************************/
/* return the control class of a variable based on its id. */
{
    int                 i;

    for( i = 0; i < curr_dialog->num_controls; i++ ) {
        if( curr_dialog->controls[i].id == id ) {
            return( curr_dialog->controls[i].control_class );
        }
    }
    SetupError( "IDS_CONTROLCLASSERROR" );
    return( GUI_BAD_CLASS );
}
Beispiel #20
0
bool TwoSstarCoeffs::check_throw() const
{
  if (m_coeffs.order == 0u)
  {
    throw SetupError( FromHere(), "order of coefficients is not configured" );
    return false;
  }
  if (m_coeffs.nb_stages == 0u)
  {
    throw SetupError( FromHere(), "nb_stages of coefficients is zero, configure coefficients \"alpha\"" );
    return false;
  }
  if (m_coeffs.beta.size() != m_coeffs.nb_stages)
  {
    throw SetupError( FromHere(), "mismatch between beta and nb_stages in coefficients" );
    return false;
  }
  if (m_coeffs.gamma.size() != m_coeffs.nb_stages)
  {
    throw SetupError( FromHere(), "mismatch between gamma and nb_stages in coefficients" );
    return false;
  }
  return true;
}
Beispiel #21
0
void Pololu::Serial::Interface::setup() {
  struct termios settings;
  memset(&settings, 0, sizeof(settings));

  settings.c_cflag |= Singleton<BaudRateFlags>::getInstance()[baudRate];
  settings.c_cflag |= Singleton<DataBitsFlags>::getInstance()[dataBits];
  settings.c_cflag |= Singleton<StopBitsFlags>::getInstance()[stopBits];
  settings.c_cflag |= Singleton<ParityFlags>::getInstance()[parity];

  settings.c_cflag |= CLOCAL;
  settings.c_iflag = IGNPAR;

  tcflush(handle, TCIOFLUSH);
  if (tcsetattr(handle, TCSANOW, &settings) < 0)
    throw SetupError(address);
}
Beispiel #22
0
void RDSolver::config_mesh()
{
  if( is_null(m_mesh) ) return;

  Mesh& mesh = *(m_mesh);

  physics::PhysModel& pm = physics(); // physcial model must have already been configured

  if( pm.ndim() != mesh.dimension() )
    throw SetupError( FromHere(), "Dimensionality mismatch. Loaded mesh ndim " + to_str(mesh.dimension()) + " and physical model dimension " + to_str(pm.ndim()) );

  // setup the fields

  prepare_mesh().configure_option_recursively( RDM::Tags::mesh(), m_mesh ); // trigger config_mesh()

  prepare_mesh().execute();

  // configure all other subcomponents with the mesh

  boost_foreach( Component& comp, find_components(*this) )
    comp.configure_option_recursively( RDM::Tags::mesh(), m_mesh );
}
Beispiel #23
0
Field& Dictionary::create_field(const std::string &name, const VarType var_type)
{
  if (var_type == ARRAY)
    throw SetupError(FromHere(), "Should not call this for array types. use create_field(name,cols)");

  Handle<Field> field = create_component<Field>(name);
  field->set_dict(*this);
  field->set_var_type(var_type);

  // @todo remove next lines when ready
  if (var_type == SCALAR)
    field->create_descriptor(name+"[scalar]",m_dim);
  else if (var_type == VECTOR_2D || var_type == VECTOR_3D)
    field->create_descriptor(name+"[vector]",m_dim);
  else if (var_type == TENSOR_2D || var_type == TENSOR_3D)
    field->create_descriptor(name+"[tensor]",m_dim);

  field->set_row_size( (Uint) var_type );
  field->resize(size());

  update_structures();

  return *field;
}
  Implementation(const URI& file, const Uint rank) :
    xml_doc(XML::parse_file(file)),
    m_rank(rank)
  {
    XmlNode cfbinary(xml_doc->content->first_node("cfbinary"));
    cf3_assert(from_str<Uint>(cfbinary.attribute_value("version")) == version());

    XmlNode nodes(cfbinary.content->first_node(("nodes")));
    XmlNode node(nodes.content->first_node("node"));
    for(; node.is_valid(); node = XmlNode(node.content->next_sibling("node")))
    {
      const Uint found_rank = from_str<Uint>(node.attribute_value("rank"));
      if(found_rank != m_rank)
        continue;

      const std::string binary_file_name = node.attribute_value("filename");

      binary_file.open(binary_file_name, std::ios_base::in | std::ios_base::binary);
      my_node = node;
    }

    if(!my_node.is_valid())
      throw SetupError(FromHere(), "No node found for rank " + to_str(m_rank));
  }
void SetupSingleSolution::execute()
{
  RDM::RDSolver& mysolver = *solver().handle< RDM::RDSolver >();

  if(is_null(m_mesh))
    throw SetupError(FromHere(), "SetupSingleSolution has no configured mesh in [" + uri().string() + "]" );

  Mesh& mesh = *m_mesh;

  Group& fields = mysolver.fields();

  const Uint nbdofs = physical_model().neqs();

  // get the geometry field group

  SpaceFields& geometry = mesh.geometry_fields();

  const std::string solution_space = mysolver.options().option("solution_space").value<std::string>();

  // check that the geometry belongs to the same space as selected by the user

  Handle< SpaceFields > solution_group;

  if( solution_space == geometry.space() )
    solution_group = geometry.handle<SpaceFields>();
  else
  {
    // check if solution space already exists
    solution_group = find_component_ptr_with_name<SpaceFields>( mesh, RDM::Tags::solution() );
    if ( is_null(solution_group) )
    {
      solution_group = mesh.create_space_and_field_group( RDM::Tags::solution(), SpaceFields::Basis::POINT_BASED, "cf3.mesh."+solution_space).handle<SpaceFields>();
    }
    else // not null so check that space is what user wants
    {
      if( solution_space != solution_group->space() )
        throw NotImplemented( FromHere(), "Changing solution space not supported" );
    }
  }

  solution_group->add_tag( solution_space );

  // configure solution

  Handle< Field > solution = find_component_ptr_with_tag<Field>( *solution_group, RDM::Tags::solution() );
  if ( is_null( solution ) )
  {
    std::string vars;
    for(Uint i = 0; i < nbdofs; ++i)
    {
     vars += "u" + to_str(i) + "[1]";
     if( i != nbdofs-1 ) vars += ",";
    }

    solution = solution_group->create_field( RDM::Tags::solution(), vars ).handle<Field>();

    solution->add_tag(RDM::Tags::solution());
  }

  /// @todo here we should check if space() order is correct,
  ///       if not the change space() by enriching or other appropriate action

  // configure residual

  Handle< Field > residual = find_component_ptr_with_tag<Field>( *solution_group, RDM::Tags::residual());
  if ( is_null( residual ) )
  {
    residual = solution_group->create_field(Tags::residual(), solution->descriptor().description() ).handle<Field>();
    residual->descriptor().prefix_variable_names("rhs_");
    residual->add_tag(Tags::residual());
  }

  // configure wave_speed

  Handle< Field > wave_speed = find_component_ptr_with_tag<Field>( *solution_group, RDM::Tags::wave_speed());
  if ( is_null( wave_speed ) )
  {
    wave_speed = solution_group->create_field( Tags::wave_speed(), "ws[1]" ).handle<Field>();
    wave_speed->add_tag(Tags::wave_speed());
  }

  // place link to the fields in the Fields group

  if( ! fields.get_child( RDM::Tags::solution() ) )
    fields.create_component<Link>( RDM::Tags::solution()   )->link_to(*solution).add_tag(RDM::Tags::solution());
  if( ! fields.get_child( RDM::Tags::residual() ) )
    fields.create_component<Link>( RDM::Tags::residual()   )->link_to(*residual).add_tag(RDM::Tags::residual());
  if( ! fields.get_child( RDM::Tags::wave_speed() ) )
    fields.create_component<Link>( RDM::Tags::wave_speed() )->link_to(*wave_speed).add_tag(RDM::Tags::wave_speed());


  /// @todo apply here the bubble insertion if needed

  // parallelize the solution if not yet done

  solution->parallelize();

  std::vector<URI> sync_fields;
  sync_fields.push_back( solution->uri() );
  mysolver.actions().get_child("Synchronize")->options().configure_option("Fields", sync_fields);

}
Beispiel #26
0
void ImposeCFL::execute()
{
  if (is_null(m_wave_speed))  throw SetupError(FromHere(), "wave_speed was not configured");
  if (is_null(m_time_step))   throw SetupError(FromHere(), "time_step Field was not set");
  if (is_null(m_time))        throw SetupError(FromHere(), "Time component was not set");

  Field& wave_speed = *m_wave_speed;
  Field& time_step = *m_time_step;

  std::vector<Real> args(3);
  args[0] = m_time->iter();
  args[1] = m_time->current_time();
  args[2] = m_cfl;
  m_cfl = m_cfl_function(args);

  if (options().value<bool>("time_accurate")) // global time stepping
  {
    Time& time = *m_time;

    cf3_assert_desc("Fields not compatible: "+to_str(time_step.size())+"!="+to_str(wave_speed.size()),time_step.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.;
    for (Uint i=0; i<wave_speed.size(); ++i)
    {
      if (wave_speed[i][0] > 0.)
      {
        dt = m_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 final simulation time
    Real tf = time.options().value<Real>("end_time");
    if( time.current_time() + dt*(1+sqrt(eps()))> tf )
      dt = tf - time.current_time();

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

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

// UNCOMMENTING THIS WILL FIX THE UPPER-LIMIT OF THE WAVESPEED FOREVER :(
// DUE TO LINE 88
//    // Fix wave-speed for visualization
//    Real glb_max_dt;
//    PE::Comm::instance().all_reduce(PE::min(), &max_dt, 1, &glb_max_dt);
//    for (Uint i=0; i<wave_speed.size(); ++i)
//    {
//      if (wave_speed[i][0] == 0.)
//      {
//        wave_speed[i][0] = cfl/glb_max_dt;
//      }
//    }
  }
  else // local time stepping
  {
    if (is_not_null(m_time))  m_time->dt() = 0.;

    // Check for a minimum value for the wave speeds
    Real min_wave_speed = math::Consts::real_max();
    for (Uint i=0; i<wave_speed.size(); ++i)
    {
      if (wave_speed[i][0] > 0.)
      {
        min_wave_speed = std::min(min_wave_speed,wave_speed[i][0]);
      }
    }
    PE::Comm::instance().all_reduce(PE::min(), &min_wave_speed, 1, &min_wave_speed);
    if (min_wave_speed == 0.)
      throw common::BadValue(FromHere(), "Minimum wave-speed cannot be zero!");

    // Calculate the time_stepicient = CFL/wave_speed
    for (Uint i=0; i<wave_speed.size(); ++i)
    {
      if (wave_speed[i][0] == 0.)
      {
        wave_speed[i][0] = min_wave_speed;
      }
      time_step[i][0] = m_cfl/wave_speed[i][0];
    }
  }
}
Real VolumeIntegral::integrate(const Field& field, const std::vector< Handle<Entities> >& entities)
{
  Real local_integral = 0.;
  boost_foreach( const Handle<Entities>& patch, entities )
  {
    if( patch->element_type().dimensionality() != patch->element_type().dimension() )
      throw SetupError( FromHere(), "Cannot compute Volume integral of surface element");

    if( is_not_null(m_quadrature) )
      remove_component("quadrature");
    m_quadrature = create_component<Quadrature>("quadrature",
        "cf3.mesh.gausslegendre."+GeoShape::Convert::instance().to_str(patch->element_type().shape())+"P"+common::to_str(m_order));

    /// Common part for every element of this patch
    const Space& space = field.space(*patch);
    const Uint nb_elems = space.size();
    const Uint nb_nodes_per_elem = space.shape_function().nb_nodes();
    const Uint nb_qdr_pts = m_quadrature->nb_nodes();
    const Uint nb_vars = field.row_size();

    RealMatrix qdr_pt_values( nb_qdr_pts, nb_vars );
    RealMatrix interpolate( nb_qdr_pts, nb_nodes_per_elem );
    RealMatrix field_pt_values( nb_nodes_per_elem, nb_vars );
    RealMatrix elem_coords;

    patch->geometry_space().allocate_coordinates(elem_coords);

    for( Uint qn=0; qn<nb_qdr_pts; ++qn)
    {
      interpolate.row(qn) = space.shape_function().value( m_quadrature->local_coordinates().row(qn) );
    }

    /// Loop over every element of this patch
    for (Uint e=0; e<nb_elems; ++e)
    {
      if( ! patch->is_ghost(e) )
      {
        patch->geometry_space().put_coordinates(elem_coords,e);

        // interpolate
        for (Uint n=0; n<nb_nodes_per_elem; ++n)
        {
          const Uint p = space.connectivity()[e][n];
          for (Uint v=0; v<nb_vars; ++v)
          {
            field_pt_values(n,v) = field[p][v];
          }
        }
        qdr_pt_values = interpolate * field_pt_values;

        // integrate
        for( Uint qn=0; qn<nb_qdr_pts; ++qn)
        {
          const Real Jdet = patch->element_type().jacobian_determinant( m_quadrature->local_coordinates().row(qn), elem_coords );
          local_integral += Jdet * m_quadrature->weights()[qn] * qdr_pt_values(qn,0);
        }
      }
    }
  }
  Real global_integral;
  PE::Comm::instance().all_reduce(PE::plus(), &local_integral, 1, &global_integral);
  return global_integral;
}
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];
    }
  }
}