From 38134d0d1f308848a5d0a57e9ce1a32253501311 Mon Sep 17 00:00:00 2001 From: Jonathan Youett <youett@math.fu-berlin.de> Date: Fri, 2 Mar 2018 14:56:41 +0100 Subject: [PATCH] Allow to hand over r-values, l-values and shared_ptr and handle ownership --- dune/gfe/geodesicfeassembler.hh | 41 ++++++++++++++++++++++---- dune/gfe/geodesicfeassemblerwrapper.hh | 7 ++++- dune/gfe/riemanniantrsolver.cc | 2 +- dune/gfe/rodassembler.cc | 2 +- dune/gfe/rodassembler.hh | 2 +- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/dune/gfe/geodesicfeassembler.hh b/dune/gfe/geodesicfeassembler.hh index c6958e50..36640199 100644 --- a/dune/gfe/geodesicfeassembler.hh +++ b/dune/gfe/geodesicfeassembler.hh @@ -8,6 +8,7 @@ #include "localgeodesicfestiffness.hh" +#include <dune/solvers/common/wrapownshare.hh> /** \brief A global FE assembler for problems involving functions that map into non-Euclidean spaces */ @@ -15,6 +16,7 @@ template <class Basis, class TargetSpace> class GeodesicFEAssembler { typedef typename Basis::GridView GridView; + using LocalStiffness = LocalGeodesicFEStiffness<Basis, TargetSpace>; //! Dimension of the grid. enum { gridDim = GridView::dimension }; @@ -25,22 +27,51 @@ class GeodesicFEAssembler { //! typedef Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock; -public: - const Basis basis_; protected: - LocalGeodesicFEStiffness<Basis,TargetSpace>* localStiffness_; + //! The global basis + const Basis basis_; + + //! The local stiffness operator + std::shared_ptr<LocalStiffness> localStiffness_; public: /** \brief Constructor for a given grid */ + GeodesicFEAssembler(const Basis& basis) + : basis_(basis) + {} + + /** \brief Constructor for a given grid */ + template <class LocalStiffnessT> GeodesicFEAssembler(const Basis& basis, - LocalGeodesicFEStiffness<Basis, TargetSpace>* localStiffness) + LocalStiffnessT&& localStiffness) : basis_(basis), - localStiffness_(localStiffness) + localStiffness_(Dune::Solvers::wrap_own_share<LocalStiffness>(std::forward<LocalStiffnessT>(localStiffness))) {} + /** \brief Set the local stiffness assembler. This can be a temporary, l-value or shared pointer. */ + template <class LocalStiffnessT> + void setLocalStiffness(LocalStiffnessT&& localStiffness) { + localStiffness_ = Dune::Solvers::wrap_own_share<LocalStiffness>(std::forward<LocalStiffnessT>(localStiffness)); + } + + /** \brief Get the local stiffness operator. */ + const LocalStiffness& getLocalStiffness() const { + return *localStiffness_; + } + + /** \brief Get the local stiffness operator. */ + LocalStiffness& getLocalStiffness() { + return *localStiffness_; + } + + /** \brief Get the basis. */ + const Basis& getBasis() const { + return basis_; + } + /** \brief Assemble the tangent stiffness matrix and the functional gradient together * * This is more efficient than computing them separately, because you need the gradient diff --git a/dune/gfe/geodesicfeassemblerwrapper.hh b/dune/gfe/geodesicfeassemblerwrapper.hh index 8dee1f1f..4570b407 100644 --- a/dune/gfe/geodesicfeassemblerwrapper.hh +++ b/dune/gfe/geodesicfeassemblerwrapper.hh @@ -62,6 +62,11 @@ public: /** \brief Get the occupation structure of the Hessian */ virtual void getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const; + /** \brief Get the basis. */ + const ScalarBasis& getBasis() const { + return basis_; + } + private: Dune::TupleVector<std::vector<MixedSpace0>,std::vector<MixedSpace1>> splitVector(const std::vector<TargetSpace>& sol) const; std::unique_ptr<MatrixType> hessianMixed_; @@ -186,4 +191,4 @@ computeEnergy(const std::vector<TargetSpace>& sol) const auto solutionSplit = splitVector(sol); return mixedAssembler_->computeEnergy(solutionSplit[_0], solutionSplit[_1]); } -#endif //GLOBAL_GEODESIC_FE_ASSEMBLERWRAPPER_HH \ No newline at end of file +#endif //GLOBAL_GEODESIC_FE_ASSEMBLERWRAPPER_HH diff --git a/dune/gfe/riemanniantrsolver.cc b/dune/gfe/riemanniantrsolver.cc index b45d502d..88d4e771 100644 --- a/dune/gfe/riemanniantrsolver.cc +++ b/dune/gfe/riemanniantrsolver.cc @@ -117,7 +117,7 @@ setup(const GridType& grid, // ////////////////////////////////////////////////////////////////////////////////////// typedef DuneFunctionsBasis<Basis> FufemBasis; - FufemBasis basis(assembler_->basis_); + FufemBasis basis(assembler_->getBasis()); OperatorAssembler<FufemBasis,FufemBasis> operatorAssembler(basis, basis); LaplaceAssembler<GridType, typename FufemBasis::LocalFiniteElement, typename FufemBasis::LocalFiniteElement> laplaceStiffness; diff --git a/dune/gfe/rodassembler.cc b/dune/gfe/rodassembler.cc index 797c006e..32300bd3 100644 --- a/dune/gfe/rodassembler.cc +++ b/dune/gfe/rodassembler.cc @@ -98,7 +98,7 @@ getStrain(const std::vector<RigidBodyMotion<double,3> >& sol, double weight = quad[pt].weight() * element.geometry().integrationElement(quadPos); - FieldVector<double,blocksize> localStrain = dynamic_cast<RodLocalStiffness<GridView, double>* >(this->localStiffness_)->getStrain(localSolution, element, quad[pt].position()); + FieldVector<double,blocksize> localStrain = std::dynamic_pointer_cast<RodLocalStiffness<GridView, double> >(this->localStiffness_)->getStrain(localSolution, element, quad[pt].position()); // Sum it all up strain[elementIdx].axpy(weight, localStrain); diff --git a/dune/gfe/rodassembler.hh b/dune/gfe/rodassembler.hh index a800cc8b..0b113a1d 100644 --- a/dune/gfe/rodassembler.hh +++ b/dune/gfe/rodassembler.hh @@ -62,7 +62,7 @@ public: auto rodEnergy() { // TODO: Does not work for other stiffness implementations - auto localFDStiffness = dynamic_cast<LocalGeodesicFEFDStiffness<Basis, RigidBodyMotion<double,3> >*>(this->localStiffness_); + auto localFDStiffness = std::dynamic_pointer_cast<LocalGeodesicFEFDStiffness<Basis, RigidBodyMotion<double,3> > >(this->localStiffness_); return const_cast<RodLocalStiffness<GridView,double>*>(dynamic_cast<const RodLocalStiffness<GridView,double>*>(localFDStiffness->localEnergy_)); } -- GitLab