Ejemplo n.º 1
0
std::pair<unsigned int, Real>
ImplicitSystem::sensitivity_solve (const ParameterVector & parameters)
{
  // Log how long the linear solve takes.
  LOG_SCOPE("sensitivity_solve()", "ImplicitSystem");

  // The forward system should now already be solved.
  // Now assemble the corresponding sensitivity system.

  if (this->assemble_before_solve)
    {
      // Build the Jacobian
      this->assembly(false, true);
      this->matrix->close();

      // Reset and build the RHS from the residual derivatives
      this->assemble_residual_derivatives(parameters);
    }

  // The sensitivity problem is linear
  LinearSolver<Number> * linear_solver = this->get_linear_solver();

  // Our iteration counts and residuals will be sums of the individual
  // results
  std::pair<unsigned int, Real> solver_params =
    this->get_linear_solve_parameters();
  std::pair<unsigned int, Real> totalrval = std::make_pair(0,0.0);

  // Solve the linear system.
  SparseMatrix<Number> * pc = this->request_matrix("Preconditioner");
  for (auto p : IntRange<unsigned int>(0, parameters.size()))
    {
      std::pair<unsigned int, Real> rval =
        linear_solver->solve (*matrix, pc,
                              this->add_sensitivity_solution(p),
                              this->get_sensitivity_rhs(p),
                              solver_params.second,
                              solver_params.first);

      totalrval.first  += rval.first;
      totalrval.second += rval.second;
    }

  // The linear solver may not have fit our constraints exactly
#ifdef LIBMESH_ENABLE_CONSTRAINTS
  for (auto p : IntRange<unsigned int>(0, parameters.size()))
    this->get_dof_map().enforce_constraints_exactly
      (*this, &this->get_sensitivity_solution(p),
       /* homogeneous = */ true);
#endif

  this->release_linear_solver(linear_solver);

  return totalrval;
}
Ejemplo n.º 2
0
// Processes completion for a module command's parameter
static char* handle_complete(const char *line, const char *word,
                             int pos, int state,
                             const char* msgid)
{
    char *ret = NULL;

    try
    {
        BOOST_ASSERT(line);
        const std::string strline(line);
        BOOST_ASSERT(word);
        const std::string strword(word);

        ModuleProcessor *processor = Factory::instance()->getModuleProcessor();
        ParameterVector completions =
            processor->getCompletion(strline, strword, pos, msgid);
        if (completions.empty())
        {
            // no completions
            return NULL;
        }

        size_t wordlen = strlen(word);
        int which = 0;

        for (ParameterVector::iterator i = completions.begin();
             i != completions.end(); i++)
        {
            if (!strncasecmp(word, i->c_str(), wordlen) &&
                ++which > state)
            {
                std::string found = *i;
                // is there any spaces
                if (found.find(' ') != std::string::npos)
                {
                    found = "\"" + found + "\"";
                }
                ret = strdup(found.c_str());
                break;
            }
        }
    }
    catch(const std::exception& err)
    {
        klk_log(KLKLOG_ERROR, "Error in handle_complete(): %s",
                err.what());
    }
    catch(...)
    {
        klk_log(KLKLOG_ERROR, "Unknown error in handle_complete()");
    }

    return ret;
}
Ejemplo n.º 3
0
// Perturb and accumulate dual weighted residuals
void HeatSystem::perturb_accumulate_residuals(ParameterVector& parameters_in)
{
  const unsigned int Np = parameters_in.size();

  for (unsigned int j=0; j != Np; ++j)
    {
      Number old_parameter = *parameters_in[j];

      *parameters_in[j] = old_parameter - dp;

      this->assembly(true, false);

      this->rhs->close();

      UniquePtr<NumericVector<Number> > R_minus = this->rhs->clone();

      // The contribution at a single time step would be [f(z;p+dp) - <partialu/partialt, z>(p+dp) - <g(u),z>(p+dp)] * dt
      // But since we compute the residual already scaled by dt, there is no need for the * dt
      R_minus_dp += -R_minus->dot(this->get_adjoint_solution(0));

      *parameters_in[j] = old_parameter + dp;

      this->assembly(true, false);

      this->rhs->close();

      UniquePtr<NumericVector<Number> > R_plus = this->rhs->clone();

      R_plus_dp += -R_plus->dot(this->get_adjoint_solution(0));

      *parameters_in[j] = old_parameter;

    }
}
Ejemplo n.º 4
0
void ParameterVector::deep_copy(ParameterVector &target) const
{
  const unsigned int Np = cast_int<unsigned int>
    (this->_params.size());
  target.clear();
  target._params.resize(Np);
  target._my_data.resize(Np);
  for (unsigned int i=0; i != Np; ++i)
    {
      target._params[i] =
        new ParameterPointer<Number>(&target._my_data[i]);
      target._my_data[i] = *(*this)[i];
    }
}
Ejemplo n.º 5
0
 /// Perform pending updates and divide all parameters by d
 void average_parameters(ParameterVector& summed_model_params,
                         const ParameterVector& model_params,
                         const ParameterVector& last_model_params,
                         const std::vector<unsigned>& last_param_update, 
                         unsigned d) const
 {
   for (unsigned p = 0; p < summed_model_params.size(); ++p) {
     if (d != last_param_update[p]) {
       unsigned n = d - last_param_update[p]-1;
       summed_model_params[p] += (n * last_model_params[p]);
     }
     summed_model_params[p] /= d;
   }
 }
