Skip to content

Commit

Permalink
Add linters and formatters, and workflows for checking and uploading …
Browse files Browse the repository at this point in the history
…to pypi
  • Loading branch information
finsberg committed Sep 18, 2024
1 parent 0a6ab3e commit 5400f89
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 52 deletions.
94 changes: 94 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
14 changes: 14 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: pre-commit

on:
pull_request:
push:
branches: [main]

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/[email protected]
42 changes: 42 additions & 0 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Release

on: [push, pull_request]

jobs:
dist:
runs-on: ubuntu-latest
container: ghcr.io/fenics/dolfinx/dolfinx:nightly
env:
DEB_PYTHON_INSTALL_LAYOUT: deb_system

steps:
- uses: actions/checkout@v4

- name: Install build dependencies
run: python3 -m pip install --upgrade build twine

- name: Build SDist and wheel
run: python3 -m build --no-isolation --sdist

- uses: actions/upload-artifact@v4
with:
path: dist/*

- name: Check metadata
run: python3 -m twine check dist/*

publish:
needs: [dist]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags')
environment: pypi
permissions:
id-token: write

steps:
- uses: actions/download-artifact@v4
with:
name: artifact
path: dist

- uses: pypa/gh-action-pypi-publish@release/v1
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ jobs:

- name: Run tests
run: python3 -m pytest

30 changes: 30 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-docstring-first
- id: debug-statements
- id: check-toml

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: 'v0.6.5'
hooks:
# Run the linter.
- id: ruff
args: [ --fix ]
# Run the formatter.
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.2
hooks:
- id: mypy
files: ^src/|^tests/
args: ["--config-file", "pyproject.toml"]
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ target_link_libraries(_scifem PRIVATE dolfinx)
set_target_properties(_scifem PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)

# Install directive for scikit-build-core
install(TARGETS _scifem LIBRARY DESTINATION ${PROJECT_NAME})
install(TARGETS _scifem LIBRARY DESTINATION ${PROJECT_NAME})
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This package contains a collection of tools for scientific computing with a focus on finite element methods. The tools are written in Python and are intended to be used in conjunction with the [dolfinx](https://github.com/FEniCS/dolfinx).

Many users that are transitioning from legacy FEniCS to FEniCSx may find the transition difficult due to the lack of some functionalities in FEniCSx. This package aims to provide some of the functionalities that are missing in FEniCSx. The package is still in its early stages and many functionalities are still missing.
Many users that are transitioning from legacy FEniCS to FEniCSx may find the transition difficult due to the lack of some functionalities in FEniCSx. This package aims to provide some of the functionalities that are missing in FEniCSx. The package is still in its early stages and many functionalities are still missing.


## Installation
Expand All @@ -21,4 +21,4 @@ If you are having issues, feature request or would like to contribute, please le


## LICENSE
MIT
MIT
43 changes: 42 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ repository = "https://github.com/scientificcomputing/scifem.git"
[project.optional-dependencies]
docs = []
test = ["pytest"]
dev = ["ruff", "mypy", "bump-my-version", "pre-commit"]


[tool.pytest.ini_options]
Expand Down Expand Up @@ -87,4 +88,44 @@ max-complexity = 10


[tool.ruff.lint.pydocstyle]
convention = "google"
convention = "google"


[tool.ruff.lint.isort]
known-first-party = ["scifem"]
known-third-party = [
"basix",
"dolfinx",
"ffcx",
"ufl",
"gmsh",
"numpy",
"pytest",
]
section-order = [
"future",
"standard-library",
"mpi",
"third-party",
"first-party",
"local-folder",
]
[tool.ruff.lint.isort.sections]
"mpi" = ["mpi4py", "petsc4py"]


[tool.bumpversion]
allow_dirty = false
commit = true
message = "Bump version: {current_version} → {new_version}"
tag = true
sign_tags = false
tag_name = "v{new_version}"
tag_message = "Bump version: {current_version} → {new_version}"
current_version = "0.1.0"


[[tool.bumpversion.files]]
filename = "pyproject.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'
92 changes: 51 additions & 41 deletions src/scifem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,64 +8,74 @@
#include <dolfinx/fem/FiniteElement.h>
#include <dolfinx/fem/FunctionSpace.h>
#include <dolfinx/mesh/Mesh.h>
#include <memory>
#include <nanobind/nanobind.h>
#include <nanobind/stl/shared_ptr.h>
#include <memory>
using namespace dolfinx;

namespace scifem
{
template <typename T>
dolfinx::fem::FunctionSpace<T> create_real_functionspace(std::shared_ptr<const dolfinx::mesh::Mesh<T>> mesh)
{
template <typename T>
dolfinx::fem::FunctionSpace<T>
create_real_functionspace(std::shared_ptr<const dolfinx::mesh::Mesh<T>> mesh)
{

basix::FiniteElement e_v = basix::create_element<T>(
basix::element::family::P, mesh::cell_type_to_basix_type(mesh->topology()->cell_type()), 0,
basix::element::lagrange_variant::unset, basix::element::dpc_variant::unset, true);
basix::FiniteElement e_v = basix::create_element<T>(
basix::element::family::P,
mesh::cell_type_to_basix_type(mesh->topology()->cell_type()), 0,
basix::element::lagrange_variant::unset,
basix::element::dpc_variant::unset, true);

// NOTE: Optimize input source/dest later as we know this a priori
std::int32_t num_dofs = (dolfinx::MPI::rank(MPI_COMM_WORLD) == 0) ? 1 : 0;
std::int32_t num_ghosts = (dolfinx::MPI::rank(MPI_COMM_WORLD) != 0) ? 1 : 0;
std::vector<std::int64_t> ghosts(num_ghosts, 0);
ghosts.reserve(1);
std::vector<int> owners(num_ghosts, 0);
owners.reserve(1);
std::shared_ptr<const dolfinx::common::IndexMap> imap =
std::make_shared<const dolfinx::common::IndexMap>(MPI_COMM_WORLD, num_dofs, ghosts, owners);
int index_map_bs = 1;
int bs = 1;
// Element dof layout
fem::ElementDofLayout dof_layout(1, e_v.entity_dofs(), e_v.entity_closure_dofs(), {}, {});
std::size_t num_cells_on_process = mesh->topology()->index_map(mesh->topology()->dim())->size_local() +
mesh->topology()->index_map(mesh->topology()->dim())->num_ghosts();
// NOTE: Optimize input source/dest later as we know this a priori
std::int32_t num_dofs = (dolfinx::MPI::rank(MPI_COMM_WORLD) == 0) ? 1 : 0;
std::int32_t num_ghosts = (dolfinx::MPI::rank(MPI_COMM_WORLD) != 0) ? 1 : 0;
std::vector<std::int64_t> ghosts(num_ghosts, 0);
ghosts.reserve(1);
std::vector<int> owners(num_ghosts, 0);
owners.reserve(1);
std::shared_ptr<const dolfinx::common::IndexMap> imap
= std::make_shared<const dolfinx::common::IndexMap>(
MPI_COMM_WORLD, num_dofs, ghosts, owners);
int index_map_bs = 1;
int bs = 1;
// Element dof layout
fem::ElementDofLayout dof_layout(1, e_v.entity_dofs(),
e_v.entity_closure_dofs(), {}, {});
std::size_t num_cells_on_process
= mesh->topology()->index_map(mesh->topology()->dim())->size_local()
+ mesh->topology()->index_map(mesh->topology()->dim())->num_ghosts();

std::vector<std::int32_t> dofmap(num_cells_on_process, 0);
dofmap.reserve(1);
std::shared_ptr<const dolfinx::fem::DofMap> real_dofmap =
std::make_shared<const dolfinx::fem::DofMap>(dof_layout, imap, index_map_bs, dofmap, bs);
std::vector<std::size_t> value_shape(0);
std::vector<std::int32_t> dofmap(num_cells_on_process, 0);
dofmap.reserve(1);
std::shared_ptr<const dolfinx::fem::DofMap> real_dofmap
= std::make_shared<const dolfinx::fem::DofMap>(dof_layout, imap,
index_map_bs, dofmap, bs);
std::vector<std::size_t> value_shape(0);

std::shared_ptr<const dolfinx::fem::FiniteElement<T>> d_el =
std::make_shared<const dolfinx::fem::FiniteElement<T>>(e_v, 1, false);
std::shared_ptr<const dolfinx::fem::FiniteElement<T>> d_el
= std::make_shared<const dolfinx::fem::FiniteElement<T>>(e_v, 1, false);

return dolfinx::fem::FunctionSpace<T>(mesh, d_el, real_dofmap, value_shape);
}
return dolfinx::fem::FunctionSpace<T>(mesh, d_el, real_dofmap, value_shape);
}
} // namespace scifem

namespace scifem_wrapper
{
template <typename T>
void declare_real_function_space(nanobind::module_ &m, std::string type)
{
std::string pyfunc_name = "create_real_functionspace_" + type;
m.def(pyfunc_name.c_str(), [](std::shared_ptr<const dolfinx::mesh::Mesh<T>> mesh)
{ return scifem::create_real_functionspace<T>(mesh); }, "Create a real function space");
}
template <typename T>
void declare_real_function_space(nanobind::module_& m, std::string type)
{
std::string pyfunc_name = "create_real_functionspace_" + type;
m.def(
pyfunc_name.c_str(),
[](std::shared_ptr<const dolfinx::mesh::Mesh<T>> mesh)
{ return scifem::create_real_functionspace<T>(mesh); },
"Create a real function space");
}

} // namespace scifem_wrapper

NB_MODULE(_scifem, m)
{
scifem_wrapper::declare_real_function_space<double>(m, "float64");
scifem_wrapper::declare_real_function_space<float>(m, "float32");
}
scifem_wrapper::declare_real_function_space<double>(m, "float64");
scifem_wrapper::declare_real_function_space<float>(m, "float32");
}
Loading

0 comments on commit 5400f89

Please sign in to comment.