Пример #1
0
void RBEIMEvaluation::initialize_eim_theta_objects()
{
  // Initialize the rb_theta objects that access the solution from this rb_eim_evaluation
  _rb_eim_theta_objects.clear();
  for(unsigned int i=0; i<get_n_basis_functions(); i++)
    {
      _rb_eim_theta_objects.push_back( build_eim_theta(i).release() );
    }
}
Пример #2
0
void RBEIMEvaluation::rb_solve(DenseVector<Number> & EIM_rhs)
{
  LOG_SCOPE("rb_solve()", "RBEIMEvaluation");

  if(EIM_rhs.size() > get_n_basis_functions())
    libmesh_error_msg("ERROR: N cannot be larger than the number of basis functions in rb_solve");

  if(EIM_rhs.size()==0)
    libmesh_error_msg("ERROR: N must be greater than 0 in rb_solve");

  const unsigned int N = EIM_rhs.size();
  DenseMatrix<Number> interpolation_matrix_N;
  interpolation_matrix.get_principal_submatrix(N, interpolation_matrix_N);

  interpolation_matrix_N.lu_solve(EIM_rhs, RB_solution);
}
Пример #3
0
void RBEIMEvaluation::rb_solve(DenseVector<Number>& EIM_rhs)
{
  START_LOG("rb_solve()", "RBEIMEvaluation");

  if(EIM_rhs.size() > get_n_basis_functions())
  {
    libMesh::err << "ERROR: N cannot be larger than the number "
                 << "of basis functions in rb_solve" << std::endl;
    libmesh_error();
  }
  if(EIM_rhs.size()==0)
  {
    libMesh::err << "ERROR: N must be greater than 0 in rb_solve" << std::endl;
    libmesh_error();
  }

  const unsigned int N = EIM_rhs.size();
  DenseMatrix<Number> interpolation_matrix_N;
  interpolation_matrix.get_principal_submatrix(N, interpolation_matrix_N);

  interpolation_matrix_N.lu_solve(EIM_rhs, RB_solution);

  STOP_LOG("rb_solve()", "RBEIMEvaluation");
}
Пример #4
0
void RBEIMEvaluation::legacy_write_offline_data_to_files(const std::string & directory_name,
                                                         const bool read_binary_data)
{
  LOG_SCOPE("legacy_write_offline_data_to_files()", "RBEIMEvaluation");

  Parent::legacy_write_offline_data_to_files(directory_name);

  // Get the number of basis functions
  unsigned int n_bfs = get_n_basis_functions();

  // The writing mode: ENCODE for binary, WRITE for ASCII
  XdrMODE mode = read_binary_data ? ENCODE : WRITE;

  // The suffix to use for all the files that are written out
  const std::string suffix = read_binary_data ? ".xdr" : ".dat";

  if(this->processor_id() == 0)
    {
      std::ostringstream file_name;

      // Next write out the interpolation_matrix
      file_name.str("");
      file_name << directory_name << "/interpolation_matrix" << suffix;
      Xdr interpolation_matrix_out(file_name.str(), mode);

      for(unsigned int i=0; i<n_bfs; i++)
        {
          for(unsigned int j=0; j<=i; j++)
            {
              interpolation_matrix_out << interpolation_matrix(i,j);
            }
        }

      // Next write out interpolation_points
      file_name.str("");
      file_name << directory_name << "/interpolation_points" << suffix;
      Xdr interpolation_points_out(file_name.str(), mode);

      for(unsigned int i=0; i<n_bfs; i++)
        {
          interpolation_points_out << interpolation_points[i](0);

          if(LIBMESH_DIM >= 2)
            interpolation_points_out << interpolation_points[i](1);

          if(LIBMESH_DIM >= 3)
            interpolation_points_out << interpolation_points[i](2);
        }
      interpolation_points_out.close();

      // Next write out interpolation_points_var
      file_name.str("");
      file_name << directory_name << "/interpolation_points_var" << suffix;
      Xdr interpolation_points_var_out(file_name.str(), mode);

      for(unsigned int i=0; i<n_bfs; i++)
        {
          interpolation_points_var_out << interpolation_points_var[i];
        }
      interpolation_points_var_out.close();
    }

  // Write out the elements associated with the interpolation points.
  // This uses mesh I/O, hence we have to do it on all processors.
  legacy_write_out_interpolation_points_elem(directory_name);
}
Пример #5
0
Real RBEIMEvaluation::rb_solve(unsigned int N)
{
  // Short-circuit if we are using the same parameters and value of N
  if( (_previous_parameters == get_parameters()) &&
      (_previous_N == N) )
    {
      return _previous_error_bound;
    }

  // Otherwise, update _previous parameters, _previous_N
  _previous_parameters = get_parameters();
  _previous_N = N;

  LOG_SCOPE("rb_solve()", "RBEIMEvaluation");

  if(N > get_n_basis_functions())
    libmesh_error_msg("ERROR: N cannot be larger than the number of basis functions in rb_solve");

  if(N==0)
    libmesh_error_msg("ERROR: N must be greater than 0 in rb_solve");

  // Get the rhs by sampling parametrized_function
  // at the first N interpolation_points
  DenseVector<Number> EIM_rhs(N);
  for(unsigned int i=0; i<N; i++)
    {
      EIM_rhs(i) = evaluate_parametrized_function(interpolation_points_var[i],
                                                  interpolation_points[i],
                                                  *interpolation_points_elem[i]);
    }



  DenseMatrix<Number> interpolation_matrix_N;
  interpolation_matrix.get_principal_submatrix(N, interpolation_matrix_N);

  interpolation_matrix_N.lu_solve(EIM_rhs, RB_solution);

  // Optionally evaluate an a posteriori error bound. The EIM error estimate
  // recommended in the literature is based on using "next" EIM point, so
  // we skip this if N == get_n_basis_functions()
  if(evaluate_RB_error_bound && (N != get_n_basis_functions()))
    {
      // Compute the a posteriori error bound
      // First, sample the parametrized function at x_{N+1}
      Number g_at_next_x = evaluate_parametrized_function(interpolation_points_var[N],
                                                          interpolation_points[N],
                                                          *interpolation_points_elem[N]);

      // Next, evaluate the EIM approximation at x_{N+1}
      Number EIM_approx_at_next_x = 0.;
      for(unsigned int j=0; j<N; j++)
        {
          EIM_approx_at_next_x += RB_solution(j) * interpolation_matrix(N,j);
        }

      Real error_estimate = std::abs(g_at_next_x - EIM_approx_at_next_x);

      _previous_error_bound = error_estimate;
      return error_estimate;
    }
  else // Don't evaluate an error bound
    {
      _previous_error_bound = -1.;
      return -1.;
    }

}
Пример #6
0
void RBEvaluation::write_offline_data_to_files(const std::string& directory_name,
                                               const bool write_binary_data)
{
  START_LOG("write_offline_data_to_files()", "RBEvaluation");

  // Get the number of basis functions
  unsigned int n_bfs = get_n_basis_functions();

  // The writing mode: ENCODE for binary, WRITE for ASCII
  XdrMODE mode = write_binary_data ? ENCODE : WRITE;

  // The suffix to use for all the files that are written out
  const std::string suffix = write_binary_data ? ".xdr" : ".dat";

  if(this->processor_id() == 0)
    {

      // Make a directory to store all the data files
      mkdir(directory_name.c_str(), 0777);
      //    if( mkdir(directory_name.c_str(), 0777) == -1)
      //    {
      //      libMesh::out << "In RBEvaluation::write_offline_data_to_files, directory "
      //                   << directory_name << " already exists, overwriting contents." << std::endl;
      //    }

      // First, write out how many basis functions we have generated
      std::ostringstream file_name;
      {
        file_name << directory_name << "/n_bfs" << suffix;
        Xdr n_bfs_out(file_name.str(), mode);
        n_bfs_out << n_bfs;
        n_bfs_out.close();
      }

      // Write out the parameter ranges
      file_name.str("");
      file_name << directory_name << "/parameter_ranges" << suffix;
      std::string continuous_param_file_name = file_name.str();

      // Write out the discrete parameter values
      file_name.str("");
      file_name << directory_name << "/discrete_parameter_values" << suffix;
      std::string discrete_param_file_name = file_name.str();
    
      write_parameter_data_to_files(continuous_param_file_name,
                                    discrete_param_file_name,
                                    write_binary_data);

      // Write out Fq representor norm data
      file_name.str("");
      file_name << directory_name << "/Fq_innerprods" << suffix;
      Xdr RB_Fq_innerprods_out(file_name.str(), mode);
      unsigned int Q_f_hat = rb_theta_expansion->get_n_F_terms()*(rb_theta_expansion->get_n_F_terms()+1)/2;
      for(unsigned int i=0; i<Q_f_hat; i++)
        {
          RB_Fq_innerprods_out << Fq_representor_innerprods[i];
        }
      RB_Fq_innerprods_out.close();

      // Write out output data
      for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
        {
          file_name.str("");
          file_name << directory_name << "/output_";
          file_name << std::setw(3)
                    << std::setprecision(0)
                    << std::setfill('0')
                    << std::right
                    << n;

          file_name << "_dual_innerprods" << suffix;
          Xdr output_dual_innerprods_out(file_name.str(), mode);

          unsigned int Q_l_hat = rb_theta_expansion->get_n_output_terms(n)*(rb_theta_expansion->get_n_output_terms(n)+1)/2;
          for(unsigned int q=0; q<Q_l_hat; q++)
            {
              output_dual_innerprods_out << output_dual_innerprods[n][q];
            }
          output_dual_innerprods_out.close();
        }


      // Write out output data to multiple files
      for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
        {
          for(unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
            {
              file_name.str("");
              file_name << directory_name << "/output_";
              file_name << std::setw(3)
                        << std::setprecision(0)
                        << std::setfill('0')
                        << std::right
                        << n;
              file_name << "_";
              file_name << std::setw(3)
                        << std::setprecision(0)
                        << std::setfill('0')
                        << std::right
                        << q_l;
              file_name << suffix;
              Xdr output_n_out(file_name.str(), mode);

              for(unsigned int j=0; j<n_bfs; j++)
                {
                  output_n_out << RB_output_vectors[n][q_l](j);
                }
              output_n_out.close();
            }
        }

      if(compute_RB_inner_product)
        {
          // Next write out the inner product matrix
          file_name.str("");
          file_name << directory_name << "/RB_inner_product_matrix" << suffix;
          Xdr RB_inner_product_matrix_out(file_name.str(), mode);
          for(unsigned int i=0; i<n_bfs; i++)
            {
              for(unsigned int j=0; j<n_bfs; j++)
                {
                  RB_inner_product_matrix_out << RB_inner_product_matrix(i,j);
                }
            }
          RB_inner_product_matrix_out.close();
        }

      // Next write out the Fq vectors
      for(unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
        {
          file_name.str("");
          file_name << directory_name << "/RB_F_";
          file_name << std::setw(3)
                    << std::setprecision(0)
                    << std::setfill('0')
                    << std::right
                    << q_f;
          file_name << suffix;
          Xdr RB_Fq_f_out(file_name.str(), mode);

          for(unsigned int i=0; i<n_bfs; i++)
            {
              RB_Fq_f_out << RB_Fq_vector[q_f](i);
            }
          RB_Fq_f_out.close();
        }

      // Next write out the Aq matrices
      for(unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
        {
          file_name.str("");
          file_name << directory_name << "/RB_A_";
          file_name << std::setw(3)
                    << std::setprecision(0)
                    << std::setfill('0')
                    << std::right
                    << q_a;
          file_name << suffix;
          Xdr RB_Aq_a_out(file_name.str(), mode);

          for(unsigned int i=0; i<n_bfs; i++)
            {
              for(unsigned int j=0; j<n_bfs; j++)
                {
                  RB_Aq_a_out << RB_Aq_vector[q_a](i,j);
                }
            }
          RB_Aq_a_out.close();
        }

      // Next write out Fq_Aq representor norm data
      file_name.str("");
      file_name << directory_name << "/Fq_Aq_innerprods" << suffix;
      Xdr RB_Fq_Aq_innerprods_out(file_name.str(), mode);

      for(unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
        {
          for(unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
            {
              for(unsigned int i=0; i<n_bfs; i++)
                {
                  RB_Fq_Aq_innerprods_out << Fq_Aq_representor_innerprods[q_f][q_a][i];
                }
            }
        }
      RB_Fq_Aq_innerprods_out.close();

      // Next write out Aq_Aq representor norm data
      file_name.str("");
      file_name << directory_name << "/Aq_Aq_innerprods" << suffix;
      Xdr RB_Aq_Aq_innerprods_out(file_name.str(), mode);

      unsigned int Q_a_hat = rb_theta_expansion->get_n_A_terms()*(rb_theta_expansion->get_n_A_terms()+1)/2;
      for(unsigned int i=0; i<Q_a_hat; i++)
        {
          for(unsigned int j=0; j<n_bfs; j++)
            {
              for(unsigned int l=0; l<n_bfs; l++)
                {
                  RB_Aq_Aq_innerprods_out << Aq_Aq_representor_innerprods[i][j][l];
                }
            }
        }
      RB_Aq_Aq_innerprods_out.close();

      // Also, write out the greedily selected parameters
      {
        file_name.str("");
        file_name << directory_name << "/greedy_params" << suffix;
        Xdr greedy_params_out(file_name.str(), mode);

        for(unsigned int i=0; i<greedy_param_list.size(); i++)
          {
            RBParameters::const_iterator it     = greedy_param_list[i].begin();
            RBParameters::const_iterator it_end = greedy_param_list[i].end();
            for( ; it != it_end; ++it)
              {
                // Need to make a copy of the value so that it's not const
                // Xdr is not templated on const's
                Real param_value = it->second;
                greedy_params_out << param_value;
              }
          }
        greedy_params_out.close();
      }

    }

  STOP_LOG("write_offline_data_to_files()", "RBEvaluation");
}
Пример #7
0
Real RBEvaluation::rb_solve(unsigned int N)
{
  START_LOG("rb_solve()", "RBEvaluation");

  if(N > get_n_basis_functions())
    libmesh_error_msg("ERROR: N cannot be larger than the number of basis functions in rb_solve");

  const RBParameters& mu = get_parameters();

  // Resize (and clear) the solution vector
  RB_solution.resize(N);

  // Assemble the RB system
  DenseMatrix<Number> RB_system_matrix(N,N);
  RB_system_matrix.zero();

  DenseMatrix<Number> RB_Aq_a;
  for(unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
    {
      RB_Aq_vector[q_a].get_principal_submatrix(N, RB_Aq_a);

      RB_system_matrix.add(rb_theta_expansion->eval_A_theta(q_a, mu), RB_Aq_a);
    }

  // Assemble the RB rhs
  DenseVector<Number> RB_rhs(N);
  RB_rhs.zero();

  DenseVector<Number> RB_Fq_f;
  for(unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
    {
      RB_Fq_vector[q_f].get_principal_subvector(N, RB_Fq_f);

      RB_rhs.add(rb_theta_expansion->eval_F_theta(q_f, mu), RB_Fq_f);
    }

  // Solve the linear system
  if(N > 0)
    {
      RB_system_matrix.lu_solve(RB_rhs, RB_solution);
    }

  // Evaluate RB outputs
  DenseVector<Number> RB_output_vector_N;
  for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
    {
      RB_outputs[n] = 0.;
      for(unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
        {
          RB_output_vectors[n][q_l].get_principal_subvector(N, RB_output_vector_N);
          RB_outputs[n] += rb_theta_expansion->eval_output_theta(n,q_l,mu)*RB_output_vector_N.dot(RB_solution);
        }
    }

  if(evaluate_RB_error_bound) // Calculate the error bounds
    {
      // Evaluate the dual norm of the residual for RB_solution_vector
      Real epsilon_N = compute_residual_dual_norm(N);

      // Get lower bound for coercivity constant
      const Real alpha_LB = get_stability_lower_bound();
      // alpha_LB needs to be positive to get a valid error bound
      libmesh_assert_greater ( alpha_LB, 0. );

      // Evaluate the (absolute) error bound
      Real abs_error_bound = epsilon_N / residual_scaling_denom(alpha_LB);

      // Now compute the output error bounds
      for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
        {
          RB_output_error_bounds[n] = abs_error_bound * eval_output_dual_norm(n, mu);
        }

      STOP_LOG("rb_solve()", "RBEvaluation");

      return abs_error_bound;
    }
  else // Don't calculate the error bounds
    {
      STOP_LOG("rb_solve()", "RBEvaluation");
      // Just return -1. if we did not compute the error bound
      return -1.;
    }
}
Пример #8
0
void RBEIMEvaluation::write_offline_data_to_files(const std::string& directory_name,
                                                  const bool read_binary_data)
{
  START_LOG("write_offline_data_to_files()", "RBEIMEvaluation");

  Parent::write_offline_data_to_files(directory_name);

  // Get the number of basis functions
  unsigned int n_bfs = get_n_basis_functions();

  // The writing mode: ENCODE for binary, WRITE for ASCII
  XdrMODE mode = read_binary_data ? ENCODE : WRITE;

  // The suffix to use for all the files that are written out
  const std::string suffix = read_binary_data ? ".xdr" : ".dat";

  if(libMesh::processor_id() == 0)
  {
    OStringStream file_name;
    
    // Next write out the interpolation_matrix
    file_name.str("");
    file_name << directory_name << "/interpolation_matrix" << suffix;
    Xdr interpolation_matrix_out(file_name.str(), mode);
    
    for(unsigned int i=0; i<n_bfs; i++)
    {
      for(unsigned int j=0; j<=i; j++)
      {
        interpolation_matrix_out << interpolation_matrix(i,j);
      }
    }

    // Also, write out the "extra" row
    file_name.str("");
    file_name << directory_name << "/extra_interpolation_matrix_row" << suffix;
    Xdr extra_interpolation_matrix_row_out(file_name.str(), mode);
    
    for(unsigned int j=0; j<n_bfs; j++)
    {
      extra_interpolation_matrix_row_out << extra_interpolation_matrix_row(j);
    }
    extra_interpolation_matrix_row_out.close();

    // Next write out interpolation_points
    file_name.str("");
    file_name << directory_name << "/interpolation_points" << suffix;
    Xdr interpolation_points_out(file_name.str(), mode);
    
    for(unsigned int i=0; i<n_bfs; i++)
    {
      interpolation_points_out << interpolation_points[i](0);

      if(LIBMESH_DIM >= 2)
        interpolation_points_out << interpolation_points[i](1);

      if(LIBMESH_DIM >= 3)
        interpolation_points_out << interpolation_points[i](2);
    }
    interpolation_points_out.close();

    // Also, write out the "extra" interpolation point
    file_name.str("");
    file_name << directory_name << "/extra_interpolation_point" << suffix;
    Xdr extra_interpolation_point_out(file_name.str(), mode);
    
    extra_interpolation_point_out << extra_interpolation_point(0);

    if(LIBMESH_DIM >= 2)
      extra_interpolation_point_out << extra_interpolation_point(1);

    if(LIBMESH_DIM >= 3)
      extra_interpolation_point_out << extra_interpolation_point(2);

    extra_interpolation_point_out.close();

    // Next write out interpolation_points_var
    file_name.str("");
    file_name << directory_name << "/interpolation_points_var" << suffix;
    Xdr interpolation_points_var_out(file_name.str(), mode);

    for(unsigned int i=0; i<n_bfs; i++)
    {
      interpolation_points_var_out << interpolation_points_var[i];
    }
    interpolation_points_var_out.close();

    // Also, write out the "extra" interpolation variable
    file_name.str("");
    file_name << directory_name << "/extra_interpolation_point_var" << suffix;
    Xdr extra_interpolation_point_var_out(file_name.str(), mode);
    
    extra_interpolation_point_var_out << extra_interpolation_point_var;
    extra_interpolation_point_var_out.close();
  }

  STOP_LOG("write_offline_data_to_files()", "RBEIMEvaluation");
}
Пример #9
0
Real RBEIMEvaluation::rb_solve(unsigned int N)
{
  // Short-circuit if we are using the same parameters and value of N
  if( (_previous_parameters == get_parameters()) && 
      (_previous_N == N) )
  {
    return _previous_error_bound;
  }
  
  // Otherwise, update _previous parameters, _previous_N
  _previous_parameters = get_parameters();
  _previous_N = N;
  
  START_LOG("rb_solve()", "RBEIMEvaluation");

  if(N > get_n_basis_functions())
  {
    libMesh::err << "ERROR: N cannot be larger than the number "
                 << "of basis functions in rb_solve" << std::endl;
    libmesh_error();
  }
  if(N==0)
  {
    libMesh::err << "ERROR: N must be greater than 0 in rb_solve" << std::endl;
    libmesh_error();
  }

  // Get the rhs by sampling parametrized_function
  // at the first N interpolation_points
  DenseVector<Number> EIM_rhs(N);
  for(unsigned int i=0; i<N; i++)
  {
    EIM_rhs(i) = evaluate_parametrized_function(interpolation_points_var[i], interpolation_points[i]);
  }



  DenseMatrix<Number> interpolation_matrix_N;
  interpolation_matrix.get_principal_submatrix(N, interpolation_matrix_N);

  interpolation_matrix_N.lu_solve(EIM_rhs, RB_solution);

  // Evaluate an a posteriori error bound
  if(evaluate_RB_error_bound)
  {
    // Compute the a posteriori error bound
    // First, sample the parametrized function at x_{N+1}
    Number g_at_next_x;
    if(N == get_n_basis_functions())
      g_at_next_x = evaluate_parametrized_function(extra_interpolation_point_var, extra_interpolation_point);
    else
      g_at_next_x = evaluate_parametrized_function(interpolation_points_var[N], interpolation_points[N]);

    // Next, evaluate the EIM approximation at x_{N+1}
    Number EIM_approx_at_next_x = 0.;
    for(unsigned int j=0; j<N; j++)
    {
      if(N == get_n_basis_functions())
      {
        EIM_approx_at_next_x += RB_solution(j) * extra_interpolation_matrix_row(j);
      }
      else
      {
        EIM_approx_at_next_x += RB_solution(j) * interpolation_matrix(N,j);
      }
    }

    Real error_estimate = std::abs(g_at_next_x - EIM_approx_at_next_x);

    STOP_LOG("rb_solve()", "RBEIMEvaluation");

    _previous_error_bound = error_estimate;
    return error_estimate;
  }
  else // Don't evaluate an error bound
  {
    STOP_LOG("rb_solve()", "RBEIMEvaluation");
    _previous_error_bound = -1.;
    return -1.;
  }

}