Ejemplo n.º 6
0
// *****************************************************************
// *****************************************************************
void LOCA::Epetra::ModelEvaluatorInterface::
setParameters(const ParameterVector& p)
{
  for (int i=0; i<p.length(); i++)
    param_vec[i] = p[i];
}
void Algorithm::SetParameterCollection(const ParameterVector& parameters){
	_parameterCollection.assign(parameters.begin(), parameters.end());
}
Ejemplo n.º 8
0
std::pair<unsigned int, Real>
EigenSystem::sensitivity_solve (const ParameterVector& parameters)
  {
    // make sure that eigensolution is already available
    libmesh_assert(_n_converged_eigenpairs);
    
    // the sensitivity is calculated based on the inner product of the left and
    // right eigen vectors.
    //
    //    y^T [A] x - lambda y^T [B] x = 0
    //    where y and x are the left and right eigenvectors
    //    d lambda/dp = (y^T (d[A]/dp - lambda d[B]/dp) x) / (y^T [B] x)
    //
    //    the denominator remain constant for all sensitivity calculations.
    //
    std::vector<Number> denom(_n_converged_eigenpairs, 0.),
    sens(_n_converged_eigenpairs, 0.);
    std::pair<Real, Real> eig_val;
    
    AutoPtr< NumericVector<Number> > x_right = NumericVector<Number>::build(this->comm()),
    x_left = NumericVector<Number>::build(this->comm()),
    tmp = NumericVector<Number>::build(this->comm());
    x_right->init(*solution); x_left->init(*solution); tmp->init(*solution);
    
    for (unsigned int i=0; i<_n_converged_eigenpairs; i++)
    {
      switch (_eigen_problem_type) {
        case HEP:
          // right and left eigenvectors are same
          // imaginary part of eigenvector for real matrices is zero
          this->eigen_solver->get_eigenpair(i, *x_right, NULL);
          denom[i] = x_right->dot(*x_right);               // x^H x
          break;
          
        case GHEP:
          // imaginary part of eigenvector for real matrices is zero
          this->eigen_solver->get_eigenpair(i, *x_right, NULL);
          matrix_B->vector_mult(*tmp, *x_right);
          denom[i] = x_right->dot(*tmp);                  // x^H B x
          
        default:
          // to be implemented for the non-Hermitian problems
          libmesh_error();
          break;
      }
    }
    
    for (unsigned int p=0; p<parameters.size(); p++)
    {
      // calculate sensitivity of matrix quantities
      this->assemble_eigensystem_sensitivity(parameters, p);
      
      // now calculate sensitivity of each eigenvalue for the parameter
      for (unsigned int i=0; i<_n_converged_eigenpairs; i++)
      {
        eig_val = this->eigen_solver->get_eigenpair(i, *x_right);
        switch (_eigen_problem_type)
        {
          case HEP:
            matrix_A->vector_mult(*tmp, *x_right);
            sens[i] = x_right->dot(*tmp);            // x^H A' x
            sens[i] /= denom[i];                     // x^H x
            break;

          case GHEP:
            matrix_A->vector_mult(*tmp, *x_right);
            sens[i] = x_right->dot(*tmp);                 // x^H A' x
            matrix_B->vector_mult(*tmp, *x_right);
            sens[i]-= eig_val.first * x_right->dot(*tmp); // - lambda x^H B' x
            sens[i] /= denom[i];                          // x^H B x
            break;
            
          default:
            // to be implemented for the non-Hermitian problems
            libmesh_error();
            break;
        }
      }
    }
    
    return std::pair<unsigned int, Real> (0, 0.);
  }
