示例#1
0
Real RBEIMConstruction::truth_solve(int plot_solution)
{
  START_LOG("truth_solve()", "RBEIMConstruction");

  int training_parameters_found_index = -1;
  if( _parametrized_functions_in_training_set_initialized )
    {
      // Check if parameters are in the training set. If so, we can just load the
      // solution from _parametrized_functions_in_training_set

      for(unsigned int i=0; i<get_n_training_samples(); i++)
        {
          if(get_parameters() == get_params_from_training_set(i))
            {
              training_parameters_found_index = i;
              break;
            }
        }
    }

  // If the parameters are in the training set, just copy the solution vector
  if(training_parameters_found_index >= 0)
    {
      *solution = *_parametrized_functions_in_training_set[training_parameters_found_index];
      update(); // put the solution into current_local_solution as well
    }
  // Otherwise, we have to compute the projection
  else
    {
      RBEIMEvaluation& eim_eval = cast_ref<RBEIMEvaluation&>(get_rb_evaluation());
      eim_eval.set_parameters( get_parameters() );

      // Compute truth representation via projection
      const MeshBase& mesh = this->get_mesh();

      UniquePtr<DGFEMContext> c = this->build_context();
      DGFEMContext &context  = cast_ref<DGFEMContext&>(*c);

      this->init_context(context);

      rhs->zero();

      MeshBase::const_element_iterator       el     = mesh.active_local_elements_begin();
      const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();

      for ( ; el != end_el; ++el)
        {
          context.pre_fe_reinit(*this, *el);
          context.elem_fe_reinit();

          // All variables should have the same quadrature rule, hence
          // we can get JxW and xyz based on first_elem_fe.
          FEBase* first_elem_fe = NULL;
          context.get_element_fe( 0, first_elem_fe );
          unsigned int n_qpoints = context.get_element_qrule().n_points();
          const std::vector<Real> &JxW = first_elem_fe->get_JxW();
          const std::vector<Point> &xyz = first_elem_fe->get_xyz();

          // Loop over qp before var because parametrized functions often use
          // some caching based on qp.
          for (unsigned int qp=0; qp<n_qpoints; qp++)
            {
              for (unsigned int var=0; var<n_vars(); var++)
                {
                  FEBase* elem_fe = NULL;
                  context.get_element_fe( var, elem_fe );
                  const std::vector<std::vector<Real> >& phi = elem_fe->get_phi();

                  DenseSubVector<Number>& subresidual_var = context.get_elem_residual( var );

                  unsigned int n_var_dofs = cast_int<unsigned int>(context.get_dof_indices( var ).size());

                  Number eval_result = eim_eval.evaluate_parametrized_function(var, xyz[qp], *(*el));
                  for (unsigned int i=0; i != n_var_dofs; i++)
                    subresidual_var(i) += JxW[qp] * eval_result * phi[i][qp];
                }
            }

          // Apply constraints, e.g. periodic constraints
          this->get_dof_map().constrain_element_vector(context.get_elem_residual(), context.get_dof_indices() );

          // Add element vector to global vector
          rhs->add_vector(context.get_elem_residual(), context.get_dof_indices() );
        }

      // Solve to find the best fit, then solution stores the truth representation
      // of the function to be approximated
      solve_for_matrix_and_rhs(*inner_product_solver, *inner_product_matrix, *rhs);

      if (assert_convergence)
        check_convergence(*inner_product_solver);
    }

  if(plot_solution > 0)
    {
#ifdef LIBMESH_HAVE_EXODUS_API
      ExodusII_IO(get_mesh()).write_equation_systems ("truth.exo",
                                                      this->get_equation_systems());
#endif
    }

  STOP_LOG("truth_solve()", "RBEIMConstruction");

  return 0.;
}
示例#2
0
Real RBEIMConstruction::truth_solve(int plot_solution)
{
  START_LOG("truth_solve()", "RBEIMConstruction");

//  matrix should have been set to inner_product_matrix during initialization
//  if(!single_matrix_mode)
//  {
//    matrix->zero();
//    matrix->add(1., *inner_product_matrix);
//  }
//  else
//  {
//    assemble_inner_product_matrix(matrix);
//  }

  int training_parameters_found_index = -1;
  if( _parametrized_functions_in_training_set_initialized )
  {
    // Check if parameters are in the training set. If so, we can just load the
    // solution from _parametrized_functions_in_training_set

    for(unsigned int i=0; i<get_n_training_samples(); i++)
    {
      if(get_parameters() == get_params_from_training_set(i))
      {
        training_parameters_found_index = i;
        break;
      }
    }
  }

  // If the parameters are in the training set, just copy the solution vector
  if(training_parameters_found_index >= 0)
  {
    *solution = *_parametrized_functions_in_training_set[training_parameters_found_index];
    update(); // put the solution into current_local_solution as well
  }
  // Otherwise, we have to compute the projection
  else
  {
    RBEIMEvaluation& eim_eval = libmesh_cast_ref<RBEIMEvaluation&>(get_rb_evaluation());
    eim_eval.set_parameters( get_parameters() );

    // Compute truth representation via projection
    const MeshBase& mesh = this->get_mesh();

    AutoPtr<FEMContext> c = this->build_context();
    FEMContext &context  = libmesh_cast_ref<FEMContext&>(*c);

    this->init_context(context);

    rhs->zero();

    MeshBase::const_element_iterator       el     = mesh.active_local_elements_begin();
    const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();

    for ( ; el != end_el; ++el)
    {
      context.pre_fe_reinit(*this, *el);
      context.elem_fe_reinit();

      for(unsigned int var=0; var<n_vars(); var++)
      {
        const std::vector<Real> &JxW =
          context.element_fe_var[var]->get_JxW();

        const std::vector<std::vector<Real> >& phi =
          context.element_fe_var[var]->get_phi();

        const std::vector<Point> &xyz =
          context.element_fe_var[var]->get_xyz();

        unsigned int n_qpoints = context.element_qrule->n_points();
        unsigned int n_var_dofs = libmesh_cast_int<unsigned int>
	  (context.dof_indices_var[var].size());

        DenseSubVector<Number>& subresidual_var = *context.elem_subresiduals[var];

        for(unsigned int qp=0; qp<n_qpoints; qp++)
          for(unsigned int i=0; i != n_var_dofs; i++)
            subresidual_var(i) += JxW[qp] * eim_eval.evaluate_parametrized_function(var, xyz[qp]) * phi[i][qp];
      }

      // Apply constraints, e.g. periodic constraints
      this->get_dof_map().constrain_element_vector(context.get_elem_residual(), context.dof_indices);

      // Add element vector to global vector
      rhs->add_vector(context.get_elem_residual(), context.dof_indices);
    }

    // Solve to find the best fit, then solution stores the truth representation
    // of the function to be approximated
    solve();

    // Make sure we didn't max out the number of iterations
    if( (this->n_linear_iterations() >=
         this->get_equation_systems().parameters.get<unsigned int>("linear solver maximum iterations")) &&
        (this->final_linear_residual() >
         this->get_equation_systems().parameters.get<Real>("linear solver tolerance")) )
    {
        libMesh::out << "Warning: Linear solver may not have converged! Final linear residual = "
                     << this->final_linear_residual() << ", number of iterations = "
                     << this->n_linear_iterations() << std::endl << std::endl;
  //     libmesh_error();
    }

    if(reuse_preconditioner)
    {
      // After we've done a solve we can now reuse the preconditioner
      // because the matrix is not changing
      linear_solver->reuse_preconditioner(true);
    }
  }

  if(plot_solution > 0)
  {
#ifdef LIBMESH_HAVE_EXODUS_API
    ExodusII_IO(get_mesh()).write_equation_systems ("truth.e",
                                                    this->get_equation_systems());
#endif
  }

  STOP_LOG("truth_solve()", "RBEIMConstruction");

  return 0.;
}
void RBConstructionBase<Base>::set_params_from_training_set(unsigned int index)
{
  set_parameters(get_params_from_training_set(index));
}