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; }
// 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; }
// 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; } }
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]; } }
/// 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; } }
// ***************************************************************** // ***************************************************************** 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()); }
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.); }
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]; } }
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); }
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; }
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; }
// 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 }