basalt-mesh 0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. basalt_mesh-0.1/.gitattributes +4 -0
  2. basalt_mesh-0.1/.github/ISSUE_TEMPLATE/bug.md +34 -0
  3. basalt_mesh-0.1/.github/ISSUE_TEMPLATE/feature.md +22 -0
  4. basalt_mesh-0.1/.github/PULL_REQUEST_TEMPLATE.md +26 -0
  5. basalt_mesh-0.1/.github/workflows/ci.yml +40 -0
  6. basalt_mesh-0.1/.github/workflows/release.yml +44 -0
  7. basalt_mesh-0.1/.gitignore +281 -0
  8. basalt_mesh-0.1/.readthedocs.yaml +23 -0
  9. basalt_mesh-0.1/CMakeLists.txt +219 -0
  10. basalt_mesh-0.1/CONTRIBUTING.md +4 -0
  11. basalt_mesh-0.1/LICENSE +21 -0
  12. basalt_mesh-0.1/PKG-INFO +89 -0
  13. basalt_mesh-0.1/README.rst +79 -0
  14. basalt_mesh-0.1/basalt/__init__.py +95 -0
  15. basalt_mesh-0.1/basalt/_core/__init__.py +9 -0
  16. basalt_mesh-0.1/docs/.gitignore +2 -0
  17. basalt_mesh-0.1/docs/Makefile +20 -0
  18. basalt_mesh-0.1/docs/_static/custom.css +23 -0
  19. basalt_mesh-0.1/docs/_static/logo.svg +9 -0
  20. basalt_mesh-0.1/docs/_templates/class.rst +7 -0
  21. basalt_mesh-0.1/docs/_templates/layout.html +4 -0
  22. basalt_mesh-0.1/docs/api.rst +40 -0
  23. basalt_mesh-0.1/docs/changelog.rst +25 -0
  24. basalt_mesh-0.1/docs/conf.py +69 -0
  25. basalt_mesh-0.1/docs/contributing.rst +103 -0
  26. basalt_mesh-0.1/docs/format.rst +99 -0
  27. basalt_mesh-0.1/docs/index.rst +13 -0
  28. basalt_mesh-0.1/docs/install.rst +187 -0
  29. basalt_mesh-0.1/docs/notebooks/tutorials/w7x_neutronics.ipynb +17525 -0
  30. basalt_mesh-0.1/docs/usage.rst +130 -0
  31. basalt_mesh-0.1/nx_journals/export_attrs.cs +725 -0
  32. basalt_mesh-0.1/nx_journals/restructure_w7x.cs +387 -0
  33. basalt_mesh-0.1/pixi.toml +84 -0
  34. basalt_mesh-0.1/pyproject.toml +92 -0
  35. basalt_mesh-0.1/src/basalt.cpp +1129 -0
  36. basalt_mesh-0.1/src/basalt.h +573 -0
  37. basalt_mesh-0.1/src/init.cpp +80 -0
  38. basalt_mesh-0.1/src/init.h +17 -0
  39. basalt_mesh-0.1/src/python/nbbasalt.cpp +43 -0
  40. basalt_mesh-0.1/tests/__init__.py +1 -0
  41. basalt_mesh-0.1/tests/conftest.py +27 -0
  42. basalt_mesh-0.1/tests/data/README.rst +119 -0
  43. basalt_mesh-0.1/tests/test_centroid_matching.py +170 -0
  44. basalt_mesh-0.1/tests/test_smoke.py +35 -0
