Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
db44ea6
Add test and check workflow
mlemayTTE Mar 24, 2025
66ab8ba
remove duplicated module install
mlemayTTE Mar 26, 2025
d99f00f
Add test and check workflow
mlemayTTE Mar 24, 2025
4528d65
remove duplicated module install
mlemayTTE Mar 26, 2025
51bc1fe
add dependency for test and set mypy and pytest
mlemayTTE Mar 28, 2025
7282e8c
Merge branch 'main' into lemay/ci/update_tests_ruff_mypy
Mar 28, 2025
dc37cbb
Merge branch 'lemay/ci/update_tests_ruff_mypy2' into lemay/ci/update_…
mlemayTTE Mar 28, 2025
8e1abec
Remove py38 and py39 from build
mlemayTTE Mar 28, 2025
281157c
Add sudo to install libgl1
mlemayTTE Mar 28, 2025
9c24115
Merge branch 'main' into lemay/ci/update_tests_ruff_mypy
mlemayTTE Mar 31, 2025
92987b9
Update mypy ci and pyprojects and minor corrections
mlemayTTE Mar 31, 2025
c4bf148
restore doc-test workflow
mlemayTTE Mar 31, 2025
8226e0e
Exclude build folder from mypy
mlemayTTE Mar 31, 2025
8f5e7ed
create separate workflow for typing
mlemayTTE Mar 31, 2025
9b7b548
remove package build from typing workflow
mlemayTTE Mar 31, 2025
1e831cb
fix test ci and check typing with single python version
mlemayTTE Mar 31, 2025
86cce5b
fix tests
mlemayTTE Mar 31, 2025
edc70b4
linting and test fix
mlemayTTE Mar 31, 2025
4f39ced
disable coverage
mlemayTTE Mar 31, 2025
9454d95
wrap test command to avoid error when no tests
mlemayTTE Apr 1, 2025
366aaae
Fix ci trame xml-tools
mlemayTTE Apr 1, 2025
3eb6940
Fix ci trame xml-tools 2
mlemayTTE Apr 1, 2025
ce13dfd
Disable failing tests on trame
mlemayTTE Apr 1, 2025
e808932
Disable failing tests on trame linting
mlemayTTE Apr 1, 2025
a3c479b
Add semantic check
mlemayTTE Apr 1, 2025
7d8a775
ci: Add semantic check
mlemayTTE Apr 1, 2025
9ce545d
rerun ci
mlemayTTE Apr 1, 2025
b664015
Merge branch 'main' into lemay/ci/update_tests_ruff_mypy
mlemayTTE Apr 2, 2025
8ac0e9b
linting after merge with main
mlemayTTE Apr 2, 2025
6389361
Merge branch 'main' into lemay/ci/update_tests_ruff_mypy
mlemayTTE Apr 4, 2025
248fa01
Fix merge issues and ci fix
mlemayTTE Apr 4, 2025
3b8e47a
Remove geomechanics tests from geos-posp
mlemayTTE Apr 4, 2025
f9c2791
Add ruff to ci and ruff fix
mlemayTTE Apr 4, 2025
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
45 changes: 36 additions & 9 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,39 @@ concurrency:


jobs:
build:
# Checks if PR title follows conventional semantics
semantic_pull_request:
permissions:
pull-requests: write # for amannn/action-semantic-pull-request to analyze PRs and
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
contents: read
runs-on: ubuntu-latest

steps:
- name: Check if the PR name has conventional semantics
if: github.event_name == 'pull_request'
uses: amannn/action-semantic-pull-request@v5.5.3
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
wip: true
# Configure that a scope doesn't need to be provided.
requireScope: false

- name: Skip the check on main branch
if: github.ref_name == 'main'
run: |
echo "This is not a Pull-Request, skipping"

build:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
max-parallel: 3
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
package-name: ["geos-ats", "geos-mesh", "geos-timehistory", "geos-xml-tools", "hdf5-wrapper", "pygeos-tools"]
python-version: ["3.10", "3.11", "3.12"]
package-name: ["geos-ats", "geos-mesh", "geos-posp", "geos-timehistory", "geos-trame", "geos-utils", "geos-xml-tools", "geos-xml-viewer", "hdf5-wrapper", "pygeos-tools"]

