Skip to content

feat: Gravity #3715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/cmake/GeosxOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ option( GEOS_ENABLE_SIMPLEPDE "Enables simple PDE physics package" ON )
option( GEOS_ENABLE_SOLIDMECHANICS "Enables solid mechanics physics package" ON )
option( GEOS_ENABLE_SURFACEGENERATION "Enables surface generation physics package" ON )
option( GEOS_ENABLE_WAVEPROPAGATION "Enables wave propagation physics package" ON )
option( GEOS_ENABLE_GRAVITY "Enables gravity physics package" ON )


#set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "" FORCE)
#blt_append_custom_compiler_flag(FLAGS_VAR CMAKE_CXX_FLAGS DEFAULT -rdynamic)
Expand Down
85 changes: 74 additions & 11 deletions src/coreComponents/dataRepository/python/PyWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

// Source includes
#include "PyWrapper.hpp"

#include "dataRepository/Wrapper.hpp"

#define VERIFY_NON_NULL_SELF( self ) \
PYTHON_ERROR_IF( self == nullptr, PyExc_RuntimeError, "Passed a nullptr as self.", nullptr )
Expand All @@ -32,16 +32,6 @@ namespace geos
namespace python
{

struct PyWrapper
{
PyObject_HEAD

static constexpr char const * docString =
"A Python interface to geos::dataRepository::WrapperBase.";

dataRepository::WrapperBase * wrapper;
};

/**
*
*/
Expand Down Expand Up @@ -100,10 +90,83 @@ static PyObject * PyWrapper_value( PyWrapper * const self, PyObject * const args
return ret;
}


template< typename T >
bool trySetValue( dataRepository::WrapperBase * base, T const & value )
{
auto * wrapper = dynamic_cast< dataRepository::Wrapper< T > * >( base );
if( wrapper )
{
wrapper->reference() = value;
return true;
}
return false;
}


PyObject * PyWrapper_setValue( PyWrapper * const self, PyObject * const args )
{
VERIFY_NON_NULL_SELF( self );
VERIFY_INITIALIZED( self );

PyObject * pyValue = nullptr;
if( !PyArg_ParseTuple( args, "O", &pyValue ) )
{
return nullptr;
}

try
{
bool success = false;

if( PyUnicode_Check( pyValue ) )
{
const char * strVal = PyUnicode_AsUTF8( pyValue );
success = trySetValue( self->wrapper, std::string( strVal ) );
if( !success )
PyErr_SetString( PyExc_TypeError, "Wrapper is not a std::string." );
}
else if( PyFloat_Check( pyValue ) )
{
double val = PyFloat_AsDouble( pyValue );
success = trySetValue( self->wrapper, val );
if( !success )
PyErr_SetString( PyExc_TypeError, "Wrapper is not a double." );
}
else if( PyLong_Check( pyValue ) )
{
long val = PyLong_AsLong( pyValue );
success = trySetValue( self->wrapper, static_cast< int >( val ) ) ||
trySetValue( self->wrapper, val );
if( !success )
PyErr_SetString( PyExc_TypeError, "Wrapper is not an int or long." );
}
else
{
PyErr_SetString( PyExc_TypeError, "Unsupported Python type for assignment." );
return nullptr;
}

if( !success )
{
return nullptr;
}

Py_RETURN_NONE;
}
catch( std::exception const & e )
{
PyErr_SetString( PyExc_RuntimeError, e.what() );
return nullptr;
}
}


BEGIN_ALLOW_DESIGNATED_INITIALIZERS

static PyMethodDef PyWrapperMethods[] = {
{ "value", (PyCFunction) PyWrapper_value, METH_VARARGS, PyWrapper_valueDocString },
{ "set_value", (PyCFunction) PyWrapper_setValue, METH_VARARGS, "Set the value of a scalar wrapper (string, int, float)." },
{ nullptr, nullptr, 0, nullptr } // Sentinel
};

Expand Down
40 changes: 40 additions & 0 deletions src/coreComponents/dataRepository/python/PyWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,26 @@ namespace geos
namespace python
{


/**
* @brief Python wrapper object for geos::dataRepository::WrapperBase.
*
* This struct defines the Python-facing interface for accessing and modifying
* wrapped C++ values from Python.
*/
struct PyWrapper
{
PyObject_HEAD

/// Documentation string for the PyWrapper Python type.
static constexpr char const * docString =
"A Python interface to geos::dataRepository::WrapperBase.";

/// Pointer to the underlying C++ WrapperBase instance.
dataRepository::WrapperBase * wrapper;
};


/**
*
*/
Expand All @@ -34,6 +54,26 @@ PyObject * createNewPyWrapper( dataRepository::WrapperBase & wrapper );
*/
PyTypeObject * getPyWrapperType();

/**
* @brief Set the value of a scalar wrapper from Python.
*
* This function allows assigning a scalar value from Python into the underlying
* C++ Wrapper<T> instance. Supported types include:
* - std::string
* - int
* - long
* - double
*
* If the type of the Python object does not match the wrapped C++ type,
* a Python TypeError is raised. Same for unsupported types.
*
* @param self Pointer to the PyWrapper instance.
* @param args A Python tuple containing a single value to assign.
* @return Py_None on success, or nullptr on failure with a Python exception set.
*/
PyObject * PyWrapper_setValue( PyWrapper * self, PyObject * args );


} // namespace python
} // namespace geos