@@ -0,0 +1,4 @@
1
+ # SCM syntax highlighting & preventing 3-way merges
2
+ pixi.lock merge=binary linguist-language=YAML linguist-generated=true
3
+ tests/data/*.x_t filter=lfs diff=lfs merge=lfs -text
4
+ tests/data/*.step filter=lfs diff=lfs merge=lfs -text
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a bug or unexpected behaviour
4
+ title: "[bug] "
5
+ labels: bug
6
+ ---
7
+
8
+ ## Description
9
+
10
+ A clear description of the bug.
11
+
12
+ ## To reproduce
13
+
14
+ Minimal, self-contained example. Include the input geometry if possible.
15
+
16
+ ```python
17
+ import basalt
18
+ # ...
19
+ ```
20
+
21
+ ## Expected behaviour
22
+
23
+ What you expected to happen.
24
+
25
+ ## Actual behaviour
26
+
27
+ What actually happened. Include the full traceback or error output.
28
+
29
+ ## Environment
30
+
31
+ - basalt version: <!-- python -c "import basalt; print(basalt.__version__)" -->
32
+ - Simmetrix SimModSuite version: <!-- e.g. 2025.0-250920 -->
33
+ - Python version: <!-- python --version -->
34
+ - OS / glibc: <!-- e.g. Ubuntu 24.04, glibc 2.39 -->
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: Feature request
3
+ about: Propose a new feature or enhancement
4
+ title: "[feature] "
5
+ labels: enhancement
6
+ ---
7
+
8
+ ## Use case
9
+
10
+ What are you trying to accomplish?
11
+
12
+ ## Proposed solution
13
+
14
+ How you imagine this would work in basalt (API sketch, behaviour, etc.).
15
+
16
+ ## Alternatives considered
17
+
18
+ Any workarounds or alternative approaches you've evaluated.
19
+
20
+ ## Additional context
21
+
22
+ Links to related issues, papers, or upstream discussions.
@@ -0,0 +1,26 @@
1
+ ## Summary
2
+
3
+ <!-- One or two sentences describing what this PR changes and why. -->
4
+
5
+ ## Related issues
6
+
7
+ <!-- Links to issues, e.g. "Closes #42" or "Refs #17". -->
8
+
9
+ ## Changes
10
+
11
+ <!-- Bullet list of the user-visible changes in this PR. -->
12
+
13
+ ## Testing
14
+
15
+ <!--
16
+ The public CI runs lint and the Sphinx build only — it does NOT run
17
+ the test suite (which requires a Simmetrix SimModSuite license).
18
+ Maintainers: confirm `pixi run build` and `pixi run pytest` pass locally
19
+ before merging.
20
+ -->
21
+
22
+ - [ ] `pixi run build` succeeds locally against my SMS install
23
+ - [ ] `pixi run pytest` passes locally
24
+ - [ ] Lint passes (`ruff check .` and `ruff format --check .`)
25
+ - [ ] Documentation updated where relevant
26
+ - [ ] Changelog entry added (`docs/changelog.rst`)
@@ -0,0 +1,40 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ lint:
10
+ name: Lint (ruff)
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/ruff-action@v3
15
+ with:
16
+ version: "0.12.10"
17
+ args: "check ."
18
+ - uses: astral-sh/ruff-action@v3
19
+ with:
20
+ version: "0.12.10"
21
+ args: "format --check ."
22
+
23
+ docs:
24
+ name: Sphinx docs build
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: prefix-dev/setup-pixi@v0.8.1
29
+ with:
30
+ pixi-version: v0.64.0
31
+ cache: true
32
+ environments: docs
33
+ - name: Build Sphinx documentation
34
+ run: pixi run -e docs docs
35
+ - name: Upload built docs as artifact
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: docs-html
39
+ path: docs/_build/html
40
+ retention-days: 14
@@ -0,0 +1,44 @@
1
+ name: Publish to PyPI
2
+
3
+ # Trusted Publisher flow: PyPI verifies our OIDC token against a configured
4
+ # pending/active publisher on the project (owner=Thea-Energy, repo=basalt,
5
+ # workflow=release.yml, environment=pypi). No API token is stored anywhere.
6
+ # See https://docs.pypi.org/trusted-publishers/.
7
+ #
8
+ # Triggers:
9
+ # - Publishing a GitHub Release (the standard path: tag + Release UI).
10
+ # - Manual workflow_dispatch with an explicit ref input (used to publish
11
+ # tags that predate this workflow, e.g. v0.1).
12
+
13
+ on:
14
+ release:
15
+ types: [published]
16
+ workflow_dispatch:
17
+ inputs:
18
+ ref:
19
+ description: 'Tag or branch to publish from (e.g. v0.1)'
20
+ required: true
21
+ default: 'main'
22
+
23
+ jobs:
24
+ publish:
25
+ name: Build sdist and publish to PyPI
26
+ runs-on: ubuntu-latest
27
+ environment:
28
+ name: pypi
29
+ url: https://pypi.org/project/basalt-mesh/
30
+ permissions:
31
+ id-token: write
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ with:
35
+ ref: ${{ github.event.release.tag_name || inputs.ref }}
36
+ - uses: actions/setup-python@v5
37
+ with:
38
+ python-version: '3.12'
39
+ - name: Build sdist
40
+ run: |
41
+ python -m pip install --upgrade build
42
+ python -m build --sdist
43
+ - name: Publish to PyPI
44
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,281 @@
1
+ doc/
2
+ docs/_build/
3
+ docs/api/generated/
4
+ docs/generated/
5
+ include/
6
+ lib/
7
+ dist/
8
+ wheelhouse/
9
+ .cache/
10
+ _deps/
11
+ build/
12
+ # Ignore CMake-generated artifacts in basalt/_core/, but keep the __init__.py
13
+ # package marker (committed so scikit-build-core's editable install can register
14
+ # `basalt._core` as a known module).
15
+ basalt/_core/*
16
+ !basalt/_core/__init__.py
17
+ autogen/
18
+ scratch/
19
+ *.lock
20
+ CLAUDE.md
21
+ *.pdf
22
+ *.json
23
+ *.Identifier
24
+
25
+ .envrc
26
+ .vscode/
27
+
28
+ *.msh
29
+ *.sms
30
+ *.smd
31
+ *.x_t
32
+ *.x_b
33
+ *.prt
34
+ *.step
35
+
36
+ # Allow test data files tracked by Git LFS
37
+ !tests/data/*.x_t
38
+ !tests/data/*.json
39
+ !tests/data/*.step
40
+ *.brep
41
+ *.log
42
+ *.lic
43
+ TheaEnergy*
44
+ *.stl
45
+ *.conda
46
+ *.so
47
+ *.pyi
48
+
49
+ *.log# pixi environments
50
+ .pixi/*
51
+ !.pixi/config.toml
52
+
53
+ Created by https://www.toptal.com/developers/gitignore/api/python,c++,cmake
54
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,c++,cmake
55
+
56
+ ### C++ ###
57
+ # Prerequisites
58
+ *.d
59
+
60
+ # Compiled Object files
61
+ *.slo
62
+ *.lo
63
+ *.o
64
+ *.obj
65
+
66
+ # Precompiled Headers
67
+ *.gch
68
+ *.pch
69
+
70
+ # Compiled Dynamic libraries
71
+ *.so
72
+ *.dylib
73
+ *.dll
74
+
75
+ # Fortran module files
76
+ *.mod
77
+ *.smod
78
+
79
+ # Compiled Static libraries
80
+ *.lai
81
+ *.la
82
+ *.a
83
+ *.lib
84
+
85
+ # Executables
86
+ *.exe
87
+ *.out
88
+ *.app
89
+
90
+ ### CMake ###
91
+ CMakeLists.txt.user
92
+ CMakeCache.txt
93
+ CMakeFiles
94
+ CMakeScripts
95
+ Testing
96
+ Makefile
97
+ !docs/Makefile
98
+ cmake_install.cmake
99
+ install_manifest.txt
100
+ compile_commands.json
101
+ CTestTestfile.cmake
102
+ _deps
103
+
104
+ ### CMake Patch ###
105
+ CMakeUserPresets.json
106
+
107
+ # External projects
108
+ *-prefix/
109
+
110
+ ### Python ###
111
+ # Byte-compiled / optimized / DLL files
112
+ __pycache__/
113
+ *.py[cod]
114
+ *$py.class
115
+
116
+ # C extensions
117
+
118
+ # Distribution / packaging
119
+ .Python
120
+ build/
121
+ develop-eggs/
122
+ dist/
123
+ downloads/
124
+ eggs/
125
+ .eggs/
126
+ lib/
127
+ lib64/
128
+ parts/
129
+ sdist/
130
+ var/
131
+ wheels/
132
+ share/python-wheels/
133
+ *.egg-info/
134
+ .installed.cfg
135
+ *.egg
136
+ MANIFEST
137
+
138
+ # PyInstaller
139
+ # Usually these files are written by a python script from a template
140
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
141
+ *.manifest
142
+ *.spec
143
+
144
+ # Installer logs
145
+ pip-log.txt
146
+ pip-delete-this-directory.txt
147
+
148
+ # Unit test / coverage reports
149
+ htmlcov/
150
+ .tox/
151
+ .nox/
152
+ .coverage
153
+ .coverage.*
154
+ .cache
155
+ nosetests.xml
156
+ coverage.xml
157
+ *.cover
158
+ *.py,cover
159
+ .hypothesis/
160
+ .pytest_cache/
161
+ cover/
162
+
163
+ # Translations
164
+ *.mo
165
+ *.pot
166
+
167
+ # Django stuff:
168
+ *.log
169
+ local_settings.py
170
+ db.sqlite3
171
+ db.sqlite3-journal
172
+
173
+ # Flask stuff:
174
+ instance/
175
+ .webassets-cache
176
+
177
+ # Scrapy stuff:
178
+ .scrapy
179
+
180
+ # Sphinx documentation
181
+ docs/_build/
182
+
183
+ # PyBuilder
184
+ .pybuilder/
185
+ target/
186
+
187
+ # Jupyter Notebook
188
+ .ipynb_checkpoints
189
+
190
+ # IPython
191
+ profile_default/
192
+ ipython_config.py
193
+
194
+ # pyenv
195
+ # For a library or package, you might want to ignore these files since the code is
196
+ # intended to run in multiple environments; otherwise, check them in:
197
+ # .python-version
198
+
199
+ # pipenv
200
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
201
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
202
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
203
+ # install all needed dependencies.
204
+ #Pipfile.lock
205
+
206
+ # poetry
207
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
208
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
209
+ # commonly ignored for libraries.
210
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
211
+ #poetry.lock
212
+
213
+ # pdm
214
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
215
+ #pdm.lock
216
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
217
+ # in version control.
218
+ # https://pdm.fming.dev/#use-with-ide
219
+ .pdm.toml
220
+
221
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
222
+ __pypackages__/
223
+
224
+ # Celery stuff
225
+ celerybeat-schedule
226
+ celerybeat.pid
227
+
228
+ # SageMath parsed files
229
+ *.sage.py
230
+
231
+ # Environments
232
+ .env
233
+ .venv
234
+ env/
235
+ venv/
236
+ ENV/
237
+ env.bak/
238
+ venv.bak/
239
+
240
+ # Spyder project settings
241
+ .spyderproject
242
+ .spyproject
243
+
244
+ # Rope project settings
245
+ .ropeproject
246
+
247
+ # mkdocs documentation
248
+ /site
249
+
250
+ # mypy
251
+ .mypy_cache/
252
+ .dmypy.json
253
+ dmypy.json
254
+
255
+ # Pyre type checker
256
+ .pyre/
257
+
258
+ # pytype static type analyzer
259
+ .pytype/
260
+
261
+ # Cython debug symbols
262
+ cython_debug/
263
+
264
+ # PyCharm
265
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
266
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
267
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
268
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
269
+ #.idea/
270
+
271
+ ### Python Patch ###
272
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
273
+ poetry.toml
274
+
275
+ # ruff
276
+ .ruff_cache/
277
+
278
+ # LSP config files
279
+ pyrightconfig.json
280
+
281
+ # End of https://www.toptal.com/developers/gitignore/api/python,c++,cmake
@@ -0,0 +1,23 @@
1
+ # Read the Docs configuration file
2
+ # https://docs.readthedocs.io/en/stable/config-file/v2.html
3
+
4
+ version: 2
5
+
6
+ build:
7
+ os: ubuntu-22.04
8
+ tools:
9
+ python: "3.12"
10
+ jobs:
11
+ post_create_environment:
12
+ - pip install pixi-cli
13
+ post_install:
14
+ - pixi install -e docs
15
+ commands:
16
+ - pixi run -e docs sphinx-build -b html docs $READTHEDOCS_OUTPUT/html
17
+
18
+ sphinx:
19
+ configuration: docs/conf.py
20
+ fail_on_warning: false
21
+
22
+ formats:
23
+ - htmlzip
@@ -0,0 +1,219 @@
1
+ cmake_minimum_required(VERSION 3.15)
2
+
3
+ project(basalt)
4
+
5
+ set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
6
+
7
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Resolves -fPIC errors
8
+
9
+ include(FetchContent)
10
+ set(FETCHCONTENT_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/_deps)
11
+ set(FETCHCONTENT_QUIET TRUE)
12
+
13
+ find_package(
14
+ Python 3.10
15
+ COMPONENTS Interpreter Development.Module
16
+ REQUIRED)
17
+
18
+
19
+ # ===============================================================================
20
+ # Nanobind
21
+ # ===============================================================================
22
+ execute_process(
23
+ COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
24
+ OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT)
25
+ find_package(nanobind CONFIG REQUIRED)
26
+
27
+
28
+ # ===============================================================================
29
+ # Simmetrix SimModSuite (bring-your-own)
30
+ # ===============================================================================
31
+ if(NOT DEFINED ENV{SIMMODSUITE_ROOT})
32
+ message(FATAL_ERROR
33
+ "SIMMODSUITE_ROOT environment variable is not set.\n"
34
+ "basalt does not bundle Simmetrix SimModSuite. Download the gmcore, mscore, pskrnl, "
35
+ "and simlicense tarballs from Simmetrix's customer portal (all at the same "
36
+ "version-datestamp), extract them into one parent directory, and set "
37
+ "SIMMODSUITE_ROOT to the resulting <version>-<datestamp>/ directory.\n"
38
+ "See docs/install.rst for full instructions.")
39
+ endif()
40
+
41
+ set(SIMMODSUITE_ROOT "$ENV{SIMMODSUITE_ROOT}" CACHE PATH "Simmetrix SimModSuite install root")
42
+
43
+ if(DEFINED ENV{SIMMODSUITE_ABI})
44
+ set(SIMMODSUITE_ABI "$ENV{SIMMODSUITE_ABI}" CACHE STRING "Simmetrix ABI subdirectory")
45
+ else()
46
+ set(SIMMODSUITE_ABI "x64_rhel9_gcc11" CACHE STRING "Simmetrix ABI subdirectory (default)")
47
+ endif()
48
+
49
+ set(SIMMODSUITE_INCLUDE "${SIMMODSUITE_ROOT}/include")
50
+ set(SIMMODSUITE_LIB "${SIMMODSUITE_ROOT}/lib/${SIMMODSUITE_ABI}")
51
+
52
+ if(NOT EXISTS "${SIMMODSUITE_INCLUDE}/SimUtil.h")
53
+ message(FATAL_ERROR
54
+ "Simmetrix headers not found at ${SIMMODSUITE_INCLUDE}/SimUtil.h. "
55
+ "Check SIMMODSUITE_ROOT and that all four module tarballs are extracted "
56
+ "into a unified install tree.")
57
+ endif()
58
+
59
+ if(NOT IS_DIRECTORY "${SIMMODSUITE_LIB}")
60
+ message(FATAL_ERROR
61
+ "Simmetrix library directory not found at ${SIMMODSUITE_LIB}. "
62
+ "Set SIMMODSUITE_ABI to your install's ABI subdirectory "
63
+ "(default: x64_rhel9_gcc11; alternatives: x64_rhel8_gcc83).")
64
+ endif()
65
+
66
+ # Glob-detect SimParasolid so version bumps (SimParasolid380 -> SimParasolid390 -> ...)
67
+ # do not require build changes.
68
+ file(GLOB SIM_PARASOLID_LIBS "${SIMMODSUITE_LIB}/libSimParasolid*.a")
69
+ list(LENGTH SIM_PARASOLID_LIBS SIM_PARASOLID_COUNT)
70
+ if(NOT SIM_PARASOLID_COUNT EQUAL 1)
71
+ message(FATAL_ERROR
72
+ "Expected exactly one libSimParasolid*.a in ${SIMMODSUITE_LIB}, "
73
+ "found ${SIM_PARASOLID_COUNT}: ${SIM_PARASOLID_LIBS}")
74
+ endif()
75
+ get_filename_component(SIM_PARASOLID_NAME "${SIM_PARASOLID_LIBS}" NAME_WE)
76
+ string(REGEX REPLACE "^lib" "" SIM_PARASOLID_LIBNAME "${SIM_PARASOLID_NAME}")
77
+
78
+ add_library(sms INTERFACE)
79
+ target_include_directories(sms INTERFACE "${SIMMODSUITE_INCLUDE}")
80
+ target_link_directories(sms INTERFACE
81
+ "${SIMMODSUITE_LIB}"
82
+ "${SIMMODSUITE_LIB}/psKrnl")
83
+
84
+ set(SMS_LINK_LIBS
85
+ ${SIM_PARASOLID_LIBNAME}
86
+ SimPartitionedMesh
87
+ SimPartitionWrapper
88
+ SimMeshing
89
+ SimMeshTools
90
+ SimModel
91
+ pskernel
92
+ SimLicense)
93
+
94
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
95
+ list(APPEND SMS_LINK_LIBS tirpc)
96
+ endif()
97
+
98
+ target_link_libraries(sms INTERFACE ${SMS_LINK_LIBS})
99
+
100
+ # Compile-time default schema dir; init.cpp setenvs P_SCHEMA from this with
101
+ # overwrite=0 (preserves customer override).
102
+ target_compile_definitions(sms INTERFACE
103
+ PSKRNL_SCHEMA_DIR="${SIMMODSUITE_LIB}/psKrnl/schema")
104
+
105
+ # ===============================================================================
106
+ # Gmsh
107
+ # ===============================================================================
108
+ find_library(GMSH_LIB gmsh)
109
+ if(NOT GMSH_LIB)
110
+ message(FATAL_ERROR "Could not find libgmsh")
111
+ endif()
112
+ get_filename_component(GMSH_LIBDIR "${GMSH_LIB}" DIRECTORY)
113
+
114
+ find_path(GMSH_INC gmsh.h)
115
+ if(NOT GMSH_INC)
116
+ message(FATAL_ERROR "Could not find gmsh.h")
117
+ endif()
118
+
119
+ include_directories(${GMSH_INC})
120
+
121
+
122
+ # ===============================================================================
123
+ # JSON
124
+ # ===============================================================================
125
+ find_package(nlohmann_json REQUIRED)
126
+
127
+ # ===============================================================================
128
+ # Logging
129
+ # ===============================================================================
130
+ set(SPDLOG_VERSION v1.12.0)
131
+ FetchContent_Declare(
132
+ spdlog URL https://github.com/gabime/spdlog/archive/${SPDLOG_VERSION}.tar.gz)
133
+
134
+ FetchContent_MakeAvailable(spdlog)
135
+
136
+ # ===============================================================================
137
+ # Main Library
138
+ # ===============================================================================
139
+ add_library(
140
+ main
141
+ src/init.cpp
142
+ src/basalt.cpp
143
+ )
144
+ target_include_directories(main PUBLIC ${SRC_DIR})
145
+ target_link_libraries(main PUBLIC
146
+ nanobind
147
+ sms
148
+ spdlog::spdlog
149
+ ${GMSH_LIB}
150
+ nlohmann_json::nlohmann_json
151
+ )
152
+
153
+ # ===============================================================================
154
+ # Python Bindings
155
+ # ===============================================================================
156
+ file(GLOB PYTHON_SOURCES ${SRC_DIR}/python/*.cpp)
157
+ nanobind_add_module(_core NB_SHARED # STATIC is the default
158
+ ${PYTHON_SOURCES})
159
+
160
+ # Each consumer sets CMAKE_INSTALL_PREFIX itself:
161
+ # - dev pixi `build` task installs with --prefix .
162
+ # - scikit-build-core installs into its temporary prefix and collects from there
163
+ # - pixi-build-python (which routes through scikit-build-core) likewise
164
+ # $ORIGIN keeps _core.so finding sibling .so files inside basalt/_core/ regardless
165
+ # of where the wheel is installed.
166
+
167
+ # Inspect RPATH with: readelf -d basalt/_core/_core.cpython-*.so | grep RUNPATH
168
+ set_property(
169
+ TARGET _core
170
+ APPEND
171
+ PROPERTY INSTALL_RPATH
172
+ "$ORIGIN:${GMSH_LIBDIR}:${SIMMODSUITE_LIB}/psKrnl")
173
+
174
+ nanobind_add_stub(
175
+ _core_stub
176
+ MODULE
177
+ _core
178
+ OUTPUT
179
+ _core.pyi
180
+ PYTHON_PATH
181
+ "."
182
+ DEPENDS
183
+ _core)
184
+
185
+ target_link_libraries(_core PRIVATE main)
186
+ target_include_directories(_core PRIVATE ${SRC_DIR}/python)
187
+ target_include_directories(_core PRIVATE ${SRC_DIR}/autogen)
188
+
189
+ set(GEN_FILES
190
+ basalt.h
191
+ )
192
+ foreach (SOURCE_FILE ${GEN_FILES})
193
+ get_filename_component(FILE_NAME ${SOURCE_FILE} NAME_WE)
194
+ set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/${SOURCE_FILE}")
195
+ set(OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/autogen")
196
+ set (OUTPUT_FILE "${OUTPUT_DIR}/bind_${FILE_NAME}.h")
197
+ list(APPEND GENERATED_FILES ${OUTPUT_FILE})
198
+
199
+ # nanobindgen does not create its output directory itself, and the sdist
200
+ # excludes the gitignored `src/autogen/` tree, so make sure the directory
201
+ # exists before invoking the generator.
202
+ file(MAKE_DIRECTORY ${OUTPUT_DIR})
203
+
204
+ add_custom_command(
205
+ OUTPUT ${OUTPUT_FILE}
206
+ COMMAND python -m nanobindgen -o ${OUTPUT_DIR}
207
+ ${INPUT_FILE}
208
+ DEPENDS ${INPUT_FILE} ${GEN_SCRIPT}
209
+ COMMENT "Generating bindings for ${SOURCE_FILE}")
210
+ endforeach ()
211
+
212
+ add_custom_target(generate_bindings DEPENDS ${GENERATED_FILES})
213
+ add_dependencies(_core generate_bindings)
214
+
215
+ # ===============================================================================
216
+ # Install
217
+ # ===============================================================================
218
+ install(TARGETS _core nanobind DESTINATION "basalt/_core")
219
+ install(FILES ${CMAKE_BINARY_DIR}/_core.pyi DESTINATION "basalt/_core" OPTIONAL)
@@ -0,0 +1,4 @@
1
+ # Contributing
2
+
3
+ See the rendered contribution guide at [docs/contributing.rst](docs/contributing.rst)
4
+ or in the published documentation.