steps:
- uses: actions/checkout@v3
Expand All @@ -31,12 +55,15 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install pytest yapf toml
python -m pip install ${{ matrix.package-name }}/
python -m pip install ./${{ matrix.package-name }}/[test]
- name: Lint with yapf
# working-directory: ./${{ matrix.package-name }}
run: |
yapf -r --diff ${{ matrix.package-name }} --style .style.yapf
# - name: Test with pytest
# working-directory: ./${{ matrix.package-name }}
# run: |
# pytest
yapf -r --diff ./${{ matrix.package-name }} --style .style.yapf
- name: Test with pytest
#working-directory: ./${{ matrix.package-name }}
run:
# python -m pytest ./${{ matrix.package-name }} --doctest-modules --junitxml=junit/test-results.xml --cov-report=xml --cov-report=html |
# wrap pytest to avoid error when no tests in the package
sh -c 'python -m pytest ./${{ matrix.package-name }}; ret=$?; [ $ret = 5 ] && exit 0 || exit $ret'

43 changes: 43 additions & 0 deletions .github/workflows/typing-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: "Pull Request Typing Check"
on:
- pull_request

# Cancels in-progress workflows for a PR when updated
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true


jobs:
build:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
max-parallel: 3
matrix:
# add packages to check typing
package-name: ["hdf5-geomechanics", "geos-posp", "geos-timehistory", "geos-utils", "geos-xml-tools", "hdf5-wrapper"]

steps:
- uses: actions/checkout@v3
- uses: mpi4py/setup-mpi@v1
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
cache: 'pip'
- name: Install package
# working-directory: ./${{ matrix.package-name }}
run: |
python -m pip install --upgrade pip
python -m pip install mypy ruff

- name: Typing check with mypy
# working-directory: ./${{ matrix.package-name }}
run: |
python -m mypy --config-file ./.mypy.ini --check-untyped-defs ./${{ matrix.package-name }}

- name: Format and linting check with ruff
# working-directory: ./${{ matrix.package-name }}
run: |
python -m ruff check --config .ruff.toml ./geos-utils
19 changes: 19 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[mypy]
python_version = 3.10

# strict = true
warn_unreachable = true
implicit_reexport = true
show_error_codes = true
show_column_numbers = true
ignore_missing_imports = true
warn_unused_configs = true
allow_redefinition = false

# ignore files in the tests directory
[mypy-tests.*]
ignore_errors = True

# ignore files in the build directory
[mypy-build.*]
ignore_errors = True
66 changes: 66 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Exclude a variety of commonly ignored directories.
extend-exclude = ["tests/data"]

line-length = 120
indent-width = 4

# Assume Python 3.9
target-version = "py39"

[lint]

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
# "UP", # pyupgrade deactivate since python39
"B", # flake8-bugbear
"SIM", # flake8-simplify
"ANN", # flake8-annotations
"C4", # flake8-comprehensions
# "I", # isort - manage by yapf
"D", # pydocstyle
]

ignore = [
"E501", # line too long, handled by yapf
"B008", # do not perform function calls in argument defaults
"C901", # too complex
"W191", # indentation contains tabs
"D100",
"D101",
"D104", # Missing docstring in public package in __init__.py files
"UP007",
"ANN401", # allows Any return
]

[lint.pydocstyle]
convention = "google"

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
docstring-code-format = true

# Set the line length limit used when formatting code snippets in
# docstrings.
docstring-code-line-length = "dynamic"
13 changes: 7 additions & 6 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

# Add python modules to be documented
python_root = '..'
python_modules = ( 'geos-ats', 'geos-mesh', 'geos-posp', 'geos-timehistory', 'geos-utils', 'geos-xml-tools', 'hdf5-wrapper',
'pygeos-tools', 'geos-geomechanics' )
python_modules = ( 'geos-ats', 'geos-mesh', 'geos-posp', 'geos-timehistory', 'geos-utils', 'geos-xml-tools', 'hdf5-wrapper', 'pygeos-tools', 'geos-geomechanics' )

for m in python_modules:
sys.path.insert( 0, os.path.abspath( os.path.join( python_root, m, 'src' ) ) )

Expand All @@ -42,15 +42,16 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [ 'sphinx_design', 'sphinx_rtd_theme', 'sphinxarg.ext', 'sphinxcontrib.programoutput',
'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.mathjax', 'sphinx.ext.napoleon',
'sphinx.ext.todo', 'sphinx.ext.viewcode' ]
extensions = [
'sphinx_design', 'sphinx_rtd_theme', 'sphinxarg.ext', 'sphinxcontrib.programoutput', 'sphinx.ext.autodoc',
'sphinx.ext.doctest', 'sphinx.ext.mathjax', 'sphinx.ext.napoleon', 'sphinx.ext.todo', 'sphinx.ext.viewcode'
]

