diff --git a/dune/gfe/assemblers/CMakeLists.txt b/dune/gfe/assemblers/CMakeLists.txt index a890d6ab41268334e9380c202ed4ceb2ff70783b..e0dfa540445ee4ad122b247b682505a90a70846a 100644 --- a/dune/gfe/assemblers/CMakeLists.txt +++ b/dune/gfe/assemblers/CMakeLists.txt @@ -14,7 +14,6 @@ install(FILES localgeodesicfestiffness.hh localintegralenergy.hh mixedgfeassembler.hh - mixedlocalgeodesicfestiffness.hh mixedlocalgfeadolcstiffness.hh nonplanarcosseratshellenergy.hh simofoxenergy.hh diff --git a/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh b/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh index fb59c5cd9437a4a758ea331daf3578031e08c929..93b6723a66aac4fde8402cac012b7023b58e97cc 100644 --- a/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh +++ b/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh @@ -63,17 +63,27 @@ public: This uses the automatic differentiation toolbox ADOL_C. */ virtual void assembleGradient(const typename Basis::LocalView& localView, - const std::vector<TargetSpace>& solution, - std::vector<typename TargetSpace::TangentVector>& gradient) const override; + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Coefficients& coefficients, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Gradient& gradient) const override; /** \brief Assemble the local stiffness matrix at the current position This uses the automatic differentiation toolbox ADOL_C. */ virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, - const std::vector<TargetSpace>& localSolution, - std::vector<typename TargetSpace::TangentVector>& localGradient, - Dune::Matrix<Dune::FieldMatrix<RT,blocksize,blocksize> >& localHessian) const override; + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Coefficients& coefficients, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Gradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Hessian& localHessian) const override; + + /** \brief Assemble the local stiffness matrix at the current position + */ + virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeCoefficients& coefficients, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeHessian& localHessian) const override + { + DUNE_THROW(Dune::NotImplemented, "!"); + } const Dune::GFE::LocalEnergy<Basis, ATargetSpace>* localEnergy_; const bool adolcScalarMode_; @@ -130,8 +140,8 @@ energy(const typename Basis::LocalView& localView, template <class Basis, class TargetSpace> void LocalGeodesicFEADOLCStiffness<Basis, TargetSpace>:: assembleGradient(const typename Basis::LocalView& localView, - const std::vector<TargetSpace>& localSolution, - std::vector<typename TargetSpace::TangentVector>& localGradient) const + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Coefficients& localSolution, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Gradient& localGradient) const { // Tape energy computation. We may not have to do this every time, but it's comparatively cheap. energy(localView, localSolution); @@ -175,9 +185,9 @@ assembleGradient(const typename Basis::LocalView& localView, template <class Basis, class TargetSpace> void LocalGeodesicFEADOLCStiffness<Basis, TargetSpace>:: assembleGradientAndHessian(const typename Basis::LocalView& localView, - const std::vector<TargetSpace>& localSolution, - std::vector<typename TargetSpace::TangentVector>& localGradient, - Dune::Matrix<Dune::FieldMatrix<RT,blocksize,blocksize> >& localHessian) const + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Coefficients& localSolution, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Gradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Hessian& localHessian) const { // Tape energy computation. We may not have to do this every time, but it's comparatively cheap. energy(localView, localSolution); diff --git a/dune/gfe/assemblers/localgeodesicfefdstiffness.hh b/dune/gfe/assemblers/localgeodesicfefdstiffness.hh index cf400921d0c5636a164ea64f85533cabf78ba8c9..6f4fe03af2ea7882a6bfbf8e85f3b1b8d56b2b63 100644 --- a/dune/gfe/assemblers/localgeodesicfefdstiffness.hh +++ b/dune/gfe/assemblers/localgeodesicfefdstiffness.hh @@ -45,7 +45,7 @@ public: RT energy (const typename Basis::LocalView& localView, const typename Dune::GFE::Impl::LocalEnergyTypes<TargetSpace>::CompositeCoefficients& coefficients) const override { - DUNE_THROW(Dune::NotImplemented, "!"); + return localEnergy_->energy(localView,coefficients); } /** \brief Assemble the element gradient of the energy functional @@ -64,6 +64,17 @@ public: std::vector<typename TargetSpace::TangentVector>& localGradient, typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Hessian& localHessian) const override; + /** \brief Assemble the local tangent matrix and gradient at the current position + + This implementation uses finite-difference approximations + */ + virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeCoefficients& localSolution, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeHessian& localHessian) const override + { + DUNE_THROW(Dune::NotImplemented, "!"); + } const Dune::GFE::LocalEnergy<Basis, ATargetSpace>* localEnergy_; diff --git a/dune/gfe/assemblers/localgeodesicfestiffness.hh b/dune/gfe/assemblers/localgeodesicfestiffness.hh index d43f18ecafc61c9dcae6a09b595c02137a1f5074..c32bf68382af1849dc7dd25122df93cef20c51b2 100644 --- a/dune/gfe/assemblers/localgeodesicfestiffness.hh +++ b/dune/gfe/assemblers/localgeodesicfestiffness.hh @@ -3,6 +3,7 @@ #include <dune/common/fmatrix.hh> #include <dune/istl/matrix.hh> +#include <dune/istl/multitypeblockmatrix.hh> #include <dune/gfe/assemblers/localfirstordermodel.hh> @@ -10,6 +11,10 @@ namespace Dune::GFE { namespace Impl { + /** \brief A class exporting container types for sets local Hesse matrices + * + * This generic template handles TargetSpaces that are not product manifolds. + */ template<class TargetSpace> class LocalStiffnessTypes : public LocalFirstOrderModelTypes<TargetSpace> @@ -24,6 +29,46 @@ namespace Dune::GFE // Type of the local Hessian using Hessian = Matrix<FieldMatrix<RT, blocksize, blocksize> >; + + using Row = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize, blocksize> > >; + using CompositeHessian = MultiTypeBlockMatrix<Row>; + }; + + /** \brief A class exporting container types for sets local Hesse matrices + * + * This is the specialization for product manifolds. + */ + template<class ... Factors> + class LocalStiffnessTypes<ProductManifold<Factors...> > + : public LocalFirstOrderModelTypes<ProductManifold<Factors...> > + { + using TargetSpace = ProductManifold<Factors...>; + + // Number type + typedef typename ProductManifold<Factors...>::ctype RT; + + using DeformationTargetSpace = std::decay_t<decltype(std::declval<TargetSpace>()[Dune::Indices::_0])>; + using OrientationTargetSpace = std::decay_t<decltype(std::declval<TargetSpace>()[Dune::Indices::_1])>; + + // Dimension of the product tangent space + constexpr static auto blocksize = TargetSpace::TangentVector::dimension; + + // Dimensions of the individual factor tangent spaces + constexpr static auto blocksize0 = DeformationTargetSpace::TangentVector::dimension; + constexpr static auto blocksize1 = OrientationTargetSpace::TangentVector::dimension; + + public: + + // Type of the local Hessian + using Hessian = Matrix<FieldMatrix<RT, blocksize, blocksize> >; + + // Type of the local Hessian + using Row0 = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize0, blocksize0> >, + Matrix<FieldMatrix<RT, blocksize0, blocksize1> > >; + using Row1 = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize1, blocksize0> >, + Matrix<FieldMatrix<RT, blocksize1, blocksize1> > >; + + using CompositeHessian = MultiTypeBlockMatrix<Row0, Row1>; }; } } @@ -41,6 +86,13 @@ public: const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Coefficients& coefficients, typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Gradient& localGradient, typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Hessian& localHessian) const = 0; + + /** \brief Assemble the local gradient and stiffness matrix at the current position -- Composite version + */ + virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeCoefficients& coefficients, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeHessian& localHessian) const = 0; }; #endif diff --git a/dune/gfe/assemblers/mixedgfeassembler.hh b/dune/gfe/assemblers/mixedgfeassembler.hh index f4182de4bf2113a77da8b48460feabe23dc37bf1..6b134d41193dfc001ed4311fa3daefd5279163a0 100644 --- a/dune/gfe/assemblers/mixedgfeassembler.hh +++ b/dune/gfe/assemblers/mixedgfeassembler.hh @@ -7,7 +7,7 @@ #include <dune/istl/matrix.hh> #include <dune/istl/multitypeblockmatrix.hh> -#include <dune/gfe/assemblers/mixedlocalgeodesicfestiffness.hh> +#include <dune/gfe/assemblers/localgeodesicfestiffness.hh> /** \brief A global FE assembler for problems involving functions that map into non-Euclidean spaces @@ -36,13 +36,13 @@ public: Dune::MultiTypeBlockVector<MatrixBlock10,MatrixBlock11> > MatrixType; const Basis basis_; - MixedLocalGeodesicFEStiffness<Basis, Dune::GFE::ProductManifold<TargetSpace0,TargetSpace1> >* localStiffness_; + LocalGeodesicFEStiffness<Basis, Dune::GFE::ProductManifold<TargetSpace0,TargetSpace1> >* localStiffness_; public: /** \brief Constructor for a given grid */ MixedGFEAssembler(const Basis& basis, - MixedLocalGeodesicFEStiffness<Basis, Dune::GFE::ProductManifold<TargetSpace0, TargetSpace1> >* localStiffness) + LocalGeodesicFEStiffness<Basis, Dune::GFE::ProductManifold<TargetSpace0, TargetSpace1> >* localStiffness) : basis_(basis), localStiffness_(localStiffness) {} diff --git a/dune/gfe/assemblers/mixedlocalgeodesicfestiffness.hh b/dune/gfe/assemblers/mixedlocalgeodesicfestiffness.hh deleted file mode 100644 index ae5620df418df9eecfa7ba56c93a6256598c7877..0000000000000000000000000000000000000000 --- a/dune/gfe/assemblers/mixedlocalgeodesicfestiffness.hh +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef DUNE_GFE_MIXEDLOCALGEODESICFESTIFFNESS_HH -#define DUNE_GFE_MIXEDLOCALGEODESICFESTIFFNESS_HH - -#include <dune/common/fmatrix.hh> - -#include <dune/istl/matrix.hh> -#include <dune/istl/multitypeblockmatrix.hh> - -#include <dune/gfe/assemblers/localfirstordermodel.hh> - -namespace Dune::GFE -{ - namespace Impl - { - template<class TargetSpace> - class MixedLocalStiffnessTypes - : public LocalFirstOrderModelTypes<TargetSpace> - { - // Number type - typedef typename TargetSpace::ctype RT; - - using DeformationTargetSpace = std::decay_t<decltype(std::declval<TargetSpace>()[Dune::Indices::_0])>; - using OrientationTargetSpace = std::decay_t<decltype(std::declval<TargetSpace>()[Dune::Indices::_1])>; - - //! Dimension of a tangent space - constexpr static int blocksize0 = DeformationTargetSpace::TangentVector::dimension; - constexpr static int blocksize1 = OrientationTargetSpace::TangentVector::dimension; - - public: - - // Type of the local Hessian - using Row0 = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize0, blocksize0> >, - Matrix<FieldMatrix<RT, blocksize0, blocksize1> > >; - using Row1 = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize1, blocksize0> >, - Matrix<FieldMatrix<RT, blocksize1, blocksize1> > >; - - using MixedHessian = Dune::MultiTypeBlockMatrix<Row0, Row1>; - }; - } -} - -/** \brief Abstract base class for second-order energy approximations on one grid element - * - * \tparam TargetSpace The space we map into. MUST be a ProductManifold with two factors - */ -template<class Basis, class TargetSpace> -class MixedLocalGeodesicFEStiffness - : public Dune::GFE::LocalFirstOrderModel<Basis,TargetSpace> -{ -public: - /** \brief Assemble the local stiffness matrix at the current position - */ - virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, - const typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::CompositeCoefficients& localConfiguration, - typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, - typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::MixedHessian& localHessian) const = 0; -}; - -#endif diff --git a/dune/gfe/assemblers/mixedlocalgfeadolcstiffness.hh b/dune/gfe/assemblers/mixedlocalgfeadolcstiffness.hh index d62186934244861875b5d72509af1b63adf1fd88..03e481f9d2545db4f088006994a8cd55bae7adf8 100644 --- a/dune/gfe/assemblers/mixedlocalgfeadolcstiffness.hh +++ b/dune/gfe/assemblers/mixedlocalgfeadolcstiffness.hh @@ -12,14 +12,14 @@ #include <dune/common/fmatrix.hh> #include <dune/istl/matrix.hh> -#include <dune/gfe/assemblers/mixedlocalgeodesicfestiffness.hh> +#include <dune/gfe/assemblers/localgeodesicfestiffness.hh> #include <dune/gfe/spaces/productmanifold.hh> /** \brief Assembles energy gradient and Hessian with ADOL-C (automatic differentiation) */ template<class Basis, class TargetSpace0, class TargetSpace1> class MixedLocalGFEADOLCStiffness - : public MixedLocalGeodesicFEStiffness<Basis,Dune::GFE::ProductManifold<TargetSpace0,TargetSpace1> > + : public LocalGeodesicFEStiffness<Basis,Dune::GFE::ProductManifold<TargetSpace0,TargetSpace1> > { using TargetSpace = Dune::GFE::ProductManifold<TargetSpace0,TargetSpace1>; @@ -37,8 +37,6 @@ class MixedLocalGFEADOLCStiffness // some other sizes constexpr static int gridDim = GridView::dimension; - using HessianType = typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::MixedHessian; - public: //! Dimension of a tangent space @@ -74,14 +72,22 @@ public: DUNE_THROW(Dune::NotImplemented, "!"); } + virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Coefficients& coefficients, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Gradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::Hessian& localHessian) const override + { + DUNE_THROW(Dune::NotImplemented, "!"); + } + /** \brief Assemble the local stiffness matrix at the current position This uses the automatic differentiation toolbox ADOL_C. */ virtual void assembleGradientAndHessian(const typename Basis::LocalView& localView, - const typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::CompositeCoefficients& localConfiguration, - typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, - HessianType& localHessian) const override; + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeCoefficients& localConfiguration, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeHessian& localHessian) const override; const Dune::GFE::LocalEnergy<Basis, Dune::GFE::ProductManifold<ATargetSpace0, ATargetSpace1> >* localEnergy_; const bool adolcScalarMode_; @@ -156,9 +162,9 @@ energy(const typename Basis::LocalView& localView, template <class Basis, class TargetSpace0, class TargetSpace1> void MixedLocalGFEADOLCStiffness<Basis, TargetSpace0, TargetSpace1>:: assembleGradientAndHessian(const typename Basis::LocalView& localView, - const typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::CompositeCoefficients& localConfiguration, - typename Dune::GFE::Impl::MixedLocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, - HessianType& localHessian) const + const typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeCoefficients& localConfiguration, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeGradient& localGradient, + typename Dune::GFE::Impl::LocalStiffnessTypes<TargetSpace>::CompositeHessian& localHessian) const { int rank = Dune::MPIHelper::getCommunication().rank();