diff --git a/inputFiles/frictionDriver/frictionDriver_Coulomb.xml b/inputFiles/frictionDriver/frictionDriver_Coulomb.xml
new file mode 100644
index 00000000000..3a1c0a5b630
--- /dev/null
+++ b/inputFiles/frictionDriver/frictionDriver_Coulomb.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inputFiles/frictionDriver/frictionDriver_base.xml b/inputFiles/frictionDriver/frictionDriver_base.xml
new file mode 100644
index 00000000000..df5ef688301
--- /dev/null
+++ b/inputFiles/frictionDriver/frictionDriver_base.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inputFiles/frictionDriver/tables/jumps.geos b/inputFiles/frictionDriver/tables/jumps.geos
new file mode 100644
index 00000000000..3c922732f7a
--- /dev/null
+++ b/inputFiles/frictionDriver/tables/jumps.geos
@@ -0,0 +1,6 @@
+0
+1e-3
+2e-3
+3e-3
+4e-3
+5e-3
diff --git a/inputFiles/frictionDriver/tables/time.geos b/inputFiles/frictionDriver/tables/time.geos
new file mode 100644
index 00000000000..e8371f00609
--- /dev/null
+++ b/inputFiles/frictionDriver/tables/time.geos
@@ -0,0 +1,6 @@
+0
+1
+2
+3
+4
+5
diff --git a/inputFiles/frictionDriver/tables/tractions.geos b/inputFiles/frictionDriver/tables/tractions.geos
new file mode 100644
index 00000000000..c80b1f6d1bd
--- /dev/null
+++ b/inputFiles/frictionDriver/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 de519ea2fdb..b64c154dd1d 100644
--- a/src/coreComponents/constitutiveDrivers/CMakeLists.txt
+++ b/src/coreComponents/constitutiveDrivers/CMakeLists.txt
@@ -29,6 +29,8 @@ set( constitutiveDrivers_headers
relativePermeability/RelpermDriver.hpp
relativePermeability/RelpermDriverRunTest.hpp
solid/TriaxialDriver.hpp
+ contact/FrictionDriver.hpp
+ contact/FrictionDriverRunTest.hpp
)
#
# Specify all sources
@@ -57,6 +59,8 @@ set( constitutiveDrivers_sources
relativePermeability/RelpermDriverTableRelativeRunTest.cpp
relativePermeability/RelpermDriverTableRelativeHysteresisRunTest.cpp
solid/TriaxialDriver.cpp
+ contact/FrictionDriver.cpp
+ contact/FrictionDriverRunTest.cpp
)
set( dependencyList ${parallelDeps} constitutive events )
diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.cpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.cpp
new file mode 100644
index 00000000000..1f475f27a45
--- /dev/null
+++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.cpp
@@ -0,0 +1,301 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * 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 "common/MpiWrapper.hpp"
+#include "constitutive/ConstitutiveManager.hpp"
+#include "constitutiveDrivers/contact/LogLevelsInfo.hpp"
+#include "constitutive/contact/FrictionBase.hpp"
+#include "constitutive/contact/FrictionSelector.hpp"
+
+#include "functions/FunctionManager.hpp"
+#include "functions/TableFunction.hpp"
+#include
+#include
+
+#include "FrictionDriver.hpp"
+
+namespace geos {
+
+using namespace dataRepository;
+using namespace constitutive;
+
+FrictionDriver::FrictionDriver(const string& name, Group * const parent)
+:
+TaskBase(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" );
+
+ registerWrapper( viewKeyStruct::outputString(), &m_outputFile ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setApplyDefaultValue( "none" ).
+ setDescription( "Output file" );
+
+ registerWrapper( viewKeyStruct::baselineString(), &m_baselineFile ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setApplyDefaultValue( "none" ).
+ setDescription( "Baseline file" );
+
+ addLogLevel< logInfo::LogOutput >();
+}
+
+void FrictionDriver::compareWithBaseline()
+{
+ // open baseline file
+
+ std::ifstream file( m_baselineFile.c_str() );
+ GEOS_THROW_IF( !file.is_open(), "Can't seem to open the baseline file " << m_baselineFile, InputError );
+
+ // discard file header
+
+ string line;
+ for( integer row=0; row < m_numColumns; ++row )
+ {
+ getline( file, line );
+ }
+
+ // read data block. we assume the file size is consistent with m_table,
+ // but check for a premature end-of-file. we then compare results value by value.
+ // we ignore the newton iteration and residual columns, as those may be platform
+ // specific.
+
+ real64 value;
+ real64 error;
+
+ for( integer row=0; row < m_table.size( 0 ); ++row )
+ {
+ for( integer col=0; col < m_table.size( 1 ); ++col )
+ {
+ GEOS_THROW_IF( file.eof(), "Baseline file appears shorter than internal results", std::runtime_error );
+ file >> value;
+
+ error = fabs( m_table[row][col]-value ) / ( fabs( value )+1 );
+ GEOS_THROW_IF( error > m_baselineTol, "Results do not match baseline at data row " << row+1
+ << " (row " << row+10 << " with header)"
+ << " and column " << col+1, std::runtime_error );
+
+ }
+ }
+
+ // check we actually reached the end of the baseline file
+
+ file >> value;
+ GEOS_THROW_IF( !file.eof(), "Baseline file appears longer than internal results", std::runtime_error );
+
+ // success
+
+ GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Comparison ........ Internal results consistent with baseline." );
+
+ file.close();
+}
+
+void FrictionDriver::outputResults()
+{
+ // TODO: improve file path output to grab command line -o directory
+ // for the moment, we just use the specified m_outputFile directly
+
+ FILE * fp = fopen( m_outputFile.c_str(), "w" );
+
+ fprintf( fp, "# column 1 = index \n" );
+ fprintf( fp, "# column 2-3 = normal and in-plane displacement jump\n" );
+ fprintf( fp, "# columns 5-7 = normal and in-place tractions\n");
+ fprintf( fp, "# columns 8 = fracture state (0:Stick,1-2:[new]Slip,3:Open)\n");
+ fprintf( fp, "# columns 9 = tau lim\n");
+
+ for( integer n = 0; n < m_table.size( 0 ); ++n )
+ {
+ for( integer col = 0; col < m_table.size( 1 ); ++col )
+ {
+ fprintf( fp, "%.4e ", m_table( n, col ) );
+ }
+ fprintf( fp, "\n" );
+ }
+ fclose( fp );
+
+}
+
+
+void FrictionDriver::postInputInitialization()
+{
+ ConstitutiveManager
+ & constitutiveManager = this->getGroupByPath< ConstitutiveManager >( "/Problem/domain/Constitutive" );
+ FrictionBase& baseFriction = constitutiveManager.getGroup< FrictionBase >( m_frictionName );
+
+// m_numPhases = baseFriction.numSubGroups();
+
+}
+
+
+bool FrictionDriver::execute( const geos::real64 GEOS_UNUSED_PARAM( time_n ),
+ const geos::real64 GEOS_UNUSED_PARAM( dt ),
+ const geos::integer GEOS_UNUSED_PARAM( cycleNumber ),
+ const geos::integer GEOS_UNUSED_PARAM( eventCounter ),
+ const geos::real64 GEOS_UNUSED_PARAM( eventProgress ),
+ geos::DomainPartition &
+ GEOS_UNUSED_PARAM( domain ) )
+{
+ // this code only makes sense in serial
+
+ GEOS_THROW_IF( MpiWrapper::commRank() > 0, "FrictionDriver should only be run in serial", std::runtime_error );
+
+
+ ConstitutiveManager
+ & constitutiveManager = this->getGroupByPath< ConstitutiveManager >( "/Problem/domain/Constitutive" );
+ FrictionBase
+ & baseFriction = constitutiveManager.getGroup< FrictionBase >( m_frictionName );
+
+ 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, " No. of Phases .......... " << m_numPhases );
+ GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Steps .................. " << m_numSteps );
+ GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Output ................. " << m_outputFile );
+ GEOS_LOG_LEVEL_RANK_0( logInfo::LogOutput, " Baseline ............... " << m_baselineFile );
+
+ // 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 );
+
+ discretization.resize( 1 ); // one element
+ baseFriction.allocateConstitutiveData( discretization, 1 ); // one quadrature point
+
+ constitutiveUpdatePassThru( baseFriction, [&]( auto & selectedFrictionModel )
+ {
+ using FRICTION_TYPE = TYPEOFREF( selectedFrictionModel );
+ resizeTables< FRICTION_TYPE >();
+ runTest< FRICTION_TYPE >( selectedFrictionModel, m_table );
+ } );
+
+ // move table back to host for output
+ m_table.move( LvArray::MemorySpace::host );
+
+ if( m_outputFile != "none" )
+ {
+ outputResults();
+ }
+
+ if( m_baselineFile != "none" )
+ {
+ compareWithBaseline();
+ }
+
+ return false;
+}
+
+
+template< typename FRICTION_TYPE >
+void FrictionDriver::resizeTables()
+{
+ ConstitutiveManager
+ & constitutiveManager = this->getGroupByPath< ConstitutiveManager >( "/Problem/domain/Constitutive" );
+ FrictionBase
+ & baseFriction = constitutiveManager.getGroup< FrictionBase >( m_frictionName );
+
+ // initialize table functions
+ FunctionManager & functionManager = FunctionManager::getInstance();
+
+ TableFunction & jumpFunction = functionManager.getGroup< TableFunction >( m_jumpFunctionName );
+ TableFunction & tractionFunction = functionManager.getGroup< TableFunction >( m_tractionFunctionName );
+
+ jumpFunction.initializeFunction();
+ tractionFunction.initializeFunction();
+
+ ArrayOfArraysView< real64 > coordinates = jumpFunction.getCoordinates();
+ real64 const minTime = coordinates[0][0];
+ real64 const maxTime = coordinates[0][coordinates.sizeOfArray( 0 )-1];
+ real64 const dt = (maxTime-minTime) / m_numSteps;
+
+ // set input columns
+ resizeTable< FRICTION_TYPE >();
+
+ // set time column
+ for( integer k=0; k ) {
+
+ cohesion = dynamic_cast(&baseFriction)->getCohesion();
+ frictionCoeff = dynamic_cast(&baseFriction)->getFrictionCoeff();
+ }
+
+ //All variation
+ for( integer nt = 0; nt < m_numSteps+1; ++nt )
+ {
+ for( integer nj = 0; nj < m_numSteps+1; ++nj )
+ {
+
+ integer index = nt * (m_numSteps+1) + nj;
+ m_table( index, NTRAC ) = tractionFunction.evaluate(&m_table(nt,TIME))*sin(m_theta * M_PI/180);
+ m_table( index, STRAC0 ) = tractionFunction.evaluate(&m_table(nt,TIME))*cos(m_theta * M_PI/180);
+ m_table( index, STRAC1 ) = tractionFunction.evaluate(&m_table(nt,TIME))*cos(m_theta * M_PI/180);
+
+ m_table( index, NJUMP ) = jumpFunction.evaluate(&m_table(nj,TIME))*sin(m_theta * M_PI/180);
+ m_table( index, SLIP0 ) = jumpFunction.evaluate(&m_table(nj,TIME))*cos(m_theta * M_PI/180);
+ m_table( index, SLIP1 ) = jumpFunction.evaluate(&m_table(nj,TIME))*cos(m_theta * M_PI/180);
+
+ m_table( index, FS ) = fields::contact::FractureState::Stick;
+
+ //Only for Coulomb
+ m_table( index, TLIM ) = cohesion - m_table(index, NTRAC) * frictionCoeff;
+
+ }
+ }
+
+}
+
+
+template< typename FRICTION_TYPE >
+void
+FrictionDriver::resizeTable()
+{
+ m_table.resize((m_numSteps + 1)*(m_numSteps + 1), m_numColumns );
+}
+
+REGISTER_CATALOG_ENTRY( TaskBase,
+ FrictionDriver,
+ string const &, dataRepository::Group * const )
+
+}
\ No newline at end of file
diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.hpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.hpp
new file mode 100644
index 00000000000..dddaffafc80
--- /dev/null
+++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriver.hpp
@@ -0,0 +1,135 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * 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_frictionDRIVER_HPP_
+#define GEOS_frictionDRIVER_HPP_
+
+#include "events/tasks/TaskBase.hpp"
+
+namespace geos
+{
+
+class FrictionDriver : public TaskBase
+{
+
+public:
+ FrictionDriver( const string & name,
+ Group * const parent );
+
+ static string catalogName()
+ { return "FrictionDriver"; }
+
+ void postInputInitialization() override;
+
+ virtual bool execute( real64 const GEOS_UNUSED_PARAM( time_n ),
+ real64 const GEOS_UNUSED_PARAM( dt ),
+ integer const GEOS_UNUSED_PARAM( cycleNumber ),
+ integer const GEOS_UNUSED_PARAM( eventCounter ),
+ real64 const GEOS_UNUSED_PARAM( eventProgress ),
+ DomainPartition &
+ GEOS_UNUSED_PARAM( domain ) ) override;
+
+ // /**
+ // * @brief Run test using loading protocol in table
+ // * @param i friction constitutive model
+ // * @param table Table with input/output time history
+ // */
+ // template< typename friction_TYPE >
+ // std::enable_if_t< std::is_same< constitutive::TableRelativePermeabilityHysteresis, friction_TYPE >::value, void >
+ // runTest( friction_TYPE & friction,
+ // const arrayView2d< real64, 1 > & table );
+
+ template< typename FRICTION_TYPE >
+ void
+ runTest( FRICTION_TYPE & friction,
+ const arrayView2d< real64, 1 > & table );
+
+ /**
+ * @brief Ouput table to file for easy plotting
+ */
+ void outputResults();
+
+ /**
+ * @brief Read in a baseline table from file and compare with computed one (for unit testing purposes)
+ */
+ void compareWithBaseline();
+
+private:
+
+ template< typename FRICTION_TYPE >
+ void resizeTable();
+
+ template< typename FRICTION_TYPE >
+ void resizeTables();
+
+ // template< typename friction_TYPE >
+ // std::enable_if_t< !std::is_same< constitutive::TableRelativePermeabilityHysteresis, friction_TYPE >::value, void >
+ // resizeTable();
+
+ /**
+ * @struct viewKeyStruct holds char strings and viewKeys for fast lookup
+ */
+ struct viewKeyStruct
+ {
+ constexpr static char const * frictionNameString()
+ { return "friction"; }
+
+ constexpr static char const * numStepsString()
+ { return "steps"; }
+
+ 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";}
+
+ constexpr static char const * outputString()
+ { return "output"; }
+
+ constexpr static char const * baselineString()
+ { return "baseline"; }
+
+ };
+
+ integer m_numSteps; ///< Number of load steps
+ static integer const m_numColumns = 9; ///< Number of columns in dat
+ enum columnKeys { TIME, NJUMP, SLIP0, SLIP1, NTRAC, STRAC0, STRAC1, FS, TLIM };
+
+ string m_jumpFunctionName; ///<
+ string m_tractionFunctionName; ///<
+
+ float m_theta, m_phi;///< x- and y-tilt of fault
+
+ string m_frictionName; ///< frictionType identifier
+ string m_outputFile; ///< Output file (optional, no output if not specified)
+
+ array2d< real64 > m_table; ///< Table storing time-history of input/output
+
+ Path m_baselineFile; ///< Baseline file (optional, for unit testing of solid models)
+
+
+ static constexpr real64 m_baselineTol = 1e-3; ///< Comparison tolerance for baseline results
+};
+
+
+}
+
+#endif //GEOS_FRICTIONDRIVER_HPP_
diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.cpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.cpp
new file mode 100644
index 00000000000..2d40f34235f
--- /dev/null
+++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.cpp
@@ -0,0 +1,26 @@
+#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 &);
+
+template
+void
+FrictionDriver::runTest(constitutive::FrictionlessContact&, const arrayView2d &);
+
+template
+void
+FrictionDriver::runTest(constitutive::RateAndStateFriction>&, const arrayView2d &);
+
+template
+void
+FrictionDriver::runTest(constitutive::RateAndStateFriction>&, const arrayView2d &);
+
+}
diff --git a/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.hpp b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.hpp
new file mode 100644
index 00000000000..cde385ff032
--- /dev/null
+++ b/src/coreComponents/constitutiveDrivers/contact/FrictionDriverRunTest.hpp
@@ -0,0 +1,74 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * 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 )
+{
+
+ array2d< real64 > jumps, tractions;
+ jumps.resize(table.size(0),3);
+ tractions.resize(table.size(0),3);
+
+ for( integer n = 0; n < table.size(0); ++n)
+ {
+ jumps[n][0] = table(n,NJUMP);
+ jumps[n][1] = table(n,SLIP0);
+ jumps[n][2] = table(n,SLIP1);
+
+ tractions[n][0] = table(n,NTRAC);
+ tractions[n][1] = table(n,STRAC0);
+ tractions[n][2] = table(n,STRAC1);
+
+ }
+
+
+ // create kernel wrapper
+ typename FRICTION_TYPE::KernelWrapper const kernelWrapper = friction.createKernelUpdates();
+
+ forAll< parallelDevicePolicy<> >( 1,
+ [ kernelWrapper, table, jumps, tractions ]
+ GEOS_HOST_DEVICE ( integer const ei )
+ {
+ for( integer i = 1; i < table.size(0) ; ++i )
+ {
+ integer fs = fields::contact::FractureState::Stick;
+ kernelWrapper.updateFractureState( jumps[i],
+ tractions[i],
+ fs );
+
+ table(i,FS) = fs;
+ }
+ } );
+
+}
+
+}
+
+
+#endif //GEOS_FRICTIONDRIVERRUNTEST_HPP_
diff --git a/src/coreComponents/constitutiveDrivers/contact/LogLevelsInfo.hpp b/src/coreComponents/constitutiveDrivers/contact/LogLevelsInfo.hpp
new file mode 100644
index 00000000000..1a0319a7db4
--- /dev/null
+++ b/src/coreComponents/constitutiveDrivers/contact/LogLevelsInfo.hpp
@@ -0,0 +1,52 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * 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.
+ * ------------------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @file LogLevelsInfo.hpp
+ * This file contains common log level informations for PVT driver
+ */
+
+#ifndef GEOS_CONSTITUTIVEDRIVERS_CONTACT_LOGLEVELSINFO_HPP_
+#define GEOS_CONSTITUTIVEDRIVERS_CONTACT_LOGLEVELSINFO_HPP_
+
+#include "common/DataTypes.hpp"
+
+namespace geos
+{
+
+namespace logInfo
+{
+
+/**
+ * @name Common LogLevels info structures. They must comply with the `is_log_level_info` trait.
+ */
+///@{
+
+/// @cond DO_NOT_DOCUMENT
+
+struct LogOutput
+{
+ static constexpr int getMinLogLevel() { return 1; }
+ static constexpr std::string_view getDescription() { return "Enable log output"; }
+};
+
+/// @endcond
+///@}
+
+}
+
+}
+
+#endif // GEOS_CONSTITUTIVEDRIVERS_CONTACT_LOGLEVELSINFO_HPP_