diff --git a/CHANGELOG.md b/CHANGELOG.md index 7431b7d0fb4d1f93c021fb256f55d2ecfcf5f029..dd48f7bd05b9f1db1ada9208d075213efda0ebf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Master +- In the `BulkCosseratDensity` class: Make the type of curvature + tensor controllable at run-time (previously, ugly preprocessor switches + where used). Among its parameters `BulkCosseratDensity` now expects + a string `curvatureType`, which has to take one of the values `norm`, + `curl`, or `wryness`. + - Building `dune-gfe` now requires Dune 2.9 or newer. Older configurations have not gotten CI-tested for quite a while, anyway. diff --git a/dune/gfe/densities/bulkcosseratdensity.hh b/dune/gfe/densities/bulkcosseratdensity.hh index c37a7d23d8b0496e10b73c18fced82a6a02e9704..6237dd9a0d9a00a665ff80fd06181abe955066ea 100644 --- a/dune/gfe/densities/bulkcosseratdensity.hh +++ b/dune/gfe/densities/bulkcosseratdensity.hh @@ -1,9 +1,6 @@ #ifndef DUNE_GFE_DENSITIES_BULKCOSSERATDENSITY_HH #define DUNE_GFE_DENSITIES_BULKCOSSERATDENSITY_HH -#define DONT_USE_CURL -#define CURVATURE_WITH_WRYNESS - #include <dune/common/fmatrix.hh> #include <dune/gfe/cosseratstrain.hh> @@ -80,6 +77,9 @@ namespace Dune::GFE { public: + /** \brief The different types of curvature tensors */ + enum CurvatureType {Norm, Curl, Wryness}; + /** \brief Constructor with a set of material parameters * \param parameters The material parameters */ @@ -94,6 +94,17 @@ namespace Dune::GFE { // Length scale parameter L_c_ = parameters.template get<double>("L_c"); + // Curvature type + const auto& curvatureString = parameters.template get<std::string>("curvatureType"); + if (curvatureString=="norm") + curvatureType_ = CurvatureType::Norm; + else if (curvatureString=="curl") + curvatureType_ = CurvatureType::Curl; + else if (curvatureString=="wryness") + curvatureType_ = CurvatureType::Wryness; + else + DUNE_THROW(NotImplemented, "Curvature type '" << curvatureString << "' is not implemented!"); + // Curvature exponent q_ = parameters.template get<double>("q"); @@ -105,8 +116,8 @@ namespace Dune::GFE { /** \brief Constructor with a set of material parameters */ - BulkCosseratDensity(double mu, double lambda, double mu_c, double L_c, double q, const std::array<double,3>& b) - : mu_(mu), lambda_(lambda), mu_c_(mu_c), L_c_(L_c), q_(q), b1_(b[0]), b2_(b[1]), b3_(b[2]) + BulkCosseratDensity(double mu, double lambda, double mu_c, double L_c, CurvatureType curvatureType, double q, const std::array<double,3>& b) + : mu_(mu), lambda_(lambda), mu_c_(mu_c), L_c_(L_c), curvatureType_(curvatureType), q_(q), b1_(b[0]), b2_(b[1]), b3_(b[2]) {} /** \brief The energy \f$ W_{mp}(\overline{U}) \f$, as written in @@ -159,30 +170,54 @@ namespace Dune::GFE { //////////////////////////////////////////////////////////////////// Tensor3<field_type,3,3,gridDim> DR = rotationValue.quaternionTangentToMatrixTangent(orientationDerivative); - strainEnergyDensity = quadraticEnergy(U); - - #ifdef CURVATURE_WITH_WRYNESS - auto curvatureTensor = wryness(R,DR); - - // The choice for the Frobenius norm here is b1=b2=1 and b3 = 1/3 - auto norm = (b1_ * GFE::dev(GFE::sym(curvatureTensor)).frobenius_norm2() - + b2_ * GFE::skew(curvatureTensor).frobenius_norm2() - + b3_ * GFE::traceSquared(curvatureTensor)); - - strainEnergyDensity += mu_ * L_c_ * L_c_ * norm; - #else - #ifdef DONT_USE_CURL - auto argument = DR; - #else - auto argument = curl(DR); - #endif + // Compute the bending energy density + strainEnergyDensity = quadraticEnergy(U); - auto norm = (b1_ * GFE::dev(GFE::sym(argument)).frobenius_norm2() - + b2_ * GFE::skew(argument).frobenius_norm2() + b3_ * GFE::traceSquared(argument)); + // Compute the curvature energy density + field_type norm = 0; + + switch (curvatureType_) + { + case CurvatureType::Norm : + { + /* This is a simplified version of the curvature energy that appears in + * + * P. Neff: "A geometrically exact Cosserat shell-model including size effects, + * avoiding degeneracy in the thin shell limit. Part I: Formal dimensional reduction + * for elastic plates and existence of minimizers for positive Cosserat couple modulus" + * Continuum Mech. Thermodyn. (2004) 16: 577–628 + * DOI: 10.1007/s00161-004-0182-4 + * + * The curvature energy given there is much more complicated, but it + * does use the full norm of DR to define the curvature. + */ + norm = DR.frobenius_norm2(); + break; + } + case CurvatureType::Curl : + { + auto curvatureTensor = curl(DR); + + // The choice for the Frobenius norm here is b1=b2=1 and b3 = 1/3 + norm = (b1_ * GFE::dev(GFE::sym(curvatureTensor)).frobenius_norm2() + + b2_ * GFE::skew(curvatureTensor).frobenius_norm2() + + b3_ * GFE::traceSquared(curvatureTensor)); + break; + } + case CurvatureType::Wryness : + { + auto curvatureTensor = wryness(R,DR); + + // The choice for the Frobenius norm here is b1=b2=1 and b3 = 1/3 + norm = (b1_ * GFE::dev(GFE::sym(curvatureTensor)).frobenius_norm2() + + b2_ * GFE::skew(curvatureTensor).frobenius_norm2() + + b3_ * GFE::traceSquared(curvatureTensor)); + break; + } + } strainEnergyDensity += mu_ * std::pow(L_c_ * L_c_ * norm,q_/2.0); - #endif return strainEnergyDensity; } @@ -190,7 +225,11 @@ namespace Dune::GFE { // Construct a copy of this density but using 'adouble' as the number type virtual std::unique_ptr<LocalDensity<Position,ATargetSpace> > makeActiveDensity() const { - return std::make_unique<BulkCosseratDensity<Position,adouble> >(mu_, lambda_, mu_c_, L_c_, q_, std::array<double,3>{b1_, b2_, b3_}); + // curvatureType_ is a local enum type, and therefore its type changes + // together with the type of the surrounding class. + auto activeCurvatureType = static_cast<typename BulkCosseratDensity<Position,adouble>::CurvatureType>(curvatureType_); + + return std::make_unique<BulkCosseratDensity<Position,adouble> >(mu_, lambda_, mu_c_, L_c_, activeCurvatureType, q_, std::array<double,3>{b1_, b2_, b3_}); } /** \brief The density depends on the microrotation value, but not on the deformation @@ -216,6 +255,9 @@ namespace Dune::GFE { /** \brief Length scale parameter */ double L_c_; + /** \brief The precise way to compute the curvature tensor */ + enum CurvatureType curvatureType_; + /** \brief Curvature exponent */ double q_; diff --git a/test/cosseratcontinuumtest.cc b/test/cosseratcontinuumtest.cc index bcc99d9ac31295d44987116dd40799d425f5c210..f09fef8116d13bf166c06b892754ebc7bbd97164 100644 --- a/test/cosseratcontinuumtest.cc +++ b/test/cosseratcontinuumtest.cc @@ -188,6 +188,7 @@ int main (int argc, char *argv[]) parameters["lambda"] = "1"; parameters["mu_c"] = "1"; parameters["L_c"] = "0.1"; + parameters["curvatureType"] = "wryness"; parameters["q"] = "2"; parameters["b1"] = "1"; parameters["b2"] = "1"; diff --git a/test/localintegralstiffnesstest.cc b/test/localintegralstiffnesstest.cc index 57ca582cc8c6a61e8cd269bed1135989371a8e40..156c3d0d44c054a6a75689d0ae8489798c3d2cde 100644 --- a/test/localintegralstiffnesstest.cc +++ b/test/localintegralstiffnesstest.cc @@ -288,6 +288,7 @@ int testCosseratBulkModel(TestSuite& test, const GridView& gridView) parameters["lambda"] = "1"; parameters["mu_c"] = "1"; parameters["L_c"] = "0.1"; + parameters["curvatureType"] = "wryness"; parameters["q"] = "2"; parameters["kappa"] = "1"; parameters["b1"] = "1";