autoclass_content = 'both'
autodoc_mock_imports = [ "ats", "h5py", "lxml", "paraview", "pygeosx", "pylvarray", "meshio", "mpi4py", "scipy" ]
autodoc_typehints = 'none'
autodoc_typehints_format = 'short'
suppress_warnings = [""]
suppress_warnings = [ "" ]
typehints_defaults = 'braces'

# The suffix(es) of source filenames.
Expand Down
20 changes: 20 additions & 0 deletions geos-ats/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies = [
"pyyaml",
"tqdm",
"requests",
"scipy",
"GitPython",
"google-cloud-storage",
"pip-system-certs",
Expand All @@ -51,3 +52,22 @@ include-package-data = true

[tool.setuptools.package-data]
"*" = ["*.js", "*.css", "*.zip"]

[tool.pytest.ini_options]
addopts = [
"--import-mode=importlib",
]
console_output_style = "count"
python_classes = "Test"
python_files = "tests_*.py"
python_functions = "tests*"
testpaths = ["tests"]
pythonpath = [
"src",
]
norecursedirs = "bin"
filterwarnings = []

[tool.coverage.run]
branch = true
source = ["src/geos/"]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy.typing as npt
from typing_extensions import Self

from geos.geomechanics.processing.geomechanicsCalculatorFunctions import (
from geos_posp.processing.geomechanicsCalculatorFunctions import (
computeStressPrincipalComponentsFromStressVector, )

__doc__ = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ def computeFailureEnvelop(
element is the ordinates.
"""
sigmaMin: float = ( self.m_sigmaMin if stressNormalMin is None else stressNormalMin )
stressNormal: npt.NDArray[ np.float64 ] = np.linspace( sigmaMin, stressNormalMax, n )
stressNormal: npt.NDArray[ np.float64 ] = np.linspace( sigmaMin, stressNormalMax, n ).astype( np.float64 )
return ( stressNormal, np.array( self.computeShearStress( stressNormal ) ) )
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# SPDX-License-Identifier: Apache-2.0
# # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies.
# SPDX-FileContributor: Alexandre Benedicto, Martin Lemay
from typing import Any
import numpy as np
import numpy.typing as npt

from geos.geomechanics.model.MohrCoulomb import MohrCoulomb
from geos_posp.processing.MohrCoulomb import MohrCoulomb
from geos.utils.algebraFunctions import getAttributeMatrixFromVector
from geos.utils.PhysicalConstants import (
EPSILON, )
Expand All @@ -30,7 +31,7 @@ def specificGravity( density: npt.NDArray[ np.float64 ], specificDensity: float

if abs( specificDensity ) < EPSILON:
return np.full_like( density, np.nan )
return density / specificDensity
return ( density / specificDensity ).astype( np.float64 )


# https://en.wikipedia.org/wiki/Elastic_modulus
Expand Down Expand Up @@ -666,7 +667,7 @@ def criticalPorePressure(
# assertion frictionAngle < np.pi/2., so sin(frictionAngle) != 1
cohesiveTerm: npt.NDArray[ np.float64 ] = ( rockCohesion * np.cos( frictionAngle ) /
( 1 - np.sin( frictionAngle ) ) )
residualTerm: npt.NDArray[ np.float64 ] = ( 3 * minimumPrincipalStress - maximumPrincipalStress ) / 2.0
residualTerm: npt.NDArray[ np.floating[ Any ] ] = ( 3 * minimumPrincipalStress - maximumPrincipalStress ) / 2.0
return cohesiveTerm + residualTerm


Expand Down Expand Up @@ -848,7 +849,8 @@ def shearCapacityUtilization( traction: npt.NDArray[ np.float64 ], rockCohesion:
assert traction.shape[ 1 ] == 3, "Traction vector must have 3 components."

scu: npt.NDArray[ np.float64 ] = np.full( traction.shape[ 0 ], np.nan )
for i, tractionVec in enumerate( traction ):
for i in range( traction.shape[ 0 ] ):
tractionVec: npt.NDArray[ np.float64 ] = traction[ i ]
# use -1 to agree with Geos convention (i.e., compression with negative stress)
stressNormal: npt.NDArray[ np.float64 ] = -1.0 * tractionVec[ 0 ]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import numpy as np
import numpy.typing as npt
import pandas as pd # type: ignore[import-untyped]
from typing_extensions import Self

dir_path = os.path.dirname( os.path.realpath( __file__ ) )
Expand Down Expand Up @@ -247,9 +246,9 @@ def test_shearCapacityUtilization( self: Self ) -> None:

# calculation
obtained: npt.NDArray[ np.float64 ] = fcts.shearCapacityUtilization( traction, rockCohesion, frictionAngle )
expected: npt.NDArray[ np.float64 ] = np.array( [ 0.899, 0.923, 0.982, 1.004, 1.048 ] )
expected: list[ float ] = [ 0.899, 0.923, 0.982, 1.004, 1.048 ]

self.assertSequenceEqual( np.round( obtained, 3 ).flatten().tolist(), expected.tolist() )
self.assertSequenceEqual( np.round( obtained, 3 ).flatten().tolist(), expected )

def test_computeStressPrincipalComponents( self: Self ) -> None:
"""Test calculation of stress principal components from stress tensor."""
Expand Down
20 changes: 14 additions & 6 deletions geos-geomechanics/tests/testsMohrCircle.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def test_MohrCoulombInit( self: Self ) -> None:
def test_computeShearStress( self: Self ) -> None:
"""Test calculation of shear stress from normal stress."""
# inputs
stressNormal: npt.NDArray[ np.float64 ] = np.linspace( 5.0e8, 1.0e9, 100 )
stressNormal: npt.NDArray[ np.float64 ] = np.linspace( 5.0e8, 1.0e9, 100 ).astype( float )
# expected values
expectedValues: npt.NDArray[ np.float64 ] = np.array( [
888163490.0,
Expand Down Expand Up @@ -184,7 +184,7 @@ def test_computeShearStress( self: Self ) -> None:
obtained: npt.NDArray[ np.float64 ] = np.array( mohrCoulomb.computeShearStress( stressNormal ) )

# test results
self.assertSequenceEqual( expectedValues.tolist(), np.round( obtained ).tolist() )
self.assertSequenceEqual( expectedValues.tolist(), np.round( obtained ).tolist() ) # type: ignore[arg-type]

def test_computeFailureEnvelop1( self: Self ) -> None:
"""Test calculation of failure envelop from minimum normal stress."""
Expand Down Expand Up @@ -221,8 +221,12 @@ def test_computeFailureEnvelop1( self: Self ) -> None:
normalStressObtained, shearStressObtained = mohrCoulomb.computeFailureEnvelop( stressNormalMax, n=10 )

# test results
self.assertSequenceEqual( normalStressExpected.tolist(), np.round( normalStressObtained ).tolist() )
self.assertSequenceEqual( shearStressExpected.tolist(), np.round( shearStressObtained ).tolist() )
self.assertSequenceEqual(
normalStressExpected.tolist(), # type: ignore[arg-type]
np.round( normalStressObtained ).tolist() )
self.assertSequenceEqual(
shearStressExpected.tolist(), # type: ignore[arg-type]
np.round( shearStressObtained ).tolist() )

def test_computeFailureEnvelop2( self: Self ) -> None:
"""Test calculation of failure envelop in user-defined range."""
Expand Down Expand Up @@ -262,5 +266,9 @@ def test_computeFailureEnvelop2( self: Self ) -> None:
n=10 )

# test results
self.assertSequenceEqual( normalStressExpected.tolist(), np.round( normalStressObtained ).tolist() )
self.assertSequenceEqual( shearStressExpected.tolist(), np.round( shearStressObtained ).tolist() )
self.assertSequenceEqual(
normalStressExpected.tolist(), # type: ignore[arg-type]
np.round( normalStressObtained ).tolist() )
self.assertSequenceEqual(
shearStressExpected.tolist(), # type: ignore[arg-type]
np.round( shearStressObtained ).tolist() )
10 changes: 1 addition & 9 deletions geos-mesh/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,5 @@ addopts = [
"--import-mode=importlib",
]
pythonpath = [
"checks", "parsing",
"src",
]

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
ignore_missing_imports = true
allow_redefinition = true
plugins = "numpy.typing.mypy_plugin"
Loading
Loading