Ejemplo n.º 9
0
 void add_parameters(ParameterVector& summed_model_params, const ParameterVector& model_params)
 {
   for (unsigned p = 0; p < summed_model_params.size(); ++p) {
     summed_model_params[p] += model_params[p];
   }
 }
Ejemplo n.º 10
0
void ImplicitSystem::qoi_parameter_hessian_vector_product (const QoISet & qoi_indices,
                                                           const ParameterVector & parameters_in,
                                                           const ParameterVector & vector,
                                                           SensitivityData & sensitivities)
{
  // We currently get partial derivatives via finite differencing
  const Real delta_p = TOLERANCE;

  ParameterVector & parameters =
    const_cast<ParameterVector &>(parameters_in);

  // We'll use a single temporary vector for matrix-vector-vector products
  std::unique_ptr<NumericVector<Number>> tempvec = this->solution->zero_clone();

  const unsigned int Np = cast_int<unsigned int>
    (parameters.size());
  const unsigned int Nq = this->n_qois();

  // For each quantity of interest q, the parameter sensitivity
  // Hessian is defined as q''_{kl} = {d^2 q}/{d p_k d p_l}.
  // Given a vector of parameter perturbation weights w_l, this
  // function evaluates the hessian-vector product sum_l(q''_{kl}*w_l)
  //
  // We calculate it from values and partial derivatives of the
  // quantity of interest function Q, solution u, adjoint solution z,
  // parameter sensitivity adjoint solutions z^l, and residual R, as:
  //
  // sum_l(q''_{kl}*w_l) =
  // sum_l(w_l * Q''_{kl}) + Q''_{uk}(u)*(sum_l(w_l u'_l)) -
  // R'_k(u, sum_l(w_l*z^l)) - R'_{uk}(u,z)*(sum_l(w_l u'_l) -
  // sum_l(w_l*R''_{kl}(u,z))
  //
  // See the adjoints model document for more details.

  // We first do an adjoint solve to get z for each quantity of
  // interest
  // if we havent already or dont have an initial condition for the adjoint
  if (!this->is_adjoint_already_solved())
    {
      this->adjoint_solve(qoi_indices);
    }

  // Get ready to fill in sensitivities:
  sensitivities.allocate_data(qoi_indices, *this, parameters);

  // We can't solve for all the solution sensitivities u'_l or for all
  // of the parameter sensitivity adjoint solutions z^l without
  // requiring O(Nq*Np) linear solves.  So we'll solve directly for their
  // weighted sum - this is just O(Nq) solves.

  // First solve for sum_l(w_l u'_l).
  this->weighted_sensitivity_solve(parameters, vector);

  // Then solve for sum_l(w_l z^l).
  this->weighted_sensitivity_adjoint_solve(parameters, vector, qoi_indices);

  for (unsigned int k=0; k != Np; ++k)
    {
      // We approximate sum_l(w_l * Q''_{kl}) with a central
      // differencing perturbation:
      // sum_l(w_l * Q''_{kl}) ~=
      // (Q(p + dp*w_l*e_l + dp*e_k) - Q(p - dp*w_l*e_l + dp*e_k) -
      // Q(p + dp*w_l*e_l - dp*e_k) + Q(p - dp*w_l*e_l - dp*e_k))/(4*dp^2)

      // The sum(w_l*R''_kl) term requires the same sort of perturbation,
      // and so we subtract it in at the same time:
      // sum_l(w_l * R''_{kl}) ~=
      // (R(p + dp*w_l*e_l + dp*e_k) - R(p - dp*w_l*e_l + dp*e_k) -
      // R(p + dp*w_l*e_l - dp*e_k) + R(p - dp*w_l*e_l - dp*e_k))/(4*dp^2)

      ParameterVector oldparameters, parameterperturbation;
      parameters.deep_copy(oldparameters);
      vector.deep_copy(parameterperturbation);
      parameterperturbation *= delta_p;
      parameters += parameterperturbation;

      Number old_parameter = *parameters[k];

      *parameters[k] = old_parameter + delta_p;
      this->assemble_qoi(qoi_indices);
      this->assembly(true, false, true);
      this->rhs->close();
      std::vector<Number> partial2q_term = this->qoi;
      std::vector<Number> partial2R_term(this->n_qois());
      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          partial2R_term[i] = this->rhs->dot(this->get_adjoint_solution(i));

      *parameters[k] = old_parameter - delta_p;
      this->assemble_qoi(qoi_indices);
      this->assembly(true, false, true);
      this->rhs->close();
      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          {
            partial2q_term[i] -= this->qoi[i];
            partial2R_term[i] -= this->rhs->dot(this->get_adjoint_solution(i));
          }

      oldparameters.value_copy(parameters);
      parameterperturbation *= -1.0;
      parameters += parameterperturbation;

      // Re-center old_parameter, which may be affected by vector
      old_parameter = *parameters[k];

      *parameters[k] = old_parameter + delta_p;
      this->assemble_qoi(qoi_indices);
      this->assembly(true, false, true);
      this->rhs->close();
      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          {
            partial2q_term[i] -= this->qoi[i];
            partial2R_term[i] -= this->rhs->dot(this->get_adjoint_solution(i));
          }

      *parameters[k] = old_parameter - delta_p;
      this->assemble_qoi(qoi_indices);
      this->assembly(true, false, true);
      this->rhs->close();
      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          {
            partial2q_term[i] += this->qoi[i];
            partial2R_term[i] += this->rhs->dot(this->get_adjoint_solution(i));
          }

      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          {
            partial2q_term[i] /= (4. * delta_p * delta_p);
            partial2R_term[i] /= (4. * delta_p * delta_p);
          }

      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          sensitivities[i][k] = partial2q_term[i] - partial2R_term[i];

      // We get (partial q / partial u), R, and
      // (partial R / partial u) from the user, but centrally
      // difference to get q_uk, R_k, and R_uk terms:
      // (partial R / partial k)
      // R_k*sum(w_l*z^l) = (R(p+dp*e_k)*sum(w_l*z^l) - R(p-dp*e_k)*sum(w_l*z^l))/(2*dp)
      // (partial^2 q / partial u partial k)
      // q_uk = (q_u(p+dp*e_k) - q_u(p-dp*e_k))/(2*dp)
      // (partial^2 R / partial u partial k)
      // R_uk*z*sum(w_l*u'_l) = (R_u(p+dp*e_k)*z*sum(w_l*u'_l) - R_u(p-dp*e_k)*z*sum(w_l*u'_l))/(2*dp)

      // To avoid creating Nq temporary vectors for q_uk or R_uk, we add
      // subterms to the sensitivities output one by one.
      //
      // FIXME: this is probably a bad order of operations for
      // controlling floating point error.

      *parameters[k] = old_parameter + delta_p;
      this->assembly(true, true);
      this->rhs->close();
      this->matrix->close();
      this->assemble_qoi_derivative(qoi_indices,
                                    /* include_liftfunc = */ true,
                                    /* apply_constraints = */ false);

      this->matrix->vector_mult(*tempvec, this->get_weighted_sensitivity_solution());

      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          {
            this->get_adjoint_rhs(i).close();
            sensitivities[i][k] += (this->get_adjoint_rhs(i).dot(this->get_weighted_sensitivity_solution()) -
                                    this->rhs->dot(this->get_weighted_sensitivity_adjoint_solution(i)) -
                                    this->get_adjoint_solution(i).dot(*tempvec)) / (2.*delta_p);
          }

      *parameters[k] = old_parameter - delta_p;
      this->assembly(true, true);
      this->rhs->close();
      this->matrix->close();
      this->assemble_qoi_derivative(qoi_indices,
                                    /* include_liftfunc = */ true,
                                    /* apply_constraints = */ false);

      this->matrix->vector_mult(*tempvec, this->get_weighted_sensitivity_solution());

      for (unsigned int i=0; i != Nq; ++i)
        if (qoi_indices.has_index(i))
          {
            this->get_adjoint_rhs(i).close();
            sensitivities[i][k] += (-this->get_adjoint_rhs(i).dot(this->get_weighted_sensitivity_solution()) +
                                    this->rhs->dot(this->get_weighted_sensitivity_adjoint_solution(i)) +
                                    this->get_adjoint_solution(i).dot(*tempvec)) / (2.*delta_p);
          }
    }

  // All parameters have been reset.
  // Don't leave the qoi or system changed - principle of least
  // surprise.
  this->assembly(true, true);
  this->rhs->close();
  this->matrix->close();
  this->assemble_qoi(qoi_indices);
}
Ejemplo n.º 11
0
std::pair<unsigned int, Real>
ImplicitSystem::weighted_sensitivity_solve (const ParameterVector & parameters_in,
                                            const ParameterVector & weights)
{
  // Log how long the linear solve takes.
  LOG_SCOPE("weighted_sensitivity_solve()", "ImplicitSystem");

  // We currently get partial derivatives via central differencing
  const Real delta_p = TOLERANCE;

  ParameterVector & parameters =
    const_cast<ParameterVector &>(parameters_in);

  // The forward system should now already be solved.

  // Now we're assembling a weighted sum of sensitivity systems:
  //
  // dR/du (u, v)(sum(w_l*u'_l)) = -sum_l(w_l*R'_l (u, v)) forall v

  // We'll assemble the rhs first, because the R' term will require
  // perturbing the system, and some applications may not be able to
  // assemble a perturbed residual without simultaneously constructing
  // a perturbed jacobian.

  // We approximate the _l partial derivatives via a central
  // differencing perturbation in the w_l direction:
  //
  // sum_l(w_l*v_l) ~= (v(p + dp*w_l*e_l) - v(p - dp*w_l*e_l))/(2*dp)

  ParameterVector oldparameters, parameterperturbation;
  parameters.deep_copy(oldparameters);
  weights.deep_copy(parameterperturbation);
  parameterperturbation *= delta_p;
  parameters += parameterperturbation;

  this->assembly(true, false, true);
  this->rhs->close();

  std::unique_ptr<NumericVector<Number>> temprhs = this->rhs->clone();

  oldparameters.value_copy(parameters);
  parameterperturbation *= -1.0;
  parameters += parameterperturbation;

  this->assembly(true, false, true);
  this->rhs->close();

  *temprhs -= *(this->rhs);
  *temprhs /= (2.0*delta_p);

  // Finally, assemble the jacobian at the non-perturbed parameter
  // values
  oldparameters.value_copy(parameters);

  // Build the Jacobian
  this->assembly(false, true);
  this->matrix->close();

  // The weighted sensitivity problem is linear
  LinearSolver<Number> * linear_solver = this->get_linear_solver();

  std::pair<unsigned int, Real> solver_params =
    this->get_linear_solve_parameters();

  const std::pair<unsigned int, Real> rval =
    linear_solver->solve (*matrix, this->add_weighted_sensitivity_solution(),
                          *temprhs,
                          solver_params.second,
                          solver_params.first);

  this->release_linear_solver(linear_solver);

  // The linear solver may not have fit our constraints exactly
#ifdef LIBMESH_ENABLE_CONSTRAINTS
  this->get_dof_map().enforce_constraints_exactly
    (*this, &this->get_weighted_sensitivity_solution(),
     /* homogeneous = */ true);
#endif

  return rval;
}
Ejemplo n.º 12
0
std::pair<unsigned int, Real>
ImplicitSystem::weighted_sensitivity_adjoint_solve (const ParameterVector & parameters_in,
                                                    const ParameterVector & weights,
                                                    const QoISet & qoi_indices)
{
  // Log how long the linear solve takes.
  LOG_SCOPE("weighted_sensitivity_adjoint_solve()", "ImplicitSystem");

  // We currently get partial derivatives via central differencing
  const Real delta_p = TOLERANCE;

  ParameterVector & parameters =
    const_cast<ParameterVector &>(parameters_in);

  // The forward system should now already be solved.
  // The adjoint system should now already be solved.
  // Now we're assembling a weighted sum of adjoint-adjoint systems:
  //
  // dR/du (u, sum_l(w_l*z^l)) = sum_l(w_l*(Q''_ul - R''_ul (u, z)))

  // FIXME: The derivation here does not yet take adjoint boundary
  // conditions into account.
  for (unsigned int i=0; i != this->n_qois(); ++i)
    if (qoi_indices.has_index(i))
      libmesh_assert(!this->get_dof_map().has_adjoint_dirichlet_boundaries(i));

  // We'll assemble the rhs first, because the R'' term will require
  // perturbing the jacobian

  // We'll use temporary rhs vectors, because we haven't (yet) found
  // any good reasons why users might want to save these:

  std::vector<std::unique_ptr<NumericVector<Number>>> temprhs(this->n_qois());
  for (unsigned int i=0; i != this->n_qois(); ++i)
    if (qoi_indices.has_index(i))
      temprhs[i] = this->rhs->zero_clone();

  // We approximate the _l partial derivatives via a central
  // differencing perturbation in the w_l direction:
  //
  // sum_l(w_l*v_l) ~= (v(p + dp*w_l*e_l) - v(p - dp*w_l*e_l))/(2*dp)

  // PETSc doesn't implement SGEMX, so neither does NumericVector,
  // so we want to avoid calculating f -= R'*z.  We'll thus evaluate
  // the above equation by first adding -v(p+dp...), then multiplying
  // the intermediate result vectors by -1, then adding -v(p-dp...),
  // then finally dividing by 2*dp.

  ParameterVector oldparameters, parameterperturbation;
  parameters.deep_copy(oldparameters);
  weights.deep_copy(parameterperturbation);
  parameterperturbation *= delta_p;
  parameters += parameterperturbation;

  this->assembly(false, true);
  this->matrix->close();

  // Take the discrete adjoint, so that we can calculate R_u(u,z) with
  // a matrix-vector product of R_u and z.
  matrix->get_transpose(*matrix);

  this->assemble_qoi_derivative(qoi_indices,
                                /* include_liftfunc = */ false,
                                /* apply_constraints = */ true);
  for (unsigned int i=0; i != this->n_qois(); ++i)
    if (qoi_indices.has_index(i))
      {
        this->get_adjoint_rhs(i).close();
        *(temprhs[i]) -= this->get_adjoint_rhs(i);
        this->matrix->vector_mult_add(*(temprhs[i]), this->get_adjoint_solution(i));
        *(temprhs[i]) *= -1.0;
      }

  oldparameters.value_copy(parameters);
  parameterperturbation *= -1.0;
  parameters += parameterperturbation;

  this->assembly(false, true);
  this->matrix->close();
  matrix->get_transpose(*matrix);

  this->assemble_qoi_derivative(qoi_indices,
                                /* include_liftfunc = */ false,
                                /* apply_constraints = */ true);
  for (unsigned int i=0; i != this->n_qois(); ++i)
    if (qoi_indices.has_index(i))
      {
        this->get_adjoint_rhs(i).close();
        *(temprhs[i]) -= this->get_adjoint_rhs(i);
        this->matrix->vector_mult_add(*(temprhs[i]), this->get_adjoint_solution(i));
        *(temprhs[i]) /= (2.0*delta_p);
      }

  // Finally, assemble the jacobian at the non-perturbed parameter
  // values.  Ignore assemble_before_solve; if we had a good
  // non-perturbed matrix before we've already overwritten it.
  oldparameters.value_copy(parameters);

  // if (this->assemble_before_solve)
  {
    // Build the Jacobian
    this->assembly(false, true);
    this->matrix->close();

    // Take the discrete adjoint
    matrix->get_transpose(*matrix);
  }

  // The weighted adjoint-adjoint problem is linear
  LinearSolver<Number> * linear_solver = this->get_linear_solver();

  // Our iteration counts and residuals will be sums of the individual
  // results
  std::pair<unsigned int, Real> solver_params =
    this->get_linear_solve_parameters();
  std::pair<unsigned int, Real> totalrval = std::make_pair(0,0.0);

  for (unsigned int i=0; i != this->n_qois(); ++i)
    if (qoi_indices.has_index(i))
      {
        const std::pair<unsigned int, Real> rval =
          linear_solver->solve (*matrix, this->add_weighted_sensitivity_adjoint_solution(i),
                                *(temprhs[i]),
                                solver_params.second,
                                solver_params.first);

        totalrval.first  += rval.first;
        totalrval.second += rval.second;
      }

  this->release_linear_solver(linear_solver);

  // The linear solver may not have fit our constraints exactly
#ifdef LIBMESH_ENABLE_CONSTRAINTS
  for (unsigned int i=0; i != this->n_qois(); ++i)
    if (qoi_indices.has_index(i))
      this->get_dof_map().enforce_constraints_exactly
        (*this, &this->get_weighted_sensitivity_adjoint_solution(i),
         /* homogeneous = */ true);
#endif

  return totalrval;
}
Ejemplo n.º 13
0
// Registers a module specific info at the driver
void ModuleInfo::registerModule()
{
    m_is_loaded = isLoaded();

    cli::ICommandList list = m_module->getCLIInfo();
    for (cli::ICommandList::iterator i = list.begin();
         i != list.end(); i++)
    {
        if (m_is_loaded == false &&
            (*i)->isRequireModule() == true)
        {
            // not load the command yet
            continue;
        }

        struct ast_cli_entry* entry =
            Factory::instance()->getGarbage()->allocEntry();
        entry->klkmodnameused = 1;

        ParameterVector cmds = Utils::getCommands((*i)->getName());
        BOOST_ASSERT(cmds.size() > 0 &&
                      cmds.size() < (AST_MAX_CMD_LEN - 2));

        // ignore module name for service module
        if (m_module->getID() == srv::MODID)
        {
            entry->klkmodnameused = 0;
            size_t j = 0;
            for (j = 0; j < AST_MAX_CMD_LEN - 1; j++)
            {
                if (j >= cmds.size())
                    break;
                entry->cmda[j] =
                    Factory::instance()->getGarbage()->allocData(cmds[j]);
            }
            entry->cmda[j] = NULL;
        }
        else
        {
            /*! Null terminated list of the words of the command */
            const std::string modname = m_module->getName();
            entry->cmda[0] =
                Factory::instance()->getGarbage()->allocData(modname);
            size_t j = 1;
            for (j = 1; j < AST_MAX_CMD_LEN - 1; j++)
            {
                if (j > cmds.size())
                    break;
                entry->cmda[j] =
                    Factory::instance()->getGarbage()->allocData(cmds[j - 1]);
            }
            entry->cmda[j] = NULL;
        }

        /*! Handler for the command (fd for output, # of arguments,
          argument list).
          Returns RESULT_SHOWUSAGE for improper arguments */
        entry->handler = handle_module;
        /*! Summary of the command (< 60 characters) */
        entry->summary =
            Factory::instance()->getGarbage()->allocData((*i)->getSummary());
        /*! Detailed usage information */
        entry->usage =
            Factory::instance()->getGarbage()->allocData((*i)->getUsage());
        /*! Generate a list of possible completions for a given word */
        //char *(*generator)(char *line, char *word, int pos, int state);
        entry->generator = handle_complete;
        /*! For linking */
        entry->next = NULL;
        /*! For keeping track of usage */
        entry->inuse = 0;

        // KLK specific data
        entry->klkname =
            Factory::instance()->getGarbage()->allocData((*i)->getName());
        entry->klkmsgid =
            Factory::instance()->getGarbage()->allocData((*i)->getMessageID());

        m_entries.push_back(entry);

        ast_cli_register(entry);
    }


#if 0
    // linking
    for (EntryList::iterator i = m_entries.begin(); i != m_entries.end(); i++)
    {
        // do linking
        EntryList::iterator next = i;
        next++;
        if (next != m_entries.end())
        {
            (*i)->next = *next;
        }
    }
#endif
}