shared_ptr<const DiscreteBoundaryOperator<ResultType>>
DiscreteBoundaryOperatorCache<BasisFunctionType, ResultType>::getWeakForm(
    const Context<BasisFunctionType, ResultType> &context,
    const AbstractBoundaryOperator<BasisFunctionType, ResultType> &op) const {
  // std::cout << "Weak form of operator of type " << typeid(op).name()
  //           << " requested from cache" << std::endl;
  typedef DiscreteBoundaryOperator<ResultType> DiscreteOp;

  shared_ptr<const AbstractBoundaryOperatorId> id = op.id();

  if (!id) { // operator is not cacheable
    // std::cout << "Noncacheable discrete operator requested" << std::endl;
    return op.assembleWeakForm(context);
  }

  // Check if a weak pointer to discrete operator exists in cache
  typename Impl::DiscreteBoundaryOperatorMap::const_iterator it =
      m_impl->discreteOps.find(id);
  if (it != m_impl->discreteOps.end()) {
    // std::cout << "Weak pointer to discrete operator found in cache" <<
    // std::endl;
    // Check if the weak pointer still refers to an existing object
    if (shared_ptr<const DiscreteOp> cachedDiscreteOp = it->second.lock()) {
      // std::cout << "Weak pointer is valid" << std::endl;
      return cachedDiscreteOp;
    } else {
      // std::cout << "Weak pointer is invalid, reconstructing discrete
      // operator" << std::endl;
      shared_ptr<const DiscreteOp> discreteOp = op.assembleWeakForm(context);
      // TODO: THIS IS NOT NOT THREAD-SAFE!!!
      it->second = discreteOp;
      return it->second.lock();
    }
  }

  // std::cout << "Discrete operator not found in cache -- constructing from
  // scratch"
  //           << std::endl;
  // Discrete operator not found in cache, construct it...
  shared_ptr<const DiscreteOp> discreteOp = op.assembleWeakForm(context);
  // and attempt to insert it into the map
  std::pair<typename Impl::DiscreteBoundaryOperatorMap::iterator, bool> result =
      m_impl->discreteOps.insert(std::make_pair(id, discreteOp));
  // Return pointer to the discrete operator that ended up in the map.
  return result.first->second.lock();

  // (Note: if another thread was faster in trying to insert a discrete
  // operator into the map, the operator we constructed (pointed by
  // discreteOp) will be destructed now, as discreteOp goes out of scope.)
}
예제 #2
0
파일: context.cpp 프로젝트: evantwout/bempp
shared_ptr<const DiscreteBoundaryOperator<ResultType>>
Context<BasisFunctionType, ResultType>::getWeakForm(
    const AbstractBoundaryOperator<BasisFunctionType, ResultType> &op) const {
  return op.assembleWeakForm(*this);
}