diff --git a/src/CabanaPD_ForceModels.hpp b/src/CabanaPD_ForceModels.hpp index a4b9c6d..a75b7e4 100644 --- a/src/CabanaPD_ForceModels.hpp +++ b/src/CabanaPD_ForceModels.hpp @@ -17,11 +17,11 @@ namespace CabanaPD { -template +template struct BaseForceModel; template <> -struct BaseForceModel<> +struct BaseForceModel { using species_type = SingleSpecies; double delta; @@ -38,14 +38,13 @@ struct BaseForceModel<> void thermalStretch( double&, const int, const int ) const {} }; -template +template struct BaseForceModel { using species_type = MultiSpecies; // Only allow one memory space. - using memory_space = - typename std::tuple_element<0, std::tuple>::type; + using memory_space = MemorySpace; using view_type_1d = Kokkos::View; view_type_1d delta; double max_delta; @@ -86,8 +85,11 @@ struct BaseForceModel void thermalStretch( double&, const int, const int ) const {} }; +template +struct BaseTemperatureModel; + template -struct BaseTemperatureModel +struct BaseTemperatureModel { using species_type = SingleSpecies; using memory_space = typename TemperatureType::memory_space; @@ -115,6 +117,53 @@ struct BaseTemperatureModel } }; +template +struct BaseTemperatureModel +{ + using species_type = MultiSpecies; + using memory_space = typename TemperatureType::memory_space; + using view_type_1d = Kokkos::View; + view_type_1d alpha; + view_type_1d temp0; + + // Particle fields + TemperatureType temperature; + ParticleType type; + + template + BaseTemperatureModel( const TemperatureType& _temp, const ArrayType _alpha, + const ArrayType _temp0, const ParticleType& _type ) + : alpha( view_type_1d( "delta", _alpha.size() ) ) + , temp0( view_type_1d( "delta", _temp0.size() ) ) + , temperature( _temp ) + , type( _type ) + { + auto init_func = KOKKOS_CLASS_LAMBDA( const int i ) + { + alpha( i ) = _alpha[i]; + temp0( i ) = _temp0[i]; + }; + using exec_space = typename memory_space::execution_space; + Kokkos::RangePolicy policy( 0, alpha.size() ); + Kokkos::parallel_for( "CabanaPD::Model::Init", policy, init_func ); + } + + void update( const TemperatureType& _temp, const ParticleType& _type ) + { + temperature = _temp; + type = _type; + } + + // Update stretch with temperature effects. + KOKKOS_INLINE_FUNCTION + void thermalStretch( double& s, const int i, const int j ) const + { + double temp_avg = + 0.5 * ( temperature( i ) + temperature( j ) ) - temp0( type( i ) ); + s -= alpha( type( i ) ) * temp_avg; + } +}; + template struct ForceModel; diff --git a/src/force/CabanaPD_ForceModels_LPS.hpp b/src/force/CabanaPD_ForceModels_LPS.hpp index 14bd9be..b42eb30 100644 --- a/src/force/CabanaPD_ForceModels_LPS.hpp +++ b/src/force/CabanaPD_ForceModels_LPS.hpp @@ -19,9 +19,9 @@ namespace CabanaPD { template <> -struct ForceModel : public BaseForceModel<> +struct ForceModel : public BaseForceModel { - using base_type = BaseForceModel<>; + using base_type = BaseForceModel; using species_type = SingleSpecies; using base_model = LPS; using fracture_type = Elastic; diff --git a/src/force/CabanaPD_ForceModels_PMB.hpp b/src/force/CabanaPD_ForceModels_PMB.hpp index dbb6fe0..55d189c 100644 --- a/src/force/CabanaPD_ForceModels_PMB.hpp +++ b/src/force/CabanaPD_ForceModels_PMB.hpp @@ -21,10 +21,10 @@ namespace CabanaPD template <> struct ForceModel - : public BaseForceModel<> + : public BaseForceModel { - using base_type = BaseForceModel<>; - using species_type = typename base_type::species_type; + using base_type = BaseForceModel; + using species_type = SingleSpecies; using base_model = PMB; using fracture_type = Elastic; using thermal_type = TemperatureIndependent; @@ -327,12 +327,13 @@ struct ForceModel template struct ForceModel : public ForceModel, - BaseTemperatureModel + BaseTemperatureModel { using memory_space = typename TemperatureType::memory_space; using base_type = ForceModel; using species_type = typename base_type::species_type; - using base_temperature_type = BaseTemperatureModel; + using base_temperature_type = + BaseTemperatureModel; using base_model = PMB; using fracture_type = Elastic; using thermal_type = TemperatureDependent; @@ -348,7 +349,6 @@ struct ForceModel // Explicitly use the temperature-dependent stretch. using base_temperature_type::thermalStretch; - // ForceModel(){}; ForceModel( const double _delta, const double _K, const TemperatureType _temp, const double _alpha, const double _temp0 = 0.0 ) @@ -358,6 +358,44 @@ struct ForceModel } }; +template +struct ForceModel + : public ForceModel, + BaseTemperatureModel +{ + using memory_space = typename TemperatureType::memory_space; + using base_type = + ForceModel; + using species_type = typename base_type::species_type; + using base_temperature_type = + BaseTemperatureModel; + using base_model = PMB; + using fracture_type = Elastic; + using thermal_type = TemperatureDependent; + + using base_type::c; + using base_type::delta; + using base_type::K; + using base_type::type; + + // Thermal parameters + using base_temperature_type::alpha; + using base_temperature_type::temp0; + + // Explicitly use the temperature-dependent stretch. + using base_temperature_type::thermalStretch; + + template + ForceModel( const ArrayType _delta, const ArrayType _K, + const TemperatureType& _temp, const ArrayType _alpha, + const ArrayType _temp0, ParticleType& _type ) + : base_type( _delta, _K, _type ) + , base_temperature_type( _temp, _alpha, _temp0 ) + { + } +}; + template auto createForceModel( PMB, Elastic, TemperatureDependent, ParticleType particles, const double delta, @@ -372,12 +410,13 @@ auto createForceModel( PMB, Elastic, TemperatureDependent, template struct ForceModel : public ForceModel, - BaseTemperatureModel + BaseTemperatureModel { using memory_space = typename TemperatureType::memory_space; using base_type = ForceModel; using species_type = typename base_type::species_type; - using base_temperature_type = BaseTemperatureModel; + using base_temperature_type = + BaseTemperatureModel; using base_model = typename base_type::base_model; using fracture_type = typename base_type::fracture_type; using thermal_type = TemperatureDependent; @@ -398,7 +437,6 @@ struct ForceModel // Explicitly use the temperature-dependent stretch. using base_temperature_type::thermalStretch; - // ForceModel(){}; ForceModel( const double _delta, const double _K, const double _G0, const TemperatureType _temp, const double _alpha, const double _temp0 = 0.0 ) @@ -418,6 +456,60 @@ struct ForceModel } }; +template +struct ForceModel + : public ForceModel, + BaseTemperatureModel +{ + using memory_space = typename TemperatureType::memory_space; + using base_type = + ForceModel; + using species_type = typename base_type::species_type; + using base_temperature_type = + BaseTemperatureModel; + using base_model = typename base_type::base_model; + using fracture_type = typename base_type::fracture_type; + using thermal_type = TemperatureDependent; + + using base_type::c; + using base_type::delta; + using base_type::K; + using base_type::type; + + // Does not use the base bond_break_coeff. + using base_type::G0; + using base_type::s0; + + // Thermal parameters + using base_temperature_type::alpha; + using base_temperature_type::temp0; + using base_temperature_type::temperature; + + // Explicitly use the temperature-dependent stretch. + using base_temperature_type::thermalStretch; + + template + ForceModel( const ArrayType _delta, const ArrayType _K, const ArrayType _G0, + const TemperatureType _temp, const ArrayType _alpha, + const ArrayType _temp0, ParticleType& _type ) + : base_type( _delta, _K, _G0, _type ) + , base_temperature_type( _temp, _alpha, _temp0 ) + { + } + + KOKKOS_INLINE_FUNCTION + bool criticalStretch( const int i, const int j, const double r, + const double xi ) const + { + double temp_avg = + 0.5 * ( temperature( i ) + temperature( j ) ) - temp0( type( i ) ); + double bond_break_coeff = ( 1.0 + s0 + alpha( type( i ) ) * temp_avg ) * + ( 1.0 + s0 + alpha( type( i ) ) * temp_avg ); + return r * r >= bond_break_coeff * xi * xi; + } +}; + template auto createForceModel( PMB, Fracture, ParticleType particles, const double delta, const double K, const double G0,