From a1a0f64fd8d0ff2a5bad4792756badb4cf361f3a Mon Sep 17 00:00:00 2001 From: Nathan Miller Date: Tue, 8 Oct 2024 12:13:54 -0600 Subject: [PATCH] FEAT: Added scale factor to the driving values --- docs/sphinx/changelog.rst | 2 + src/cpp/tardigrade_hydra.cpp | 3 + src/cpp/tardigrade_hydra.h | 53 +++- src/cpp/tardigrade_hydraMicromorphic.cpp | 2 + src/cpp/tardigrade_hydraMicromorphic.h | 25 +- src/cpp/tests/test_tardigrade_hydra.cpp | 247 +++++++++++++++++- .../test_tardigrade_hydraMicromorphic.cpp | 247 ++++++++++++++++++ 7 files changed, 567 insertions(+), 12 deletions(-) diff --git a/docs/sphinx/changelog.rst b/docs/sphinx/changelog.rst index fd3eb6a..5e19dbc 100644 --- a/docs/sphinx/changelog.rst +++ b/docs/sphinx/changelog.rst @@ -18,6 +18,8 @@ New Features - Added softened cohesion function (:pull:`169`). By `Nathan Miller`_. - Added the minimum cohesion and softening ratio as optional parameters to the micromorphic Drucker-Prager plasticity (:pull:`171`). By `Nathan Miller`_. - Added a relaxed solver as the default (:pull:`172`). By `Nathan Miller`_. +- Added ability to turn on additional messages for failed solves (:pull:`177`). By `Nathan Miller`_. +- Added the ability to scale the incoming load information by a scale factor (:pull:`178`). By `Nathan Miller`_. Internal Changes ================ diff --git a/src/cpp/tardigrade_hydra.cpp b/src/cpp/tardigrade_hydra.cpp index f5cbed8..ff69589 100644 --- a/src/cpp/tardigrade_hydra.cpp +++ b/src/cpp/tardigrade_hydra.cpp @@ -85,6 +85,9 @@ namespace tardigradeHydra{ * 0. A diagonal pre-conditioner populate by the inverse of the absolute largest entries of the Jacobian's rows */ + // Initialize the scaled-quantities + setScaledQuantities( ); + // Decompose the state variable vector initializing all of the configurations decomposeStateVariableVector( ); diff --git a/src/cpp/tardigrade_hydra.h b/src/cpp/tardigrade_hydra.h index 802aa87..db289e3 100644 --- a/src/cpp/tardigrade_hydra.h +++ b/src/cpp/tardigrade_hydra.h @@ -1081,25 +1081,25 @@ namespace tardigradeHydra{ const unsigned int* getConfigurationUnknownCount( ){ return &_configuration_unknown_count; } //! Get a reference to the current time - const floatType* getTime( ){ return &_time; } + const floatType* getTime( ){ return getScaledTime( ); } //! Get a reference to the change in time - const floatType* getDeltaTime( ){ return &_deltaTime; } + const floatType* getDeltaTime( ){ return getScaledDeltaTime( ); } //! Get a reference to the current temperature - const floatType* getTemperature( ){ return &_temperature; }; + const floatType* getTemperature( ){ return getScaledTemperature( ); }; //! Get a reference to the previous temperature const floatType* getPreviousTemperature( ){ return &_previousTemperature; }; //! Get a reference to the deformation gradient - const secondOrderTensor* getDeformationGradient( ){ return &_deformationGradient; } + const secondOrderTensor* getDeformationGradient( ){ return getScaledDeformationGradient( ); } //! Get a reference to the previous deformation gradient const secondOrderTensor* getPreviousDeformationGradient( ){ return &_previousDeformationGradient; } //! Get a reference to the additional degrees of freedom - const floatVector* getAdditionalDOF( ){ return &_additionalDOF; } + const floatVector* getAdditionalDOF( ){ return getScaledAdditionalDOF( ); } //! Get a reference to the previous additional degrees of freedom const floatVector* getPreviousAdditionalDOF( ){ return &_previousAdditionalDOF; } @@ -1491,6 +1491,22 @@ namespace tardigradeHydra{ //! Get the failure output string const std::string getFailureOutput( ){ return _failure_output.str( ); } + //! Get a scale factor for the deformation + const floatType *getScaleFactor( ){ return &_scale_factor; } + + //! Set the value of the scale factor. Will automatically re-calculate the deformation + const void setScaleFactor( const floatType &value ){ _scale_factor = value; setScaledQuantities( ); updateUnknownVector( *getUnknownVector( ) ); } + + const floatType *getScaledTime( ){ return &_scaled_time; } + + const floatType *getScaledDeltaTime( ){ return &_scaled_deltaTime; } + + const floatType *getScaledTemperature( ){ return &_scaled_temperature; } + + const floatVector *getScaledDeformationGradient( ){ return &_scaled_deformationGradient; } + + const floatVector *getScaledAdditionalDOF( ){ return &_scaled_additionalDOF; } + protected: // Setters that the user may need to access but not override @@ -1536,6 +1552,21 @@ namespace tardigradeHydra{ virtual void performGradientStep( const floatVector &X0 ); + //! Update the scaled quantities + virtual void setScaledQuantities( ){ + + _scaled_time = ( _scale_factor - 1 ) * _deltaTime + _time; + + _scaled_deltaTime = _scale_factor * _deltaTime; + + _scaled_temperature = _scale_factor * ( _temperature - _previousTemperature ) + _previousTemperature; + + _scaled_deformationGradient = _scale_factor * ( _deformationGradient - _previousDeformationGradient ) + _previousDeformationGradient; + + _scaled_additionalDOF = _scale_factor * ( _additionalDOF - _previousAdditionalDOF ) + _previousAdditionalDOF; + + } + const floatType *get_baseResidualNorm( ); const floatVector *get_basedResidualNormdX( ); @@ -1765,6 +1796,16 @@ namespace tardigradeHydra{ floatVector _parameters; //!< The model parameters + floatType _scaled_time; //!< The current time scaled by the scaling factor + + floatType _scaled_deltaTime; //!< The change in time scaled by the scaling factor + + floatType _scaled_temperature; //!< The current temperature scaled by the scaling factor + + secondOrderTensor _scaled_deformationGradient; //!< The current deformation gradient scaled by the scaling factor + + floatVector _scaled_additionalDOF; //!< The current additional degrees of freedom scaled by the scaling factor + unsigned int _numConfigurations; //!< The number of configurations unsigned int _numNonLinearSolveStateVariables; //!< The number of state variables which will be solved in the Newton-Raphson loop @@ -1905,6 +1946,8 @@ namespace tardigradeHydra{ std::stringstream _failure_output; //!< Additional failure output information + floatType _scale_factor = 1.0; //!< A scale factor applied to the incoming loading (deformation, temperature, etc.) + TARDIGRADE_HYDRA_DECLARE_ITERATION_STORAGE( private, configurations, floatVector, passThrough ) TARDIGRADE_HYDRA_DECLARE_PREVIOUS_STORAGE( private, previousConfigurations, floatVector, passThrough ) diff --git a/src/cpp/tardigrade_hydraMicromorphic.cpp b/src/cpp/tardigrade_hydraMicromorphic.cpp index 69fabe2..ab60800 100644 --- a/src/cpp/tardigrade_hydraMicromorphic.cpp +++ b/src/cpp/tardigrade_hydraMicromorphic.cpp @@ -57,6 +57,8 @@ namespace tardigradeHydra{ * \param &lsAlpha: The alpha term for the line search (defaults to 1e-4) */ + setScaledQuantities( ); + decomposeStateVariableVectorMicroConfigurations( ); } diff --git a/src/cpp/tardigrade_hydraMicromorphic.h b/src/cpp/tardigrade_hydraMicromorphic.h index 04e110d..aec0c53 100644 --- a/src/cpp/tardigrade_hydraMicromorphic.h +++ b/src/cpp/tardigrade_hydraMicromorphic.h @@ -39,13 +39,13 @@ namespace tardigradeHydra{ const bool use_preconditioner=false, const unsigned int preconditioner_type=0 ); //! Get the current micro-deformation tensor - const secondOrderTensor *getMicroDeformation( ){ return &_microDeformation; } + const secondOrderTensor *getMicroDeformation( ){ return getScaledMicroDeformation( ); } //! Get the previous micro-deformation tensor const secondOrderTensor *getPreviousMicroDeformation( ){ return &_previousMicroDeformation; } //! Get the current spatial gradient w.r.t. the reference configuration of the micro-deformation tensor - const thirdOrderTensor *getGradientMicroDeformation( ){ return &_gradientMicroDeformation; } + const thirdOrderTensor *getGradientMicroDeformation( ){ return getScaledGradientMicroDeformation( ); } //! Get the previous spatial gradient w.r.t. the reference configuration of the micro-deformation tensor const thirdOrderTensor *getPreviousGradientMicroDeformation( ){ return &_previousGradientMicroDeformation; } @@ -78,6 +78,10 @@ namespace tardigradeHydra{ floatVector getPreviousFollowingMicroConfigurationJacobian( const unsigned int &index ); + const secondOrderTensor *getScaledMicroDeformation( ){ return &_scaled_microDeformation; } + + const thirdOrderTensor *getScaledGradientMicroDeformation( ){ return &_scaled_gradientMicroDeformation; } + const floatVector *getFlatdXdD( ){ /*! * Get the total derivative of the unknown vector w.r.t. the deformation. @@ -101,6 +105,19 @@ namespace tardigradeHydra{ virtual void decomposeStateVariableVectorMicroConfigurations( ); + virtual void setScaledQuantities( ) override{ + /*! + * Scale the current values by the scale factor + */ + + hydraBase::hydraBase::setScaledQuantities( ); + + _scaled_microDeformation = ( *getScaleFactor( ) ) * ( _microDeformation - _previousMicroDeformation ) + _previousMicroDeformation; + + _scaled_gradientMicroDeformation = ( *getScaleFactor( ) ) * ( _gradientMicroDeformation - _previousGradientMicroDeformation ) + _previousGradientMicroDeformation; + + } + private: secondOrderTensor _microDeformation; //!< The current micro-deformation @@ -111,6 +128,10 @@ namespace tardigradeHydra{ thirdOrderTensor _previousGradientMicroDeformation; //!< The previous spatial gradient of the micro-deformation w.r.t. the reference coordinates + secondOrderTensor _scaled_microDeformation; //!< The current micro-deformation scaled by the scale factor + + thirdOrderTensor _scaled_gradientMicroDeformation; //!< The spatial gradient of the micro-deformation w.r.t. the reference coordinates scaled by the scale factor + void setFirstMicroConfigurationJacobians( ); void setPreviousFirstMicroConfigurationJacobians( ); diff --git a/src/cpp/tests/test_tardigrade_hydra.cpp b/src/cpp/tests/test_tardigrade_hydra.cpp index 17672af..bd1a00f 100644 --- a/src/cpp/tests/test_tardigrade_hydra.cpp +++ b/src/cpp/tests/test_tardigrade_hydra.cpp @@ -46,19 +46,19 @@ namespace tardigradeHydra{ static void checkTime( hydraBase &hydra ){ - BOOST_CHECK( &hydra._time == hydra.getTime( ) ); + BOOST_CHECK( &hydra._scaled_time == hydra.getScaledTime( ) ); } static void checkDeltaTime( hydraBase &hydra ){ - BOOST_CHECK( &hydra._deltaTime == hydra.getDeltaTime( ) ); + BOOST_CHECK( &hydra._scaled_deltaTime == hydra.getScaledDeltaTime( ) ); } static void checkTemperature( hydraBase &hydra ){ - BOOST_CHECK( &hydra._temperature == hydra.getTemperature( ) ); + BOOST_CHECK( &hydra._scaled_temperature == hydra.getScaledTemperature( ) ); } @@ -70,7 +70,7 @@ namespace tardigradeHydra{ static void checkDeformationGradient( hydraBase &hydra ){ - BOOST_CHECK( &hydra._deformationGradient == hydra.getDeformationGradient( ) ); + BOOST_CHECK( &hydra._scaled_deformationGradient == hydra.getScaledDeformationGradient( ) ); } @@ -82,7 +82,7 @@ namespace tardigradeHydra{ static void checkAdditionalDOF( hydraBase &hydra ){ - BOOST_CHECK( &hydra._additionalDOF == hydra.getAdditionalDOF( ) ); + BOOST_CHECK( &hydra._scaled_additionalDOF == hydra.getScaledAdditionalDOF( ) ); } @@ -1108,6 +1108,243 @@ BOOST_AUTO_TEST_CASE( test_hydraBase_decomposeStateVariableVector, * boost::unit } +BOOST_AUTO_TEST_CASE( test_hydraBase_decomposeStateVariableVector2, * boost::unit_test::tolerance( DEFAULT_TEST_TOLERANCE ) ){ + + class residualBaseMock : public tardigradeHydra::residualBase{ + + using tardigradeHydra::residualBase::residualBase; + + }; + + class residualBaseMockStress : public tardigradeHydra::residualBase{ + + using tardigradeHydra::residualBase::residualBase; + + using tardigradeHydra::residualBase::setStress; + + floatVector cauchyStress = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + virtual void setStress( ) override{ + + setStress( cauchyStress ); + + } + + }; + + class hydraBaseMock : public tardigradeHydra::hydraBase{ + + public: + + residualBaseMockStress r1; + + residualBaseMock r2; + + residualBaseMock r3; + + unsigned int s1 = 36; + + unsigned int s2 = 2; + + unsigned int s3 = 3; + + using tardigradeHydra::hydraBase::hydraBase; + + using tardigradeHydra::hydraBase::setResidualClasses; + + virtual void setResidualClasses( ){ + + r1 = residualBaseMockStress( this, s1 ); + + r2 = residualBaseMock( this, s2 ); + + r3 = residualBaseMock( this, s3 ); + + std::vector< tardigradeHydra::residualBase* > residuals( 3 ); + + residuals[ 0 ] = &r1; + + residuals[ 1 ] = &r2; + + residuals[ 2 ] = &r3; + + setResidualClasses( residuals ); + + } + + }; + + floatType time = 1.1; + + floatType deltaTime = 2.2; + + floatType temperature = 5.3; + + floatType previousTemperature = 23.4; + + floatVector deformationGradient = { 0.39293837, -0.42772133, -0.54629709, + 0.10262954, 0.43893794, -0.15378708, + 0.9615284 , 0.36965948, -0.0381362 }; + + floatVector previousDeformationGradient = { -0.21576496, -0.31364397, 0.45809941, + -0.12285551, -0.88064421, -0.20391149, + 0.47599081, -0.63501654, -0.64909649 }; + + floatVector previousStateVariables = { 0.53155137, 0.53182759, 0.63440096, 0.84943179, 0.72445532, + 0.61102351, 0.72244338, 0.32295891, 0.36178866, 0.22826323, + 0.29371405, 0.63097612, 0.09210494, 0.43370117, 0.43086276, + 0.4936851 , 0.42583029, 0.31226122, 0.42635131, 0.89338916, + 0.94416002, 0.50183668, 0.62395295, 0.1156184 , 0.31728548, + 0.41482621, 0.86630916, 0.25045537, 0.48303426, 0.98555979, + 0.51948512, 0.61289453, 0.12062867, 0.8263408 , 0.60306013, + 0.54506801, 0.34276383, 0.30412079 }; + + floatMatrix configurationsAnswer = { + { 1.05936416, -0.30634264, -0.86204928, + 0.03274674, 0.17917379, -0.22403642, + 1.24895144, -0.21368066, -1.05360316 }, + { 1.53155137, 0.53182759, 0.63440096, + 0.84943179, 1.72445532, 0.61102351, + 0.72244338, 0.32295891, 1.36178866 }, + { 1.22826323, 0.29371405, 0.63097612, + 0.09210494, 1.43370117, 0.43086276, + 0.4936851 , 0.42583029, 1.31226122 }, + { 1.42635131, 0.89338916, 0.94416002, + 0.50183668, 1.62395295, 0.1156184 , + 0.31728548, 0.41482621, 1.86630916 } + }; + + floatMatrix previousConfigurationsAnswer = { + { -0.41803693, -0.10444357, 0.58891991, + 0.33131016, -0.34276201, -0.04604603, + 1.32949612, -0.42712653, -1.03631144 }, + { 1.53155137, 0.53182759, 0.63440096, + 0.84943179, 1.72445532, 0.61102351, + 0.72244338, 0.32295891, 1.36178866 }, + { 1.22826323, 0.29371405, 0.63097612, + 0.09210494, 1.43370117, 0.43086276, + 0.4936851 , 0.42583029, 1.31226122 }, + { 1.42635131, 0.89338916, 0.94416002, + 0.50183668, 1.62395295, 0.1156184 , + 0.31728548, 0.41482621, 1.86630916 } + }; + + floatType scale_factor = 0.68; + + floatMatrix inverseConfigurationsAnswer( 4 ); + + floatMatrix previousInverseConfigurationsAnswer( 4 ); + + for ( unsigned int i = 0; i < 4; i++ ){ + + Eigen::Map< const Eigen::Matrix< floatType, 3, 3, Eigen::RowMajor > > map_configuration( configurationsAnswer[ i ].data( ), 3, 3 ); + + inverseConfigurationsAnswer[ i ] = floatVector( 9, 0 ); + Eigen::Map< Eigen::Matrix< floatType, 3, 3, Eigen::RowMajor > > map_inverseConfiguration( inverseConfigurationsAnswer[ i ].data( ), 3, 3 ); + + map_inverseConfiguration = map_configuration.inverse( ).eval( ); + + Eigen::Map< const Eigen::Matrix< floatType, 3, 3, Eigen::RowMajor > > map_previousConfiguration( previousConfigurationsAnswer[ i ].data( ), 3, 3 ); + + previousInverseConfigurationsAnswer[ i ] = floatVector( 9, 0 ); + Eigen::Map< Eigen::Matrix< floatType, 3, 3, Eigen::RowMajor > > map_previousInverseConfiguration( previousInverseConfigurationsAnswer[ i ].data( ), 3, 3 ); + + map_previousInverseConfiguration = map_previousConfiguration.inverse( ).eval( ); + + } + + floatVector nonLinearSolveStateVariablesAnswer = { 0.25045537, 0.48303426, 0.98555979, + 0.51948512, 0.61289453 }; + + floatVector previousNonLinearSolveStateVariablesAnswer = { 0.25045537, 0.48303426, 0.98555979, + 0.51948512, 0.61289453 }; + + floatVector additionalStateVariablesAnswer = { 0.12062867, 0.8263408 , 0.60306013, + 0.54506801, 0.34276383, 0.30412079 }; + + floatVector additionalDOF = { }; + + floatVector previousAdditionalDOF = { }; + + floatVector previousAdditionalStateVariablesAnswer = { 0.12062867, 0.8263408 , 0.60306013, + 0.54506801, 0.34276383, 0.30412079 }; + + floatVector parameters = { 1, 2, 3, 4, 5 }; + + unsigned int numConfigurations = 4; + + unsigned int numNonLinearSolveStateVariables = 5; + + unsigned int dimension = 3; + + hydraBaseMock hydra( time, deltaTime, temperature, previousTemperature, deformationGradient, previousDeformationGradient, + additionalDOF, previousAdditionalDOF, + previousStateVariables, parameters, numConfigurations, numNonLinearSolveStateVariables, dimension ); + + tardigradeHydra::unit_test::hydraBaseTester::decomposeStateVariableVector( hydra ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( configurationsAnswer ) == *hydra.get_configurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousConfigurationsAnswer ) == *hydra.get_previousConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( inverseConfigurationsAnswer ) == *hydra.get_inverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousInverseConfigurationsAnswer ) == *hydra.get_previousInverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( nonLinearSolveStateVariablesAnswer == *hydra.get_nonLinearSolveStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousNonLinearSolveStateVariablesAnswer == *hydra.get_previousNonLinearSolveStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( additionalStateVariablesAnswer == *hydra.get_additionalStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousAdditionalStateVariablesAnswer == *hydra.get_previousAdditionalStateVariables( ), CHECK_PER_ELEMENT ); + + hydra.setScaleFactor( scale_factor ); + + configurationsAnswer[ 0 ] = { 0.58659581, -0.24173494, -0.39773914, + 0.12828703, 0.01215433, -0.1670795 , + 1.27472574, -0.28198334, -1.04806981 }, + + inverseConfigurationsAnswer[ 0 ] = { -13.52872661, -31.91604776, 10.22204935, + -17.74983625, -24.36324336, 10.61990622, + -11.67885744, -32.26328862, 8.6212508 }; + + additionalStateVariablesAnswer = { }; //Goes away because of the reset + + floatType scaled_time = ( scale_factor - 1) * deltaTime + time; + + floatType scaled_deltaTime = scale_factor * deltaTime; + + floatType scaled_temperature = scale_factor * ( temperature - previousTemperature ) + previousTemperature; + + floatVector scaled_deformationGradient = scale_factor * ( deformationGradient - previousDeformationGradient ) + previousDeformationGradient; + + BOOST_TEST( tardigradeVectorTools::appendVectors( configurationsAnswer ) == *hydra.get_configurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousConfigurationsAnswer ) == *hydra.get_previousConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( inverseConfigurationsAnswer ) == *hydra.get_inverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousInverseConfigurationsAnswer ) == *hydra.get_previousInverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( nonLinearSolveStateVariablesAnswer == *hydra.get_nonLinearSolveStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousNonLinearSolveStateVariablesAnswer == *hydra.get_previousNonLinearSolveStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( additionalStateVariablesAnswer == *hydra.get_additionalStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousAdditionalStateVariablesAnswer == *hydra.get_previousAdditionalStateVariables( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( scaled_time == *hydra.getTime( ) ); + + BOOST_TEST( scaled_deltaTime == *hydra.getDeltaTime( ) ); + + BOOST_TEST( scaled_temperature == *hydra.getTemperature( ) ); + + BOOST_TEST( scaled_deformationGradient == *hydra.getDeformationGradient( ) ); + +} + BOOST_AUTO_TEST_CASE( test_hydraBase_getSubConfiguration, * boost::unit_test::tolerance( DEFAULT_TEST_TOLERANCE ) ){ floatType time = 1.1; diff --git a/src/cpp/tests/test_tardigrade_hydraMicromorphic.cpp b/src/cpp/tests/test_tardigrade_hydraMicromorphic.cpp index f9f0615..5de1868 100644 --- a/src/cpp/tests/test_tardigrade_hydraMicromorphic.cpp +++ b/src/cpp/tests/test_tardigrade_hydraMicromorphic.cpp @@ -225,6 +225,253 @@ BOOST_AUTO_TEST_CASE( test_tardigrade_hydraBaseMicromorphic_constructor, * boost } +BOOST_AUTO_TEST_CASE( test_tardigrade_hydraBaseMicromorphic_constructor2, * boost::unit_test::tolerance( DEFAULT_TEST_TOLERANCE ) ){ + + floatType time = 1.23; + + floatType deltaTime = 2.34; + + floatType temperature = 3.45; + + floatType previousTemperature = 4.56; + + floatVector deformationGradient = { 1, 2, 2, 4, 5, 6, 7, 8, 9 }; + + floatVector previousDeformationGradient = { 10, 11, 12, 13, 14, 15, 16, 16, 18 }; + + floatVector microDeformation = { 18, 20, 21, 22, 23, 24, 25, 26, 27 }; + + floatVector previousMicroDeformation = { 28, 29, 30, 31, 32, 33, 34, 35, 33 }; + + floatVector gradientMicroDeformation = { 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62 }; + + floatVector previousGradientMicroDeformation = { 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89 }; + + floatVector previousStateVariables = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, + -0.01, -0.02, -0.03, -0.04, -0.05, -0.06, -0.07, -0.08, -0.09, + 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00, + 10.00, 11.00, 12.00, 13.00, 14.00, 15.00, 16.00, 17.00, 18.00, + 19.00, 20.00, 21.00, 22.00, 23.00, 24.00, 25.00, 26.00, 27.00, + -1.00, -2.00, -3.00, -4.00, -5.00, -6.00 }; + + floatMatrix configurationsAnswer = { { 0.80151542, 1.75875283, 1.71599025, 3.43145793, 4.30238634, 5.17331475, 6.12262672, 6.91517157, 7.70771643 }, + { 1.01, 0.02, 0.03, 0.04, 1.05, 0.06, 0.07, 0.08, 1.09 } }; + + floatMatrix previousConfigurationsAnswer = { { 8.81379551, 9.5279568 , 10.2421181 , 11.50496429, 12.14074203, 12.77651977, 14.23044766, 13.79655112, 15.36265459 }, + { 1.01, 0.02, 0.03, 0.04, 1.05, 0.06, 0.07, 0.08, 1.09 } }; + + floatMatrix inverseConfigurationsAnswer = { { -1. , -0.64666667, 0.65666667, 2. , -1.65666667, 0.66666667, -1. , 2. , -0.99 }, + { 0.99259711, -0.01689601, -0.02638913, -0.03431458, 0.95697614, -0.05173315, -0.06122627, -0.06915172, 0.92292284 } }; + + floatMatrix previousInverseConfigurationsAnswer = { { -1.96 , 0.97 , 0.5 , -0.97 , 1.98 , -1. , 2.68666667, -2.67666667, 0.5 }, + { 0.99259711, -0.01689601, -0.02638913, -0.03431458, 0.95697614, -0.05173315, -0.06122627, -0.06915172, 0.92292284 } }; + + floatMatrix microConfigurationsAnswer = { { 20.92702193, 23.6257958 , 25.32456968, 25.37137468, 27.1869842 , 29.00259373, 28.8021693 , 30.72388588, 32.64560245 }, + { 0.99, -0.02, -0.03, -0.04, 0.95, -0.06, -0.07, -0.08, 0.91 } }; + + floatMatrix inverseMicroConfigurationsAnswer = { { -1. , 1.92 , -0.93 , 2. , -13.07 , 10.06 , -1. , 10.60666667, -8.61666667 }, + { 1.01355812, 0.02428672, 0.03501533, 0.04786607, 1.05965574, 0.07144541, 0.08217402, 0.09502476, 1.1078755 } }; + + floatMatrix previousMicroConfigurationsAnswer = { { 32.23296392, 34.26078755, 36.28861118, 35.66375855, 37.79768922, 39.9316199 , 38.84803112, 41.04951662, 40.25100212 }, + { 0.99, -0.02, -0.03, -0.04, 0.95, -0.06, -0.07, -0.08, 0.91 } }; + + floatMatrix previousInverseMicroConfigurationsAnswer = { { -11.1 , 10.42333333, -0.33333333, 10.91 , -10.58666667, 0.66666667, -0.41333333, 0.73666667, -0.33333333 }, + { 1.01355812, 0.02428672, 0.03501533, 0.04786607, 1.05965574, 0.07144541, 0.08217402, 0.09502476, 1.1078755 } }; + + floatVector parameters = { 0.1, 0.2, 0.3, 0.4 }; + + unsigned int numConfigurations = 2; + + unsigned int numNonLinearSolveStateVariables = 6; + + unsigned int dimension = 3; + + unsigned int configuration_unknown_count = 45; + + floatType tolr = 1e-2; + + floatType tola = 1e-3; + + unsigned int maxIterations = 24; + + unsigned int maxLSIterations = 45; + + floatType lsAlpha = 2.3; + + class residualBaseMock : public tardigradeHydra::residualBase{ + + using tardigradeHydra::residualBase::residualBase; + + }; + + class residualBaseMockStress : public tardigradeHydra::residualBase{ + + using tardigradeHydra::residualBase::residualBase; + + using tardigradeHydra::residualBase::setStress; + + floatVector stress = { 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45 }; + + virtual void setStress( ) override{ + + setStress( stress ); + + } + + }; + + class hydraBaseMicromorphicMock : public tardigradeHydra::hydraBaseMicromorphic{ + + public: + + unsigned int ndecomp = 0; + + unsigned int nsrc = 0; + + residualBaseMockStress r1; + + residualBaseMock r2; + + unsigned int s1 = 45; + + unsigned int s2 = 51; + + using tardigradeHydra::hydraBaseMicromorphic::hydraBaseMicromorphic; + + using tardigradeHydra::hydraBase::setResidualClasses; + + virtual void setResidualClasses( ){ + + r1 = residualBaseMockStress( this, s1 ); + + r2 = residualBaseMock( this, s2 ); + + std::vector< tardigradeHydra::residualBase* > residuals( 2 ); + + residuals[ 0 ] = &r1; + + residuals[ 1 ] = &r2; + + setResidualClasses( residuals ); + + } + + }; + + hydraBaseMicromorphicMock hydra( time, deltaTime, temperature, previousTemperature, deformationGradient, previousDeformationGradient, + microDeformation, previousMicroDeformation, gradientMicroDeformation, previousGradientMicroDeformation, + { }, { }, + previousStateVariables, parameters, + numConfigurations, numNonLinearSolveStateVariables, + dimension, configuration_unknown_count, + tolr, tola, maxIterations, maxLSIterations, lsAlpha ); + + BOOST_TEST( time == *hydra.getTime( ) ); + + BOOST_TEST( deltaTime == *hydra.getDeltaTime( ) ); + + BOOST_TEST( temperature == *hydra.getTemperature( ) ); + + BOOST_TEST( previousTemperature == *hydra.getPreviousTemperature( ) ); + + BOOST_TEST( deformationGradient == *hydra.getDeformationGradient( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousDeformationGradient == *hydra.getPreviousDeformationGradient( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( microDeformation == *hydra.getMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousMicroDeformation == *hydra.getPreviousMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( gradientMicroDeformation == *hydra.getGradientMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousGradientMicroDeformation == *hydra.getPreviousGradientMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( configurationsAnswer ) == *hydra.get_configurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousConfigurationsAnswer ) == *hydra.get_previousConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( inverseConfigurationsAnswer ) == *hydra.get_inverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousInverseConfigurationsAnswer ) == *hydra.get_previousInverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( microConfigurationsAnswer ) == *hydra.get_microConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousMicroConfigurationsAnswer ) == *hydra.get_previousMicroConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( inverseMicroConfigurationsAnswer ) == *hydra.get_inverseMicroConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousInverseMicroConfigurationsAnswer ) == *hydra.get_previousInverseMicroConfigurations( ), CHECK_PER_ELEMENT ); + + floatType scale_factor = 0.68; + + hydra.setScaleFactor( scale_factor ); + + floatType scaled_time = ( scale_factor - 1 ) * deltaTime + time; + + floatType scaled_deltaTime = scale_factor * deltaTime; + + floatType scaled_temperature = scale_factor * ( temperature - previousTemperature ) + previousTemperature; + + floatVector scaled_deformationGradient = scale_factor * ( deformationGradient - previousDeformationGradient ) + previousDeformationGradient; + + floatVector scaled_microDeformation = scale_factor * ( microDeformation - previousMicroDeformation ) + previousMicroDeformation; + + floatVector scaled_gradientMicroDeformation = scale_factor * ( gradientMicroDeformation - previousGradientMicroDeformation ) + previousGradientMicroDeformation; + + configurationsAnswer[ 0 ] = { 3.36544504, 4.2448981 , 4.44435116, 6.01497997, 6.81066016, 7.60634036, 8.71712942, 9.11721303, 10.15729664 }; + + inverseConfigurationsAnswer[ 0 ] = { -0.12122531, -1.8436894 , 1.4336981 , 3.69897495, -3.23648435, 0.80516088, -3.21617129, 4.48735505, -1.854682 }; + + microConfigurationsAnswer[ 0 ] = { 24.54492337, 27.02899316, 28.83306296, 28.66493751, 30.58240981, 32.4998821 , 32.01684508, 34.02808772, 35.07933035 }; + + inverseMicroConfigurationsAnswer[ 0 ] = { -1.2869465 , 1.28214968, -0.13007957, 1.36076467, -2.41554301, 1.11945836, -0.14539197, 1.1729392 , -0.93868068 }; + + BOOST_TEST( scaled_time == *hydra.getTime( ) ); + + BOOST_TEST( scaled_deltaTime == *hydra.getDeltaTime( ) ); + + BOOST_TEST( scaled_temperature == *hydra.getTemperature( ) ); + + BOOST_TEST( previousTemperature == *hydra.getPreviousTemperature( ) ); + + BOOST_TEST( scaled_deformationGradient == *hydra.getDeformationGradient( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousDeformationGradient == *hydra.getPreviousDeformationGradient( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( scaled_microDeformation == *hydra.getMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousMicroDeformation == *hydra.getPreviousMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( scaled_gradientMicroDeformation == *hydra.getGradientMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( previousGradientMicroDeformation == *hydra.getPreviousGradientMicroDeformation( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( configurationsAnswer ) == *hydra.get_configurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousConfigurationsAnswer ) == *hydra.get_previousConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( inverseConfigurationsAnswer ) == *hydra.get_inverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousInverseConfigurationsAnswer ) == *hydra.get_previousInverseConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( microConfigurationsAnswer ) == *hydra.get_microConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousMicroConfigurationsAnswer ) == *hydra.get_previousMicroConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( inverseMicroConfigurationsAnswer ) == *hydra.get_inverseMicroConfigurations( ), CHECK_PER_ELEMENT ); + + BOOST_TEST( tardigradeVectorTools::appendVectors( previousInverseMicroConfigurationsAnswer ) == *hydra.get_previousInverseMicroConfigurations( ), CHECK_PER_ELEMENT ); + +} + BOOST_AUTO_TEST_CASE( test_tardigrade_hydraBaseMicromorphic_getSubMicroConfiguration, * boost::unit_test::tolerance( DEFAULT_TEST_TOLERANCE ) ){ floatType time = 1.23;