diff --git a/inputFiles/constitutiveDriver/friction/frictionDriver_Coulomb.xml b/inputFiles/constitutiveDriver/friction/frictionDriver_Coulomb.xml new file mode 100644 index 00000000000..6fd8f7907a2 --- /dev/null +++ b/inputFiles/constitutiveDriver/friction/frictionDriver_Coulomb.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/inputFiles/constitutiveDriver/friction/frictionDriver_base.xml b/inputFiles/constitutiveDriver/friction/frictionDriver_base.xml new file mode 100644 index 00000000000..bf4b23983db --- /dev/null +++ b/inputFiles/constitutiveDriver/friction/frictionDriver_base.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/constitutiveDriver/friction/tables/jumps.geos b/inputFiles/constitutiveDriver/friction/tables/jumps.geos new file mode 100644 index 00000000000..3c922732f7a --- /dev/null +++ b/inputFiles/constitutiveDriver/friction/tables/jumps.geos @@ -0,0 +1,6 @@ +0 +1e-3 +2e-3 +3e-3 +4e-3 +5e-3 diff --git a/inputFiles/constitutiveDriver/friction/tables/time.geos b/inputFiles/constitutiveDriver/friction/tables/time.geos new file mode 100644 index 00000000000..e8371f00609 --- /dev/null +++ b/inputFiles/constitutiveDriver/friction/tables/time.geos @@ -0,0 +1,6 @@ +0 +1 +2 +3 +4 +5 diff --git a/inputFiles/constitutiveDriver/friction/tables/tractions.geos b/inputFiles/constitutiveDriver/friction/tables/tractions.geos new file mode 100644 index 00000000000..c80b1f6d1bd --- /dev/null +++ b/inputFiles/constitutiveDriver/friction/tables/tractions.geos @@ -0,0 +1,6 @@ +0 +1e6 +2e6 +3e6 +4e6 +5e6 diff --git a/src/coreComponents/constitutive/contact/CoulombFriction.hpp b/src/coreComponents/constitutive/contact/CoulombFriction.hpp index e5a3387743d..5bf8057fef6 100644 --- a/src/coreComponents/constitutive/contact/CoulombFriction.hpp +++ b/src/coreComponents/constitutive/contact/CoulombFriction.hpp @@ -182,6 +182,14 @@ class CoulombFriction : public FrictionBase */ KernelWrapper createKernelUpdates() const; + /// getting cohesion value + real64 getCohesion() const + { return m_cohesion; } + + /// getting friction coeff + real64 getFrictionCoeff() const + { return m_frictionCoefficient; } + /** * @struct Set of "char const *" and keys for data specified in this class. */ diff --git a/src/coreComponents/constitutiveDrivers/CMakeLists.txt b/src/coreComponents/constitutiveDrivers/CMakeLists.txt index cbc198074d6..b3554ad559c 100644 --- a/src/coreComponents/constitutiveDrivers/CMakeLists.txt +++ b/src/coreComponents/constitutiveDrivers/CMakeLists.txt @@ -29,12 +29,16 @@ set( constitutiveDrivers_headers relativePermeability/RelpermDriver.hpp relativePermeability/RelpermDriverRunTest.hpp solid/TriaxialDriver.hpp + contact/FrictionDriver.hpp + contact/FrictionDriverRunTest.hpp ) # # Specify all sources # set( constitutiveDrivers_sources ConstitutiveDriver.cpp + contact/FrictionDriver.cpp + contact/FrictionDriverRunTest.cpp fluid/multiFluid/PVTDriver.cpp fluid/multiFluid/constant/PVTDriverRunTestInvariantImmiscibleFluid.cpp fluid/multiFluid/blackOil/PVTDriverRunTestDeadOilFluid.cpp diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.cpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.cpp new file mode 100644 index 00000000000..c2538822f04 --- /dev/null +++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.cpp @@ -0,0 +1,205 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +#include "FrictionDriver.hpp" + +#include "constitutive/ConstitutiveManager.hpp" +#include "constitutiveDrivers/LogLevelsInfo.hpp" +#include "constitutive/contact/FrictionBase.hpp" +#include "constitutive/contact/FrictionSelector.hpp" + +#include "functions/FunctionManager.hpp" +#include "functions/TableFunction.hpp" + +namespace geos +{ + +using namespace dataRepository; +using namespace constitutive; + +FrictionDriver::FrictionDriver( const string & name, Group * const parent ) + : ConstitutiveDriver( name, parent ) +{ + registerWrapper( viewKeyStruct::frictionNameString(), &m_frictionName ). + setRTTypeName( rtTypes::CustomTypes::groupNameRef ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Friction model to test" ); + + registerWrapper( viewKeyStruct::numStepsString(), &m_numSteps ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Number of sample step to take in both jumps and traction increments" ); + + registerWrapper( viewKeyStruct::jumpFunctionString(), &m_jumpFunctionName ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Name of the input function representing jump function along world x-axis" ); + + registerWrapper( viewKeyStruct::tractionFunctionString(), &m_tractionFunctionName ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Name of the input function representing traction function along world x-axis" ); + + registerWrapper( viewKeyStruct::thetaString(), &m_theta ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Number of increment step to take in both jumps and traction increments" ); + + registerWrapper( viewKeyStruct::phiString(), &m_phi ). + setInputFlag( InputFlags::INVALID ). + setDescription( "Number of increment step to take in both jumps and traction increments" ); + + addLogLevel< logInfo::LogOutput >(); +} + +void FrictionDriver::postInputInitialization() +{ + ConstitutiveDriver::postInputInitialization(); + + // Check that the functions exist + FunctionManager & functionManager = FunctionManager::getInstance(); + GEOS_ERROR_IF( !functionManager.hasGroup< TableFunction >( m_jumpFunctionName ), + GEOS_FMT( "Jump function with name '{}' not found", m_jumpFunctionName ), + getWrapperDataContext( viewKeyStruct::jumpFunctionString() ) ); + + GEOS_ERROR_IF( !functionManager.hasGroup< TableFunction >( m_tractionFunctionName ), + GEOS_FMT( "Traction function with name '{}' not found", m_tractionFunctionName ), + getWrapperDataContext( viewKeyStruct::tractionFunctionString() ) ); + + string_array columnNames; + getColumnNames( columnNames ); + integer const numCols = static_cast< integer >(columnNames.size()); + + // initialize functions + TableFunction & jumpFunction = functionManager.getGroup< TableFunction >( m_jumpFunctionName ); + TableFunction & tractionFunction = functionManager.getGroup< TableFunction >( m_tractionFunctionName ); + + jumpFunction.initializeFunction(); + tractionFunction.initializeFunction(); + + // TODO: Maybe we should take the maximum extent of jumpFunction and tractionFunction + ArrayOfArraysView< real64 > coordinates = jumpFunction.getCoordinates(); + real64 const minTime = coordinates[0][0]; + real64 const maxTime = coordinates[0][coordinates.sizeOfArray( 0 )-1]; + + // Allocate the data + allocateTable( numCols, minTime, maxTime ); + + // set input columns + initializeTable(); +} + +bool FrictionDriver::execute() +{ + FrictionBase & baseFriction = getFriction(); + + GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, "Launching Friction Driver" ); + GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Friction ............... " << m_frictionName ); + GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Type ................... " << baseFriction.getCatalogName() ); + GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Steps .................. " << m_numSteps ); + GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Output ................. " << m_outputFile ); + + // create a dummy discretization with one quadrature point for + // storing constitutive data + + conduit::Node node; + dataRepository::Group rootGroup( "root", node ); + dataRepository::Group discretization( "discretization", &rootGroup ); + + integer const numRows = m_table.size( 0 ); + discretization.resize( numRows ); // numRows elements + baseFriction.allocateConstitutiveData( discretization, 1 ); // one quadrature point + + constitutiveUpdatePassThru( baseFriction, [&]( auto & selectedFrictionModel ) + { + using FRICTION_TYPE = TYPEOFREF( selectedFrictionModel ); + runTest< FRICTION_TYPE >( selectedFrictionModel, m_table ); + } ); + + return false; +} + +void FrictionDriver::getColumnNames( string_array & columnNames ) const +{ + columnNames.emplace_back( "time" ); + columnNames.emplace_back( "traction,normal" ); + columnNames.emplace_back( "traction,tangent1" ); + columnNames.emplace_back( "traction,tangent2" ); + columnNames.emplace_back( "displacement jump,normal" ); + columnNames.emplace_back( "displacement jump,tangent1" ); + columnNames.emplace_back( "displacement jump,tangent2" ); + columnNames.emplace_back( "fracture state" ); + + if( dynamic_cast< CoulombFriction const * >(&getFriction()) != nullptr ) + { + columnNames.emplace_back( "tau limit" ); + } +} + +void FrictionDriver::initializeTable() +{ + integer const numRows = m_table.size( 0 ); + + FunctionManager & functionManager = FunctionManager::getInstance(); + TableFunction const & jumpFunction = functionManager.getGroup< TableFunction >( m_jumpFunctionName ); + TableFunction const & tractionFunction = functionManager.getGroup< TableFunction >( m_tractionFunctionName ); + + real64 const cos_theta = cos( m_theta * M_PI/180.0 ); + real64 const sin_theta = sin( m_theta * M_PI/180.0 ); + + real64 const cos_phi = cos( m_phi * M_PI/180.0 ); + real64 const sin_phi = sin( m_phi * M_PI/180.0 ); + + for( integer index = 0; index < numRows; ++index ) + { + real64 const time = m_table( index, TIME ); + + real64 const traction = tractionFunction.evaluate( &time ); + real64 const jump = jumpFunction.evaluate( &time ); + + m_table( index, NTRAC ) = traction*sin_theta; + m_table( index, STRAC0 ) = traction*cos_theta*cos_phi; + m_table( index, STRAC1 ) = traction*cos_theta*sin_phi; + + m_table( index, NJUMP ) = jump*sin_theta; + m_table( index, SLIP0 ) = jump*cos_theta*cos_phi; + m_table( index, SLIP1 ) = jump*cos_theta*sin_phi; + + m_table( index, FS ) = fields::contact::FractureState::Stick; + } + + if( CoulombFriction const * coulombFriction = dynamic_cast< CoulombFriction const * >(&getFriction()) ) + { + real64 const cohesion = coulombFriction->getCohesion(); + real64 const frictionCoeff = coulombFriction->getFrictionCoeff(); + for( integer index = 0; index < numRows; ++index ) + { + real64 const normal_traction = m_table( index, NTRAC ); + m_table( index, TLIM ) = cohesion - normal_traction * frictionCoeff; + } + } +} + +FrictionBase & FrictionDriver::getFriction() +{ + return getConstitutiveManager().getGroup< FrictionBase >( m_frictionName ); +} + +FrictionBase const & FrictionDriver::getFriction() const +{ + return getConstitutiveManager().getGroup< FrictionBase >( m_frictionName ); +} + +REGISTER_CATALOG_ENTRY( TaskBase, + FrictionDriver, + string const &, dataRepository::Group * const ) + +} diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.hpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.hpp new file mode 100644 index 00000000000..d912eed02d6 --- /dev/null +++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.hpp @@ -0,0 +1,92 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +#ifndef GEOS_CONSTITUTIVEDRIVERS_CONTACT_FRICTIONDRIVER_HPP +#define GEOS_CONSTITUTIVEDRIVERS_CONTACT_FRICTIONDRIVER_HPP + +#include "constitutiveDrivers/ConstitutiveDriver.hpp" + +namespace geos +{ +namespace constitutive +{ +class FrictionBase; +} + +class FrictionDriver : public ConstitutiveDriver +{ +public: + FrictionDriver( const string & name, + Group * const parent ); + + static string catalogName() + { return "FrictionDriver"; } + + void postInputInitialization() override; + + bool execute() override; + + void getColumnNames( string_array & columnNames ) const override; + + template< typename FRICTION_TYPE > + void + runTest( FRICTION_TYPE & friction, + const arrayView2d< real64, 1 > & table ); + +private: + /** + * @brief Get the friction model from the catalog + */ + constitutive::FrictionBase & getFriction(); + constitutive::FrictionBase const & getFriction() const; + + void initializeTable(); + + /** + * @struct viewKeyStruct holds char strings and viewKeys for fast lookup + */ + struct viewKeyStruct : ConstitutiveDriver::viewKeyStruct + { + constexpr static char const * frictionNameString() + { return "friction"; } + + constexpr static char const * jumpFunctionString() + { return "jumpControl"; } + + constexpr static char const * tractionFunctionString() + { return "tractionControl"; } + + constexpr static char const * thetaString() + { return "xTiltAngle";} + + constexpr static char const * phiString() + { return "yTiltAngle";} + }; + + // Time is defined in base class + enum columnKeys { NJUMP = 1, SLIP0, SLIP1, NTRAC, STRAC0, STRAC1, FS, TLIM }; + + string m_jumpFunctionName; ///< + string m_tractionFunctionName; ///< + + real64 m_theta{0.0}; ///< x-tilt of fault + real64 m_phi{0.0}; ///< y-tilt of fault + + string m_frictionName; ///< frictionType identifier +}; + +} + +#endif //GEOS_CONSTITUTIVEDRIVERS_CONTACT_FRICTIONDRIVER_HPP diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.cpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.cpp new file mode 100644 index 00000000000..f06fe66436d --- /dev/null +++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.cpp @@ -0,0 +1,27 @@ +#include "FrictionDriverRunTest.hpp" +#include "constitutive/contact/CoulombFriction.hpp" +#include "constitutive/contact/FrictionlessContact.hpp" +#include "constitutive/contact/RateAndStateFriction.hpp" +#include + + +namespace geos +{ + +template +void +FrictionDriver::runTest( constitutive::CoulombFriction &, const arrayView2d< real64 > & ); + +template +void +FrictionDriver::runTest( constitutive::FrictionlessContact &, const arrayView2d< real64 > & ); + +template +void +FrictionDriver::runTest( constitutive::RateAndStateFriction< std::integral_constant< bool, true > > &, const arrayView2d< real64 > & ); + +template +void +FrictionDriver::runTest( constitutive::RateAndStateFriction< std::integral_constant< bool, false > > &, const arrayView2d< real64 > & ); + +} diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.hpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.hpp new file mode 100644 index 00000000000..5c0e5875dfa --- /dev/null +++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.hpp @@ -0,0 +1,61 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +#ifndef GEOS_FRICTIONDRIVERRUNTEST_HPP_ +#define GEOS_FRICTIONDRIVERRUNTEST_HPP_ + +#include "constitutiveDrivers/contact/FrictionDriver.hpp" +#include "physicsSolvers/solidMechanics/contact/FractureState.hpp" +#include "constitutive/solid/SolidFields.hpp" + +namespace geos +{ + +template< typename FRICTION_TYPE > +void +FrictionDriver::runTest( FRICTION_TYPE & friction, + const arrayView2d< real64 > & table ) +{ + // Create kernel wrapper + typename FRICTION_TYPE::KernelWrapper const kernelWrapper = friction.createKernelUpdates(); + + integer const numRows = m_table.size( 0 ); + forAll< parallelDevicePolicy<> >( numRows, + [ kernelWrapper, table ] + GEOS_HOST_DEVICE ( integer const ei ) + { + stackArray1d< real64, 3 > jump( 3 ); + stackArray1d< real64, 3 > traction( 3 ); + + jump[0] = table( ei, NJUMP ); + jump[1] = table( ei, SLIP0 ); + jump[2] = table( ei, SLIP1 ); + + traction[0] = table( ei, NTRAC ); + traction[1] = table( ei, STRAC0 ); + traction[2] = table( ei, STRAC1 ); + + integer fracture_state = fields::contact::FractureState::Stick; + kernelWrapper.updateFractureState( jump.toSliceConst(), + traction.toSliceConst(), + fracture_state ); + + table( ei, FS ) = fracture_state; + } ); +} + +} + +#endif //GEOS_FRICTIONDRIVERRUNTEST_HPP_ diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index 9a9bb51d843..30a9887b6a5 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -569,6 +569,10 @@ + + + + @@ -6266,6 +6270,7 @@ When set to `all` output both convergence & iteration information to a csv.--> + @@ -6380,6 +6385,29 @@ Information output from lower logLevels is added with the desired log level + + + + + + + + + + + + + + + + + + + + + + + +