Expand Down
5 changes: 5 additions & 0 deletions src/coreComponents/dataRepository/unitTests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ set( dataRepository_tests
testXmlWrapper.cpp
testBufferOps.cpp )


if( ENABLE_PYGEOSX )
list( APPEND dataRepository_tests testPyWrapper_setValue.cpp )
endif()

set( dependencyList ${parallelDeps} gtest dataRepository )

if( ENABLE_CUDA AND ENABLE_CUDA_NVTOOLSEXT )
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* ------------------------------------------------------------------------------------------------------------
* 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 <gtest/gtest.h>
#include <Python.h>
#include "dataRepository/Group.hpp"
#include "dataRepository/Wrapper.hpp"

#include "dataRepository/python/PyWrapper.hpp"



using namespace geos::python;
using namespace geos::dataRepository;


class PythonEnvironment : public ::testing::Environment
{
public:
void SetUp() override { Py_Initialize(); }
void TearDown() override { Py_Finalize(); }
};

::testing::Environment * const pythonEnv = ::testing::AddGlobalTestEnvironment( new PythonEnvironment );


template< typename T >
void testSetValue( PyObject * arg, const T & expected, const std::string & typeName )
{
conduit::Node node;
Group rootGroup( "root", node );
Group dummyGroup( "dummy", &rootGroup );
T * value = new T( expected );
auto * wrapper = new Wrapper< T >( "test", dummyGroup, value );

PyWrapper pyWrapper;
pyWrapper.wrapper = wrapper;

PyObject * result = PyWrapper_setValue( &pyWrapper, arg );
ASSERT_NE( result, nullptr ) << "Failed to set value for type: " << typeName;

EXPECT_EQ( wrapper->reference(), expected );

delete wrapper;
Py_DECREF( arg );
Py_XDECREF( result );
}


TEST( PyWrapperSetValue, SetString )
{
PyObject * arg = Py_BuildValue( "(s)", "hello" );
testSetValue< std::string >( arg, "hello", "string" );
}

TEST( PyWrapperSetValue, SetDouble )
{
PyObject * arg = Py_BuildValue( "(d)", 3.14 );
testSetValue< double >( arg, 3.14, "double" );
}

TEST( PyWrapperSetValue, SetInt )
{
PyObject * arg = Py_BuildValue( "(i)", 42 );
testSetValue< int >( arg, 42, "int" );
}

TEST( PyWrapperSetValue, SetLong )
{
PyObject * arg = Py_BuildValue( "(l)", 123456789L );
testSetValue< long >( arg, 123456789L, "long" );
}


TEST( PyWrapperSetValue, TypeMismatch )
{
conduit::Node node;
Group rootGroup( "root", node );
Group dummyGroup( "dummy", &rootGroup );
int * value = new int(0);
auto * wrapper = new Wrapper< int >( "test", dummyGroup, value );

PyWrapper pyWrapper;
pyWrapper.wrapper = wrapper;

PyObject * arg = Py_BuildValue( "(s)", "not an int" );
PyObject * result = PyWrapper_setValue( &pyWrapper, arg );

EXPECT_EQ( result, nullptr );
EXPECT_TRUE( PyErr_Occurred() );
PyErr_Clear();

delete wrapper;
Py_DECREF( arg );
}


TEST( PyWrapperSetValue, UnsupportedType )
{
conduit::Node node;
Group rootGroup( "root", node );
Group dummyGroup( "dummy", &rootGroup );
auto * wrapper = new Wrapper< std::vector< int > >( "test", dummyGroup, new std::vector< int >() );

PyWrapper pyWrapper;
pyWrapper.wrapper = wrapper;

PyObject * dict = PyDict_New();
PyObject * arg = Py_BuildValue( "(O)", dict );
PyObject * result = PyWrapper_setValue( &pyWrapper, arg );

EXPECT_EQ( result, nullptr );
EXPECT_TRUE( PyErr_Occurred());
PyErr_Clear();

delete wrapper;
Py_DECREF( dict );
Py_DECREF( arg );
}
7 changes: 5 additions & 2 deletions src/coreComponents/fileIO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ set( fileIO_headers
timeHistory/BufferedHistoryIO.hpp
timeHistory/PackCollection.hpp
timeHistory/HDFHistoryIO.hpp
timeHistory/HistoryCollection.hpp )
timeHistory/HistoryCollection.hpp
timeHistory/ScatterDataProvider.hpp
timeHistory/ScatterDataHistoryCollection.hpp )

#
# Specify all sources
Expand All @@ -54,7 +56,8 @@ set( fileIO_sources
timeHistory/HDFFile.cpp
timeHistory/HistoryCollectionBase.cpp
timeHistory/PackCollection.cpp
timeHistory/HDFHistoryIO.cpp )
timeHistory/HDFHistoryIO.cpp
timeHistory/ScatterDataHistoryCollection.cpp )

set( dependencyList ${parallelDeps} events mesh HDF5::HDF5 )
if( ENABLE_PYGEOSX )
Expand Down
Loading
Loading