diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 4dda091cc..d1e309bd2 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
arch: [x86_64]
- cw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
+ cw_build: ["cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*"]
steps:
- uses: actions/checkout@v4
@@ -35,7 +35,7 @@ jobs:
strategy:
matrix:
arch: [arm64]
- cw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
+ cw_build: ["cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*"]
steps:
- uses: actions/checkout@v4
@@ -60,7 +60,7 @@ jobs:
strategy:
matrix:
arch: [x86_64]
- cw_build: ["cp39*many*", "cp310*many*", "cp311*many*", "cp312*many*", "cp313*many*"]
+ cw_build: ["cp310*many*", "cp311*many*", "cp312*many*", "cp313*many*", "cp314*many*"]
steps:
- uses: actions/checkout@v4
@@ -85,7 +85,7 @@ jobs:
strategy:
matrix:
arch: [AMD64]
- cw_build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"]
+ cw_build: ["cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*"]
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/test_full.yml b/.github/workflows/test_full.yml
index 21b502252..9f060ac53 100644
--- a/.github/workflows/test_full.yml
+++ b/.github/workflows/test_full.yml
@@ -18,7 +18,7 @@ jobs:
SPLINEPY_GITHUB_ACTIONS_BUILD: True
strategy:
matrix:
- python-version: [3.9, "3.10", "3.11", "3.12", "3.13"]
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
diff --git a/.gitmodules b/.gitmodules
index 2d8a696ec..b5ddf721c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -3,10 +3,10 @@
url = git@github.com:pybind/pybind11.git
[submodule "third_party/napf"]
path = third_party/napf
- url = git@github.com:tataratat/napf.git
+ url = git@github.com:isosuite/napf.git
[submodule "third_party/BSplineLib"]
path = third_party/BSplineLib
- url = git@github.com:tataratat/BSplineLib.git
+ url = git@github.com:isosuite/BSplineLib.git
[submodule "third_party/bezman"]
path = third_party/bezman
- url = git@github.com:tataratat/bezman.git
+ url = git@github.com:isosuite/bezman.git
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 388115dcd..0be11c149 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -6,7 +6,8 @@
# use default options for ci
ci:
- autoupdate_schedule: "weekly"
+ autoupdate_branch: 'develop'
+ autoupdate_schedule: "monthly"
submodules: false
repos:
@@ -24,24 +25,19 @@ repos:
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
+ exclude: '^tests/data/.*$'
- id: mixed-line-ending
- id: requirements-txt-fixer
- id: trailing-whitespace
-- repo: https://github.com/psf/black-pre-commit-mirror
- rev: "26.3.1"
- hooks:
- - id: black
- additional_dependencies: [tomli]
-
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.15.7
+ rev: v0.15.16
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/pre-commit/mirrors-clang-format
- rev: v22.1.1
+ rev: v22.1.5
hooks:
- id: clang-format
types_or: [c, c++]
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..c182baa29
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,157 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [0.2.1] - 2026-06
+
+### Added
+
+#### Swept Surface/Solid Generation
+- New `splinepy.helpme.create.swept()` function for generating swept surfaces and solids by sweeping a cross-section along a trajectory spline ([examples/show_swept.py](examples/show_swept.py))
+ - Supports curve (1D) and surface (2D) cross-sections to produce surfaces and solids respectively
+ - Cross-section orientation uses the projection-normal method (Siltanen & Woodward), following [The NURBS Book](https://link.springer.com/book/10.1007/978-3-642-59223-2), Piegl & Tiller, 2nd ed., Chapter 10.4
+ - Supports closed trajectories with orientation correction (p. 483 of the NURBS book)
+ - `anchor` parameter controls which reference point of the cross-section is placed on the trajectory (`"parametric"`, `"control_box"`, `"geometry_box"`, or `"auto"`)
+ - `set_on_trajectory` parameter selects between placement at trajectory knot evaluation points or trajectory control points
+ - Optional `rotation_adaption` parameter for additional rotation of the cross-section around the trajectory tangent
+ - Added swept surface image to README and documentation
+
+#### IGA Assembly: `FieldIntegrator` and `Transformation`
+- New `Transformation` class in `splinepy.helpme.integrate` encapsulating all quadrature and geometry transformation data needed for IGA discretization:
+ - Precomputes quadrature points, supports, Jacobians, Jacobian inverses, and Jacobian determinants per element
+ - Configurable quadrature orders
+- New `FieldIntegrator` class in `splinepy.helpme.integrate` providing a high-level interface for PDE assembly:
+ - `assemble_matrix(function)` — assembles the global stiffness matrix
+ - `assemble_vector(function)` — assembles the global load vector
+ - `assemble_matrix_and_vector(function)` — assembles both simultaneously
+ - `L2_projection(function)` — computes the L2 projection of a function onto the spline space
+ - `compute_error(function, norm)` — computes the L2 or H1 error of the current solution
+ - `apply_homogeneous_dirichlet_boundary_conditions()` — enforces homogeneous Dirichlet BCs
+ - `apply_dirichlet_boundary_conditions(function)` — enforces inhomogeneous Dirichlet BCs from a given function
+ - `solve_linear_system()` — solves the assembled linear system using `scipy.sparse.linalg.spsolve`
+ - Uses sparse matrix assembly via `scipy.sparse.dok_matrix`
+
+#### Microstructure: Tile Parameter Handling and Sensitivities
+- Extended `TileBase` with standardised class attributes and properties for parameter validation and introspection:
+ - `_parameter_bounds` / `parameter_bounds` — bounds for each tile parameter
+ - `_parameters_shape` / `parameters_shape` — shape of the parameter array
+ - `_default_parameter_value` / `default_parameter_value` — default values for tile parameters
+ - `_sensitivities_implemented` / `sensitivities_implemented` — flag indicating whether parameter sensitivities are implemented
+ - `_closure_directions` / `closure_directions` — list of supported closure directions
+ - `check_params(parameters)` — validates user-supplied parameters against bounds
+ - `_process_input(parameters, parameter_sensitivities)` — shared input-processing logic
+ - `_check_custom_parameter(value, param_name, bounds)` — validates individual parameters
+- Derived tile classes now inherit common parameter-processing code from `TileBase`, reducing code duplication
+- Changed `evaluation_points`, `para_dim`, and `dim` from class methods to instance properties for consistency
+- Added `n_info_per_eval_point` property to `TileBase`
+- Derivatives (parameter sensitivities) implemented or fixed for:
+ - `HollowOctagon` (with and without closure)
+ - `HollowOctagonExtrude` (added working closure, with derivatives)
+ - `Armadillo`
+ - `Chi` tile (fixed)
+ - `InverseCross3D` (restructured and fixed)
+ - `CubeVoid` (fixed)
+ - `EllipsVoid` (fixed)
+- Fourth-order accurate finite-difference calculation for numerical verification of parameter sensitivities
+- Sensitivities calculation now outputs evaluation points when it fails for easier debugging
+- `Microstructure`: integers are now accepted as tile parameters alongside floats
+
+#### Multipatch
+- Added `Multipatch.set_interface_orientations(interface_orientations)` setter for manually specifying interface orientations, enabling export of scalar-field splines where automatic Jacobian-based orientation computation is not possible
+
+#### Examples
+- Added `examples/show_swept.py` demonstrating swept surface and solid construction
+- Added `examples/iga/galerkin_laplace_problem_field_integrator.py` demonstrating Galerkin IGA for the Laplace problem using `FieldIntegrator`
+- Added `examples/iga/collocation_stokes_problem_sparse.py` demonstrating IGA collocation for the Stokes problem using sparse matrices
+
+### Changed
+
+#### CI/CD and Python Support
+- Dropped Python 3.9 support; added Python 3.14 support (updated workflows and `pyproject.toml` classifiers)
+- Switched macOS CI runner from deprecated `macos-13` to `macos-15-intel` for continued x86_64 testing
+- Fixed wheel naming convention issue in CI
+
+#### Microstructure
+- Refactored all tile classes to use common functions from `TileBase`, reducing code duplication significantly
+- `TileBase`: removed class methods in favour of instance/class properties for `dim`, `para_dim`, and `evaluation_points`
+- `TileBase`: removed unneeded classmethods to simplify the class hierarchy
+- `Microstructure`: replaced bare `assert` statements with proper `raise` expressions for parameter validation; improved error messages
+- `Microstructure`: updated `zip` calls to use `strict=True` for stricter length checking (Python 3.10+)
+- `Chi` tile is now excluded from macro-sensitivity tests (analytical sensitivities not yet finalized)
+- `HollowOctagonExtrude` removed from the list of skipped test tiles
+
+#### Integration (`helpme/integrate.py`)
+- Extracted `_default_quadrature_orders(spline)` helper function (previously inlined in `_get_quadrature_information`)
+- Improved docstrings for `_get_integral_measure`, `_get_quadrature_information`, and related functions
+- Corrected typos in docstrings (`paramtric` → `parametric`, `Determinante` → `Determinant`)
+
+#### Gismo IO (`splinepy/io/gismo.py`)
+- Added helper functions for Gismo export
+- Fixed patch range text format for multi-patch exports
+
+#### IRIT IO (`splinepy/io/irit.py`)
+- Updated `zip` calls to use `strict=True`
+
+#### MFEM IO (`splinepy/io/mfem.py`)
+- Fixed test data for Cartesian 2D and 3D meshes
+
+#### PR Template
+- Updated pull request template to use `develop` as the default base branch
+
+### Fixed
+
+- **`helpme/create.py`**: Fixed error in rotation matrix calculation for e2 entries in swept surface generation; improved input validation and error messages throughout
+- **`helpme/integrate.py`**: Fixed typos and improved docstrings
+- **`microstructure/tiles`**: Fixed incorrect ordering in finite-difference sensitivity calculation; fixed derivative implementations for `Chi`, `CubeVoid`, `EllipsVoid`, `InverseCross3D`; fixed typo causing errors in `HollowOctagonExtrude`
+- **`microstructure/microstructure.py`**: Fixed typo in class docstring (`facilitatae` → `facilitate`)
+- **`multipatch.py`**: Added check to verify that Jacobians exist before computing interface orientations
+- **`bspline.py`**: Allow any negative number in the knot vector (previously restricted), fixing issue [#476](https://github.com/isosuite/splinepy/pull/476)
+- **`utils/data.py`**: Minor fixes
+- **Various IO modules**: Fixed miscellaneous issues and improved error handling
+
+### Tests
+
+- Added `tests/test_microtiles.py` with comprehensive parametrised tests for all microtile classes:
+ - All tiles lie within the unit cube for default parameters
+ - Tiles with non-default parameters
+ - Closure tests
+ - Tile derivative (sensitivity) tests, including closure derivatives
+ - Macro-sensitivity tests (finite-difference verification)
+- Added `tests/test_microstructure.py` with additional microstructure integration tests
+- Added test for `Transformation` class in `tests/helpme/test_integrate.py`
+- Extended `tests/helpme/test_create.py` with swept surface tests, including:
+ - Comparison of swept vs extruded surfaces
+ - Custom cross-section normal vector
+ - Anchor modes
+ - Derivative checks
+- Fixed RNG seed, sensitivity step size, and number of random test points for reproducible results
+- Updated various existing tests for compatibility with Python 3.10+ `zip(strict=True)` changes
+
+## [0.2.0] - 2025-06-01
+
+- Physical function integration in `helpme/integrate.py`
+- Gismo export helper functions
+- Python 3.13 support
+- Various bug fixes and CI/CD maintenance
+
+## [0.1.3] - 2024
+
+- Proximity / nearest-point query updates
+
+## [0.1.2] - 2024
+
+- MFEM 3D single-patch IO
+- Padding initializer for splines
+
+## [0.1.1] - 2024
+
+- Initial stable release series
+
+[0.2.1]: https://github.com/isosuite/splinepy/compare/v0.2.0...v0.2.1
+[0.2.0]: https://github.com/isosuite/splinepy/compare/v0.1.3...v0.2.0
+[0.1.3]: https://github.com/isosuite/splinepy/compare/v0.1.2...v0.1.3
+[0.1.2]: https://github.com/isosuite/splinepy/compare/v0.1.1...v0.1.2
+[0.1.1]: https://github.com/isosuite/splinepy/releases/tag/v0.1.1
diff --git a/README.md b/README.md
index 4cf35bfcb..3e3f46ad6 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@

**splinepy - Library for prototyping spline geometries of arbitrary dimensions and degrees, and IGA**
-[](https://github.com/tataratat/splinepy/actions)
+[](https://github.com/isosuite/splinepy/actions)
[](https://badge.fury.io/py/splinepy)
-[](https://mybinder.org/v2/gh/tataratat/try-splinepy/main)
+[](https://mybinder.org/v2/gh/isosuite/try-splinepy/main)

@@ -19,7 +19,7 @@ pip install splinepy
You can install it directly from the source:
```bash
-git clone git@github.com:tataratat/splinepy.git
+git clone git@github.com:isosuite/splinepy.git
cd splinepy
git submodule update --init --recursive
pip install -e .
@@ -27,15 +27,15 @@ pip install -e .
## Documentation
Here are links to related documentation for the library:
-- [Documentation home](https://tataratat.github.io/splinepy)
-- [Introduction to splines](https://tataratat.github.io/splinepy/spline_intro.html#introduction-to-splines)
-- [Spline visualization](https://tataratat.github.io/splinepy/spline_intro.html#visualizing-splines)
+- [Documentation home](https://isosuite.github.io/splinepy)
+- [Introduction to splines](https://isosuite.github.io/splinepy/spline_intro.html#introduction-to-splines)
+- [Spline visualization](https://isosuite.github.io/splinepy/spline_intro.html#visualizing-splines)
## Quick start
### 1. Create a spline
-Here, we will create a [NURBS](https://tataratat.github.io/splinepy/_generated/splinepy.nurbs.NURBS.html#splinepy.nurbs.NURBS) for the following example. Alternatively, we can also create [Bezier](https://tataratat.github.io/splinepy/_generated/splinepy.bezier.Bezier.html#splinepy.bezier.Bezier), [RationalBezier](https://tataratat.github.io/splinepy/_generated/splinepy.rational_bezier.RationalBezier.html#splinepy.rational_bezier.RationalBezier), and [BSpline](https://tataratat.github.io/splinepy/_generated/splinepy.bspline.BSpline.html#splinepy.bspline.BSpline).
+Here, we will create a [NURBS](https://isosuite.github.io/splinepy/_generated/splinepy.nurbs.NURBS.html#splinepy.nurbs.NURBS) for the following example. Alternatively, we can also create [Bezier](https://isosuite.github.io/splinepy/_generated/splinepy.bezier.Bezier.html#splinepy.bezier.Bezier), [RationalBezier](https://isosuite.github.io/splinepy/_generated/splinepy.rational_bezier.RationalBezier.html#splinepy.rational_bezier.RationalBezier), and [BSpline](https://isosuite.github.io/splinepy/_generated/splinepy.bspline.BSpline.html#splinepy.bspline.BSpline).
```python
import splinepy
@@ -73,9 +73,9 @@ nurbs.show()
### 2. Modifications
All the splines can be modified. For example, by
1. directly accessing properties,
-2. [elevating degrees](https://tataratat.github.io/splinepy/_generated/splinepy.spline.Spline.elevate_degrees.html#splinepy.spline.Spline.elevate_degrees),
-3. [inserting knots](https://tataratat.github.io/splinepy/_generated/splinepy.bspline.BSplineBase.insert_knots.html#splinepy.bspline.BSplineBase.insert_knots),
-4. [reducing degrees](https://tataratat.github.io/splinepy/_generated/splinepy.bspline.BSplineBase.reduce_degrees.html) and [removing knots](https://tataratat.github.io/splinepy/_generated/splinepy.bspline.BSplineBase.remove_knots.html) with a specified tolerance
+2. [elevating degrees](https://isosuite.github.io/splinepy/_generated/splinepy.spline.Spline.elevate_degrees.html#splinepy.spline.Spline.elevate_degrees),
+3. [inserting knots](https://isosuite.github.io/splinepy/_generated/splinepy.bspline.BSplineBase.insert_knots.html#splinepy.bspline.BSplineBase.insert_knots),
+4. [reducing degrees](https://isosuite.github.io/splinepy/_generated/splinepy.bspline.BSplineBase.reduce_degrees.html) and [removing knots](https://isosuite.github.io/splinepy/_generated/splinepy.bspline.BSplineBase.remove_knots.html) with a specified tolerance
*Note: currently {3, 4} are limited to BSpline families.*
```python
@@ -130,7 +130,7 @@ p_basis0 = nurbs.basis(queries, nthreads=2)
splinepy.settings.NTHREADS = 3
p_basis1 = nurbs.basis(queries)
```
-We also implemented [point inversion](https://tataratat.github.io/splinepy/_generated/splinepy.spline.Spline.proximities.html#splinepy-spline-spline-proximities) for splines.
+We also implemented [point inversion](https://isosuite.github.io/splinepy/_generated/splinepy.spline.Spline.proximities.html#splinepy-spline-spline-proximities) for splines.
```python
# see docs for options
para_coordinates = nurbs.proximities(physical_coordinates)
@@ -153,11 +153,11 @@ In cases, where you may have to compute derivatives at the inverted locations or
```
### 4. Helper Modules
-There's a list of helper modules under the namespace `splinepy.helpme` to boost prototyping efficiencies. Please check out the full list [here](https://tataratat.github.io/splinepy/_generated/splinepy.helpme.html)!
+There's a list of helper modules under the namespace `splinepy.helpme` to boost prototyping efficiencies. Please check out the full list [here](https://isosuite.github.io/splinepy/_generated/splinepy.helpme.html)!
Here are some highlights.
#### 4.1 Create
-[splinepy.helpme.create](https://tataratat.github.io/splinepy/_generated/splinepy.helpme.create.html#module-splinepy.helpme.create) module can help you create several primitive shapes and another spline based on the existing spline.
+[splinepy.helpme.create](https://isosuite.github.io/splinepy/_generated/splinepy.helpme.create.html#module-splinepy.helpme.create) module can help you create several primitive shapes and another spline based on the existing spline.
```python
# basic splines
box = splinepy.helpme.create.box(1, 2, 3) # length per dim
@@ -171,7 +171,7 @@ torus = splinepy.helpme.create.torus(
splinepy.show(["box", box], ["disk", disk], ["torus", torus])
```

-For the latter, you can directly access such functions through [spline.create](https://tataratat.github.io/splinepy/_generated/splinepy.spline.Spline.create.html#splinepy.spline.Spline.create).
+For the latter, you can directly access such functions through [spline.create](https://isosuite.github.io/splinepy/_generated/splinepy.spline.Spline.create.html#splinepy.spline.Spline.create).
```python
# based on existing splines
extruded = nurbs.create.extruded(extrusion_vector=[1, 2, 3])
@@ -182,9 +182,17 @@ revolved = nurbs.create.revolved(
splinepy.show(["extruded", extruded], ["revolved", revolved])
```

+You can also create swept surfaces and solids along spline trajectories.
+```python
+swept = splinepy.helpme.create.swept(
+ cross_section=splinepy.helpme.create.circle(0.5).nurbs,
+ trajectory=trajectory,
+)
+```
+
### 4.2 Extract
-Using [splinepy.helpme.extract](https://tataratat.github.io/splinepy/_generated/splinepy.helpme.extract.html#module-splinepy.helpme.extract) module, you can extract meshes (as a [gustaf](https://tataratat.github.io/gustaf/index.html) object)
+Using [splinepy.helpme.extract](https://isosuite.github.io/splinepy/_generated/splinepy.helpme.extract.html#module-splinepy.helpme.extract) module, you can extract meshes (as a [gustaf](https://isosuite.github.io/gustaf/index.html) object)
```python
# extract meshes as gustaf objects
control_mesh = nurbs.extract.control_mesh()
@@ -198,7 +206,7 @@ splinepy.show(
)
```

-or part of splines from an existing spline using [spline.extract](https://tataratat.github.io/splinepy/_generated/splinepy.spline.Spline.extract.html#splinepy.spline.Spline.extract).
+or part of splines from an existing spline using [spline.extract](https://isosuite.github.io/splinepy/_generated/splinepy.spline.Spline.extract.html#splinepy.spline.Spline.extract).
```python
# extract splines
boundaries = nurbs.extract.boundaries()
@@ -226,7 +234,7 @@ splinepy.show(

#### 4.3 Free-form deformation
-Together with mesh types of [gustaf](https://tataratat.github.io/gustaf), we can perform [free-form deformation](https://tataratat.github.io/splinepy/_generated/splinepy.helpme.ffd.FFD.html)
+Together with mesh types of [gustaf](https://isosuite.github.io/gustaf), we can perform [free-form deformation](https://isosuite.github.io/splinepy/_generated/splinepy.helpme.ffd.FFD.html)
```python
import gustaf as gus
@@ -248,7 +256,7 @@ deformed = ffd.mesh

#### 4.4 Fitting
-You can [fit](https://tataratat.github.io/splinepy/_generated/splinepy.helpme.fit.html#module-splinepy.helpme.fit) your point data using splines.
+You can [fit](https://isosuite.github.io/splinepy/_generated/splinepy.helpme.fit.html#module-splinepy.helpme.fit) your point data using splines.
```python
data = [
[-0.955, 0.293],
@@ -279,8 +287,8 @@ splinepy.show(
#### 4.5 Mapper
-[Mapper](https://tataratat.github.io/splinepy/_generated/splinepy.helpme.mapper.Mapper.html#splinepy.helpme.mapper.Mapper) class is a geometric mapping helper that brings expression and derivatives into the physical domain.
-This is especially useful for trying collocation methods. Here, we show how you can create a left hand side matrix for a laplace problem - see [this example](https://github.com/tataratat/splinepy/blob/main/examples/iga/collocation_laplace_problem_sparse.py) for a full solution:
+[Mapper](https://isosuite.github.io/splinepy/_generated/splinepy.helpme.mapper.Mapper.html#splinepy.helpme.mapper.Mapper) class is a geometric mapping helper that brings expression and derivatives into the physical domain.
+This is especially useful for trying collocation methods. Here, we show how you can create a left hand side matrix for a laplace problem - see [this example](https://github.com/isosuite/splinepy/blob/main/examples/iga/collocation_laplace_problem_sparse.py) for a full solution:

```python
@@ -305,14 +313,14 @@ laplacian_matrix = splinepy.utils.data.make_matrix(
```
### 5. Microstructure
-(Rational) Bezier splines in splinepy are capable of [composition](https://tataratat.github.io/splinepy/_generated/splinepy.bezier.BezierBase.compose.html#splinepy.bezier.BezierBase.compose), where you can place a spline (inner spline/function) into another spline (outer spline/function) in an exact fashion.
+(Rational) Bezier splines in splinepy are capable of [composition](https://isosuite.github.io/splinepy/_generated/splinepy.bezier.BezierBase.compose.html#splinepy.bezier.BezierBase.compose), where you can place a spline (inner spline/function) into another spline (outer spline/function) in an exact fashion.
We can systematically perform this to create certain shapes that consist of multiple inner splines.
-The resulting shapes are called [microstructure](https://tataratat.github.io/splinepy/_generated/splinepy.microstructure.microstructure.Microstructure.html#splinepy.microstructure.microstructure.Microstructure)s and the inner spline that serves as a basis shape is called [tile](https://tataratat.github.io/splinepy/_generated/splinepy.microstructure.tiles.tile_base.TileBase.html#splinepy.microstructure.tiles.tile_base.TileBase).
+The resulting shapes are called [microstructure](https://isosuite.github.io/splinepy/_generated/splinepy.microstructure.microstructure.Microstructure.html#splinepy.microstructure.microstructure.Microstructure)s and the inner spline that serves as a basis shape is called [tile](https://isosuite.github.io/splinepy/_generated/splinepy.microstructure.tiles.tile_base.TileBase.html#splinepy.microstructure.tiles.tile_base.TileBase).
splinepy has several tiles that are ready to use.
-Implementations of available tiles can be found [here](https://tataratat.github.io/splinepy/_generated/splinepy.microstructure.tiles.html).
-However, it is easier to access them through [module functions](https://tataratat.github.io/splinepy/_generated/splinepy.microstructure.tiles.html):
+Implementations of available tiles can be found [here](https://isosuite.github.io/splinepy/_generated/splinepy.microstructure.tiles.html).
+However, it is easier to access them through [module functions](https://isosuite.github.io/splinepy/_generated/splinepy.microstructure.tiles.html):
```python
splinepy.microstructure.tiles.show()
```
@@ -344,12 +352,12 @@ generated = microstructure.create()

-Please take a look at [this example](https://github.com/tataratat/splinepy/blob/main/examples/show_microstructures.py) for a broad overview of what microstructures can do!
+Please take a look at [this example](https://github.com/isosuite/splinepy/blob/main/examples/show_microstructures.py) for a broad overview of what microstructures can do!
### 6. Multipatch
-In practice, including [Microstructure](https://tataratat.github.io/splinepy/_generated/splinepy.microstructure.microstructure.Microstructure.html#splinepy.microstructure.microstructure.Microstructure)s, it is common to work with multiple patches.
-For that, we provide a [Multipatch](https://tataratat.github.io/splinepy/_generated/splinepy.multipatch.Multipatch.html#splinepy.multipatch.Multipatch) class, equipped with various useful functionalities:
+In practice, including [Microstructure](https://isosuite.github.io/splinepy/_generated/splinepy.microstructure.microstructure.Microstructure.html#splinepy.microstructure.microstructure.Microstructure)s, it is common to work with multiple patches.
+For that, we provide a [Multipatch](https://isosuite.github.io/splinepy/_generated/splinepy.multipatch.Multipatch.html#splinepy.multipatch.Multipatch) class, equipped with various useful functionalities:
- patch interface identification
- boundary patch identification
- boundary assignment with various options
@@ -381,7 +389,7 @@ splinepy.io.gismo.export("microstructure.xml", generated)

### 7. Input/output and vector graphics
-splinepy supports various [IO formats](https://tataratat.github.io/splinepy/_generated/splinepy.io.html).
+splinepy supports various [IO formats](https://isosuite.github.io/splinepy/_generated/splinepy.io.html).
Most notably, [gismo](https://github.com/gismo/gismo) and [mfem](https://github.com/mfem/mfem) formats allow a seamless transition to analysis. In addition splinepy is also able to import and export the `iges` format. Specifically, `Type 126` (B-Spline curve) and `Type 128` (B-Spline surface).
```python
# export
@@ -392,16 +400,16 @@ quarter_circle = splinepy.io.mfem.load("quarter_circle.mesh")
```
-[svg format](https://tataratat.github.io/splinepy/_generated/splinepy.io.svg.export.html#splinepy.io.svg.export) enables true vector graphic export which preserves the smoothness of splines for publications/documentation. Try to zoom in!
+[svg format](https://isosuite.github.io/splinepy/_generated/splinepy.io.svg.export.html#splinepy.io.svg.export) enables true vector graphic export which preserves the smoothness of splines for publications/documentation. Try to zoom in!
```python
splinepy.io.svg.export("nurbs.svg", nurbs)
```

## Try online
-You can also try splinepy online by clicking the [Binder](https://mybinder.org/v2/gh/tataratat/try-splinepy/main) badge above!
+You can also try splinepy online by clicking the [Binder](https://mybinder.org/v2/gh/isosuite/try-splinepy/main) badge above!
## Contributing
splinepy welcomes any form of contributions!
-Feel free to write us an [issue](https://github.com/tataratat/splinepy/issues) or start a [discussion](https://github.com/tataratat/splinepy/discussions).
-Contribution guidelines can be found [here](https://tataratat.github.io/splinepy/CONTRIBUTING.html).
+Feel free to write us an [issue](https://github.com/isosuite/splinepy/issues) or start a [discussion](https://github.com/isosuite/splinepy/discussions).
+Contribution guidelines can be found [here](https://isosuite.github.io/splinepy/CONTRIBUTING.html).
diff --git a/docs/markdown/spline_plotting.md b/docs/markdown/spline_plotting.md
index 513db8653..fc874055c 100644
--- a/docs/markdown/spline_plotting.md
+++ b/docs/markdown/spline_plotting.md
@@ -1,7 +1,7 @@
# Visualization
One of the highlights of splinepy is that we can visualize splines.
Most of the classes have their own `show()` function to visualize current state of each object.
-Visualizations utilize mesh types and data structures of [gustaf](https://tataratat.github.io/gustaf/).
+Visualizations utilize mesh types and data structures of [gustaf](https://isosuite.github.io/gustaf/).
Then, actual rendering happens with [vedo](https://vedo.embl.es) - a powerful scientific analysis and visualization library - check them out for details!
The following will give a brief introduction to spline visualization.
@@ -63,7 +63,7 @@ nurbs.show()

You can easily plot data on splines.
Scalar data can be represented with a colormap and vector data can be represented with arrows.
-You can take a look at [this example](https://github.com/tataratat/splinepy/blob/main/examples/show_spline_data.py) for detailed introduction.
+You can take a look at [this example](https://github.com/isosuite/splinepy/blob/main/examples/show_spline_data.py) for detailed introduction.
```python
# set data - we will plot self spline, which will plot coordinates
nurbs.spline_data["coords"] = nurbs
@@ -92,7 +92,7 @@ nurbs.show() # Nr. 3
```
## Examples
-Take a look at the examples folder for more!
+Take a look at the examples folder for more!
## Notebook plotting
diff --git a/docs/source/_static/show_swept.png b/docs/source/_static/show_swept.png
new file mode 100644
index 000000000..37c1db052
Binary files /dev/null and b/docs/source/_static/show_swept.png differ
diff --git a/docs/source/handle_markdown.py b/docs/source/handle_markdown.py
index 8bb227723..97bb569a6 100644
--- a/docs/source/handle_markdown.py
+++ b/docs/source/handle_markdown.py
@@ -16,7 +16,6 @@
import pathlib
import re
import warnings
-from typing import List, Tuple
# Path to this file.
file_path = os.path.abspath(os.path.dirname(__file__))
@@ -38,7 +37,7 @@ def get_markdown_links(line: str) -> str:
return possible or ""
-def get_special_links(line: str) -> List[Tuple[str, str]]:
+def get_special_links(line: str) -> list[tuple[str, str]]:
"""Get the special links from a string.
Args:
@@ -49,8 +48,7 @@ def get_special_links(line: str) -> List[Tuple[str, str]]:
"""
possible = [
- x[::-1]
- for x in re.findall(r"
", line)
+ x[::-1] for x in re.findall(r"
", line)
]
return possible or ""
@@ -72,7 +70,7 @@ def get_github_path_from(link):
_type_: _description_
"""
return str(pathlib.Path(link).resolve()).replace(
- repo_root, "https://raw.githubusercontent.com/tataratat/splinepy/main/"
+ repo_root, "https://raw.githubusercontent.com/isosuite/splinepy/main/"
)
@@ -112,9 +110,7 @@ def get_common_parent(path1: str, path2: str) -> str:
}
-def process_file(
- file: str, relative_links: bool = True, return_content: bool = False
-):
+def process_file(file: str, relative_links: bool = True, return_content: bool = False):
"""Process a markdown file.
This function will process a markdown file. It will replace all relative
@@ -149,9 +145,7 @@ def process_file(
stacklevel=3,
)
continue
- if item[1].startswith(
- ("http", "#")
- ): # skip http links and anchors
+ if item[1].startswith(("http", "#")): # skip http links and anchors
if "badge" in item[1]:
continue
line = line.replace( # noqa: PLW2901
@@ -172,17 +166,13 @@ def process_file(
"See documentation for examples.",
)
elif not relative_links: # generate links to github repo
- new_path = get_github_path_from(
- pathlib.Path(item[1]).resolve()
- )
+ new_path = get_github_path_from(pathlib.Path(item[1]).resolve())
else: # generate relative links
common_sub_path, steps_back = get_common_parent(
item[1], folder_to_save_to
)
new_path = "../" * steps_back + str(
- pathlib.Path(item[1])
- .resolve()
- .relative_to(common_sub_path)
+ pathlib.Path(item[1]).resolve().relative_to(common_sub_path)
)
line = line.replace(item[1], str(new_path)) # noqa: PLW2901
@@ -200,9 +190,7 @@ def process_file(
if item[0].startswith("http"): # skip http links and anchors
continue
elif not relative_links: # generate links to github repo
- new_path = get_github_path_from(
- pathlib.Path(item[1]).resolve()
- )
+ new_path = get_github_path_from(pathlib.Path(item[1]).resolve())
else:
# just link to static folder in docs
new_path = "_static/" + str(pathlib.Path(item[1]).name)
@@ -214,9 +202,7 @@ def process_file(
if return_content:
return content
- with open(
- os.path.join(folder_to_save_to, os.path.basename(file)), "w"
- ) as f:
+ with open(os.path.join(folder_to_save_to, os.path.basename(file)), "w") as f:
f.write(content)
@@ -229,9 +215,7 @@ def prepare_file_for_PyPI():
Args:
file (str): Path to the README file.
"""
- content = process_file(
- "README.md", relative_links=False, return_content=True
- )
+ content = process_file("README.md", relative_links=False, return_content=True)
with open("README.md", "w") as f:
f.write(content)
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 5941a0b6c..da6df798d 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -16,7 +16,7 @@ Table of Contents
:caption: Library
:maxdepth: 1
- Github
+ Github
Contributing
API Reference
diff --git a/examples/iga/collocation_stokes_problem_sparse.py b/examples/iga/collocation_stokes_problem_sparse.py
new file mode 100644
index 000000000..aa00655eb
--- /dev/null
+++ b/examples/iga/collocation_stokes_problem_sparse.py
@@ -0,0 +1,445 @@
+r"""
+This file implements a stokes test case based on the example stated in
+"Finite Element Methods for Flow Problems", Donea and Huerta p.306
+chapter 6.8.1 example with analytical solution.
+"""
+
+import matplotlib.pyplot as plt
+import numpy as np
+from scipy.sparse import bmat, linalg
+
+import splinepy as sp
+
+###
+# Inputs
+###
+
+# Define the dynamic viscosity
+viscosity = 1
+mass_factor = 1e-1 # Weight the incompressibility equations in the LSQ solve
+impose_pressure_bcs = False # Impose BCS for pressure
+
+# Define the Geometry (simple first order unit square)
+geometry = sp.BSpline(
+ degrees=[1, 1],
+ control_points=[[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]],
+ knot_vectors=[[0, 0, 1, 1], [0, 0, 1, 1]],
+)
+
+
+solution_field_pressure = sp.BSpline(
+ degrees=geometry.degrees,
+ control_points=np.ones((geometry.control_points.shape[0], 1)),
+ knot_vectors=geometry.knot_vectors,
+)
+solution_field_pressure.elevate_degrees([0, 1])
+# Refinement leads to quadratic spline with 10x10cps
+solution_field_pressure.uniform_refine([1], 7)
+solution_field_pressure.uniform_refine([0], 7)
+
+# Create Raviart-Thomas mixed style splines
+solution_field_velocity_u = solution_field_pressure.copy()
+# For div-conforming tensor-product spaces in 2D, the x-velocity has
+# one higher degree in x, and the y-velocity has one higher degree in y.
+solution_field_velocity_u.elevate_degrees([0])
+solution_field_velocity_v = solution_field_pressure.copy()
+solution_field_velocity_v.elevate_degrees([1])
+
+###
+# Source Functions
+###
+
+
+def source_function_u(x_vec):
+ x = x_vec[:, 0]
+ y = x_vec[:, 1]
+ return (
+ (12 - 24 * y) * x**4
+ + (-24 + 48 * y) * x**3
+ + (12 - 48 * y + 72 * y**2 - 48 * y**3) * x**2
+ + (-2 + 24 * y - 72 * y**2 + 48 * y**3) * x
+ + (1 - 4 * y + 12 * y**2 - 8 * y**3)
+ )
+
+
+def source_function_v(x_vec):
+ x = x_vec[:, 0]
+ y = x_vec[:, 1]
+ return (
+ (8 - 48 * y + 48 * y**2) * x**3
+ + (-12 + 72 * y - 72 * y**2) * x**2
+ + (4 - 24 * y + 48 * y**2 - 48 * y**3 + 24 * y**4) * x
+ + (-12 * y**2 + 24 * y**3 - 12 * y**4)
+ )
+
+
+def boundary_conditions_u(x_vec):
+ return np.zeros(x_vec.shape[0])
+
+
+def boundary_conditions_v(x_vec):
+ return np.zeros(x_vec.shape[0])
+
+
+def boundary_conditions_p(x_vec):
+ x = x_vec[:, 0]
+ return x * (1.0 - x)
+
+
+###
+# Computation of greville abscissae
+###
+greville_points_u = solution_field_velocity_u.greville_abscissae()
+greville_points_v = solution_field_velocity_v.greville_abscissae()
+greville_points_p = solution_field_pressure.greville_abscissae()
+
+###
+# Computation of the matrices
+###
+mapper_u = solution_field_velocity_u.mapper(reference=geometry)
+mapper_v = solution_field_velocity_v.mapper(reference=geometry)
+mapper_p = solution_field_pressure.mapper(reference=geometry)
+
+# FIRST ROW ----------
+# A_u_tu = mu * delta(u)
+A_u_tu = -viscosity * sp.utils.data.make_matrix(
+ *mapper_u.basis_laplacian_and_support(greville_points_u),
+ solution_field_velocity_u.cps.shape[0],
+ as_array=False,
+)
+# A_v_tu = 0
+A_v_tu = None
+# A_p_tu = dpdx
+gradient_p, support_p = mapper_p.basis_gradient_and_support(greville_points_u)
+A_p_tu = sp.utils.data.make_matrix(
+ gradient_p[:, :, 0],
+ support_p,
+ solution_field_pressure.cps.shape[0],
+ as_array=False,
+)
+# RHS
+rhs_u = source_function_u(geometry.evaluate(greville_points_u))
+
+# SECOND ROW ----------
+# A_u_tv = 0
+A_u_tv = None
+# A_v_tv = mu * delta(v)
+A_v_tv = -viscosity * sp.utils.data.make_matrix(
+ *mapper_v.basis_laplacian_and_support(greville_points_v),
+ solution_field_velocity_v.cps.shape[0],
+ as_array=False,
+)
+# A_p_tv
+gradient_p, support_p = mapper_p.basis_gradient_and_support(greville_points_v)
+A_p_tv = sp.utils.data.make_matrix(
+ gradient_p[:, :, 1],
+ support_p,
+ solution_field_pressure.cps.shape[0],
+ as_array=False,
+)
+# RHS
+rhs_v = source_function_v(geometry.evaluate(greville_points_v))
+
+# THIRD ROW ----------
+# A_u_tp dudx
+gradient_u, support_u = mapper_u.basis_gradient_and_support(greville_points_p)
+A_u_tp = sp.utils.data.make_matrix(
+ mass_factor * gradient_u[:, :, 0],
+ support_u,
+ solution_field_velocity_u.cps.shape[0],
+ as_array=False,
+)
+# A_v_tp dvdx
+gradient_v, support_v = mapper_v.basis_gradient_and_support(greville_points_p)
+A_v_tp = sp.utils.data.make_matrix(
+ mass_factor * gradient_v[:, :, 1],
+ support_v,
+ solution_field_velocity_v.cps.shape[0],
+ as_array=False,
+)
+# A_p_tp = 0
+A_p_tp = None
+# RHS
+rhs_p = mass_factor * np.zeros(greville_points_p.shape[0])
+
+
+###
+# Imposition of BCs
+###
+# For U-Velocity
+boundary_evaluation_point_ids_u = np.concatenate(
+ (
+ solution_field_velocity_u.multi_index[0, :],
+ solution_field_velocity_u.multi_index[-1, :],
+ solution_field_velocity_u.multi_index[1:-1, 0],
+ solution_field_velocity_u.multi_index[1:-1, -1],
+ )
+)
+boundary_evaluation_points_u = greville_points_u[
+ boundary_evaluation_point_ids_u
+]
+
+# Create matrices and RHS
+A_u_tpbcu = sp.utils.data.make_matrix(
+ *solution_field_velocity_u.basis_and_support(boundary_evaluation_points_u),
+ solution_field_velocity_u.cps.shape[0],
+ as_array=False,
+)
+A_v_tpbcu = None
+A_p_tpbcu = None
+rhs_tpbcu = boundary_conditions_u(boundary_evaluation_points_u)
+
+# For V-velocity
+boundary_evaluation_point_ids_v = np.concatenate(
+ (
+ solution_field_velocity_v.multi_index[0, :],
+ solution_field_velocity_v.multi_index[-1, :],
+ solution_field_velocity_v.multi_index[1:-1, 0],
+ solution_field_velocity_v.multi_index[1:-1, -1],
+ )
+)
+boundary_evaluation_points_v = greville_points_v[
+ boundary_evaluation_point_ids_v
+]
+
+# Create matrices and RHS
+A_u_tpbcv = None
+A_v_tpbcv = sp.utils.data.make_matrix(
+ *solution_field_velocity_v.basis_and_support(boundary_evaluation_points_v),
+ solution_field_velocity_v.cps.shape[0],
+ as_array=False,
+)
+A_p_tpbcv = None
+rhs_tpbcv = boundary_conditions_v(boundary_evaluation_points_v)
+
+# For Pressure Field (redundant?)
+if impose_pressure_bcs:
+ # boundary conditions only applied to the sides x=0 and x=1
+ # To apply to all 4 sides see bc for velocity field
+ boundary_evaluation_point_ids_p = np.concatenate(
+ (
+ solution_field_pressure.multi_index[0, :],
+ solution_field_pressure.multi_index[-1, :],
+ )
+ )
+ boundary_evaluation_points_p = greville_points_p[
+ boundary_evaluation_point_ids_p
+ ]
+
+ # Create matrices and RHS
+ A_u_tpbcp = None
+ A_v_tpbcp = None
+ A_p_tpbcp = sp.utils.data.make_matrix(
+ *solution_field_pressure.basis_and_support(
+ boundary_evaluation_points_p
+ ),
+ solution_field_pressure.cps.shape[0],
+ as_array=False,
+ )
+ rhs_tpbcp = boundary_conditions_p(boundary_evaluation_points_p)
+
+
+###
+# Solve linear system
+###
+rhs_all = np.concatenate([rhs_u, rhs_v, rhs_p, rhs_tpbcu, rhs_tpbcv])
+block_matrices = [
+ [A_u_tu, A_v_tu, A_p_tu],
+ [A_u_tv, A_v_tv, A_p_tv],
+ [A_u_tp, A_v_tp, A_p_tp],
+ [A_u_tpbcu, A_v_tpbcu, A_p_tpbcu],
+ [A_u_tpbcv, A_v_tpbcv, A_p_tpbcv],
+]
+
+# L2-imposition of boundary conditions for the pressure field (optional)
+if impose_pressure_bcs:
+ rhs_all = np.concatenate([rhs_all, rhs_tpbcp])
+ block_matrices.append([A_u_tpbcp, A_v_tpbcp, A_p_tpbcp])
+
+matrix_all = bmat(block_matrices, format=A_u_tu.format)
+solution_vector, istop, itn, r1norm = linalg.lsqr(
+ matrix_all,
+ rhs_all,
+ atol=1e-12,
+ btol=1e-12,
+ iter_lim=100 * matrix_all.shape[1],
+ # calc_var=True
+)[:4]
+print(f"LSQR istop={istop}, iterations={itn}, residual={r1norm:.3e}")
+
+
+# Plot Matrix
+plt.spy(matrix_all)
+plt.show()
+
+
+###
+# Assign solution to original splines
+###
+solution_field_velocity_u.control_points = np.reshape(
+ solution_vector[: solution_field_velocity_u.cps.shape[0]], (-1, 1)
+)
+solution_field_velocity_v.control_points = np.reshape(
+ solution_vector[
+ solution_field_velocity_u.cps.shape[0] : -(
+ solution_field_pressure.cps.shape[0]
+ )
+ ],
+ (-1, 1),
+)
+solution_field_pressure.control_points = np.reshape(
+ solution_vector[-(solution_field_pressure.cps.shape[0]) :], (-1, 1)
+)
+
+
+###
+# Plot and analysis
+###
+
+# Analytical solutions
+
+
+def analytical_solution_u(geometry, on):
+ x_vec = geometry.evaluate(on)
+ x = x_vec[:, 0]
+ y = x_vec[:, 1]
+ return (x**2) * (1.0 - x) * (1.0 - x) * (2 * y - 6 * y**2 + 4 * y**3)
+
+
+def error_u(solution_u):
+ def _error_u(data, on):
+ sol = solution_u.evaluate(on)
+ ansol = analytical_solution_u(data, on)
+ return np.abs(sol.flat - ansol)
+
+ return _error_u
+
+
+def analytical_solution_v(geometry, on):
+ x_vec = geometry.evaluate(on)
+ x = x_vec[:, 0]
+ y = x_vec[:, 1]
+ return -(y**2) * (1.0 - y) * (1.0 - y) * (2 * x - 6 * x**2 + 4 * x**3)
+
+
+def error_v(solution_v):
+ def _error_v(data, on):
+ sol = solution_v.evaluate(on)
+ ansol = analytical_solution_v(data, on)
+ return np.abs(sol.flat - ansol)
+
+ return _error_v
+
+
+def analytical_solution_p(geometry, on):
+ x_vec = geometry.evaluate(on)
+ x = x_vec[:, 0]
+ return x * (1 - x)
+
+
+# if we do not impose pressure BCs, we need to align the computed pressure
+# field with the analytical solution because the pressure field is only
+# determined up to a constant
+pressure_error_offset = 0.0
+if not impose_pressure_bcs:
+ # we choose the offset as the minimum value of the computed pressure field
+ # such that the computed pressure field is (theoretically) non-negative
+ pressure_error_offset = solution_field_pressure.evaluate(
+ greville_points_p
+ ).min()
+
+
+def error_p(solution_p):
+ def _error_p(data, on):
+ sol = solution_p.evaluate(on)
+ corr_sol = sol.flatten() - pressure_error_offset
+ ansol = analytical_solution_p(data, on)
+ return np.abs(corr_sol - ansol)
+
+ return _error_p
+
+
+# Plot geometry and fields
+geometry.spline_data["field"] = solution_field_pressure
+geometry.show_options["data"] = "field"
+geometry.show_options["cmap"] = "jet"
+geometry.show_options["lighting"] = "off"
+geometry.show_options["scalarbar"] = True
+solution_p = geometry.copy()
+geometry.spline_data["field"] = solution_field_velocity_v
+solution_v = geometry.copy()
+geometry.spline_data["field"] = solution_field_velocity_u
+solution_u = geometry.copy()
+geometry.spline_data["field"] = sp.SplineDataAdaptor(
+ geometry, function=error_u(solution_field_velocity_u)
+)
+error_field_u = geometry.copy()
+geometry.spline_data["field"] = sp.SplineDataAdaptor(
+ geometry, function=error_v(solution_field_velocity_v)
+)
+error_field_v = geometry.copy()
+geometry.spline_data["field"] = sp.SplineDataAdaptor(
+ geometry, function=error_p(solution_field_pressure)
+)
+error_field_p = geometry.copy()
+
+
+###
+# Loss function u
+###
+
+# Check Loss function
+sample_points = greville_points_p
+mapper_u = solution_field_velocity_u.mapper(reference=geometry)
+mapper_v = solution_field_velocity_v.mapper(reference=geometry)
+mapper_p = solution_field_pressure.mapper(reference=geometry)
+
+
+def loss_function_u(data, on):
+ return np.abs(
+ -viscosity * mapper_u.laplacian(on).ravel()
+ + mapper_p.gradient(on)[:, 0, 0]
+ - source_function_u(data.evaluate(on))
+ )
+
+
+def loss_function_v(data, on):
+ return np.abs(
+ -viscosity * mapper_v.laplacian(on).ravel()
+ + mapper_p.gradient(on)[:, 0, 1]
+ - source_function_v(data.evaluate(on))
+ )
+
+
+def loss_function_p(_data, on):
+ return np.abs(
+ mass_factor
+ * (mapper_u.gradient(on)[:, 0, 0] + mapper_v.gradient(on)[:, 0, 1])
+ )
+
+
+geometry.spline_data["field"] = sp.SplineDataAdaptor(
+ geometry, function=loss_function_u
+)
+loss_u = geometry.copy()
+geometry.spline_data["field"] = sp.SplineDataAdaptor(
+ geometry, function=loss_function_v
+)
+loss_v = geometry.copy()
+geometry.spline_data["field"] = sp.SplineDataAdaptor(
+ geometry, function=loss_function_p
+)
+loss_p = geometry.copy()
+sp.show(
+ ["U-Velocity", solution_u],
+ ["V-velocity", solution_v],
+ ["Pressure", solution_p],
+ ["|U - U_exp|", error_field_u],
+ ["|V - V_exp|", error_field_v],
+ ["|P - P_exp|", error_field_p],
+ ["|R(u)|", loss_u],
+ ["|R(v)|", loss_v],
+ ["|R(p)|", loss_p],
+ knots=True,
+ control_points=False,
+)
diff --git a/examples/iga/galerkin_laplace_problem_field_integrator.py b/examples/iga/galerkin_laplace_problem_field_integrator.py
new file mode 100644
index 000000000..a9ac952d8
--- /dev/null
+++ b/examples/iga/galerkin_laplace_problem_field_integrator.py
@@ -0,0 +1,177 @@
+r"""
+This is a showcase of splinepy's FieldIntegrator class. It solves the Poisson
+equation in the form
+.. math::
+ -\Delta u = f
+with source term f=1.
+
+First, homogeneous Dirichlet boundary conditions are applied. Then, a mix of homogeneous
+and inhomogeneous Dirichlet boundary conditions are applied on 3 of 4 boundaries. A
+zero Neumann boundary condition is implicitly applied on the fourth boundary.
+"""
+
+import numpy as np
+
+import splinepy as sp
+
+# Number of refinements for the solution field
+n_refine = 15
+
+
+def prepare_geometry_and_solution_field():
+ """
+ Creates single patch geometry and solution field with h- and p-refinement
+
+ Returns
+ -----------------
+ geometry: splinepy.BSpline
+ The geometry object
+ solution_field: splinepy.BSpline
+ The solution field with refinements. Its control points serve as the degree of
+ freedoms (DoFs) of the solution. It is initialized to a vector of ones.
+ """
+ # Define the Geometry
+ geometry = sp.BSpline(
+ degrees=[2, 2],
+ control_points=[
+ [0.0, 0.0],
+ [1.0, 0.5],
+ [2.0, 0.2],
+ [0.5, 1.5],
+ [1.0, 1.5],
+ [1.5, 1.5],
+ [0.0, 3.0],
+ [1.0, 2.5],
+ [2.0, 3.0],
+ ],
+ knot_vectors=[[0, 0, 0, 1, 1, 1], [0, 0, 0, 1, 1, 1]],
+ )
+
+ # Define the solution field
+ solution_field = geometry.copy()
+ # Initialize solution vector
+ solution_field.control_points = np.ones(
+ (geometry.control_points.shape[0], 1)
+ )
+
+ # Apply p-refinement
+ solution_field.elevate_degrees([0, 1, 0, 1])
+ # Apply uniform h-refinement
+ new_knots = np.linspace(1 / n_refine, 1, n_refine, endpoint=False)
+ solution_field.insert_knots(0, new_knots)
+ solution_field.insert_knots(1, new_knots)
+
+ return geometry, solution_field
+
+
+def poisson_lhs(mapper, quad_points, quad_weights, jacobian_det):
+ """
+ Assemble the system matrix of the Poisson equation.
+
+ Parameters
+ -----------
+ mapper: splinepy.helpme.mapper.Mapper
+ Mapper of solution field
+ quad_points: np.ndarray
+ Quadrature points
+ quad_weights: np.ndarray
+ Quadrature weights
+ jacobian_det: np.ndarray
+ Determinant of Jacobian, evaluated at quadrature points
+
+ Returns
+ -----------
+ element_matrix: np.ndarray
+ Element matrix
+ """
+ bf_gradient, _ = mapper.basis_gradient_and_support(quad_points)
+ element_matrix = np.einsum(
+ "qid,qjd,q,q->ij",
+ bf_gradient,
+ bf_gradient,
+ quad_weights,
+ jacobian_det,
+ optimize=True,
+ )
+ return element_matrix.ravel()
+
+
+def poisson_rhs(mapper, quad_points, quad_weights, jacobian_det):
+ """
+ Assemble the rhs of the Poisson equation with f=1
+
+ Parameters
+ -----------
+ mapper: splinepy.helpme.mapper.Mapper
+ Mapper of solution field
+ quad_points: np.ndarray
+ Quadrature points
+ quad_weights: np.ndarray
+ Quadrature weights
+ jacobian_det: np.ndarray
+ Determinant of Jacobian, evaluated at quadrature points
+
+ Returns
+ -----------
+ element_vector: np.ndarray
+ Element vector
+ """
+ bf = mapper._field_reference.basis(quad_points)
+ element_vector = np.einsum(
+ "qj,q,q->j", bf, quad_weights, jacobian_det, optimize=True
+ )
+ return element_vector
+
+
+def show_solution(geometry, solution_field):
+ """Visualize the solution"""
+ geometry.spline_data["field"] = solution_field
+ geometry.show_options["data"] = "field"
+ geometry.show_options["cmap"] = "jet"
+ geometry.show_options["lighting"] = "off"
+ geometry.show_options["scalarbar"] = True
+ geometry.show(knots=True, control_points=False)
+
+
+if __name__ == "__main__":
+ # Create geometry and solution field with h- and p-refinement
+ geometry, solution_field = prepare_geometry_and_solution_field()
+
+ fi = sp.helpme.integrate.FieldIntegrator(
+ geometry=geometry, solution_field=solution_field
+ )
+
+ # Assemble the linear system for the Poisson equation
+ fi.assemble_matrix(poisson_lhs)
+ fi.assemble_vector(poisson_rhs)
+
+ # Apply homogeneous Dirichlet boundary conditions
+ fi.apply_homogeneous_dirichlet_boundary_conditions()
+ # Solve linear system to obtain solution vector, which is stored as the
+ # solution_field's control points
+ fi.solve_linear_system()
+ # Plot geometry and field
+ show_solution(geometry, solution_field)
+
+ # Function for inhomogeneous Dirichlet boundary conditions
+ def dirichlet_function(points):
+ """
+ On the boundary apply: g(x,y) = x/4
+ """
+ return points[:, 0] / 4
+
+ # Assemble again to override previous boundary conditions
+ fi.assemble_matrix(poisson_lhs)
+ fi.assemble_vector(poisson_rhs)
+
+ # Apply boundary conditions on 3 boundaries (west, south and north boundary)
+ fi.apply_homogeneous_dirichlet_boundary_conditions(west=True)
+ fi.apply_dirichlet_boundary_conditions(
+ dirichlet_function, south=True, north=True
+ )
+ # For zero Neumann boundary conditions we can keep the matrix and rhs as they are
+
+ # Solve linear system
+ fi.solve_linear_system()
+ # Plot resulting solution
+ show_solution(geometry, solution_field)
diff --git a/examples/ipynb/notebook_showcase_k3d.ipynb b/examples/ipynb/notebook_showcase_k3d.ipynb
index b576fe425..32e4a0f4f 100644
--- a/examples/ipynb/notebook_showcase_k3d.ipynb
+++ b/examples/ipynb/notebook_showcase_k3d.ipynb
@@ -192,9 +192,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Have you heard of spline composition? With this method, you can create spline based microstructures in exact fashion. This is one of the highlights of the `splinepy`. For more information, please take a look at splinepy's [docs](https://tataratat.github.io/splinepy/_generated/splinepy.bezier.BezierBase.compose.html#splinepy.bezier.BezierBase.compose)\n",
+ "Have you heard of spline composition? With this method, you can create spline based microstructures in exact fashion. This is one of the highlights of the `splinepy`. For more information, please take a look at splinepy's [docs](https://isosuite.github.io/splinepy/_generated/splinepy.bezier.BezierBase.compose.html#splinepy.bezier.BezierBase.compose)\n",
"\n",
- "Creating microstructures require two ingredients: outer spline (also known as deformation function, outer function, ...) and a microtile. For this example, we will use empty torus as outer spline and 2d cross as microtile (see other available ready-to-use microtiles [here](https://tataratat.github.io/splinepy/_generated/splinepy.microstructure.tiles.html))."
+ "Creating microstructures require two ingredients: outer spline (also known as deformation function, outer function, ...) and a microtile. For this example, we will use empty torus as outer spline and 2d cross as microtile (see other available ready-to-use microtiles [here](https://isosuite.github.io/splinepy/_generated/splinepy.microstructure.tiles.html))."
]
},
{
diff --git a/examples/show_microstructures.py b/examples/show_microstructures.py
index 35d6d22b8..14d74dc04 100644
--- a/examples/show_microstructures.py
+++ b/examples/show_microstructures.py
@@ -346,13 +346,13 @@ def foo(x):
generator.parametrization_function = foo
inverse_microstructure = generator.create(
- closing_face="z", seperator_distance=0.4, center_expansion=1.3
+ closing_face="z", separator_distance=0.4, center_expansion=1.3
)
# Plot the results
_, showables_inverse = generator.show(
closing_face="z",
- seperator_distance=0.4,
+ separator_distance=0.4,
center_expansion=1.3,
title="Parametrized Inverse Microstructure",
control_points=False,
@@ -365,7 +365,7 @@ def foo(x):
# Corresponding Structure
generator.microtile = splinepy.microstructure.tiles.get("Cross3D")
microstructure = generator.create(
- closing_face="z", seperator_distance=0.4, center_expansion=1.3
+ closing_face="z", separator_distance=0.4, center_expansion=1.3
)
_, showables = generator.show(
closing_face="z",
diff --git a/examples/show_readme.py b/examples/show_readme.py
index d7456e08a..ead7f06f0 100644
--- a/examples/show_readme.py
+++ b/examples/show_readme.py
@@ -97,7 +97,7 @@
para_queries = []
phys_queries = []
colors = ["red", "yellow", "blue"]
-for q, pc, c in zip(queries, physical_coordinates, colors):
+for q, pc, c in zip(queries, physical_coordinates, colors, strict=False):
para_q, phys_q = gus.Vertices([q]), gus.Vertices([pc])
para_q.show_options["c"] = c
para_q.show_options["r"] = 10
diff --git a/examples/show_swept.py b/examples/show_swept.py
new file mode 100644
index 000000000..54eceed16
--- /dev/null
+++ b/examples/show_swept.py
@@ -0,0 +1,241 @@
+import gustaf as gus
+import numpy as np
+
+import splinepy
+
+if __name__ == "__main__":
+
+ ### TRAJECTORY ###
+
+ # define a hook-trajectory
+ dict_trajectory = {
+ "degrees": [3],
+ "knot_vectors": [
+ [0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0, 1.0, 1.0, 1.0]
+ ],
+ "control_points": np.array(
+ [
+ [0.5, 0],
+ [0.5, 2],
+ [1.0, 3],
+ [2.0, 4],
+ [2.15, 5],
+ [1.8, 5.9],
+ [1.0, 6.2],
+ [-0.25, 6],
+ [-0.5, 5],
+ ]
+ ),
+ }
+
+ # create spline of trajectory dict
+ trajectory = splinepy.BSpline(**dict_trajectory)
+
+ # refine trajectory by inserting knots and control points
+ trajectory.uniform_refine(0, 1)
+
+ ### CROSS SECTIONS ###
+
+ # 1. create a circular 1D-line-cross-section
+ cross_section_circle = splinepy.helpme.create.circle(0.5).nurbs
+
+ # 2. create a circular 2D-surface-cross-section
+ cross_section_disk = splinepy.helpme.create.surface_circle(0.5).nurbs
+
+ # 3. create a rectangular 2D-surface-cross-section
+ cross_section_plate = splinepy.helpme.create.box(1, 1).nurbs
+
+ # 4. create a more complex 1D-line-cross-section
+ # use an asymmetric rational curve so control-box and geometry-box anchors
+ # visibly differ
+ cross_section_rectangle_line = splinepy.helpme.create.circle(0.55).nurbs
+ cross_section_rectangle_line.control_points[:, 0] *= 1.2
+ cross_section_rectangle_line.control_points[:, 1] *= 0.8
+ cross_section_rectangle_line.control_points[1] += np.array([0.9, -0.15])
+ cross_section_rectangle_line.control_points[2] += np.array([0.45, 0.55])
+ cross_section_rectangle_line.control_points[5] += np.array([-0.35, -0.45])
+ cross_section_rectangle_line.weights[1] *= 0.25
+ cross_section_rectangle_line.weights[2] *= 0.45
+ cross_section_rectangle_line.weights[5] *= 0.5
+
+ # Define a custom normal vector for the cross-section when:
+ # a) The cross-section is not planar in the x-y plane, or
+ # b) Crooked sweeping is desired
+ cs_nv = np.array([1, 0, 1])
+
+ ### SWEEP ###
+
+ # create swept surface
+ swept_surface_circle = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_circle,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ # create crooked swept solid (circular nr. 1)
+ # the cross-section's normal vector is not default; crooked sweeping
+ swept_solid_disk_1 = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_disk,
+ cross_section_normal=cs_nv,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ # create swept solid (circular nr. 2)
+ # the cross-sections are set on the trajectory's control points (default)
+ swept_solid_disk_2 = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_disk,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ # create swept solid (circular nr. 3)
+ # the cross-sections are set on the trajectory's evaluation points
+ swept_solid_disk_3 = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_disk,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=True,
+ rotation_adaption=None,
+ )
+
+ # create swept solid (rectangular nr. 1)
+ swept_solid_plate_1 = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_plate,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ # create swept solid (rectangular nr. 2)
+ # rotation adaption with 45 degrees
+ swept_solid_plate_2 = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_plate,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=45 * np.pi / 180,
+ )
+
+ # create swept surfaces to compare anchor placement strategies
+ swept_surface_rectangle_parametric = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_rectangle_line,
+ cross_section_normal=None,
+ anchor="parametric",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ swept_surface_rectangle_control_box = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_rectangle_line,
+ cross_section_normal=None,
+ anchor="control_box",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ swept_surface_rectangle_geometry_box = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_rectangle_line,
+ cross_section_normal=None,
+ anchor="geometry_box",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ swept_surface_rectangle_auto = splinepy.helpme.create.swept(
+ trajectory=trajectory,
+ cross_section=cross_section_rectangle_line,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+ )
+
+ ### VISUALIZATION ###
+
+ # first window: swept surface
+ gus.show(
+ ["Trajectory", trajectory],
+ ["1D Cross Section", cross_section_circle],
+ ["Swept Surface", swept_surface_circle],
+ resolution=51,
+ control_mesh=False,
+ control_point_ids=False,
+ )
+
+ # adjust show options
+ swept_solid_disk_2.show_options["alpha"] = 0.3
+ swept_solid_disk_3.show_options["alpha"] = 0.3
+ trajectory.show_options["control_points"] = False
+
+ # second window: swept solids (circular)
+ gus.show(
+ ["2D Cross Section", cross_section_disk],
+ ["Swept Solid - Crooked Sweeping", swept_solid_disk_1],
+ [
+ "Swept Solid - Set on Control Points",
+ swept_solid_disk_2,
+ trajectory,
+ ],
+ [
+ "Swept Solid - Set on Evaluation Points",
+ swept_solid_disk_3,
+ trajectory,
+ ],
+ resolution=51,
+ control_mesh=False,
+ control_point_ids=False,
+ )
+
+ # third window: swept solids (rectangular)
+ gus.show(
+ ["New Cross Section", cross_section_plate],
+ ["Swept Solid without Rotation", swept_solid_plate_1],
+ ["Swept Solid with 45° Rotation", swept_solid_plate_2],
+ resolution=51,
+ control_mesh=False,
+ control_point_ids=False,
+ )
+
+ # fourth window: anchor placement for line cross-sections
+ gus.show(
+ ["Rectangle Line Cross Section", cross_section_rectangle_line],
+ [
+ "Anchor: parametric",
+ swept_surface_rectangle_parametric,
+ trajectory,
+ ],
+ [
+ "Anchor: control_box",
+ swept_surface_rectangle_control_box,
+ trajectory,
+ ],
+ [
+ "Anchor: geometry_box",
+ swept_surface_rectangle_geometry_box,
+ trajectory,
+ ],
+ [
+ "Anchor: auto",
+ swept_surface_rectangle_auto,
+ trajectory,
+ ],
+ resolution=51,
+ control_mesh=False,
+ control_point_ids=False,
+ )
diff --git a/pyproject.toml b/pyproject.toml
index c071f106b..9590bd36c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,16 +10,16 @@ authors = [
license = {file = "LICENSE"}
description = "Library for prototyping spline geometries of arbitrary dimensions and degrees, and IGA"
keywords = ["bezier", "rational bezier", "bspline", "nurbs", "multi patch"]
-urls = {Homepage = "https://github.com/tataratat/splinepy"}
+urls = {Homepage = "https://github.com/isosuite/splinepy"}
classifiers=[
"Development Status :: 4 - Beta",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Natural Language :: English",
"Topic :: Scientific/Engineering",
]
@@ -91,7 +91,7 @@ lint.select = [
"A", # flake8-builtins
]
lint.fixable = ["ALL"]
-target-version = "py38"
+target-version = "py310"
lint.ignore = [
"PLR2004", # TODO!
"PLR0912", # Too many branches
@@ -113,9 +113,6 @@ lint.ignore = [
ignore-words-list = "connec,tye,ned"
skip="./docs/source/_generated/**,./docs/build/*,./build/*,./third_party/*,./tests/data/*.svg,*.html,*.js"
-[tool.black]
-line-length = 79
-exclude = "third_party"
[tool.blackdoc]
line-length = 75
diff --git a/splinepy/_version.py b/splinepy/_version.py
index d3ec452c3..3ced3581b 100644
--- a/splinepy/_version.py
+++ b/splinepy/_version.py
@@ -1 +1 @@
-__version__ = "0.2.0"
+__version__ = "0.2.1"
diff --git a/splinepy/bspline.py b/splinepy/bspline.py
index e0d6f7320..237e3c255 100644
--- a/splinepy/bspline.py
+++ b/splinepy/bspline.py
@@ -108,8 +108,7 @@ def insert_knots(self, parametric_dimension, knots):
if min(knots) < min(self.knot_vectors[parametric_dimension]):
raise ValueError(
- "One of the query knots not in valid knot range. "
- "(Too small)"
+ "One of the query knots not in valid knot range. (Too small)"
)
inserted = _splinepy_core.insert_knots(
@@ -171,7 +170,7 @@ def determine_new_knots(kv_unique, n_knots):
return new_knots
# determine new knots for each para_dim and insert the knots
- for para_dim, n_k in zip(para_dims, n_knots):
+ for para_dim, n_k in zip(para_dims, n_knots, strict=True):
new_knots = determine_new_knots(
# recompute unique to allow duplicating para_dims.
kv_unique=self.unique_knots[para_dim],
@@ -303,8 +302,7 @@ def remove_knots(self, parametric_dimension, knots, tolerance=None):
if min(knots) < min(self.knot_vectors[parametric_dimension]):
raise ValueError(
- "One of the query knots not in valid knot range. "
- "(Too small)"
+ "One of the query knots not in valid knot range. (Too small)"
)
removed = _splinepy_core.remove_knots(
@@ -319,7 +317,6 @@ def remove_knots(self, parametric_dimension, knots, tolerance=None):
self._logd(f"Tried to remove {len(knots)} knot(s).")
self._logd(f"Actually removed {sum(removed)} knot(s).")
-
return removed
def normalize_knot_vectors(self):
diff --git a/splinepy/helpme/check.py b/splinepy/helpme/check.py
index 86f975bd0..4b6013d43 100644
--- a/splinepy/helpme/check.py
+++ b/splinepy/helpme/check.py
@@ -38,9 +38,9 @@ def valid_queries(spline, queries):
error_query = _np.argmin(queries, axis=0)[error_dim]
raise ValueError(
f"Query request out of bounds in parametric dimension "
- f"{error_dim}. Detected query {queries[error_query,:]} at "
+ f"{error_dim}. Detected query {queries[error_query, :]} at "
f"positions {error_query}, which is out of bounds with "
- f"minimum values {bounds[0,:]}."
+ f"minimum values {bounds[0, :]}."
)
# Check maximum value
@@ -50,9 +50,9 @@ def valid_queries(spline, queries):
error_query = _np.argmax(queries, axis=0)[error_dim]
raise ValueError(
f"Query request out of bounds in parametric dimension "
- f"{error_dim}. Detected query {queries[error_query,:]} at "
+ f"{error_dim}. Detected query {queries[error_query, :]} at "
f"positions {error_query}, which is out of bounds with "
- f"maximum values {bounds[1,:]}."
+ f"maximum values {bounds[1, :]}."
)
return True
@@ -78,7 +78,7 @@ def clamped_knot_vectors(spline, warning=True):
if degrees is None or knot_vectors is None:
return None
- for d, kv in zip(degrees, knot_vectors):
+ for d, kv in zip(degrees, knot_vectors, strict=True):
kv_arr = _np.asanyarray(kv)
front = all(abs(kv_arr[: (d + 1)] - kv_arr[0]) < _settings.TOLERANCE)
diff --git a/splinepy/helpme/create.py b/splinepy/helpme/create.py
index 1e3d4ee3d..7ba756846 100644
--- a/splinepy/helpme/create.py
+++ b/splinepy/helpme/create.py
@@ -36,9 +36,7 @@ def embedded(spline, new_dimension):
if spline.dim > new_dimension:
spline_dict = spline.todict()
- spline_dict["control_points"] = spline_dict["control_points"][
- :, :new_dimension
- ]
+ spline_dict["control_points"] = spline_dict["control_points"][:, :new_dimension]
return type(spline)(**spline_dict)
elif spline.dim < new_dimension:
spline_dict = spline.todict()
@@ -105,10 +103,7 @@ def extruded(spline, extrusion_vector=None):
)
)
else:
- raise ValueError(
- "Dimension Mismatch between extrusion extrusion vector "
- "and spline."
- )
+ raise ValueError("Dimension Mismatch between extrusion vector and spline.")
# Start Extrusion
spline_dict = {}
@@ -118,9 +113,7 @@ def extruded(spline, extrusion_vector=None):
if spline.has_knot_vectors:
spline_dict["knot_vectors"] = spline.knot_vectors + [[0, 0, 1, 1]]
if spline.is_rational:
- spline_dict["weights"] = _np.concatenate(
- (spline.weights, spline.weights)
- )
+ spline_dict["weights"] = _np.concatenate((spline.weights, spline.weights))
return type(spline)(**spline_dict)
@@ -161,9 +154,7 @@ def revolved(
axis = _np.asarray(axis).ravel()
# Check Axis dimension
if spline.control_points.shape[1] > axis.shape[0]:
- raise ValueError(
- "Dimension Mismatch between extrusion axis and spline."
- )
+ raise ValueError("Dimension Mismatch between extrusion axis and spline.")
elif spline.control_points.shape[1] < axis.shape[0]:
_log.debug(
"Control Point dimension is smaller than axis dimension,"
@@ -173,9 +164,7 @@ def revolved(
cps = _np.hstack(
(
spline.control_points,
- _np.zeros(
- (len(spline.control_points), expansion_dimension)
- ),
+ _np.zeros((len(spline.control_points), expansion_dimension)),
)
)
else:
@@ -213,24 +202,20 @@ def revolved(
center = _np.asarray(center).ravel()
# Check Axis dimension
if not (problem_dimension == center.shape[0]):
- raise ValueError(
- "Dimension Mismatch between axis and center of rotation."
- )
+ raise ValueError("Dimension Mismatch between axis and center of rotation.")
cps -= center
# The parametric dimension is independent of the revolution but the
# rotation-matrix is only implemented for 2D and 3D problems
if cps.shape[1] not in {2, 3}:
raise NotImplementedError(
- "Sorry," "revolutions only implemented for 2D and 3D splines"
+ "Sorry, revolutions only implemented for 2D and 3D splines"
)
# Angle must be (0, pi) non including
# Rotation is always performed in half steps
PI = _np.pi
- minimum_n_knot_spans = int(
- _np.ceil((abs(angle) + abs(_settings.TOLERANCE)) / PI)
- )
+ minimum_n_knot_spans = int(_np.ceil((abs(angle) + abs(_settings.TOLERANCE)) / PI))
if n_knot_spans is None or (n_knot_spans < minimum_n_knot_spans):
n_knot_spans = minimum_n_knot_spans
@@ -276,9 +261,7 @@ def revolved(
if spline.has_knot_vectors:
kv = [0, 0, 0]
[kv.extend([i + 1, i + 1]) for i in range(n_knot_spans - 1)]
- spline_dict["knot_vectors"] = spline.knot_vectors + [
- kv + [n_knot_spans] * 3
- ]
+ spline_dict["knot_vectors"] = spline.knot_vectors + [kv + [n_knot_spans] * 3]
if spline.is_rational:
mid_weights = spline.weights * weight
spline_dict["weights"] = spline.weights
@@ -298,6 +281,401 @@ def revolved(
return type(spline)(**spline_dict)
+def swept(
+ cross_section,
+ trajectory,
+ cross_section_normal=None,
+ anchor="auto",
+ set_on_trajectory=False,
+ rotation_adaption=None,
+):
+ """
+ Sweeps a cross-section along a trajectory. The cross-section
+ receives rotation into the direction of the trajectory tangent
+ vector and is then placed either at the evaluation points of the
+ trajectory's knots or at the trajectory's control points. This
+ depends on the value of the set_on_trajectory parameter. It can
+ create both a surface or a solid, depending on the dimension of
+ the cross-section.
+
+ The sweeping process has some limitations, since the cross-section
+ cannot be preserved exactly along the whole trajectory.
+
+ This implementation follows the skinning-based swept surface
+ construction described in The NURBS Book, Piegl & Tiller, 2nd
+ edition, chapter 10.4, where cross-section instances are placed
+ along the trajectory and skinned afterwards.
+
+ The cross-section orientation is determined using the projection
+ normal method of Siltanen and Woodward, as described in chapter
+ 10.4, Eq. (10.27). For closed trajectories, the orientation is
+ corrected as described on p. 483.
+
+ Parameters
+ ----------
+ cross_section : Spline
+ Cross-section to be swept. Requires parametric dimension 1 or 2
+ trajectory : Spline
+ Trajectory along which the cross-section is swept.
+ Requires parametric dimension 1
+ cross_section_normal : np.array
+ Normal vector of the cross-section
+ Default is [0, 0, 1]
+ anchor : str
+ Defines which reference point of the cross-section is placed on the
+ trajectory during sweeping.
+ ``"parametric"`` uses the point evaluated at the center of the
+ parametric bounds.
+ ``"control_box"`` uses the center of the control-point bounding box.
+ ``"geometry_box"`` uses the center of the bounding box of sampled
+ geometric points on the cross-section.
+ ``"auto"`` uses ``"geometry_box"`` for curve cross-sections and
+ ``"parametric"`` for surface cross-sections.
+ set_on_trajectory : bool
+ If True, the cross-section will be placed at the evaluation
+ points of the trajectory. If False, the cross-section will be
+ placed at the control points of the trajectory.
+ Default is False.
+ rotation_adaption : float
+ Angle in radians by which the cross-section is rotated around
+ the trajectory tangent vector. This is an additional rotation
+ if the user wants to adapt the cross-section rotation.
+ Example with rectangular cross-section:
+ . x
+ . x x x x x x x
+ . x x x x
+ . x x --> rotation around pi/4 --> x x
+ . x x x x
+ . x x x x x x x
+ . x
+
+ Returns
+ -------
+ swept_spline : Spline
+ Spline resulting from the sweep
+
+ Examples
+ --------
+ See ``examples/show_swept.py`` for example usages of ``swept()``.
+ """
+
+ from splinepy import NURBS as _NURBS
+ from splinepy import BSpline as _BSpline
+ from splinepy import Spline
+
+ ### INPUT CHECKS ###
+
+ if isinstance(cross_section, Spline) and isinstance(trajectory, Spline):
+ if not isinstance(cross_section, (_BSpline, _NURBS)):
+ raise TypeError("cross_section must be an instance of BSpline or NURBS")
+ if not isinstance(trajectory, (_BSpline, _NURBS)):
+ raise TypeError("trajectory must be an instance of BSpline or NURBS")
+ else:
+ raise TypeError("cross_section and trajectory must be instances of Spline")
+ if not trajectory.para_dim == 1:
+ raise ValueError("trajectory must have a parametric dimension of 1")
+
+ if cross_section.para_dim > 2:
+ raise ValueError("cross_section must have a parametric dimension of at most 2")
+
+ if not isinstance(set_on_trajectory, bool):
+ raise TypeError("set_on_trajectory must be a boolean")
+
+ if rotation_adaption is not None:
+ try:
+ rotation_adaption = float(rotation_adaption)
+ except TypeError:
+ raise TypeError("rotation_adaption must be a number (float, int) or None")
+
+ if cross_section_normal is None:
+ cross_section_normal = _np.array([0, 0, 1])
+ # add debug message
+ _log.debug("No cross_section_normal given. Defaulting to [0, 0, 1].")
+ else:
+ try:
+ cross_section_normal = _np.asarray(cross_section_normal).ravel()
+ except (TypeError, ValueError):
+ raise TypeError("cross_section_normal must be array-like and a 3D vector")
+ if cross_section_normal.shape != (3,):
+ raise ValueError("cross_section_normal must be array-like and a 3D vector")
+
+ if not isinstance(anchor, str):
+ raise TypeError("anchor must be a string")
+ anchor = anchor.lower()
+ if anchor == "auto":
+ anchor = "geometry_box" if cross_section.para_dim == 1 else "parametric"
+ if anchor not in {"parametric", "control_box", "geometry_box"}:
+ raise ValueError(
+ "anchor must be one of 'auto', 'parametric', "
+ "'control_box', or 'geometry_box'"
+ )
+
+ ### STARTING CALCULATIONS ###
+
+ # make copies so we can work on it inplace
+ trajectory = trajectory.create.embedded(3)
+ cross_section = cross_section.create.embedded(3)
+
+ # initialize parameter values
+ par_value = trajectory.greville_abscissae()
+ par_value = par_value.reshape(-1, 1)
+
+ ### TRANSFORMATION MATRICES ###
+
+ # tangent vector 'e1' of trajectory at parameter value 0
+ e1 = trajectory.derivative([par_value[0]], [1])
+ e1_norm = _np.linalg.norm(e1)
+ if e1_norm < _settings.TOLERANCE:
+ raise ValueError(
+ "Cannot determine initial sweep direction from trajectory "
+ "because the first tangent is too small."
+ )
+ e1 = (e1 / e1_norm).ravel()
+
+ # evaluating a vector normal to e1
+ vec = [-e1[1], e1[0], -e1[2]]
+ B = []
+ # avoid dividing by zero
+ temp_cross = _np.cross(e1, vec)
+ if _np.linalg.norm(temp_cross) > _settings.TOLERANCE:
+ B.append(temp_cross / _np.linalg.norm(temp_cross))
+ else:
+ vec = [e1[2], -e1[1], e1[0]]
+ temp_cross = _np.cross(e1, vec)
+ B.append(temp_cross / _np.linalg.norm(temp_cross))
+ # add debug message
+ _log.debug(
+ "The initial trajectory direction led to an ambiguous sweep "
+ "orientation. Using an alternative internal reference direction."
+ )
+
+ # initialize transformation matrices and tangent-vector-collection
+ T = []
+ A = []
+ tang_collection = [e1]
+
+ # evaluating transformation matrices for each trajectory point
+ for i in range(len(par_value)):
+ # calculation according to NURBS Book, eq. 10.27
+ # tangent vector e1 on trajectory at parameter value i
+ if i > 0:
+ e1 = trajectory.derivative([par_value[i]], [1])
+ e1_norm = _np.linalg.norm(e1)
+ if e1_norm < _settings.TOLERANCE:
+ e1 = tang_collection[-1]
+ e1_norm = _np.linalg.norm(e1)
+ # add debug message
+ _log.debug(
+ "The trajectory tangent is too small at parametric value "
+ f"{par_value[i]}. Reusing the previous tangent direction "
+ "to continue the sweep frame construction."
+ )
+ e1 = (e1 / e1_norm).ravel()
+ # collecting tangent vectors for later use
+ tang_collection.append(e1)
+
+ # projecting B_(i) onto the plane normal to e1
+ B.append(B[i] - _np.dot(B[i], e1) * e1)
+ if _np.linalg.norm(B[i + 1]) < _settings.TOLERANCE:
+ _log.warning(
+ "The automatically constructed sweep orientation became "
+ f"degenerate at parametric value {par_value[i]}. Applying a "
+ "small numerical adjustment to continue."
+ )
+ B[i + 1] += _settings.TOLERANCE
+ B[i + 1] /= _np.linalg.norm(B[i + 1])
+
+ # defining e2 and e3 vectors
+ e3 = B[i + 1]
+ e2 = _np.cross(e3, e1)
+
+ # array of transformation matrices from global to local coordinates
+ T.append(_np.vstack((e1, e2, e3)))
+
+ # array of transformation matrices from local to global coordinates
+ A.append(T[i].T)
+
+ # separate procedure, if trajectory is closed and B[0] != B[-1]
+ # recalculate B-vector and middle the values between B and B_rec
+ # according to NURBS Book, Piegl & Tiller, 2nd edition, p. 483
+ is_trajectory_closed = _np.allclose(
+ trajectory.evaluate([[0]]),
+ trajectory.evaluate([par_value[-1]]),
+ atol=_settings.TOLERANCE,
+ rtol=1e-8,
+ )
+ is_B_start_equal_B_end = _np.allclose(
+ B[0], B[-1], atol=_settings.TOLERANCE, rtol=1e-8
+ )
+
+ if is_trajectory_closed and not is_B_start_equal_B_end:
+ # reset transformation matrices
+ T = []
+ A = []
+ # preallocate B_rec
+ B_rec = [None] * len(B)
+ # make sure start of B_rec is equal to the end of B
+ B_rec[0] = B[-1]
+ # redo the calculation of B using tang_collection from before
+ # in order to avoid recalculating the tangent vectors;
+ # calculation according to NURBS Book, eq. 10.27
+ for i in range(len(par_value)):
+ B_rec[i + 1] = (
+ B_rec[i] - _np.dot(B_rec[i], tang_collection[i]) * tang_collection[i]
+ )
+ if _np.linalg.norm(B_rec[i + 1]) < _settings.TOLERANCE:
+ _log.warning(
+ "The corrected sweep orientation for the closed "
+ f"trajectory became degenerate at parametric value "
+ f"{par_value[i]}. Applying a small numerical adjustment "
+ "to continue."
+ )
+ B_rec[i + 1] += _settings.TOLERANCE
+ B_rec[i + 1] /= _np.linalg.norm(B_rec[i + 1])
+ # middle point between B and B_rec
+ B_rec[i + 1] = (B[i + 1] + B_rec[i + 1]) * 0.5
+ # normalizing B_rec
+ B_rec[i + 1] /= _np.linalg.norm(B_rec[i + 1])
+ # defining e2 and e3 axis-vectors
+ e3 = B_rec[i + 1]
+ e2 = _np.cross(e3, tang_collection[i])
+
+ # array of transformation matrices from global to local coordinates
+ T.append(_np.vstack((tang_collection[i], e2, e3)))
+
+ # array of transformation matrices from local to global coordinates
+ A.append(T[i].T)
+
+ # check if the beginning and the end of the B-vector are the same
+ if not _np.allclose(B_rec[0], B_rec[-1], rtol=1e-3):
+ _log.warning(
+ "The sweep orientation could only be matched approximately "
+ "because the closed trajectory has non-matching tangent "
+ "directions at its start and end."
+ )
+
+ ### ROTATION MATRIX ###
+ # rotates cross-section normal vector into global e1 direction
+
+ # skip calculation if cross-section normal vector is default
+ if _np.array_equal(cross_section_normal, _np.array([0, 0, 1])):
+ R = _np.array([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]])
+ # else, calculate rotation matrix for given cross-section normal vector
+ else:
+ # calculate angle of cross-section normal vector around e2-axis
+ angle_of_cs_normal_1 = _np.arctan2(
+ cross_section_normal[2], cross_section_normal[0]
+ )
+
+ # calculate angle of cross-section normal vector around e3-axis
+ angle_of_cs_normal_2 = _np.arctan2(
+ cross_section_normal[1], cross_section_normal[2]
+ )
+
+ # calculate rotation matrix for cross-section normal vector
+ R1 = _arr.rotation_matrix_around_axis(
+ axis=[0, 1, 0], rotation=angle_of_cs_normal_1, degree=False
+ )
+ R2 = _arr.rotation_matrix_around_axis(
+ axis=[0, 0, 1], rotation=angle_of_cs_normal_2, degree=False
+ )
+ R = _np.matmul(R2, R1)
+
+ # rotate cross-section around trajectory tangent vector (e1) if wanted
+ if rotation_adaption is not None:
+ R = _np.matmul(
+ _arr.rotation_matrix_around_axis(
+ axis=[1, 0, 0], rotation=rotation_adaption, degree=False
+ ),
+ R,
+ )
+
+ # remove numerical noise
+ R = _np.where(_np.abs(R) < _settings.TOLERANCE, 0, R)
+
+ ### SWEEPING PROCESS ###
+
+ # evaluate center of cross-section and translate to origin
+ if anchor == "parametric":
+ cross_para_center = _np.mean(cross_section.parametric_bounds, axis=0)
+ cs_center = cross_section.evaluate(
+ cross_para_center.reshape(-1, cross_section.para_dim)
+ ).ravel()
+ elif anchor == "control_box":
+ cs_min = cross_section.control_points.min(axis=0)
+ cs_max = cross_section.control_points.max(axis=0)
+ cs_center = 0.5 * (cs_min + cs_max)
+ else: # geometry_box
+ if cross_section.para_dim == 1:
+ sample_resolution = max(101, 4 * cross_section.control_points.shape[0])
+ else:
+ sample_resolution = int(_np.ceil(625 ** (1 / cross_section.para_dim)))
+ sample_resolution = max(5, min(25, sample_resolution))
+
+ sample_axes = [
+ _np.linspace(
+ cross_section.parametric_bounds[0, i],
+ cross_section.parametric_bounds[1, i],
+ sample_resolution,
+ )
+ for i in range(cross_section.para_dim)
+ ]
+ sample_queries = _np.stack(
+ _np.meshgrid(*sample_axes, indexing="ij"),
+ axis=-1,
+ ).reshape(-1, cross_section.para_dim)
+ sampled_points = cross_section.evaluate(sample_queries)
+ cs_min = sampled_points.min(axis=0)
+ cs_max = sampled_points.max(axis=0)
+ cs_center = 0.5 * (cs_min + cs_max)
+
+ centered_cross_section_cps = cross_section.control_points - cs_center
+
+ # set cross-section control points along trajectory
+ swept_spline_cps = []
+ rotated_cross_section_cps = centered_cross_section_cps @ R.T
+ for i, par_val in enumerate(par_value):
+ # evaluate trajectory if user wants to set cross-section on trajectory.
+ if set_on_trajectory:
+ section_origin = trajectory.evaluate([par_val]).ravel()
+ else:
+ section_origin = trajectory.control_points[i]
+
+ swept_spline_cps.append(rotated_cross_section_cps @ A[i].T + section_origin)
+
+ # create spline dictionary
+ dict_swept_spline = {
+ "degrees": [*cross_section.degrees, *trajectory.degrees],
+ "knot_vectors": [
+ *cross_section.knot_vectors,
+ *trajectory.knot_vectors,
+ ],
+ "control_points": _np.asarray(swept_spline_cps).reshape(-1, cross_section.dim),
+ }
+
+ # add weights properly if spline is rational
+ if cross_section.is_rational or trajectory.is_rational:
+
+ def weights(spline):
+ if spline.is_rational:
+ return spline.weights
+ return _np.ones(spline.control_points.shape[0])
+
+ trajectory_weights = weights(trajectory)
+ cross_section_weights = weights(cross_section)
+ dict_swept_spline["weights"] = _np.outer(
+ trajectory_weights, cross_section_weights
+ ).reshape(-1, 1)
+ spline_type = _NURBS
+ else:
+ spline_type = _BSpline
+
+ # create swept spline
+ swept_spline = spline_type(**dict_swept_spline)
+
+ return swept_spline
+
+
def from_bounds(parametric_bounds, physical_bounds):
"""Creates a minimal spline with given parametric bounds, physical bounds.
Physical bounds can have less or equal number of
@@ -406,6 +784,7 @@ def determinant_spline(spline):
spline.unique_knots,
spline.knot_multiplicities,
multiplicity_increase,
+ strict=True,
):
# increase knot multiplicities:
# @ each inner knot -> mult_inc + 1
@@ -420,7 +799,9 @@ def determinant_spline(spline):
[
len(kvs_ds) - d_ds - 1
for kvs_ds, d_ds in zip(
- knot_vectors_determinant_spline, degrees_determinant_spline
+ knot_vectors_determinant_spline,
+ degrees_determinant_spline,
+ strict=True,
)
]
)
@@ -478,9 +859,7 @@ def parametric_view(spline, axes=True, conform=False):
para_spline: BSpline
"""
p_bounds = spline.parametric_bounds
- para_spline = from_bounds(
- parametric_bounds=p_bounds, physical_bounds=p_bounds
- )
+ para_spline = from_bounds(parametric_bounds=p_bounds, physical_bounds=p_bounds)
# process to create conforming para_view splines
if conform:
@@ -506,7 +885,7 @@ def parametric_view(spline, axes=True, conform=False):
# process knots to insert
if spline.has_knot_vectors:
for i, (kv, d) in enumerate(
- zip(spline.knot_vectors, spline.degrees)
+ zip(spline.knot_vectors, spline.degrees, strict=True)
):
n_repeating = int(d + 1)
query = kv[n_repeating:-n_repeating]
diff --git a/splinepy/helpme/integrate.py b/splinepy/helpme/integrate.py
index 4fdec2440..c2c3fd3af 100644
--- a/splinepy/helpme/integrate.py
+++ b/splinepy/helpme/integrate.py
@@ -3,6 +3,11 @@
import numpy as _np
from splinepy.utils.data import cartesian_product as _cartesian_product
+from splinepy.utils.data import has_scipy as _has_scipy
+
+if _has_scipy:
+ from scipy.sparse import dok_matrix as _dok_matrix
+ from scipy.sparse.linalg import spsolve as _spsolve
def _get_integral_measure(spline):
@@ -15,7 +20,7 @@ def _get_integral_measure(spline):
.. math::
\\mathcal{J}_S = det(\\mathbf(J))
- If the physical dimension is bigger then the paramtric dimension it will
+ If the physical dimension is bigger than the parametric dimension it will
return
.. math::
@@ -24,12 +29,13 @@ def _get_integral_measure(spline):
Parameters
----------
spline : Spline / Multipatch
- For parametric and physical dimension
+ The spline object for which the measure of one of its patches is determined
Returns
-------
measure : Callable
- single patch only
+ A function which computes the jacobian's determinant for a single patch.
+ It takes a patch and query positions in the parametric domain as input
"""
# Check dimensionality
if spline.dim == spline.para_dim:
@@ -53,11 +59,25 @@ def measure(spline_patch, positions):
raise ValueError("`Volume` not supported if para_dim > dim")
+def _default_quadrature_orders(spline):
+ # Expected degree for quadrature based on spline's degrees and parametric dimension
+ expected_degree = spline.degrees * spline.para_dim + 1
+ if spline.is_rational:
+ expected_degree += 2
+ spline._logd("Integration on rational spline is only approximation")
+
+ # Gauss-Legendre is exact for polynomials 2*n-1
+ return _np.ceil((expected_degree + 1) * 0.5).astype("int")
+
+
def _get_quadrature_information(spline, orders=None):
"""
- Select appropriate integration order (gauss-legendre)
+ Select appropriate integration order (gauss-legendre).
- Determinante of a polynomial spline with para_dim==dim has degree
+ Determines the integration points and weights for numerical integration
+ based on the given spline and the optionally given quadrature orders.
+
+ Determinant of a polynomial spline with para_dim==dim has degree
.. math::
p_i^{det} = n_{dim} \\cdot p_i - 1
@@ -73,16 +93,17 @@ def _get_quadrature_information(spline, orders=None):
Parameters
----------
spline : Spline
- Spline for integration
+ The spline object for which the quadrature information is determined.
orders : array-like (optional)
- Orders along every parametric dimension
+ Orders along every parametric dimension. If not provided, default quadrature
+ orders will be used.
Returns
-------
positions : np.ndarray
- quadrature position in unit-square
+ Quadrature points in unit-square
weights : np.ndarray
- quadrature weights
+ Quadrature weights
"""
# Determine integration points
@@ -91,15 +112,8 @@ def _get_quadrature_information(spline, orders=None):
# Determine integration orders
if orders is None:
- expected_degree = spline.degrees * spline.para_dim + 1
- if spline.is_rational:
- expected_degree += 2
- spline._logd(
- "Integration on rational spline is only approximation"
- )
+ quad_orders = _default_quadrature_orders(spline)
- # Gauss-Legendre is exact for polynomials 2*n-1
- quad_orders = _np.ceil((expected_degree + 1) * 0.5).astype("int")
else:
quad_orders = _np.ascontiguousarray(orders, dtype=int).flatten()
if quad_orders.size != spline.para_dim:
@@ -124,22 +138,24 @@ def _get_quadrature_information(spline, orders=None):
def volume(spline, orders=None):
r"""Compute volume of a given spline
+ Uses quadrature to compute volume. Can handle patches with multiple elements.
+
Parameters
----------
spline : Spline
(self if called via integrator)
- splinepy - spline type
+ The spline object for which the volume is computed.
orders : array-like (optional)
order for gauss quadrature
Returns
-------
volume : float
- Integral of dim-dimensional object
+ The computed volume of the spline
"""
from splinepy.spline import Spline as _Spline
- # Check i_nput type
+ # Check input type
if not isinstance(spline, _Spline):
raise NotImplementedError("integration only works for splines")
@@ -160,24 +176,22 @@ def volume(spline, orders=None):
return volume
-def _user_function(
+def parametric_function(
spline,
function,
orders=None,
- physical=False,
):
- """Integrate a function defined within the selected domain
+ """Integrate a function defined within the parametric domain
Parameters
----------
spline : Spline
- (self if called via integrator)
+ The geometry over which the function is integrated
function : Callable
+ The user-defined function to integrate. It takes points in the parametric
+ dimension as input and outputs a scalar or an array of scalars.
orders : optional
- physical : bool
- If True, the function is defined in the physical domain. If False,
- the function is defined in the parametric domain.
- Default is False.
+ Quadrature orders for numerical integration
Returns
-------
@@ -193,13 +207,6 @@ def _user_function(
meas = _get_integral_measure(spline)
positions, weights = _get_quadrature_information(spline, orders)
- # define function to integrate
- def _function(position):
- if physical:
- return function(spline.evaluate(position))
- else:
- return function(position)
-
# Calculate Volume
if spline.has_knot_vectors:
# positions must be mapped into each knot-element
@@ -209,73 +216,90 @@ def _function(position):
initial = function([positions[0]])
result = _np.zeros(initial.shape[1])
for bezier_element in para_view.extract.beziers():
- # Get the bezier element scaling factor to get the correct
- # element size from original knot element
- knot_element_scaling_factor = _np.prod(
- _np.diff(bezier_element.control_point_bounds, axis=0)
- )
quad_positions = bezier_element.evaluate(positions)
result += _np.einsum(
"i...,i,i->...",
- _function(quad_positions),
- meas(spline, quad_positions) * knot_element_scaling_factor,
+ function(quad_positions),
+ meas(spline, quad_positions),
weights,
optimize=True,
)
+
else:
result = _np.einsum(
"i...,i,i->...",
- _function(positions),
+ function(positions),
meas(spline, positions),
weights,
- optimize=True,
)
return result
-def parametric_function(
+def physical_function(
spline,
function,
orders=None,
):
- """Integrate a function defined within the parametric domain
+ """Integrate a function defined within the selected domain
Parameters
----------
spline : Spline
- (self if called via integrator)
+ The geometry over which the function is integrated
function : Callable
+ The user-defined function to integrate.
orders : optional
+ Quadrature order in parametric domain for numerical integration
Returns
-------
integral : np.ndarray
"""
- return _user_function(spline, function, orders=orders, physical=False)
+ from splinepy.spline import Spline as _Spline
+ # Check input type
+ if not isinstance(spline, _Spline):
+ raise NotImplementedError("integration only works for splines")
-def physical_function(
- spline,
- function,
- orders=None,
-):
- """Integrate a function defined within the physical domain
+ # Retrieve aux info
+ meas = _get_integral_measure(spline)
+ positions, weights = _get_quadrature_information(spline, orders)
- Parameters
- ----------
- spline : Spline
- The geometry over which the function is integrated
- function : Callable
- The user-defined function to integrate. Can also be vector-valued
- orders : optional
- Quadrature order in parametric domain for numerical integration
+ # define function to integrate
+ def _function(position):
+ return function(spline.evaluate(position))
- Returns
- -------
- integral : np.ndarray
- The computed integral. It is vector-valued if function is vector-valued
- """
- return _user_function(spline, function, orders=orders, physical=True)
+ # Calculate Volume
+ if spline.has_knot_vectors:
+ # positions must be mapped into each knot-element
+ para_view = spline.create.parametric_view(axes=False)
+
+ # get initial shape
+ initial = function([positions[0]])
+ result = _np.zeros(initial.shape[1])
+ for bezier_element in para_view.extract.beziers():
+ # Get the bezier element scaling factor to get the correct
+ # element size from original knot element
+ knot_element_scaling_factor = _np.prod(
+ _np.diff(bezier_element.control_point_bounds, axis=0)
+ )
+ quad_positions = bezier_element.evaluate(positions)
+ result += _np.einsum(
+ "i...,i,i->...",
+ _function(quad_positions),
+ meas(spline, quad_positions) * knot_element_scaling_factor,
+ weights,
+ optimize=True,
+ )
+ else:
+ result = _np.einsum(
+ "i...,i,i->...",
+ _function(positions),
+ meas(spline, positions),
+ weights,
+ optimize=True,
+ )
+ return result
class Integrator:
@@ -312,3 +336,1015 @@ def parametric_function(self, *args, **kwargs):
@_wraps(physical_function)
def physical_function(self, *args, **kwargs):
return physical_function(self._helpee, *args, **kwargs)
+
+
+class Transformation:
+ """Helper class to be used for the numerical integration of field variables on a
+ single-patch geometry.
+
+ It computes the elements within the patch and for each one of them the quadrature
+ points and the Jacobian at those points.
+
+ Parameters
+ ----------
+ spline: spline
+ The geometry
+ solution_field: None or spline
+ Solution field as spline function. If not given, supports and quadrature
+ will be calculated for geometry
+ orders: None or list
+ Quadrature orders. If not given, default quadrature orders will be used
+ """
+
+ __slots__ = (
+ "_spline",
+ "_solution_field",
+ "_mapper",
+ "_para_dim",
+ "_ukv",
+ "_n_elems",
+ "_quad_positions",
+ "_quad_weights",
+ "_grid_ids",
+ "_all_supports",
+ "_all_element_quad_points",
+ "_all_jacobians",
+ "_all_jacobian_inverses",
+ "_all_jacobian_determinants",
+ "_all_element_measures",
+ )
+
+ def __init__(self, spline, solution_field=None, orders=None):
+ self._spline = spline
+ self._solution_field = solution_field
+ if solution_field is not None:
+ self._mapper = self._solution_field.mapper(reference=self._spline)
+
+ self._para_dim = spline.para_dim
+ if self._para_dim == 3:
+ raise NotImplementedError("Not yet tested for 3D")
+
+ if solution_field is None:
+ self._ukv = spline.unique_knots
+ else:
+ self._ukv = self._solution_field.unique_knots
+ n_elems_per_dim = [len(kv) - 1 for kv in self._ukv]
+ self._n_elems = _np.prod(n_elems_per_dim)
+
+ # Gauss-Legendre quadrature points and weights
+ spline_for_quad = spline if solution_field is None else solution_field
+
+ if orders is None:
+ quad_positions = []
+ quad_weights = []
+ for dim_quadrature_order in _default_quadrature_orders(
+ spline_for_quad
+ ):
+ quad_position, quad_weight = _np.polynomial.legendre.leggauss(
+ deg=dim_quadrature_order
+ )
+ # Make quadrature points go from [0,1] instead of [-1,1]
+ quad_positions.append((quad_position + 1) / 2)
+ # Adjust weights accordingly
+ quad_weights.append(quad_weight / 2)
+
+ self._quad_positions = _cartesian_product(quad_positions)
+ self._quad_weights = _np.prod(
+ _cartesian_product(quad_weights), axis=1
+ )
+ else:
+ self._quad_positions, self._quad_weights = (
+ _get_quadrature_information(spline_for_quad, orders)
+ )
+
+ # Precompute grid IDs
+ self._grid_ids = _cartesian_product(
+ [_np.arange(n_elems) for n_elems in n_elems_per_dim],
+ reverse=True,
+ )
+
+ self._all_supports = None
+ self._all_element_quad_points = None
+ self._all_jacobians = None
+ self._all_jacobian_inverses = None
+ self._all_jacobian_determinants = None
+ self._all_element_measures = None
+
+ def check_element_id_validity(self, element_id):
+ """Check if given element ID is valid
+
+ Parameters
+ -----------
+ element_id: int
+ ID of element in spline's element. ID-array is 1D
+ """
+ assert element_id >= 0
+ assert element_id < self._n_elems
+
+ @property
+ def all_supports(self):
+ """Supports of all quadrature points.
+ List of entries of support"""
+ return self._all_supports
+
+ @property
+ def all_quad_points(self):
+ """Quadrature points of all elements.
+ Dimensions [, , 2]"""
+ return self._all_element_quad_points
+
+ @property
+ def all_jacobians(self):
+ """Jacobians of all elements.
+ Dimensions [ , , ]"""
+ return self._all_jacobians
+
+ @property
+ def all_jacobian_inverses(self):
+ """Inverses of Jacobians of all elements.
+ Dimensions [ , , ]"""
+ return self._all_jacobian_inverses
+
+ @property
+ def all_jacobian_determinants(self):
+ """Determinants of Jacobians of all elements.
+ Dimensions [ ]"""
+ return self._all_jacobian_determinants
+
+ @property
+ def quadrature_weights(self):
+ return self._quad_weights
+
+ def get_element_grid_id(self, element_id):
+ """Compute element ID in grid.
+
+ The grid follows splinepy's ordering: first it goes into the x-direction,
+ after that into the y-direction.
+
+ Parameters
+ ----------
+ element_id: int
+ ID of spline's element in element grid
+
+ Returns
+ ---------
+ element_grid_id: list
+ The grid ID of the element.
+ """
+ if self._para_dim == 3:
+ raise NotImplementedError(
+ "Element grid ID not yet implemented for 3D"
+ )
+
+ return self._grid_ids[element_id, :]
+
+ def get_element_quad_points(self, element_id):
+ """Compute the quadrature points for a given element.
+
+ Parameters
+ -----------
+ element_id: int
+ ID of spline's element in element grid
+
+ Returns
+ -----------
+ element_quad_points: np.ndarray
+ Quadrature points for element
+ """
+ self.check_element_id_validity(element_id)
+
+ if self._all_element_quad_points is not None:
+ return self._all_element_quad_points[element_id]
+
+ element_grid_id = self.get_element_grid_id(element_id)
+
+ element_corner_points = _np.vstack(
+ [
+ ukv_dim[e_dim_id : (e_dim_id + 2)]
+ for ukv_dim, e_dim_id in zip(
+ self._ukv, element_grid_id, strict=True
+ )
+ ]
+ )
+ element_lengths = _np.diff(element_corner_points, axis=1).ravel()
+ element_midpoints = _np.mean(element_corner_points, axis=1)
+
+ # Bring center to origin and scale
+ element_quad_points = (self._quad_positions - 0.5) * element_lengths
+ # Apply offset
+ element_quad_points += element_midpoints
+
+ return element_quad_points
+
+ def get_element_support(self, element_id):
+ """Get support for quadrature points in element
+
+ Parameters
+ ------------
+ element_id: int
+ ID of spline's element in element grid
+
+ Returns
+ ---------
+ support: np.ndarray
+ Support for element. All quadrature points have same support
+ """
+ element_quad_points = self.get_element_quad_points(element_id)
+
+ # All quad points in element have same support, therefore take arbitrary
+ # one
+ relevant_quad_point = element_quad_points[0, :]
+
+ if self._solution_field is None:
+ return self._spline.support(relevant_quad_point)
+ else:
+ return self._solution_field.support(relevant_quad_point)
+
+ def jacobian(self, element_id):
+ """Return Jacobian of single element at quadrature points
+
+ Parameters
+ ------------
+ element_id: list
+ ID of spline's element in element grid
+
+ Returns
+ ---------
+ element_jacobian: np.ndarray
+ Jacobian of element evaluated at quadrature points
+ """
+ if self._all_jacobians is not None:
+ return self._all_jacobians[element_id]
+
+ element_quad_points = self.get_element_quad_points(element_id)
+
+ return self._spline.jacobian(element_quad_points)
+
+ def jacobian_inverse(self, element_id):
+ """Return inverse of Jacobian of single element, evaluated at quadrature points
+
+ Parameters
+ ------------
+ element_id: list
+ ID of spline's element in element grid
+
+ Returns
+ ---------
+ element_inverse_jacobian: np.ndarray
+ Inverse of Jacobian of element evaluated at quadrature points
+ """
+ if self._all_jacobian_inverses is not None:
+ return self._all_jacobian_inverses[element_id]
+
+ element_jacobians = self.jacobian(element_id)
+ element_jacobian_inverse = _np.stack(
+ [
+ _np.linalg.inv(element_jacobian)
+ for element_jacobian in element_jacobians
+ ]
+ )
+
+ return element_jacobian_inverse
+
+ def jacobian_determinant(self, element_id):
+ """Return determinant of Jacobian of single element, evaluated at
+ quadrature points
+
+ Parameters
+ ------------
+ element_id: list
+ ID of element in grid
+
+ Returns
+ ---------
+ element_jacobian_determinant: np.ndarray
+ Determinant of Jacobian of element evaluated at quadrature points
+ """
+ if self._all_jacobian_determinants is not None:
+ return self._all_jacobian_determinants[element_id]
+
+ element_jacobians = self.jacobian(element_id)
+ return _np.array(
+ [
+ _np.linalg.det(element_jacobian)
+ for element_jacobian in element_jacobians
+ ]
+ )
+
+ def compute_all_element_quad_points(self, recompute=False):
+ """Compute the quadrature points of all elements
+
+ Parameters
+ ----------
+ recompute: bool (optional)
+ If True, recompute the qudrature points. Default is no recomputation
+ """
+ if self._all_element_quad_points is not None and not recompute:
+ return
+
+ # compute element lengths and center points
+ element_lengths = _cartesian_product(
+ [_np.diff(dim_ukv) for dim_ukv in self._ukv]
+ )
+ element_midpoints = (
+ _cartesian_product([dim_ukv[:-1] for dim_ukv in self._ukv])
+ + element_lengths / 2
+ )
+ # Scale quad points for each element
+ quad_points_centered = _np.einsum(
+ "ij,hj->hij", self._quad_positions, element_lengths
+ )
+ # apply offset to quad points
+ n_elements, n_quad_points, _ = quad_points_centered.shape
+ offsets = element_midpoints - element_lengths / 2
+ self._all_element_quad_points = quad_points_centered + _np.repeat(
+ (offsets).reshape(n_elements, 1, -1), n_quad_points, 1
+ )
+
+ def compute_all_supports(self, recompute=False):
+ """Compute the support for all quadrature points
+
+ Parameters
+ --------------
+ recompute: bool (optional)
+ If True, recomputes the supports. The default is no recomputation
+ """
+ if self._all_supports is not None and not recompute:
+ return
+
+ self.compute_all_element_quad_points(recompute=recompute)
+ relevant_spline = (
+ self._spline
+ if self._solution_field is None
+ else self._solution_field
+ )
+ self._all_supports = [
+ relevant_spline.support(quad_points[:1, :]).ravel()
+ for quad_points in self._all_element_quad_points
+ ]
+
+ def compute_all_element_jacobians(self, recompute=False):
+ """Compute Jacobians of each element at each quadrature point
+
+ Parameters
+ ----------
+ recompute: bool (optional)
+ If True, recomputes the Jacobians. Default option is no recomputation
+ """
+ if self._all_jacobians is not None and not recompute:
+ return
+
+ self.compute_all_element_quad_points(recompute=recompute)
+ self._all_jacobians = _np.stack(
+ [
+ self._spline.jacobian(quad_points)
+ for quad_points in self._all_element_quad_points
+ ]
+ )
+
+ def compute_all_element_jacobian_inverses(self, recompute=False):
+ """Compute Jacobians' inverses of each element at each quadrature point
+
+ Parameters
+ ----------
+ recompute: bool (optional)
+ If True, recompute Jacobians' inverses. Default is no recomputation
+ """
+ if self._all_jacobian_inverses is not None and not recompute:
+ return
+
+ self.compute_all_element_jacobians(recompute=recompute)
+
+ self._all_jacobian_inverses = _np.stack(
+ [
+ _np.stack(
+ [
+ _np.linalg.inv(element_jacobian)
+ for element_jacobian in element_jacobians
+ ]
+ )
+ for element_jacobians in self._all_jacobians
+ ]
+ )
+
+ def compute_all_element_jacobian_determinants(self, recompute=False):
+ """Compute Jacobians' determinants of each element at each quadrature point
+
+ Parameters
+ ----------
+ recompute: bool
+ Recompute Jacobians' determinants
+ """
+ if self._all_jacobian_determinants is not None and not recompute:
+ return
+
+ self.compute_all_element_jacobians(recompute=recompute)
+
+ self._all_jacobian_determinants = _np.stack(
+ [
+ _np.stack(
+ [
+ _np.linalg.det(element_jacobian)
+ for element_jacobian in element_jacobians
+ ]
+ )
+ for element_jacobians in self._all_jacobians
+ ]
+ )
+
+ def compute_all_element_measures(self, recompute=False):
+ """Computes the measures of all elements in parametric space. Assumes
+ tensor-product-like structure.
+ """
+ if self._all_element_measures is not None and not recompute:
+ return
+
+ element_lengths = [_np.diff(ukv) for ukv in self._ukv]
+ self._all_element_measures = _np.prod(
+ _cartesian_product(element_lengths), axis=1
+ )
+
+
+class FieldIntegrator:
+ """
+ Class for the numerical evaluation of a PDE on a single-patch geometry.
+
+ On initialization it sets up solution field, its mapper, precomputes the
+ transformation and calculate the number of DoFs.
+
+
+
+ Parameters
+ ----------
+ geometry: spline
+ The geometry
+ solution_field: None or spline
+ Solution field. If not given, quadrature and supports will be calculated
+ using the geometry
+ orders: None or list
+ Quadrature order in each dimension. If not given, default quadrature
+ will be used
+ """
+
+ __slots__ = (
+ "_helpee",
+ "_solution_field",
+ "_mapper",
+ "_global_rhs",
+ "_global_system_matrix",
+ "_trafo",
+ "_supports",
+ "_ndofs",
+ )
+
+ def __init__(self, geometry, solution_field=None, orders=None):
+ self._helpee = geometry
+ if solution_field is None:
+ self._solution_field = geometry.copy()
+ self._solution_field.control_points = _np.zeros(
+ (geometry.cps.shape[0], 1)
+ )
+ else:
+ self._solution_field = solution_field
+ self._ndofs = int(
+ _np.prod(
+ [
+ len(kv) - 1 - deg
+ for deg, kv in zip(
+ self._solution_field.degrees,
+ self._solution_field.knot_vectors,
+ strict=True,
+ )
+ ]
+ )
+ )
+ self._mapper = self._solution_field.mapper(reference=self._helpee)
+
+ self.reset(orders)
+
+ def reset(self, orders=None):
+ """Sets up the transformation and resets the lhs and rhs.
+
+ Parameters
+ ------------
+ orders: None or list
+ If given, these orders will be used for quadrature. Otherwise, default
+ quadrature orders will be used.
+ """
+ self._trafo = Transformation(
+ self._helpee, self._solution_field, orders
+ )
+ self.precompute_transformation()
+
+ self._supports = None
+ self._global_rhs = None
+ self._global_system_matrix = None
+
+ def precompute_transformation(self):
+ """Computes the quadrature points, jacobians and their determinants
+ of all elements in spline"""
+ self._trafo.compute_all_supports()
+ self._trafo.compute_all_element_jacobian_determinants()
+
+ @property
+ def supports(self):
+ """
+ Get the quadrature points' supports.
+
+ Returns
+ -------
+ supports: np.ndarray
+ The supports
+ """
+ if self._supports is None:
+ self._supports = self._helpee.supports(self._trafo.all_quad_points)
+
+ return self._supports
+
+ def assemble_matrix(self, function, matrixout=None):
+ """Assemble the system matrix for a given function. If system matrix is
+ already assembled, it will add values on top of existing matrix.
+
+ Parameters
+ ------------
+ function: callable
+ Function which defines how to assemble an element matrix
+ matrixout: np.ndarray / scipy.sparse matrix
+ Assembled matrix will be stored there. Default is global system matrix
+ """
+ # Initialize system matrix if not already
+ if self._global_system_matrix is None and matrixout is None:
+ global_size = (self._ndofs, self._ndofs)
+ if _has_scipy:
+ self._global_system_matrix = _dok_matrix(global_size)
+ else:
+ self._global_system_matrix = _np.zeros(global_size)
+
+ # If other matrix is used, check if it compatible
+ if matrixout is not None:
+ if _has_scipy:
+ assert isinstance(
+ matrixout, _dok_matrix
+ ), "Matrixout must be scipy sparse dok matrix"
+ else:
+ assert isinstance(matrixout, _np.ndarray)
+ assert matrixout.shape == (self._ndofs, self._ndofs)
+
+ system_matrix = (
+ self._global_system_matrix if matrixout is None else matrixout
+ )
+
+ quad_weights = self._trafo.quadrature_weights
+
+ # Element loop
+ for element_jacobian_det, element_support, element_quad_points in zip(
+ self._trafo.all_jacobian_determinants,
+ self._trafo.all_supports,
+ self._trafo.all_quad_points,
+ strict=True,
+ ):
+ element_matrix = function(
+ mapper=self._mapper,
+ quad_points=element_quad_points,
+ quad_weights=quad_weights,
+ jacobian_det=element_jacobian_det,
+ )
+ matrix_element_support = _cartesian_product(
+ [element_support, element_support]
+ )
+ system_matrix[
+ matrix_element_support[:, 0], matrix_element_support[:, 1]
+ ] += element_matrix
+
+ def assemble_vector(self, function, current_sol=None, vectorout=None):
+ """Assemble the rhs for a given function. If rhs is already assembled,
+ it will add values on top of existing rhs.
+
+ Parameters
+ ------------
+ function: callable
+ Function which defines how to assemble an element vector
+ current_sol: np.ndarray
+ Current solution vector. Needed for nonlinear forms
+ vectorout: np.ndarray
+ Assembled rhs vector will be stored there. Default is global rhs
+ """
+ # Initialize rhs vector
+ if self._global_rhs is None:
+ self._global_rhs = _np.zeros(self._ndofs)
+
+ # Ensure that current solution has right dimensions
+ if current_sol is not None:
+ assert len(current_sol) == self._ndofs
+
+ if vectorout is not None:
+ assert isinstance(vectorout, _np.ndarray)
+ assert len(vectorout) == self._ndofs
+
+ rhs_vector = self._global_rhs if vectorout is None else vectorout
+
+ # Prepare function arguments, which stay the same for all elements
+ function_args = {
+ "mapper": self._mapper,
+ "quad_weights": self._trafo.quadrature_weights,
+ }
+
+ # Element loop
+ for element_jacobian_det, element_support, element_quad_points in zip(
+ self._trafo.all_jacobian_determinants,
+ self._trafo.all_supports,
+ self._trafo.all_quad_points,
+ strict=True,
+ ):
+ # Assemble element vector
+ function_args["quad_points"] = element_quad_points
+ function_args["jacobian_det"] = element_jacobian_det
+ if current_sol is not None:
+ function_args["current_sol"] = current_sol[element_support]
+ element_vector = function(**function_args)
+
+ # Add element vector to global rhs vector
+ rhs_vector[element_support] += element_vector
+
+ def assemble_matrix_and_vector(
+ self, function, current_sol=None, matrixout=None, vectorout=None
+ ):
+ """Assemble the system matrix and rhs vector for a given function. If system
+ matrix is already assembled, it will add values on top of existing matrix.
+ The same goes for the rhs vector
+
+ Parameters
+ ------------
+ function: callable
+ Function which defines how to assemble an element matrix and vector
+ current_sol: np.ndarray
+ Current solution vector. Needed for nonlinear forms
+ matrixout: np.ndarray / scipy.sparse matrix
+ Assembled matrix will be stored there. Default is global system matrix
+ vectorout: np.ndarray
+ Assembled rhs vector will be stored there. Default is global rhs
+ """
+ # Initialize system matrix if not already
+ if self._global_system_matrix is None and matrixout is None:
+ global_size = (self._ndofs, self._ndofs)
+ if _has_scipy:
+ self._global_system_matrix = _dok_matrix(global_size)
+ else:
+ self._global_system_matrix = _np.zeros(global_size)
+
+ # If other matrix is used, check if it compatible
+ if matrixout is not None:
+ if _has_scipy:
+ assert isinstance(
+ matrixout, _dok_matrix
+ ), "Matrixout must be scipy sparse dok matrix"
+ else:
+ assert isinstance(matrixout, _np.ndarray)
+ assert matrixout.shape == (self._ndofs, self._ndofs)
+
+ # Set matrix accordingly
+ system_matrix = (
+ self._global_system_matrix if matrixout is None else matrixout
+ )
+
+ # Initialize rhs vector
+ if self._global_rhs is None:
+ self._global_rhs = _np.zeros(self._ndofs)
+
+ # Ensure that current solution has right dimensions
+ if current_sol is not None:
+ assert len(current_sol) == self._ndofs
+
+ if vectorout is not None:
+ assert isinstance(vectorout, _np.ndarray)
+ assert len(vectorout) == self._ndofs
+
+ # Set rhs vector accordingly
+ rhs_vector = self._global_rhs if vectorout is None else vectorout
+
+ # Prepare function arguments, which stay the same for all elements
+ function_args = {
+ "mapper": self._mapper,
+ "quad_weights": self._trafo.quadrature_weights,
+ }
+
+ # Element loop
+ for element_jacobian_det, element_support, element_quad_points in zip(
+ self._trafo.all_jacobian_determinants,
+ self._trafo.all_supports,
+ self._trafo.all_quad_points,
+ strict=True,
+ ):
+ # Assemble element matrix and vector
+ function_args["quad_points"] = element_quad_points
+ function_args["jacobian_det"] = element_jacobian_det
+ if current_sol is not None:
+ function_args["current_sol"] = current_sol[element_support]
+ element_matrix, element_vector = function(**function_args)
+
+ # Add element vector to global system matrix
+ matrix_element_support = _cartesian_product(
+ [element_support, element_support]
+ )
+ system_matrix[
+ matrix_element_support[:, 0], matrix_element_support[:, 1]
+ ] += element_matrix
+
+ # Add element vector to global rhs vector
+ rhs_vector[element_support] += element_vector
+
+ def L2_projection(self, function):
+ """Perform an L2-projection of a function
+
+ Parameters
+ ----------------
+ function: callable
+ Function to L2-project
+
+ Returns
+ -------------
+ dof_values: np.ndarray
+ L2-projected values for Dofs
+ """
+
+ def dirichlet_lhs_and_rhs(
+ mapper, quad_points, quad_weights, jacobian_det
+ ):
+ # Assemble system matrix
+ bf_values = mapper._field_reference.basis(quad_points)
+ element_matrix = _np.einsum(
+ "qi,qj,q,q->ij",
+ bf_values,
+ bf_values,
+ quad_weights,
+ jacobian_det,
+ optimize=True,
+ )
+
+ # Assemble rhs
+ quad_points_forward = mapper._geometry_reference.evaluate(
+ quad_points
+ )
+ function_values = function(quad_points_forward)
+ element_vector = _np.einsum(
+ "qj,q,q,q->j",
+ bf_values,
+ function_values,
+ quad_weights,
+ jacobian_det,
+ optimize=True,
+ )
+
+ return element_matrix.ravel(), element_vector
+
+ # Initialiye mass matrix and rhs
+ global_size = (self._ndofs, self._ndofs)
+ mass_matrix = (
+ _dok_matrix(global_size) if _has_scipy else _np.zeros(global_size)
+ )
+ rhs_vector = _np.zeros(self._ndofs)
+ # Assemble lhs and rhs
+ self.assemble_matrix_and_vector(
+ dirichlet_lhs_and_rhs, matrixout=mass_matrix, vectorout=rhs_vector
+ )
+
+ # Solve system to get all dofs
+ dof_values = _np.empty(self._ndofs)
+ if _has_scipy:
+ dof_values = _spsolve(mass_matrix.tocsr(), rhs_vector)
+ else:
+ dof_values = _np.linalg.solve(mass_matrix, rhs_vector)
+
+ return dof_values
+
+ def check_if_assembled(self):
+ """
+ Check if system matrix and rhs are already assembled
+ """
+ if self._global_system_matrix is None or self._global_rhs is None:
+ raise ValueError("System is not yet fully assembled")
+
+ def get_boundary_dofs(
+ self,
+ all_boundaries=True,
+ north=False,
+ east=False,
+ south=False,
+ west=False,
+ ):
+ """
+ Get indices of boundary dofs. Assumes that control points are arranged
+ in the following way: first one is the southwest corner, then the first
+ dimension goes from west to east and second dimension goes from south to
+ north.
+
+ Parameters
+ ------------------
+ all_boundaries: bool
+ If True, get indices of all boundary dofs and ignores values for
+ north, south, east and west. On the other, if any boundary is selected,
+ this value will be ignored
+ north: bool
+ If True, return indices for north boundary of geometry
+ east: bool
+ south: bool
+ west: bool
+
+ Returns
+ -------------
+ indices: np.ndarray
+ Indices of relevant boundary dofs
+ """
+ relevant_spline = (
+ self._helpee
+ if self._solution_field is None
+ else self._solution_field
+ )
+
+ multi_index = relevant_spline.multi_index
+
+ multi_indices = [
+ multi_index[0, :],
+ multi_index[-1, :],
+ multi_index[:, 0],
+ multi_index[:, -1],
+ ]
+
+ # If at least one boundary is True, set all_boundaries to False
+ if north or east or south or west:
+ all_boundaries = False
+
+ boundaries = (
+ [True] * 4 if all_boundaries else [west, east, south, north]
+ )
+
+ indices = _np.unique(
+ _np.hstack(
+ [
+ index
+ for index, boundary in zip(
+ multi_indices, boundaries, strict=True
+ )
+ if boundary
+ ]
+ )
+ )
+
+ return indices
+
+ def apply_homogeneous_dirichlet_boundary_conditions(
+ self,
+ all_boundaries=True,
+ north=False,
+ east=False,
+ south=False,
+ west=False,
+ ):
+ """
+ Assembles homogeneous Dirichlet boundary conditions
+
+ Parameters
+ -------------
+ all_boundaries: bool
+ If True, get indices of all boundary dofs and ignores values for
+ north, south, east and west
+ north: bool
+ If True, sets homogeneous Dirichlet condition on north boundary
+ east: bool
+ south: bool
+ west: bool
+ """
+ self.check_if_assembled()
+
+ indices = self.get_boundary_dofs(
+ all_boundaries, north, east, south, west
+ )
+
+ self._global_system_matrix[indices, :] = 0
+ self._global_system_matrix[indices, indices] = 1
+ self._global_rhs[indices] = 0
+
+ def apply_dirichlet_boundary_conditions(
+ self,
+ function,
+ return_values=False,
+ all_boundaries=True,
+ north=False,
+ east=False,
+ south=False,
+ west=False,
+ ):
+ """
+ Applies Dirichlet boundary conditions via L2-projection.
+
+ Firstly, the function is L2-projected on the whole domain, but only the DoFs
+ corresponding to the boundaries are taken into account.
+
+ Parameters
+ -------------
+ function: callable
+ Function to apply. Input are points, output is scalar
+ return_values: bool
+ If True, computed values and the corresponding DoF indices will be returned
+ and not applied to global system matrix or the global rhs. If False, values
+ will be applied to system matrix and rhs and nothing will be returned
+ all_boundaries: bool
+ If True, get indices of all boundary dofs and ignores values for
+ north, south, east and west
+ north: bool
+ If True, sets homogeneous Dirichlet condition on north boundary
+ east: bool
+ south: bool
+ west: bool
+ """
+ if not return_values:
+ self.check_if_assembled()
+
+ dof_vector = self.L2_projection(function)
+
+ # Get relevant dofs
+ indices = self.get_boundary_dofs(
+ all_boundaries, north, east, south, west
+ )
+
+ if return_values:
+ return dof_vector[indices], indices
+ else:
+ # Apply Dirichlet to relevant boundary dofs
+ self._global_system_matrix[indices, :] = 0
+ self._global_system_matrix[indices, indices] = 1
+ self._global_rhs[indices] = dof_vector[indices]
+
+ def solve_linear_system(self):
+ """
+ Solve linear system for system matrix and rhs
+ """
+ self.check_if_assembled()
+
+ if _has_scipy:
+ solution_vector = _spsolve(
+ self._global_system_matrix.tocsr(), self._global_rhs
+ )
+ else:
+ solution_vector = _np.linalg.solve(
+ self._global_system_matrix, self._global_rhs
+ )
+ self._solution_field.control_points = solution_vector.reshape(-1, 1)
+
+ def compute_error(self, function, norm="l2"):
+ """
+ Compute error to some given function(s) w.r.t a norm
+
+ Parameters
+ -------------
+ function: callable
+ Analytical function(s) to compare to
+ norm: str
+ Used norm for error calculation
+
+ Returns
+ ------------------
+ error_integration: np.ndarray
+ Value(s) of error in given norm
+ """
+ self._trafo.compute_all_element_jacobian_determinants()
+
+ # Evaluate function and solution values
+ all_quad_points = self._trafo._all_element_quad_points.reshape(
+ -1, self._helpee.para_dim
+ )
+ all_physical_points = self._helpee.evaluate(all_quad_points)
+ all_function_values = function(all_physical_points)
+ solution_values = self._solution_field.evaluate(all_quad_points)
+ error_values = all_function_values - solution_values
+ # Take the norm into consideration
+ if norm == "l1":
+ error_norm_values = _np.abs(error_values)
+ elif norm == "l2":
+ error_norm_values = _np.power(error_values, 2)
+ elif norm == "linf":
+ return _np.max(_np.abs(error_values))
+ else:
+ raise NotImplementedError(f"{norm}-norm not implemented")
+
+ # Integrate error
+ quad_weights = self._trafo._quad_weights
+ n_weights = quad_weights.shape[0]
+ quad_weights = _np.tile(
+ quad_weights, len(solution_values) // len(quad_weights)
+ )
+ self._trafo.compute_all_element_measures()
+
+ error_integration = _np.einsum(
+ "i...,i,i->...",
+ error_norm_values,
+ self._trafo._all_jacobian_determinants.ravel()
+ * _np.repeat(self._trafo._all_element_measures, n_weights),
+ quad_weights,
+ optimize=True,
+ )
+
+ if norm == "l1":
+ return error_integration
+ elif norm == "l2":
+ return _np.sqrt(error_integration)
diff --git a/splinepy/io/gismo.py b/splinepy/io/gismo.py
index ec66f5662..9b1405540 100644
--- a/splinepy/io/gismo.py
+++ b/splinepy/io/gismo.py
@@ -270,7 +270,7 @@ def add_assembly_options(
children_list = []
for label, description, value, number_type in zip(
- labels, descriptions, values, number_types
+ labels, descriptions, values, number_types, strict=True
):
children_list.append(
{
@@ -644,7 +644,9 @@ def export(
boundary_data.text = "\n".join(
[
str(patch_id + index_offset) + " " + str(local_face_id + 1)
- for (patch_id, local_face_id) in zip(*face_id_list)
+ for (patch_id, local_face_id) in zip(
+ *face_id_list, strict=True
+ )
]
)
else:
@@ -657,7 +659,9 @@ def export(
boundary_data.text = "\n".join(
[
str(sid + index_offset) + " " + str(bid + 1)
- for (sid, bid) in zip(boundary_spline, boundary_face)
+ for (sid, bid) in zip(
+ boundary_spline, boundary_face, strict=True
+ )
]
)
###
@@ -685,7 +689,9 @@ def export(
bc.text = "\n".join(
[
str(sid) + " " + str(bid + 1)
- for (sid, bid) in zip(bc_data_i[0], bc_data_i[1])
+ for (sid, bid) in zip(
+ bc_data_i[0], bc_data_i[1], strict=True
+ )
]
)
@@ -704,9 +710,9 @@ def export(
as_base64=as_base64,
field_mask=field_mask,
)
- field_xml.find("MultiPatch").find("patches").text = (
- f"{index_offset} " f"{n_patches - 1 + index_offset}"
- )
+ field_xml.find("MultiPatch").find(
+ "patches"
+ ).text = f"{index_offset} {n_patches - 1 + index_offset}"
if int(_python_version.split(".")[1]) >= 9 and indent:
_ET.indent(field_xml)
file_content = _ET.tostring(field_xml)
@@ -723,7 +729,7 @@ def export(
if n_patches != len(multipatch.patches):
raise RuntimeError("Help - some patches were not recognised")
- patch_range.text = f"{index_offset} " f"{n_patches - 1 + index_offset}"
+ patch_range.text = f"{index_offset} {n_patches - 1 + index_offset}"
# Add additional options to the xml file
if additional_blocks is not None:
@@ -976,12 +982,11 @@ def make_dictionary(ETelement):
list_of_options.append(make_dictionary(child))
else:
_debug(
- f"Found unsupported keyword {child.tag}, which will be"
- " ignored"
+ f"Found unsupported keyword {child.tag}, which will be ignored"
)
continue
- _debug(f"Found a total of {len(list_of_splines)} " f"BSplines and NURBS")
+ _debug(f"Found a total of {len(list_of_splines)} BSplines and NURBS")
multipatch = _Multipatch(list_of_splines)
if interface_array is not None:
if invalid_integer in interface_array:
diff --git a/splinepy/io/irit.py b/splinepy/io/irit.py
index b00dca1d7..6fe88983e 100644
--- a/splinepy/io/irit.py
+++ b/splinepy/io/irit.py
@@ -62,7 +62,9 @@ def extract_relevant_text(lines):
spline_list = []
# Loop over text file data
- for type, data in zip(spline_strings[1::2], spline_strings[2::2]):
+ for type, data in zip(
+ spline_strings[1::2], spline_strings[2::2], strict=True
+ ):
# Dictionary of current spline
spline = {}
diff --git a/splinepy/io/mfem.py b/splinepy/io/mfem.py
index 750c9b951..f2d2cdec3 100644
--- a/splinepy/io/mfem.py
+++ b/splinepy/io/mfem.py
@@ -448,6 +448,7 @@ def _corner_vertex_ids(spline):
for row, boundary_id in zip(
boundaries.reshape(-1, n_vertex_per_boundary).tolist(),
boundary_ids.tolist(),
+ strict=True,
)
)
)
@@ -456,7 +457,7 @@ def _corner_vertex_ids(spline):
f.write(f"\n\nedges\n{0}\n")
# Write Number Of vertices
- f.write(f"\nvertices\n{int(_np.max(vertex_ids)+1)}\n\n")
+ f.write(f"\nvertices\n{int(_np.max(vertex_ids) + 1)}\n\n")
# Export Splines
f.write("patches\n\n")
@@ -497,6 +498,7 @@ def _corner_vertex_ids(spline):
for (coords, weight) in zip(
spline.control_points.tolist(),
spline.weights.tolist(),
+ strict=True,
)
)
+ "\n\n"
diff --git a/splinepy/io/svg.py b/splinepy/io/svg.py
index b8fd6e40b..93d704f2a 100644
--- a/splinepy/io/svg.py
+++ b/splinepy/io/svg.py
@@ -271,7 +271,7 @@ def _export_gustaf_object(
cmap_style = gus_object.show_options.get("cmap", "jet")
colors = [
_rgb_2_hex(r, g, b)
- for r, g, b, in _color_map(
+ for r, g, b in _color_map(
values.ravel(), name=cmap_style, vmin=v_min, vmax=v_max
)
]
@@ -284,7 +284,7 @@ def _export_gustaf_object(
id="control_points",
)
- for vertex, color in zip(gus_object.vertices, colors):
+ for vertex, color in zip(gus_object.vertices, colors, strict=True):
_ET.SubElement(
svg_control_points,
"circle",
@@ -320,7 +320,7 @@ def _export_gustaf_object(
svg_labels.attrib["stroke"] = "none"
dx = radius
- for ctp, label in zip(gus_object.vertices, labels):
+ for ctp, label in zip(gus_object.vertices, labels, strict=True):
text_element = _ET.SubElement(
svg_labels,
"text",
@@ -395,7 +395,7 @@ def _export_control_mesh(
"g",
id="mesh",
style=(
- f"fill:none;stroke:{_rgb_2_hex(r,g,b)};stroke-opacity:{a};"
+ f"fill:none;stroke:{_rgb_2_hex(r, g, b)};stroke-opacity:{a};"
f"stroke-width:{stroke_width};stroke-linecap:round"
),
)
@@ -442,7 +442,6 @@ def _export_control_mesh(
# Then control points
if control_point_requested:
-
# Relevant options:
# - control_point_ids
# - control_point_alpha
@@ -735,7 +734,7 @@ def _add_scalar_bar(svg_element, box_size, **kwargs):
"g",
id="tick_mark_lines",
style=(
- f"fill:none;stroke:{_rgb_2_hex(r,g,b)};stroke-opacity:{a};"
+ f"fill:none;stroke:{_rgb_2_hex(r, g, b)};stroke-opacity:{a};"
f"stroke-width:{stroke_width};stroke-linecap:round"
),
)
@@ -775,7 +774,7 @@ def _add_scalar_bar(svg_element, box_size, **kwargs):
),
)
- for mark, position in zip(tick_marks, tick_mark_positions):
+ for mark, position in zip(tick_marks, tick_mark_positions, strict=True):
# Draw a line
_ET.SubElement(
svg_tick_marks,
@@ -987,7 +986,6 @@ def _approximate_curve(original_spline, tolerance):
# Check if a field is to be plotted
if spline.show_options.get("data", None) is not None:
-
# spline.show()
_export_spline_field(
spline, svg_spline, box_min_x, box_max_y, **kwargs
@@ -1008,15 +1006,15 @@ def _approximate_curve(original_spline, tolerance):
spline_copy = _approximate_curve(spline, tolerance)
bezier_elements = spline_copy.extract.beziers()
path_d = (
- f"M {bezier_elements[0].cps[0,0]-box_min_x},"
- f"{box_max_y - bezier_elements[0].cps[0,1]}"
+ f"M {bezier_elements[0].cps[0, 0] - box_min_x},"
+ f"{box_max_y - bezier_elements[0].cps[0, 1]}"
)
path_d += " ".join(
[
(
- f" C {s.cps[1,0]-box_min_x},{box_max_y - s.cps[1,1]}"
- f" {s.cps[2,0]-box_min_x},{box_max_y - s.cps[2,1]}"
- f" {s.cps[3,0]-box_min_x},{box_max_y - s.cps[3,1]}"
+ f" C {s.cps[1, 0] - box_min_x},{box_max_y - s.cps[1, 1]}"
+ f" {s.cps[2, 0] - box_min_x},{box_max_y - s.cps[2, 1]}"
+ f" {s.cps[3, 0] - box_min_x},{box_max_y - s.cps[3, 1]}"
)
for s in bezier_elements
]
@@ -1027,7 +1025,7 @@ def _approximate_curve(original_spline, tolerance):
# draw path
d=path_d,
style=(
- f"fill:none;stroke:{_rgb_2_hex(r,g,b)};stroke-opacity:{a};"
+ f"fill:none;stroke:{_rgb_2_hex(r, g, b)};stroke-opacity:{a};"
f"stroke-width:{spline.show_options.get('lw', 0.01)};"
"stroke-linecap:round"
),
@@ -1048,16 +1046,16 @@ def _approximate_curve(original_spline, tolerance):
bezier_elements += spline_copy.extract.beziers()
path_d = (
- f"M {bezier_elements[0].cps[0,0]-box_min_x},"
- f"{box_max_y - bezier_elements[0].cps[0,1]}"
+ f"M {bezier_elements[0].cps[0, 0] - box_min_x},"
+ f"{box_max_y - bezier_elements[0].cps[0, 1]}"
)
path_d += " ".join(
[
(
f" C"
- f" {s.cps[1,0]-box_min_x},{box_max_y - s.cps[1,1]}"
- f" {s.cps[2,0]-box_min_x},{box_max_y - s.cps[2,1]}"
- f" {s.cps[3,0]-box_min_x},{box_max_y - s.cps[3,1]}"
+ f" {s.cps[1, 0] - box_min_x},{box_max_y - s.cps[1, 1]}"
+ f" {s.cps[2, 0] - box_min_x},{box_max_y - s.cps[2, 1]}"
+ f" {s.cps[3, 0] - box_min_x},{box_max_y - s.cps[3, 1]}"
)
for s in bezier_elements
]
@@ -1069,8 +1067,8 @@ def _approximate_curve(original_spline, tolerance):
# draw path
d=path_d,
style=(
- f"fill:{_rgb_2_hex(r,g,b)};fill-opacity:{a};stroke:none;"
- f"stroke-linecap:{kwargs.get('linecap','round')}"
+ f"fill:{_rgb_2_hex(r, g, b)};fill-opacity:{a};stroke:none;"
+ f"stroke-linecap:{kwargs.get('linecap', 'round')}"
),
)
@@ -1094,7 +1092,6 @@ def _approximate_curve(original_spline, tolerance):
ukvs = spline.unique_knots[0]
knot_projected = spline.evaluate(ukvs.reshape(-1, 1))
for x, y in knot_projected:
-
_ET.SubElement(
svg_knots,
"rect",
@@ -1103,13 +1100,11 @@ def _approximate_curve(original_spline, tolerance):
height=str(lw),
width=str(lw),
style=(
- f"fill:{_rgb_2_hex(r,g,b)};stroke:none;"
- f"fill-opacity:{a};"
+ f"fill:{_rgb_2_hex(r, g, b)};stroke:none;fill-opacity:{a};"
),
)
else:
-
# Extract knot lines as splines
knot_lines = []
for knot in spline.unique_knots[0]:
@@ -1123,16 +1118,16 @@ def _approximate_curve(original_spline, tolerance):
spline_copy = _approximate_curve(knot_line, tolerance)
bezier_elements = spline_copy.extract.beziers()
path_d = (
- f"M {bezier_elements[0].cps[0,0]-box_min_x},"
- f"{box_max_y - bezier_elements[0].cps[0,1]}"
+ f"M {bezier_elements[0].cps[0, 0] - box_min_x},"
+ f"{box_max_y - bezier_elements[0].cps[0, 1]}"
)
path_d += " ".join(
[
(
- f" C {s.cps[1,0]-box_min_x},"
- f"{box_max_y - s.cps[1,1]}"
- f" {s.cps[2,0]-box_min_x},{box_max_y - s.cps[2,1]}"
- f" {s.cps[3,0]-box_min_x},{box_max_y - s.cps[3,1]}"
+ f" C {s.cps[1, 0] - box_min_x},"
+ f"{box_max_y - s.cps[1, 1]}"
+ f" {s.cps[2, 0] - box_min_x},{box_max_y - s.cps[2, 1]}"
+ f" {s.cps[3, 0] - box_min_x},{box_max_y - s.cps[3, 1]}"
)
for s in bezier_elements
]
@@ -1143,10 +1138,10 @@ def _approximate_curve(original_spline, tolerance):
# draw path
d=path_d,
style=(
- f"fill:none;stroke:{_rgb_2_hex(r,g,b)};"
+ f"fill:none;stroke:{_rgb_2_hex(r, g, b)};"
f"stroke-opacity:{a};"
f"stroke-width:{lw};"
- f"stroke-linecap:{kwargs.get('linecap','round')}"
+ f"stroke-linecap:{kwargs.get('linecap', 'round')}"
),
)
diff --git a/splinepy/microstructure/microstructure.py b/splinepy/microstructure/microstructure.py
index 366935651..ec3424750 100644
--- a/splinepy/microstructure/microstructure.py
+++ b/splinepy/microstructure/microstructure.py
@@ -9,7 +9,7 @@
class Microstructure(_SplinepyBase):
- """Helper class to facilitatae the construction of microstructures."""
+ """Helper class to facilitate the construction of microstructures."""
def __init__(
self,
@@ -18,7 +18,7 @@ def __init__(
microtile=None,
parametrization_function=None,
):
- """Helper class to facilitatae the construction of microstructures.
+ """Helper class to facilitate the construction of microstructures.
Parameters
----------
@@ -79,8 +79,7 @@ def deformation_function(self, deformation_function):
if not isinstance(deformation_function, _PySpline):
raise ValueError(
- "Deformation function must be splinepy-Spline."
- " e.g. splinepy.NURBS"
+ "Deformation function must be splinepy-Spline. e.g. splinepy.NURBS"
)
self._deformation_function = deformation_function
@@ -120,9 +119,7 @@ def tiling(self, tiling):
None
"""
if not isinstance(tiling, list) and not isinstance(tiling, int):
- raise ValueError(
- "Tiling mus be either list of integers of integer " "value"
- )
+ raise ValueError("Tiling mus be either list of integers of integer value")
self._tiling = tiling
# Is defaulted to False using function arguments
self._sanity_check()
@@ -263,7 +260,7 @@ def _additional_knots(self, knot_span_wise):
# Create Spline that will be used to iterate over parametric space
ukvs = self.deformation_function.unique_knots
if knot_span_wise:
- for tt, ukv in zip(self.tiling, ukvs):
+ for tt, ukv in zip(self.tiling, ukvs, strict=True):
inv_t = 1 / tt
new_knots = [
ukv[i - 1] + j * inv_t * (ukv[i] - ukv[i - 1])
@@ -276,7 +273,7 @@ def _additional_knots(self, knot_span_wise):
"New knots will be inserted one by one with the objective"
" to evenly distribute tiles within the parametric domain"
)
- for i_pd, (tt, ukv) in enumerate(zip(self.tiling, ukvs)):
+ for i_pd, (tt, ukv) in enumerate(zip(self.tiling, ukvs, strict=True)):
n_current_spans = len(ukv) - 1
if tt == n_current_spans:
continue
@@ -358,10 +355,8 @@ def _compute_tiling_prerequisites(
# First step : insert all required knots into the deformation function
# spline
if macro_sensitivity:
- knot_insertion_matrix = (
- deformation_function_copy.knot_insertion_matrix(
- 0, additional_knots[0]
- )
+ knot_insertion_matrix = deformation_function_copy.knot_insertion_matrix(
+ 0, additional_knots[0]
)
deformation_function_copy.insert_knots(0, additional_knots[0])
for i_pd, akv in enumerate(additional_knots[1:], start=1):
@@ -427,8 +422,8 @@ def _compute_tiling_prerequisites(
def create(
self,
closing_face=None,
- knot_span_wise=None,
- macro_sensitivities=None,
+ knot_span_wise=True,
+ macro_sensitivities=False,
**kwargs,
):
"""Create a Microstructure.
@@ -455,18 +450,15 @@ def create(
if not self._sanity_check():
raise ValueError("Not enough information provided, abort")
- # Set default values
- if knot_span_wise is None:
- knot_span_wise = True
- if macro_sensitivities is None:
- macro_sensitivities = False
+ if isinstance(knot_span_wise, bool) is False:
+ raise TypeError("knot_span_wise must be a bool")
+ if isinstance(macro_sensitivities, bool) is False:
+ raise TypeError("macro_senstivities must be a bool")
# check if user wants closed structure
if closing_face is not None:
if not hasattr(self.microtile, "_closing_tile"):
- raise ValueError(
- "Microtile does not provide closing tile definition"
- )
+ raise ValueError("Microtile does not provide closing tile definition")
closing_face_dim = {"x": 0, "y": 1, "z": 2}.get(closing_face)
if closing_face is None:
raise ValueError(
@@ -485,9 +477,7 @@ def create(
# Check if parametrized
is_parametrized = self.parametrization_function is not None
- parameter_sensitivities = (
- self.parameter_sensitivity_function is not None
- )
+ parameter_sensitivities = self.parameter_sensitivity_function is not None
if parameter_sensitivities and not is_parametrized:
raise ValueError(
@@ -532,10 +522,7 @@ def create(
# Prepare field for derivatives
if macro_sensitivities or parameter_sensitivities:
spline_list_derivs = [
- []
- for i in range(
- n_parameter_sensitivities + n_macro_sensitivities
- )
+ [] for _ in range(n_parameter_sensitivities + n_macro_sensitivities)
]
spline_list_ms = []
@@ -557,9 +544,7 @@ def create(
# If the sensitivities are requested, evaluate the sensitivity
# function, which must be provided by the user
if parameter_sensitivities:
- tile_sensitivities = self.parameter_sensitivity_function(
- positions
- )
+ tile_sensitivities = self.parameter_sensitivity_function(positions)
# To avoid unnecessary constructions (if a parameter
# sensitivity evaluates to zero), perform only those that are
# in the support of a specific design variable
@@ -604,9 +589,7 @@ def create(
tile_patch, compute_sensitivities=True
)
spline_list_ms.append(composed)
- basis_function_compositions.append(
- basis_function_composition
- )
+ basis_function_compositions.append(basis_function_composition)
else:
for tile_patch in tile:
spline_list_ms.append(def_fun.compose(tile_patch))
@@ -618,7 +601,7 @@ def create(
for j in anti_support:
spline_list_derivs[j].extend(empty_splines)
for j, deris in enumerate(derivatives):
- for tile_v, tile_deriv in zip(tile, deris):
+ for tile_v, tile_deriv in zip(tile, deris, strict=True):
spline_list_derivs[support[j]].append(
def_fun.composition_derivative(tile_v, tile_deriv)
)
@@ -642,16 +625,10 @@ def create(
control_points = _np.zeros(
(cps.shape[0], self._deformation_function.dim)
)
- ii_ctps, jj_dim = divmod(
- j_cc, self._deformation_function.dim
- )
+ ii_ctps, jj_dim = divmod(j_cc, self._deformation_function.dim)
control_points[:, jj_dim] = mapped_cps[:, ii_ctps]
- spline_list_derivs[
- n_parameter_sensitivities + j_cc
- ].append(
- type(patch_info[0])(
- patch_info[0].degrees, control_points
- )
+ spline_list_derivs[n_parameter_sensitivities + j_cc].append(
+ type(patch_info[0])(patch_info[0].degrees, control_points)
)
# Use a multipatch object to bundle all information
@@ -723,8 +700,7 @@ def _sanity_check(self):
or (self.tiling is None)
):
self._logd(
- "Current information not sufficient,"
- " awaiting further assignments"
+ "Current information not sufficient, awaiting further assignments"
)
return False
# Check if microtile object fulfils requirements
@@ -768,9 +744,7 @@ def _sanity_check(self):
"attribute `evaluation_points`, that is required for"
" a parametrized microstructure construction"
)
- result = self._parametrization_function(
- self._microtile.evaluation_points
- )
+ result = self._parametrization_function(self._microtile.evaluation_points)
if not isinstance(result, _np.ndarray):
raise ValueError(
"Function outline of parametrization function must be "
@@ -781,9 +755,7 @@ def _sanity_check(self):
return True
# Check sensitivity function
- result = self.parameter_sensitivity_function(
- self._microtile.evaluation_points
- )
+ result = self.parameter_sensitivity_function(self._microtile.evaluation_points)
if (not isinstance(result, _np.ndarray)) or (not result.ndim == 3):
raise ValueError(
"Function outline of parameter sensitivity function must "
@@ -823,8 +795,7 @@ def __init__(self, microtile):
for m in microtile:
if not isinstance(m, _PySpline):
raise ValueError(
- "Microtiles must be (list of) "
- "splinepy-Splines. e.g. splinepy.NURBS"
+ "Microtiles must be (list of) splinepy-Splines. e.g. splinepy.NURBS"
)
# Extract beziers for every non Bezier patch else this just
# returns itself
diff --git a/splinepy/microstructure/tiles/__init__.py b/splinepy/microstructure/tiles/__init__.py
index 3b35a1f5c..d301320e4 100644
--- a/splinepy/microstructure/tiles/__init__.py
+++ b/splinepy/microstructure/tiles/__init__.py
@@ -8,6 +8,7 @@
armadillo,
chi,
cross_2d,
+ cross_3d,
cross_3d_linear,
cube_void,
double_lattice,
@@ -42,6 +43,7 @@
"chi",
"cross_2d",
"cube_void",
+ "cross_3d",
"cross_3d_linear",
"double_lattice",
"ellips_v_oid",
@@ -86,7 +88,7 @@ def _summarize_tiles():
key = SubClass.__qualname__
# save types and sort with direction
tile_types[key] = SubClass
- dim = SubClass.dim
+ dim = SubClass._dim
if dim == 1:
d1[key] = SubClass
elif dim == 2:
@@ -123,7 +125,7 @@ def by_dim(para_dim=None, dim=None):
para_dim = int(para_dim)
filtered = {}
for key, value in pool.items():
- if value.para_dim == para_dim:
+ if value._para_dim == para_dim:
filtered[key] = value
# overwrite pool with filtered
diff --git a/splinepy/microstructure/tiles/armadillo.py b/splinepy/microstructure/tiles/armadillo.py
index e7f39aa66..8e4712d99 100644
--- a/splinepy/microstructure/tiles/armadillo.py
+++ b/splinepy/microstructure/tiles/armadillo.py
@@ -20,11 +20,25 @@ class Armadillo(_TileBase):
_dim = 3
_evaluation_points = _np.array([[0.5, 0.5, 0.5]])
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _closure_directions = [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max",
+ ]
+ _parameter_bounds = [[0.0, 0.5]]
+ _parameters_shape = (1, 1)
+ _default_parameter_value = 0.2
+
+ _CONTACT_LENGTH_BOUNDS = [0.0, 0.99]
def _closing_tile(
self,
parameters=None,
- parameter_sensitivities=None, # TODO
+ parameter_sensitivities=None,
contact_length=0.3,
closure=None,
**kwargs, # noqa ARG002
@@ -58,4104 +72,5017 @@ def _closing_tile(
if closure is None:
raise ValueError("No closing direction given")
- if not isinstance(contact_length, float):
- raise ValueError("Invalid Type for radius")
+ self._check_custom_parameter(
+ contact_length, "contact length", self._CONTACT_LENGTH_BOUNDS
+ )
- if not ((contact_length > 0) and (contact_length < 0.99)):
- raise ValueError("The length of a side must be in (0.01, 0.99)")
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
- if parameters is None:
- self._logd("Setting parameters to default values (0.2)")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ v_wall_thickness = parameters[0, 0]
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ v_half_contact_length = contact_length * 0.5
+ v_inner_half_contact_length = contact_length * v_wall_thickness
+ else:
+ v_wall_thickness = parameter_sensitivities[
+ 0, 0, i_derivative - 1
+ ]
+ v_zero = 0.0
+ v_one_half = 0.0
+ v_one = 0.0
+ v_half_contact_length = 0.0
+ v_inner_half_contact_length = contact_length * v_wall_thickness
+
+ spline_list = []
+
+ if closure == "x_min":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
)
- * 0.2
- )
- self.check_params(parameters)
+ connection_front_right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
+ front = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
+ connection_back_left = _np.array(
+ [
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- v_wall_thickness = parameters[0, 0]
- spline_list = []
- v_zero = 0.0
- v_one_half = 0.5
- v_one = 1.0
- v_half_contact_length = contact_length * 0.5
- v_inner_half_contact_length = contact_length * parameters[0, 0]
+ left = _np.array(
+ [
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- if closure == "x_min":
- # set points:
- right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ connection_front_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_front_right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ back = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- front = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ connection_back_right = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- connection_back_left = _np.array(
- [
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- left = _np.array(
- [
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_zero,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ top = _np.array(
+ [
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ ]
+ )
- connection_front_left = _np.array(
- [
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_zero,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ connection_front_bottom = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- back = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ connection_front_top = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ ]
+ )
- connection_back_right = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ connection_back_bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ connection_back_top = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- top = _np.array(
- [
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- ]
- )
+ connection_top_right = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_front_bottom = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ connection_top_left = _np.array(
+ [
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_front_top = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- ]
- )
-
- connection_back_bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_top = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_right = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_left = _np.array(
- [
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_bottom_left = _np.array(
- [
- [
- v_zero,
- v_one,
- v_zero,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- elif closure == "x_max":
- # set points:
- right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_zero,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_zero,
- ],
- ]
- )
-
- connection_front_right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- front = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- connection_back_left = _np.array(
- [
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- left = _np.array(
- [
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_front_left = _np.array(
- [
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- back = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_right = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_zero,
- ],
- ]
- )
-
- bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- top = _np.array(
- [
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- ]
- )
-
- connection_front_bottom = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_front_top = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- ]
- )
-
- connection_back_bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_top = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_right = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_left = _np.array(
- [
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_bottom_left = _np.array(
- [
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_one,
- v_zero,
- ],
- [
- v_one,
- v_zero,
- v_zero,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- elif closure == "y_min":
- # set points:
- right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- connection_front_right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- front = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- connection_back_left = _np.array(
- [
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
- ]
- )
-
- left = _np.array(
- [
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_front_left = _np.array(
- [
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- back = _np.array(
- [
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_right = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_zero,
- v_zero,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- top = _np.array(
- [
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- ]
- )
-
- connection_front_bottom = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_front_top = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- ]
- )
-
- connection_back_bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one,
- v_zero,
- v_zero,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_top = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_right = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_left = _np.array(
- [
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_bottom_left = _np.array(
- [
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- elif closure == "y_max":
- # set points:
- # set points:
- right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- connection_front_right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_zero,
- ],
- ]
- )
-
- front = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_zero,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_zero,
- ],
- ]
- )
-
- connection_back_left = _np.array(
- [
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- left = _np.array(
- [
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_left = _np.array(
- [
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_zero,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- back = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ connection_bottom_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- connection_back_right = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ connection_bottom_right = _np.array(
+ [
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ elif closure == "x_max":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ ]
+ )
- top = _np.array(
- [
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- ]
- )
+ connection_front_right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- connection_front_bottom = _np.array(
- [
- [
- v_one,
- v_one,
- v_zero,
- ],
- [
- v_zero,
- v_one,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ front = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- connection_front_top = _np.array(
- [
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- ]
- )
+ connection_back_left = _np.array(
+ [
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- connection_back_bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ left = _np.array(
+ [
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_back_top = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ connection_front_left = _np.array(
+ [
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_top_right = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ back = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_front_left = _np.array(
- [
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ connection_back_right = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ ]
+ )
+
+ bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ top = _np.array(
+ [
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ ]
+ )
+
+ connection_front_bottom = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_front_top = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_back_bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_top = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_right = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_left = _np.array(
+ [
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_bottom_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_bottom_right = _np.array(
+ [
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ elif closure == "y_min":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ front = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_left = _np.array(
+ [
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ ]
+ )
+
+ left = _np.array(
+ [
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_left = _np.array(
+ [
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_bottom_left = _np.array(
- [
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ back = _np.array(
+ [
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ connection_back_right = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- elif closure == "z_max":
- # set points:
- right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- connection_front_right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ top = _np.array(
+ [
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ ]
+ )
- front = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ connection_front_bottom = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_front_top = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_back_bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_top = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_right = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_left = _np.array(
+ [
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_bottom_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_bottom_right = _np.array(
+ [
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ elif closure == "y_max":
+ # set points:
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ ]
+ )
+
+ front = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ ]
+ )
+
+ connection_back_left = _np.array(
+ [
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ left = _np.array(
+ [
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_left = _np.array(
+ [
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ back = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_right = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
- connection_back_left = _np.array(
- [
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- left = _np.array(
- [
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ top = _np.array(
+ [
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ ]
+ )
- connection_front_left = _np.array(
- [
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ connection_front_bottom = _np.array(
+ [
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- back = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ connection_front_top = _np.array(
+ [
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ ]
+ )
- connection_back_right = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
+ connection_back_bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_top = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_right = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_left = _np.array(
+ [
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_bottom_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_bottom_right = _np.array(
+ [
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ elif closure == "z_max":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ front = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_left = _np.array(
+ [
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ left = _np.array(
+ [
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_left = _np.array(
+ [
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ back = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_right = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ top = _np.array(
+ [
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ ]
+ )
- bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ connection_front_bottom = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- top = _np.array(
- [
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- ]
- )
+ connection_front_top = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ ]
+ )
- connection_front_bottom = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ connection_back_bottom = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_front_top = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- ]
- )
+ connection_back_top = _np.array(
+ [
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_back_bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
+ connection_top_right = _np.array(
+ [
+ [
+ v_one,
+ v_one,
+ v_one,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_top_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_bottom_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_bottom_right = _np.array(
+ [
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ elif closure == "z_min":
+ # set points:
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_right = _np.array(
+ [
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ front = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_left = _np.array(
+ [
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ left = _np.array(
+ [
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_front_left = _np.array(
+ [
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ back = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
+
+ connection_back_right = _np.array(
+ [
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ -v_wall_thickness + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ ]
+ )
+
+ bottom = _np.array(
+ [
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ top = _np.array(
+ [
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ ]
+ )
+
+ connection_front_bottom = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_front_top = _np.array(
+ [
+ [
+ v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_one,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ ]
+ )
+
+ connection_back_bottom = _np.array(
+ [
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_zero,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_back_top = _np.array(
- [
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ connection_back_top = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_top_right = _np.array(
- [
- [
- v_one,
- v_one,
- v_one,
- ],
- [
- v_one,
- v_zero,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ connection_top_right = _np.array(
+ [
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_top_left = _np.array(
- [
- [
- v_zero,
- v_one,
- v_one,
- ],
- [
- v_zero,
- v_zero,
- v_one,
- ],
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ connection_top_left = _np.array(
+ [
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_bottom_left = _np.array(
- [
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ connection_bottom_left = _np.array(
+ [
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_zero,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
+ connection_bottom_right = _np.array(
+ [
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one,
+ v_zero,
+ ],
+ [
+ v_one,
+ v_zero,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
+
+ for control_points in [
+ right,
+ connection_front_right,
+ front,
+ connection_back_left,
+ left,
+ connection_front_left,
+ back,
+ connection_back_right,
+ bottom,
+ top,
+ connection_front_bottom,
+ connection_front_top,
+ connection_back_bottom,
+ connection_back_top,
+ connection_top_right,
+ connection_top_left,
+ connection_bottom_left,
+ connection_bottom_right,
+ ]:
+ spline_list.append(
+ _Bezier(degrees=[1, 1, 1], control_points=control_points)
+ )
+
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
+
+ return (splines, derivatives)
+
+ def create_tile(
+ self,
+ parameters=None,
+ parameter_sensitivities=None, # TODO
+ contact_length=0.3,
+ closure=None,
+ **kwargs, # noqa ARG002
+ ):
+ """Create a microtile based on the parameters that describe the wall
+ thicknesses.
+
+ Thickness parameters are used to describe the inner radius of the
+ outward facing branches
+
+ Parameters
+ ----------
+ parameters : np.array
+ One evaluation point with one parameter is used. This parameter
+ describes the thickness of the wall. The parameters must be a
+ two-dimensional np.array, where the value must be between 0.01
+ and 0.49
+ parameter_sensitivities: np.ndarray
+ Describes the parameter sensitivities with respect to some design
+ variable. In case the design variables directly apply to the
+ parameter itself, they evaluate as delta_ij
+ contact_length : float
+ the length of the wall that contacts the other microstructure
+ closure : str
+ parametric dimension that needs to be closed, given in the form
+ "x_min", "x_max", etc.
+
+ Returns
+ -------
+ microtile_list : list(splines)
+ derivative_list : list / None
+ """
+
+ self._check_custom_parameter(
+ contact_length, "contact length", self._CONTACT_LENGTH_BOUNDS
+ )
+
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
+
+ if closure is not None:
+ return self._closing_tile(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ contact_length=contact_length,
+ closure=closure,
+ **kwargs,
)
- elif closure == "z_min":
- # set points:
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ v_wall_thickness = parameters[0, 0]
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ v_half_contact_length = contact_length * 0.5
+ v_inner_half_contact_length = contact_length * v_wall_thickness
+ else:
+ v_wall_thickness = parameter_sensitivities[
+ 0, 0, i_derivative - 1
+ ]
+ v_zero = 0.0
+ v_one_half = 0.0
+ v_one = 0.0
+ v_half_contact_length = 0.0
+ v_inner_half_contact_length = contact_length * v_wall_thickness
+
+ spline_list = []
+
# set points:
right = _np.array(
[
@@ -4520,23 +5447,23 @@ def _closing_tile(
bottom = _np.array(
[
[
- v_one,
- v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
v_zero,
],
[
- v_zero,
- v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
v_zero,
],
[
- v_one,
- v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
v_zero,
],
[
- v_zero,
- v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
v_zero,
],
[
@@ -4620,13 +5547,13 @@ def _closing_tile(
v_one_half - v_half_contact_length,
],
[
- v_one,
- v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
v_zero,
],
[
- v_zero,
- v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
v_zero,
],
[
@@ -4699,1286 +5626,301 @@ def _closing_tile(
connection_back_bottom = _np.array(
[
- [
- v_one,
- v_zero,
- v_zero,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
- ],
[
v_one_half + v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
v_one_half - v_half_contact_length,
v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_top = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
],
[
v_one_half - v_half_contact_length,
v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_right = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
],
[
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_top_left = _np.array(
- [
- [
- v_one_half - v_half_contact_length,
v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
v_zero,
v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
],
- ]
- )
-
- connection_bottom_left = _np.array(
- [
[
- v_zero,
- v_one_half + v_half_contact_length,
v_one_half - v_half_contact_length,
- ],
- [
v_zero,
v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_zero,
- v_one,
- v_zero,
- ],
- [
- v_zero,
- v_zero,
- v_zero,
],
[
- v_one_half - v_wall_thickness,
v_one_half + v_inner_half_contact_length,
v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
v_one_half - v_wall_thickness,
],
[
v_one_half - v_inner_half_contact_length,
v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
+ v_one_half - v_wall_thickness,
],
[
- v_wall_thickness + v_one_half,
v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
v_one_half - v_inner_half_contact_length,
],
[
- v_wall_thickness + v_one_half,
-v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
v_one_half - v_inner_half_contact_length,
],
+ ]
+ )
+
+ connection_back_top = _np.array(
+ [
[
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
v_one,
- v_one,
- v_zero,
],
[
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
v_one,
- v_zero,
- v_zero,
],
[
v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
],
[
- v_one_half + v_inner_half_contact_length,
v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_bottom_left)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_bottom_right)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_bottom)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_bottom)
- )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_top)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_top)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_top_right)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_left)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=right))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_right)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=back))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_left)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=left))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_top_left)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=front))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_right)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=bottom))
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=top))
-
- return (spline_list, None)
-
- def create_tile(
- self,
- parameters=None,
- parameter_sensitivities=None, # TODO
- contact_length=0.3,
- closure=None,
- **kwargs, # noqa ARG002
- ):
- """Create a microtile based on the parameters that describe the wall
- thicknesses.
-
- Thickness parameters are used to describe the inner radius of the
- outward facing branches
-
- Parameters
- ----------
- parameters : np.array
- One evaluation point with one parameter is used. This parameter
- describes the thickness of the wall. The parameters must be a
- two-dimensional np.array, where the value must be between 0.01
- and 0.49
- parameter_sensitivities: np.ndarray
- Describes the parameter sensitivities with respect to some design
- variable. In case the design variables directly apply to the
- parameter itself, they evaluate as delta_ij
- contact_length : float
- the length of the wall that contacts the other microstructure
- closure : str
- parametric dimension that needs to be closed, given in the form
- "x_min", "x_max", etc.
-
- Returns
- -------
- microtile_list : list(splines)
- derivative_list : list / None
- """
-
- if not isinstance(contact_length, float):
- raise ValueError("Invalid Type for radius")
-
- if not ((contact_length > 0) and (contact_length < 0.99)):
- raise ValueError("The length of a side must be in (0.01, 0.99)")
-
- if parameters is None:
- self._logd("Setting parameters to default values (0.2)")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- self.check_params(parameters)
-
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
-
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
-
- if closure is not None:
- return self._closing_tile(
- parameters=parameters,
- parameter_sensitivities=parameter_sensitivities,
- contact_length=contact_length,
- closure=closure,
- **kwargs,
- )
-
- v_wall_thickness = parameters[0, 0]
- v_zero = 0.0
- v_one_half = 0.5
- v_one = 1.0
- v_half_contact_length = contact_length * 0.5
- v_half_contact_length = contact_length * 0.5
- v_inner_half_contact_length = contact_length * parameters[0, 0]
-
- spline_list = []
-
- # set points:
- right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- connection_front_right = _np.array(
- [
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- front = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- connection_back_left = _np.array(
- [
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- left = _np.array(
- [
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_front_left = _np.array(
- [
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_zero,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- back = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_right = _np.array(
- [
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- -v_wall_thickness + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half + v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- ]
- )
-
- bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- top = _np.array(
- [
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- ]
- )
-
- connection_front_bottom = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- connection_front_top = _np.array(
- [
- [
- v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_one,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- ]
- )
-
- connection_back_bottom = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_zero,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- ],
- ]
- )
-
- connection_back_top = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- -v_half_contact_length + v_one_half,
- v_zero,
- v_one_half + v_half_contact_length,
- ],
- [
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- [
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ -v_half_contact_length + v_one_half,
+ v_zero,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_top_right = _np.array(
- [
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half + v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
+ connection_top_right = _np.array(
[
- v_one_half + v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_top_left = _np.array(
- [
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_one,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_one,
- ],
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_wall_thickness,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
+ connection_top_left = _np.array(
[
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- ],
- ]
- )
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_one,
+ ],
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_wall_thickness,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ ],
+ ]
+ )
- connection_bottom_left = _np.array(
- [
- [
- v_zero,
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_zero,
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_wall_thickness,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half - v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
+ connection_bottom_left = _np.array(
[
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
+ [
+ v_zero,
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_zero,
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_wall_thickness,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- connection_bottom_right = _np.array(
- [
- [
- v_one,
- v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_one,
- -v_half_contact_length + v_one_half,
- v_one_half - v_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_wall_thickness + v_one_half,
- -v_inner_half_contact_length + v_one_half,
- v_one_half - v_inner_half_contact_length,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half + v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_half_contact_length,
- v_one_half - v_half_contact_length,
- v_zero,
- ],
- [
- v_one_half + v_inner_half_contact_length,
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
+ connection_bottom_right = _np.array(
[
- v_one_half + v_inner_half_contact_length,
- v_one_half - v_inner_half_contact_length,
- v_one_half - v_wall_thickness,
- ],
- ]
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=right))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_right)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=back))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_left)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=left))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_left)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=front))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_right)
- )
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=bottom))
-
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=top))
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_top)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_front_bottom)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_bottom)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_back_top)
- )
-
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_top_right)
- )
+ [
+ v_one,
+ v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_one,
+ -v_half_contact_length + v_one_half,
+ v_one_half - v_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_wall_thickness + v_one_half,
+ -v_inner_half_contact_length + v_one_half,
+ v_one_half - v_inner_half_contact_length,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half + v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_half_contact_length,
+ v_one_half - v_half_contact_length,
+ v_zero,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ [
+ v_one_half + v_inner_half_contact_length,
+ v_one_half - v_inner_half_contact_length,
+ v_one_half - v_wall_thickness,
+ ],
+ ]
+ )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_top_left)
- )
+ for control_points in [
+ right,
+ connection_front_right,
+ front,
+ connection_back_left,
+ left,
+ connection_front_left,
+ back,
+ connection_back_right,
+ bottom,
+ top,
+ connection_front_bottom,
+ connection_front_top,
+ connection_back_bottom,
+ connection_back_top,
+ connection_top_right,
+ connection_top_left,
+ connection_bottom_left,
+ connection_bottom_right,
+ ]:
+ spline_list.append(
+ _Bezier(degrees=[1, 1, 1], control_points=control_points)
+ )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_bottom_left)
- )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=connection_bottom_right)
- )
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
- return (spline_list, None)
+ return (splines, derivatives)
diff --git a/splinepy/microstructure/tiles/chi.py b/splinepy/microstructure/tiles/chi.py
index b8430d0dc..4a48132dd 100644
--- a/splinepy/microstructure/tiles/chi.py
+++ b/splinepy/microstructure/tiles/chi.py
@@ -16,8 +16,12 @@ class Chi(_TileBase):
_dim = 2
_para_dim = 1
- _evaluation_points = _np.array([[0.5, 0.5]])
+ _evaluation_points = _np.array([[0.5]])
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _parameter_bounds = [[-_np.pi / 2, _np.pi / 2]]
+ _parameters_shape = (1, 1)
+ _default_parameter_value = _np.pi / 8
def create_tile(
self,
@@ -41,28 +45,10 @@ def create_tile(
microtile_list : list(splines)
"""
- # set to default if nothing is given
- if parameters is None:
- self._logd(
- "Tile request is not parametrized, setting default Pi/8"
- )
- parameters = _np.array([[_np.pi / 8]])
- else:
- if not (
- _np.all(parameters >= -_np.pi * 0.5)
- and _np.all(parameters < _np.pi * 0.5)
- ):
- raise ValueError("The parameter must be in -Pi/2 and Pi/2")
- pass
- self.check_params(parameters)
-
- # Check if user requests derivative splines
- if self.check_param_derivatives(parameter_sensitivities):
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
splines = []
for i_derivative in range(n_derivatives + 1):
@@ -75,12 +61,13 @@ def create_tile(
s = r * _np.sin(alpha)
c = r * _np.cos(alpha)
else:
- alpha = parameter_sensitivities[0, 0, i_derivative - 1]
+ alpha = parameters[0, 0] + _np.pi / 4
+ dalpha = float(parameter_sensitivities[0, 0, i_derivative - 1])
v_one_half = 0.0
v_zero = 0.0
r = _np.sqrt(0.125)
- s = r * _np.cos(alpha)
- c = -r * _np.sin(alpha)
+ s = dalpha * r * _np.cos(alpha)
+ c = dalpha * -r * _np.sin(alpha)
# Init return value
spline_list = []
diff --git a/splinepy/microstructure/tiles/cross_2d.py b/splinepy/microstructure/tiles/cross_2d.py
index 083d0c65a..990db61f2 100644
--- a/splinepy/microstructure/tiles/cross_2d.py
+++ b/splinepy/microstructure/tiles/cross_2d.py
@@ -26,6 +26,23 @@ class Cross2D(_TileBase):
]
)
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _closure_directions = ["x_min", "x_max", "y_min", "y_max"]
+ _parameters_shape = (4, 1)
+ _default_parameter_value = 0.2
+
+ # Default value of center_expansion
+ _center_expansion = 1.0
+
+ # Dynamical computation of parameter bounds depending on center expansion
+ @property
+ def _parameter_bounds(self):
+ max_radius = min(0.5, (0.5 / self._center_expansion))
+ return [[0.0, max_radius]] * 4
+
+ _BOUNDARY_WIDTH_BOUNDS = [0.0, 0.5]
+ _FILLING_HEIGHT_BOUNDS = [0.0, 1.0]
+ _CENTER_EXPANSION_BOUNDS = [0.5, 1.5]
def _closing_tile(
self,
@@ -66,36 +83,17 @@ def _closing_tile(
if closure is None:
raise ValueError("No closing direction given")
- if parameters is None:
- self._logd("Tile request is not parametrized, setting default 0.2")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- self.check_params(parameters)
-
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError("Thickness out of range (0, .5)")
-
- if not (0.0 < float(boundary_width) < 0.5):
- raise ValueError("Boundary Width is out of range")
-
- if not (0.0 < float(filling_height) < 1.0):
- raise ValueError("Filling must be in (0,1)")
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
- # Check if user requests derivative splines
- if parameter_sensitivities is not None:
- # Check format
- self.check_param_derivatives(parameter_sensitivities)
-
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ self._check_custom_parameter(
+ boundary_width, "boundary width", self._BOUNDARY_WIDTH_BOUNDS
+ )
+ self._check_custom_parameter(
+ filling_height, "filling height", self._FILLING_HEIGHT_BOUNDS
+ )
splines = []
for i_derivative in range(n_derivatives + 1):
@@ -414,41 +412,16 @@ def create_tile(
derivative_list : list / None
"""
- if not isinstance(center_expansion, float):
- raise ValueError("Invalid Type")
-
- if not ((center_expansion > 0.5) and (center_expansion < 1.5)):
- raise ValueError("Center Expansion must be in (.5,1.5)")
-
- max_radius = min(0.5, (0.5 / center_expansion))
-
- # set to default if nothing is given
- if parameters is None:
- self._logd("Setting branch thickness to default 0.2")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- self.check_params(parameters)
-
- if not (_np.all(parameters > 0) and _np.all(parameters < max_radius)):
- raise ValueError(f"Thickness out of range (0, {max_radius})")
-
- self.check_param_derivatives(parameter_sensitivities)
+ self._check_custom_parameter(
+ center_expansion, "center expansion", self._CENTER_EXPANSION_BOUNDS
+ )
- # Check if user requests derivative splines
- if parameter_sensitivities is not None:
- # Check format
- self.check_param_derivatives(parameter_sensitivities)
+ self._center_expansion = center_expansion
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
# Closure requested, pass to function
if closure is not None:
diff --git a/splinepy/microstructure/tiles/cross_3d.py b/splinepy/microstructure/tiles/cross_3d.py
index 8752c9881..95fe347b0 100644
--- a/splinepy/microstructure/tiles/cross_3d.py
+++ b/splinepy/microstructure/tiles/cross_3d.py
@@ -28,6 +28,23 @@ class Cross3D(_TileBase):
]
)
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _closure_directions = ["z_min", "z_max"]
+ _parameters_shape = (6, 1)
+ _default_parameter_value = 0.2
+
+ # Default value of center_expansion
+ _center_expansion = 1.0
+
+ # Dynamical computation of parameter bounds depending on center expansion
+ @property
+ def _parameter_bounds(self):
+ max_radius = min(0.5, (0.5 / self._center_expansion))
+ return [[0.0, max_radius]] * 6
+
+ _BOUNDARY_WIDTH_BOUNDS = [0.0, 0.5]
+ _FILLING_HEIGHT_BOUNDS = [0.0, 1.0]
+ _CENTER_EXPANSION_BOUNDS = [0.5, 1.5]
def _closing_tile(
self,
@@ -68,32 +85,17 @@ def _closing_tile(
if closure is None:
raise ValueError("No closing direction given")
- if parameters is None:
- self._logd("Tile request is not parametrized, setting default 0.2")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError("Thickness out of range (0, .5)")
-
- # Check if user requests derivative splines
- if parameter_sensitivities is not None:
- self.check_param_derivatives(parameter_sensitivities)
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
-
- if not (0.0 < float(boundary_width) < 0.5):
- raise ValueError("Boundary Width is out of range")
-
- if not (0.0 < float(filling_height) < 1.0):
- raise ValueError("Filling must be in (0,1)")
+ self._check_custom_parameter(
+ boundary_width, "boundary width", self._BOUNDARY_WIDTH_BOUNDS
+ )
+ self._check_custom_parameter(
+ filling_height, "filling height", self._FILLING_HEIGHT_BOUNDS
+ )
splines = []
for i_derivative in range(n_derivatives + 1):
@@ -518,45 +520,23 @@ def create_tile(
derivative_list : list / None
"""
- if not isinstance(center_expansion, float):
- raise ValueError("Invalid Type")
+ self._check_custom_parameter(
+ center_expansion, "center expansion", self._CENTER_EXPANSION_BOUNDS
+ )
- if not ((center_expansion > 0.5) and (center_expansion < 1.5)):
- raise ValueError("Center Expansion must be in (.5,1.5)")
+ self._center_expansion = center_expansion
- # Max radius, so there is no tanglement in the crosstile
- max_radius = min(0.5, (0.5 / center_expansion))
-
- # set to default if nothing is given
- if parameters is None:
- self._logd("Setting branch thickness to default 0.2")
- parameters = (
- _np.ones(
- (
- self._evaluation_points.shape[0],
- self._n_info_per_eval_point,
- )
- )
- * 0.2
- )
-
- # Check for type and consistency
- self.check_params(parameters)
- if _np.any(parameters <= 0) or _np.any(parameters > max_radius):
- raise ValueError(
- f"Radii must be in (0,{max_radius}) for "
- f"center_expansion {center_expansion}"
- )
-
- if parameter_sensitivities is not None:
- self.check_param_derivatives(parameter_sensitivities)
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
if closure is not None:
+ if closure not in self._closure_directions:
+ raise NotImplementedError(
+ f"Closure '{closure}' not implemented. Supported closures are: "
+ + f"{self._closure_directions}"
+ )
return self._closing_tile(
parameters=parameters,
parameter_sensitivities=parameter_sensitivities,
diff --git a/splinepy/microstructure/tiles/cross_3d_linear.py b/splinepy/microstructure/tiles/cross_3d_linear.py
index 3e5901371..9f23404b4 100644
--- a/splinepy/microstructure/tiles/cross_3d_linear.py
+++ b/splinepy/microstructure/tiles/cross_3d_linear.py
@@ -28,6 +28,23 @@ class Cross3DLinear(_TileBase):
]
)
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _closure_directions = ["z_min", "z_max"]
+ _parameters_shape = (6, 1)
+ _default_parameter_value = 0.2
+
+ # Default value of center_expansion
+ _center_expansion = 1.0
+
+ # Dynamical computation of parameter bounds depending on center expansion
+ @property
+ def _parameter_bounds(self):
+ max_radius = min(0.5, (0.5 / self._center_expansion))
+ return [[0.0, max_radius]] * 6
+
+ _BOUNDARY_WIDTH_BOUNDS = [0.0, 0.5]
+ _FILLING_HEIGHT_BOUNDS = [0.0, 1.0]
+ _CENTER_EXPANSION_BOUNDS = [0.5, 1.5]
def _closing_tile(
self,
@@ -46,7 +63,7 @@ def _closing_tile(
Six evaluation points with one parameter is used. This parameter
describes the radius of the cylinder at the evaluation point.
The parameters must be a two-dimensional np.array, where the
- value must be between 0.01 and 0.49
+ value must be between 0.0 and 0.5 (not inclusive)
parameter_sensitivities: np.ndarray(6, 1, para_dim)
Describes the parameter sensitivities with respect to some design
variable. In case the design variables directly apply to the
@@ -68,32 +85,17 @@ def _closing_tile(
if closure is None:
raise ValueError("No closing direction given")
- if parameters is None:
- self._logd("Tile request is not parametrized, setting default 0.2")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError("Thickness out of range (0, .5)")
-
- # Check if user requests derivative splines
- if parameter_sensitivities is not None:
- self.check_param_derivatives(parameter_sensitivities)
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
-
- if not (0.0 < float(boundary_width) < 0.5):
- raise ValueError("Boundary Width is out of range")
-
- if not (0.0 < float(filling_height) < 1.0):
- raise ValueError("Filling must be in (0,1)")
+ self._check_custom_parameter(
+ boundary_width, "boundary width", self._BOUNDARY_WIDTH_BOUNDS
+ )
+ self._check_custom_parameter(
+ filling_height, "filling height", self._FILLING_HEIGHT_BOUNDS
+ )
splines = []
for i_derivative in range(n_derivatives + 1):
@@ -199,8 +201,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.maximum(
- center_ctps
- - _np.array([center_width, v_zero, v_zero]),
+ center_ctps - _np.array([center_width, v_zero, v_zero]),
v_zero,
)
if i_derivative == 0
@@ -214,8 +215,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.maximum(
- center_ctps
- - _np.array([v_zero, center_width, v_zero]),
+ center_ctps - _np.array([v_zero, center_width, v_zero]),
v_zero,
)
if i_derivative == 0
@@ -229,8 +229,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.minimum(
- center_ctps
- + _np.array([center_width, v_zero, v_zero]),
+ center_ctps + _np.array([center_width, v_zero, v_zero]),
v_one,
)
if i_derivative == 0
@@ -244,8 +243,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.minimum(
- center_ctps
- + _np.array([v_zero, center_width, v_zero]),
+ center_ctps + _np.array([v_zero, center_width, v_zero]),
v_one,
)
if i_derivative == 0
@@ -353,8 +351,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.maximum(
- center_ctps
- - _np.array([center_width, v_zero, v_zero]),
+ center_ctps - _np.array([center_width, v_zero, v_zero]),
v_zero,
)
if i_derivative == 0
@@ -368,8 +365,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.maximum(
- center_ctps
- - _np.array([v_zero, center_width, v_zero]),
+ center_ctps - _np.array([v_zero, center_width, v_zero]),
v_zero,
)
if i_derivative == 0
@@ -383,8 +379,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.minimum(
- center_ctps
- + _np.array([center_width, v_zero, v_zero]),
+ center_ctps + _np.array([center_width, v_zero, v_zero]),
v_one,
)
if i_derivative == 0
@@ -398,8 +393,7 @@ def _closing_tile(
degrees=[1, 1, 1],
control_points=(
_np.minimum(
- center_ctps
- + _np.array([v_zero, center_width, v_zero]),
+ center_ctps + _np.array([v_zero, center_width, v_zero]),
v_one,
)
if i_derivative == 0
@@ -474,43 +468,16 @@ def create_tile(
derivative_list : list / None
"""
- if not isinstance(center_expansion, float):
- raise ValueError("Invalid Type")
+ self._check_custom_parameter(
+ center_expansion, "center expansion", self._CENTER_EXPANSION_BOUNDS
+ )
- if not ((center_expansion > 0.5) and (center_expansion < 1.5)):
- raise ValueError("Center Expansion must be in (.5,1.5)")
+ self._center_expansion = center_expansion
- # Max radius, so there is no tanglement in the crosstile
- max_radius = min(0.5, (0.5 / center_expansion))
-
- # set to default if nothing is given
- if parameters is None:
- self._logd("Setting branch thickness to default 0.2")
- parameters = (
- _np.ones(
- (
- self._evaluation_points.shape[0],
- self._n_info_per_eval_point,
- )
- )
- * 0.2
- )
-
- # Check for type and consistency
- self.check_params(parameters)
- if _np.any(parameters <= 0) or _np.any(parameters > max_radius):
- raise ValueError(
- f"Radii must be in (0,{max_radius}) for "
- f"center_expansion {center_expansion}"
- )
-
- if parameter_sensitivities is not None:
- self.check_param_derivatives(parameter_sensitivities)
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
if closure is not None:
return self._closing_tile(
@@ -524,13 +491,12 @@ def create_tile(
for i_derivative in range(n_derivatives + 1):
# Constant auxiliary values
if i_derivative == 0:
- [x_min_r, x_max_r, y_min_r, y_max_r, z_min_r, z_max_r] = (
- parameters[:, 0]
- )
+ [x_min_r, x_max_r, y_min_r, y_max_r, z_min_r, z_max_r] = parameters[
+ :, 0
+ ]
v_one_half = 0.5
center_r = center_expansion * _np.mean(parameters[:, 0])
else:
-
[x_min_r, x_max_r, y_min_r, y_max_r, z_min_r, z_max_r] = (
parameter_sensitivities[:, :, i_derivative - 1].flatten()
)
@@ -555,9 +521,7 @@ def create_tile(
]
)
spline_list.append(
- _Bezier(
- degrees=[1, 1, 1], control_points=center_points + center
- )
+ _Bezier(degrees=[1, 1, 1], control_points=center_points + center)
)
# X-Axis branches
diff --git a/splinepy/microstructure/tiles/cube_void.py b/splinepy/microstructure/tiles/cube_void.py
index be4f1ab3a..0ac29e965 100644
--- a/splinepy/microstructure/tiles/cube_void.py
+++ b/splinepy/microstructure/tiles/cube_void.py
@@ -25,6 +25,17 @@ class CubeVoid(_TileBase):
_para_dim = 3
_evaluation_points = _np.array([[0.5, 0.5, 0.5]])
_n_info_per_eval_point = 4
+ _sensitivities_implemented = True
+ # TODO: clever parameter bounds and checks if given parametrization would
+ # still lie in unit cube
+ _parameter_bounds = [
+ [0.0, 1.0],
+ [0.0, 1.0],
+ [-_np.pi / 2, _np.pi / 2],
+ [-_np.pi / 2, _np.pi / 2],
+ ]
+ _parameters_shape = (1, 4)
+ _default_parameter_value = _np.array([[0.5, 0.5, 0.0, 0.0]])
# Aux values
_sphere_ctps = _np.array(
@@ -54,7 +65,7 @@ def _rotation_matrix_y(self, angle):
def _rotation_matrix_y_deriv(self, angle):
cc, ss = _np.cos(angle), _np.sin(angle)
- return _np.array([[-ss, 0, -cc], [0, 1, 0], [cc, 0, -ss]])
+ return _np.array([[-ss, 0, -cc], [0, 0, 0], [cc, 0, -ss]])
def create_tile(
self,
@@ -90,21 +101,16 @@ def create_tile(
microtile_list : list(splines)
derivatives : list> / None
""" # set to default if nothing is given
- if parameters is None:
- parameters = _np.array([0.5, 0.5, 0, 0]).reshape(1, 1, 4)
+
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
# Create center ellipsoid
# RotY * RotX * DIAG(r_x, r_yz) * T_base
[r_x, r_yz, rot_x, rot_y] = parameters.flatten()
- # Check if user requests derivative splines
- if self.check_param_derivatives(parameter_sensitivities):
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
-
# Prepare auxiliary matrices and values
diag = _np.diag([r_x, r_yz, r_yz])
rotMx = self._rotation_matrix_x(rot_x)
diff --git a/splinepy/microstructure/tiles/double_lattice.py b/splinepy/microstructure/tiles/double_lattice.py
index ad8f6e803..eda6cd5d8 100644
--- a/splinepy/microstructure/tiles/double_lattice.py
+++ b/splinepy/microstructure/tiles/double_lattice.py
@@ -20,6 +20,12 @@ class DoubleLattice(_TileBase):
_para_dim = 2
_evaluation_points = _np.array([[0.5, 0.5]])
_n_info_per_eval_point = 2
+ _sensitivities_implemented = True
+ _parameter_bounds = [[0.0, 1 / (2 * (1 + _np.sqrt(2)))]] * 2
+ _parameters_shape = (1, 2)
+ _default_parameter_value = 0.1
+
+ _CONTACT_LENGTH_BOUNDS = [0.0, 1.0]
def create_tile(
self,
@@ -44,38 +50,20 @@ def create_tile(
correlates with thickness of branches and entouring wall
contact_length : double
required for conformity between tiles, sets the length of the center
- block on the tiles boundary
+ block on the tile's boundary
Returns
-------
microtile_list : list(splines)
"""
- if not isinstance(contact_length, float):
- raise ValueError("Invalid Type")
- if not ((contact_length > 0.0) and (contact_length < 1.0)):
- raise ValueError("Contact length must be in (0.,1.)")
-
- # set to default if nothing is given
- if parameters is None:
- self._logd("Tile request is not parametrized, setting default 0.2")
- parameters = _np.ones((1, 2)) * 0.1
- if not (
- _np.all(parameters > 0)
- and _np.all(parameters < 0.5 / (1 + _np.sqrt(2)))
- ):
- raise ValueError(
- "Parameters must be between 0.01 and 0.5/(1+sqrt(2))=0.207"
- )
-
- self.check_params(parameters)
-
- # Check if user requests derivative splines
- if self.check_param_derivatives(parameter_sensitivities):
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ self._check_custom_parameter(
+ contact_length, "contact length", self._CONTACT_LENGTH_BOUNDS
+ )
+
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
splines = []
for i_derivative in range(n_derivatives + 1):
diff --git a/splinepy/microstructure/tiles/ellips_v_oid.py b/splinepy/microstructure/tiles/ellips_v_oid.py
index 4b6e7bf23..37d12c669 100644
--- a/splinepy/microstructure/tiles/ellips_v_oid.py
+++ b/splinepy/microstructure/tiles/ellips_v_oid.py
@@ -7,6 +7,9 @@
class EllipsVoid(_TileBase):
"""Void in form of an ellipsoid set into a unit cell.
+ TODO: Currently this tile is skipped for testing, since the control points easily
+ lie outside of the unit cube, even though the tile itself lies within it
+
The Ellips(v)oid :D
Parametrization acts on the elipsoid's orientation as well as on its
@@ -27,6 +30,18 @@ class EllipsVoid(_TileBase):
_para_dim = 3
_evaluation_points = _np.array([[0.5, 0.5, 0.5]])
_n_info_per_eval_point = 4
+ _sensitivities_implemented = True
+ # TODO: clever parameter bounds and checks if given parametrization would
+ # still lie in unit cube
+ # Due to ellipsoid, control points very easily lie outside unit cube
+ _parameter_bounds = [
+ [0.0, 1.0],
+ [0.0, 1.0],
+ [-_np.pi / 2, _np.pi / 2],
+ [-_np.pi / 2, _np.pi / 2],
+ ]
+ _parameters_shape = (1, 4)
+ _default_parameter_value = _np.array([[0.5, 0.5, 0, 0]])
# Aux values
_c0 = 0.5 / 3**0.5
@@ -80,7 +95,7 @@ def _rotation_matrix_y(self, angle):
def _rotation_matrix_y_deriv(self, angle):
cc, ss = _np.cos(angle), _np.sin(angle)
- return _np.array([[-ss, 0, -cc], [0, 1, 0], [cc, 0, -ss]])
+ return _np.array([[-ss, 0, -cc], [0, 0, 0], [cc, 0, -ss]])
def create_tile(
self,
@@ -116,21 +131,15 @@ def create_tile(
microtile_list : list(splines)
derivatives: list> / None
""" # set to default if nothing is given
- if parameters is None:
- parameters = _np.array([0.5, 0.5, 0, 0]).reshape(1, 1, 4)
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
# Create center ellipsoid
# RotY * RotX * DIAG(r_x, r_yz) * T_base
[r_x, r_yz, rot_x, rot_y] = parameters.flatten()
- # Check if user requests derivative splines
- if self.check_param_derivatives(parameter_sensitivities):
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
-
# Prepare auxiliary matrices and values
diag = _np.diag([r_x, r_yz, r_yz])
rotMx = self._rotation_matrix_x(rot_x)
diff --git a/splinepy/microstructure/tiles/hollow_cube.py b/splinepy/microstructure/tiles/hollow_cube.py
index fa8c15795..222124009 100644
--- a/splinepy/microstructure/tiles/hollow_cube.py
+++ b/splinepy/microstructure/tiles/hollow_cube.py
@@ -28,6 +28,10 @@ class HollowCube(_TileBase):
]
)
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _parameter_bounds = [[0.0, 0.5]] * 7
+ _parameters_shape = (7, 1)
+ _default_parameter_value = 0.2
def create_tile(
self,
@@ -53,27 +57,10 @@ def create_tile(
-------
microtile_list : list(splines)
"""
-
- if parameters is None:
- self._logd("Setting parameters to default value (0.2)")
- parameters = (
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- self.check_params(parameters)
-
- if not (_np.all(parameters > 0.0) and _np.all(parameters < 0.5)):
- raise ValueError("The wall thickness must be in (0.0 and 0.5)")
-
- if self.check_param_derivatives(parameter_sensitivities):
- n_derivatives = parameter_sensitivities.shape[2]
- derivatives = []
- else:
- n_derivatives = 0
- derivatives = None
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
splines = []
diff --git a/splinepy/microstructure/tiles/hollow_octagon.py b/splinepy/microstructure/tiles/hollow_octagon.py
index 20a628e17..e50fe53c6 100644
--- a/splinepy/microstructure/tiles/hollow_octagon.py
+++ b/splinepy/microstructure/tiles/hollow_octagon.py
@@ -18,11 +18,18 @@ class HollowOctagon(_TileBase):
_para_dim = 2
_evaluation_points = _np.array([[0.5, 0.5]])
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _closure_directions = ["x_min", "x_max", "y_min", "y_max"]
+ _parameter_bounds = [[0.0, 0.5]]
+ _parameters_shape = (1, 1)
+ _default_parameter_value = 0.2
+
+ _CONTACT_LENGTH_BOUNDS = [0.0, 0.99]
def _closing_tile(
self,
parameters=None,
- parameter_sensitivities=None, # TODO
+ parameter_sensitivities=None,
contact_length=0.2,
closure=None,
):
@@ -50,263 +57,426 @@ def _closing_tile(
"""
if closure is None:
raise ValueError("No closing direction given")
+ if isinstance(closure, int):
+ closure = self._closure_directions[closure]
+ if closure not in self._closure_directions:
+ raise ValueError(
+ f"Closure direction {closure} not implemented. "
+ f"Choose from {self._closure_directions}"
+ )
+
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
+
+ v_h_void = parameters[0, 0]
- if parameters is None:
- self._log("Tile request is not parametrized, setting default 0.2")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ v_outer_c_h = contact_length * 0.5
+ v_inner_c_h = contact_length * v_h_void
+ else:
+ v_zero = 0.0
+ v_one_half = 0.0
+ v_one = 0.0
+ v_h_void = parameter_sensitivities[0, 0, i_derivative - 1]
+ v_outer_c_h = 0.0
+ v_inner_c_h = contact_length * v_h_void
+
+ spline_list = []
+
+ if closure == "x_min":
+ # set points:
+ right = _np.array(
+ [
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, -v_outer_c_h + v_one_half],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_outer_c_h + v_one_half],
+ ]
)
- * 0.2
- )
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
+ right_top = _np.array(
+ [
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_outer_c_h + v_one_half],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- self.check_params(parameters)
+ top = _np.array(
+ [
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
+ bottom_left = _np.array(
+ [
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, v_zero],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_zero],
+ ]
+ )
- v_h_void = parameters[0, 0]
- if not ((v_h_void > 0.01) and (v_h_void < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
+ left = _np.array(
+ [
+ [v_zero, v_zero],
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, v_one],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ ]
+ )
- spline_list = []
- v_zero = 0.0
- v_one_half = 0.5
- v_one = 1.0
- v_outer_c_h = contact_length * 0.5
- v_inner_c_h = contact_length * parameters[0, 0]
+ top_left = _np.array(
+ [
+ [v_zero, v_one],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [-v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ ]
+ )
- if closure == "x_min":
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- ]
- )
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_zero],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ ]
+ )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
+ bottom_right = _np.array(
+ [
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_zero],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, -v_outer_c_h + v_one_half],
+ ]
+ )
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
+ elif closure == "x_max":
+ right = _np.array(
+ [
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, v_zero],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_one],
+ ]
+ )
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- ]
- )
+ right_top = _np.array(
+ [
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_one],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- left = _np.array(
- [
- [v_zero, v_zero],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_one],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
+ top = _np.array(
+ [
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- top_left = _np.array(
- [
- [v_zero, v_one],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
+ bottom_left = _np.array(
+ [
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, -v_outer_c_h + v_one_half],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_zero],
+ ]
+ )
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- ]
- )
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [-v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ ]
+ )
- elif closure == "x_max":
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, v_zero],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_one],
- ]
- )
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_zero],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ ]
+ )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_one],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
+ bottom_right = _np.array(
+ [
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_zero],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, v_zero],
+ ]
+ )
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
+ elif closure == "y_min":
+ # set points:
+ right = _np.array(
+ [
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, -v_outer_c_h + v_one_half],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_outer_c_h + v_one_half],
+ ]
+ )
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- ]
- )
+ right_top = _np.array(
+ [
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_outer_c_h + v_one_half],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
+ top = _np.array(
+ [
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
+ bottom_left = _np.array(
+ [
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, -v_outer_c_h + v_one_half],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [v_zero, v_zero],
+ ]
+ )
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, v_zero],
- ]
- )
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [-v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ ]
+ )
- elif closure == "y_min":
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- ]
- )
+ bottom = _np.array(
+ [
+ [v_one, v_zero],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [v_zero, v_zero],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ ]
+ )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
+ bottom_right = _np.array(
+ [
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [v_one, v_zero],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, -v_outer_c_h + v_one_half],
+ ]
+ )
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
+ elif closure == "y_max":
+ # set points:
+ right = _np.array(
+ [
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, -v_outer_c_h + v_one_half],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_outer_c_h + v_one_half],
+ ]
+ )
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_zero, v_zero],
- ]
- )
+ right_top = _np.array(
+ [
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_one, v_outer_c_h + v_one_half],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_one, v_one],
+ ]
+ )
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
+ top = _np.array(
+ [
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_one, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ [v_zero, v_one],
+ ]
+ )
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
+ bottom_left = _np.array(
+ [
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, -v_outer_c_h + v_one_half],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_zero],
+ ]
+ )
- bottom = _np.array(
- [
- [v_one, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_zero, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_zero, v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_one, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- ]
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
+ [v_zero, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
+ ]
+ )
+
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [-v_outer_c_h + v_one_half, v_zero],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ ]
+ )
+
+ bottom_right = _np.array(
+ [
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
+ [v_outer_c_h + v_one_half, v_zero],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
+ [v_one, -v_outer_c_h + v_one_half],
+ ]
+ )
+
+ for control_points in [
+ right,
+ right_top,
+ bottom,
+ bottom_left,
+ left,
+ top_left,
+ top,
+ bottom_right,
+ ]:
+ spline_list.append(
+ _Bezier(degrees=[1, 1], control_points=control_points)
+ )
+
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
+
+ return (splines, derivatives)
+
+ def create_tile(
+ self,
+ parameters=None,
+ parameter_sensitivities=None,
+ contact_length=0.2,
+ closure=None,
+ **kwargs, # noqa ARG002
+ ):
+ """Create a microtile based on the parameters that describe the wall
+ thicknesses.
+
+ Thickness parameters are used to describe the inner radius of the
+ outward facing branches
+
+ Parameters
+ ----------
+ parameters : np.array(1, 1)
+ One evaluation point with one parameter is used. This parameter
+ specifies the distance from the center to the inner edge, where
+ the value must be between non-inclusive (0, 0.5).
+ parameter_sensitivities: np.ndarray
+ Describes the parameter sensitivities with respect to some design
+ variable. In case the design variables directly apply to the
+ parameter itself, they evaluate as delta_ij
+ contact_length : float
+ the length of the wall that contacts the other microstructure
+ closure : str
+ parametric dimension that needs to be closed, given in the form
+ "x_min", "x_max", etc.
+
+ Returns
+ -------
+ microtile_list : list(splines)
+ derivatives: list> / None
+ """
+ self._check_custom_parameter(
+ contact_length, "contact length", self._CONTACT_LENGTH_BOUNDS
+ )
+
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
+
+ if closure is not None:
+ return self._closing_tile(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ contact_length=contact_length,
+ closure=closure,
)
- elif closure == "y_max":
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ v_h_void = parameters[0, 0]
+ v_outer_c_h = contact_length * 0.5
+ v_inner_c_h = contact_length * v_h_void
+ else:
+ v_zero = 0.0
+ v_one_half = 0.0
+ v_one = 0.0
+ v_h_void = parameter_sensitivities[0, 0, i_derivative - 1]
+ v_outer_c_h = 0.0
+ v_inner_c_h = contact_length * v_h_void
+
+ spline_list = []
+
# set points:
right = _np.array(
[
@@ -322,16 +492,16 @@ def _closing_tile(
[v_h_void + v_one_half, v_inner_c_h + v_one_half],
[v_one, v_outer_c_h + v_one_half],
[v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_one, v_one],
+ [v_outer_c_h + v_one_half, v_one],
]
)
top = _np.array(
[
[v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_one, v_one],
+ [v_outer_c_h + v_one_half, v_one],
[-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_zero, v_one],
+ [-v_outer_c_h + v_one_half, v_one],
]
)
@@ -357,7 +527,7 @@ def _closing_tile(
[
[v_zero, v_outer_c_h + v_one_half],
[-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_zero, v_one],
+ [-v_outer_c_h + v_one_half, v_one],
[-v_inner_c_h + v_one_half, v_h_void + v_one_half],
]
)
@@ -380,195 +550,23 @@ def _closing_tile(
]
)
- spline_list.append(_Bezier(degrees=[1, 1], control_points=right))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=right_top))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=bottom))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=bottom_left))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=left))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=top_left))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=top))
-
- spline_list.append(
- _Bezier(degrees=[1, 1], control_points=bottom_right)
- )
-
- return (spline_list, None)
-
- def create_tile(
- self,
- parameters=None,
- parameter_sensitivities=None, # TODO
- contact_length=0.2,
- closure=None,
- **kwargs, # noqa ARG002
- ):
- """Create a microtile based on the parameters that describe the wall
- thicknesses.
-
- Thickness parameters are used to describe the inner radius of the
- outward facing branches
-
- Parameters
- ----------
- parameters : np.array(1, 1)
- One evaluation point with one parameter is used. This parameter
- specifies the distance from the center to the inner edge, where
- the value must be between non-inclusive (0, 0.5).
- parameter_sensitivities: np.ndarray
- Describes the parameter sensitivities with respect to some design
- variable. In case the design variables directly apply to the
- parameter itself, they evaluate as delta_ij
- contact_length : float
- the length of the wall that contacts the other microstructure
- closure : str
- parametric dimension that needs to be closed, given in the form
- "x_min", "x_max", etc.
-
- Returns
- -------
- microtile_list : list(splines)
- derivatives: list> / None
- """
-
- if not isinstance(contact_length, float):
- raise ValueError("Invalid Type for radius")
-
- if not ((contact_length > 0) and (contact_length < 0.99)):
- raise ValueError("The length of a side must be in (0.01, 0.99)")
-
- if parameters is None:
- self._logd("Setting parameters to default values (0.2)")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
+ for control_points in [
+ right,
+ right_top,
+ bottom,
+ bottom_left,
+ left,
+ top_left,
+ top,
+ bottom_right,
+ ]:
+ spline_list.append(
+ _Bezier(degrees=[1, 1], control_points=control_points)
)
- * 0.2
- )
-
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
-
- self.check_params(parameters)
-
- v_h_void = parameters[0, 0]
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
-
- if closure is not None:
- return self._closing_tile(
- parameters=parameters,
- parameter_sensitivities=parameter_sensitivities, # TODO
- contact_length=contact_length,
- closure=closure,
- )
-
- v_zero = 0.0
- v_one_half = 0.5
- v_one = 1.0
- v_outer_c_h = contact_length * 0.5
- v_inner_c_h = contact_length * parameters[0, 0]
-
- spline_list = []
-
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- ]
- )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
-
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
-
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- ]
- )
-
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
-
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
-
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
-
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- ]
- )
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=right))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=right_top))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=bottom))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=bottom_left))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=left))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=top_left))
-
- spline_list.append(_Bezier(degrees=[1, 1], control_points=top))
-
- spline_list.append(
- _Bezier(degrees=[1, 1], control_points=bottom_right)
- )
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
- return (spline_list, None)
+ return (splines, derivatives)
diff --git a/splinepy/microstructure/tiles/hollow_octagon_extrude.py b/splinepy/microstructure/tiles/hollow_octagon_extrude.py
index 82e738d23..a49bfc3cb 100644
--- a/splinepy/microstructure/tiles/hollow_octagon_extrude.py
+++ b/splinepy/microstructure/tiles/hollow_octagon_extrude.py
@@ -18,12 +18,20 @@ class HollowOctagonExtrude(_TileBase):
_para_dim = 3
_evaluation_points = _np.array([[0.5, 0.5, 0.5]])
_n_info_per_eval_point = 1
+ _sensitivities_implemented = True
+ _closure_directions = ["x_min", "x_max", "y_min", "y_max"]
+ _parameter_bounds = [[0.0, 0.5]]
+ _parameters_shape = (1, 1)
+ _default_parameter_value = 0.2
+
+ _CONTACT_LENGTH_BOUNDS = [0.0, 0.99]
def create_tile(
self,
parameters=None,
- parameter_sensitivities=None, # TODO
+ parameter_sensitivities=None,
contact_length=0.2,
+ closure=None,
**kwargs, # noqa ARG002
):
"""Create a microtile based on the parameters that describe the wall
@@ -50,177 +58,193 @@ def create_tile(
derivatives: list> / None
"""
- if not isinstance(contact_length, float):
- raise ValueError("Invalid Type for radius")
-
- if not ((contact_length > 0) and (contact_length < 0.99)):
- raise ValueError("The length of a side must be in (0.01, 0.99)")
-
- if parameters is None:
- self._logd("Setting parameters to default values (0.2)")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
-
- self.check_params(parameters)
-
- v_h_void = parameters[0, 0]
- if not ((v_h_void > 0.01) and (v_h_void < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
-
- v_zero = 0.0
- v_one_half = 0.5
- v_one = 1.0
- v_outer_c_h = contact_length * 0.5
- v_inner_c_h = contact_length * parameters[0, 0]
-
- spline_list = []
-
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_zero],
- [v_one, -v_outer_c_h + v_one_half, 0.0],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half, 0.0],
- [v_one, v_outer_c_h + v_one_half, 0.0],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
- [v_one, -v_outer_c_h + v_one_half, v_one],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
- [v_one, v_outer_c_h + v_one_half, v_one],
- ]
+ self._check_custom_parameter(
+ contact_length, "contact length", self._CONTACT_LENGTH_BOUNDS
)
-
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
- [v_one, v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
- [v_outer_c_h + v_one_half, v_one, v_zero],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
- [v_one, v_outer_c_h + v_one_half, v_one],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
- [v_outer_c_h + v_one_half, v_one, v_one],
- ]
+ # Process input
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
)
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
- [v_outer_c_h + v_one_half, v_one, v_zero],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
- [-v_outer_c_h + v_one_half, v_one, v_zero],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
- [v_outer_c_h + v_one_half, v_one, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
- [-v_outer_c_h + v_one_half, v_one, v_one],
- ]
- )
-
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_zero],
- [v_zero, -v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_zero],
- [-v_outer_c_h + v_one_half, v_zero, v_zero],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
- [v_zero, -v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
- [-v_outer_c_h + v_one_half, v_zero, v_one],
- ]
- )
+ v_h_void = parameters[0, 0]
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half, v_zero],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_zero],
- [v_zero, v_outer_c_h + v_one_half, v_zero],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
- [v_zero, -v_outer_c_h + v_one_half, v_one],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
- [v_zero, v_outer_c_h + v_one_half, v_one],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
- ]
- )
+ if closure is not None:
+ return self._closing_tile(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ closure=closure,
+ contact_length=contact_length,
+ **kwargs,
+ )
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half, v_zero],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
- [-v_outer_c_h + v_one_half, v_one, v_zero],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
- [v_zero, v_outer_c_h + v_one_half, v_one],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
- [-v_outer_c_h + v_one_half, v_one, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
- ]
- )
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ v_outer_c_h = contact_length * 0.5
+ v_inner_c_h = contact_length * v_h_void
+ else:
+ v_zero = 0.0
+ v_one_half = 0.0
+ v_one = 0.0
+ v_h_void = parameter_sensitivities[0, 0, i_derivative - 1]
+ v_outer_c_h = 0.0
+ v_inner_c_h = contact_length * v_h_void
+
+ spline_list = []
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_zero],
- [-v_outer_c_h + v_one_half, v_zero, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_zero],
- [v_outer_c_h + v_one_half, v_zero, v_one],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
- [-v_outer_c_h + v_one_half, v_zero, v_one],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
- ]
- )
+ # set points:
+ right = _np.array(
+ [
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_zero],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_zero],
- [v_outer_c_h + v_one_half, v_zero, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_zero],
- [v_one, -v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
- [v_outer_c_h + v_one_half, v_zero, v_one],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
- [v_one, -v_outer_c_h + v_one_half, v_one],
- ]
- )
+ right_top = _np.array(
+ [
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=right))
+ top = _np.array(
+ [
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=right_top)
- )
+ bottom_left = _np.array(
+ [
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=bottom))
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [-v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
+ ]
+ )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=bottom_left)
- )
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_zero],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_zero],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [-v_h_void + v_one_half, v_inner_c_h + v_one_half, v_one],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ [-v_inner_c_h + v_one_half, v_h_void + v_one_half, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=left))
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_zero],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ [-v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=top_left))
+ bottom_right = _np.array(
+ [
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_zero],
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_zero],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [v_inner_c_h + v_one_half, -v_h_void + v_one_half, v_one],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [v_h_void + v_one_half, -v_inner_c_h + v_one_half, v_one],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1, 1], control_points=top))
+ for control_points in [
+ right,
+ right_top,
+ top,
+ bottom_left,
+ left,
+ top_left,
+ bottom,
+ bottom_right,
+ ]:
+ spline_list.append(
+ _Bezier(degrees=[1, 1, 1], control_points=control_points)
+ )
- spline_list.append(
- _Bezier(degrees=[1, 1, 1], control_points=bottom_right)
- )
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
- return (spline_list, None)
+ return (splines, derivatives)
- def closing_tile(
+ def _closing_tile(
self,
parameters=None,
- parameter_sensitivities=None, # TODO
+ parameter_sensitivities=None,
contact_length=0.2,
closure=None,
+ **kwargs, # noqa ARG002
):
"""Create a closing tile to match with closed surface.
@@ -234,7 +258,7 @@ def closing_tile(
Describes the parameter sensitivities with respect to some design
variable. In case the design variables directly apply to the
parameter itself, they evaluate as delta_ij
- closure : int
+ closure : int or str
parametric dimension that needs to be closed. Positive values mean
that minimum parametric dimension is requested. That means,
i.e. -2 closes the tile at maximum z-coordinate.
@@ -249,352 +273,990 @@ def closing_tile(
"""
if closure is None:
raise ValueError("No closing direction given")
-
- if parameters is None:
- self._log("Tile request is not parametrized, setting default 0.2")
- parameters = _np.array(
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- if not (_np.all(parameters[0] > 0) and _np.all(parameters[0] < 0.5)):
+ if isinstance(closure, int):
+ closure = self._closure_directions[closure]
+ if closure not in self._closure_directions:
raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
+ f"Closure direction {closure} not implemented. "
+ f"Choose from {self._closure_directions}"
)
- self.check_params(parameters)
-
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
+ # Process input
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
v_h_void = parameters[0, 0]
- if not ((v_h_void > 0.01) and (v_h_void < 0.5)):
- raise ValueError(
- "The thickness of the wall must be in (0.01 and 0.49)"
- )
- spline_list = []
- v_zero = 0.0
- v_one_half = 0.5
- v_one = 1.0
- v_outer_c_h = contact_length * 0.5
- v_inner_c_h = contact_length * parameters[0, 0]
-
- if closure == "x_min":
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- ]
- )
-
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
-
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
-
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- ]
- )
-
- left = _np.array(
- [
- [v_zero, v_zero],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_one],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
-
- top_left = _np.array(
- [
- [v_zero, v_one],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
-
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ v_outer_c_h = contact_length * 0.5
+ v_inner_c_h = contact_length * parameters[0, 0]
+ else:
+ v_h_void = parameter_sensitivities[0, 0, i_derivative - 1]
+ v_zero, v_one_half, v_one = [0.0, 0.0, 0.0]
+ v_outer_c_h = 0.0
+ v_inner_c_h = contact_length * v_h_void
+
+ spline_list = []
+
+ if closure == "x_min":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- ]
- )
+ right_top = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- elif closure == "x_max":
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, v_zero],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_one],
- ]
- )
+ top = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_one],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
+ bottom_left = _np.array(
+ [
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_zero, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_zero, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ ]
+ )
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
+ left = _np.array(
+ [
+ [v_zero, v_zero, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_one, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_zero, v_one],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_one, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- ]
- )
+ top_left = _np.array(
+ [
+ [v_zero, v_one, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_one, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
+ bottom_right = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ elif closure == "x_max":
+ right = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_zero, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_one, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_zero, v_one],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_one, v_one],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, v_zero],
- ]
- )
+ right_top = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_one, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_one, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- elif closure == "y_min":
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- ]
- )
+ top = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- ]
- )
+ bottom_left = _np.array(
+ [
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ ]
+ )
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- ]
- )
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_zero, v_zero],
- ]
- )
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [-v_outer_c_h + v_one_half, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
+ bottom_right = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_zero, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_zero, v_one],
+ ]
+ )
- bottom = _np.array(
- [
- [v_one, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_zero, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ elif closure == "y_min":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_one, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- ]
- )
+ right_top = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- elif closure == "y_max":
- # set points:
- right = _np.array(
- [
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- ]
- )
+ top = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ ]
+ )
- right_top = _np.array(
- [
- [v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_one, v_outer_c_h + v_one_half],
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_one, v_one],
- ]
- )
+ bottom_left = _np.array(
+ [
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_zero, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_zero, v_one],
+ ]
+ )
- top = _np.array(
- [
- [v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_one, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- [v_zero, v_one],
- ]
- )
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- bottom_left = _np.array(
- [
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- ]
- )
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- left = _np.array(
- [
- [v_zero, -v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- ]
- )
+ bottom = _np.array(
+ [
+ [v_one, v_zero, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_zero, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_zero, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_zero, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- top_left = _np.array(
- [
- [v_zero, v_outer_c_h + v_one_half],
- [-v_h_void + v_one_half, v_inner_c_h + v_one_half],
- [v_zero, v_one],
- [-v_inner_c_h + v_one_half, v_h_void + v_one_half],
- ]
- )
+ bottom_right = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_zero, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_one, v_zero, v_one],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- bottom = _np.array(
- [
- [v_outer_c_h + v_one_half, v_zero],
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [-v_outer_c_h + v_one_half, v_zero],
- [-v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- ]
- )
+ elif closure == "y_max":
+ # set points:
+ right = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- bottom_right = _np.array(
- [
- [v_inner_c_h + v_one_half, -v_h_void + v_one_half],
- [v_outer_c_h + v_one_half, v_zero],
- [v_h_void + v_one_half, -v_inner_c_h + v_one_half],
- [v_one, -v_outer_c_h + v_one_half],
- ]
- )
+ right_top = _np.array(
+ [
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_one, v_zero],
+ [
+ v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, v_outer_c_h + v_one_half, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_one, v_one, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=right))
+ top = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_one, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_one, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_one, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_one, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=right_top))
+ bottom_left = _np.array(
+ [
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=bottom))
+ left = _np.array(
+ [
+ [v_zero, -v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, -v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=bottom_left))
+ top_left = _np.array(
+ [
+ [v_zero, v_outer_c_h + v_one_half, v_zero],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_one, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_zero, v_outer_c_h + v_one_half, v_one],
+ [
+ -v_h_void + v_one_half,
+ v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_zero, v_one, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=left))
+ bottom = _np.array(
+ [
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [-v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ -v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=top_left))
+ bottom_right = _np.array(
+ [
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_zero,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_zero],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_zero,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_zero],
+ [
+ v_inner_c_h + v_one_half,
+ -v_h_void + v_one_half,
+ v_one,
+ ],
+ [v_outer_c_h + v_one_half, v_zero, v_one],
+ [
+ v_h_void + v_one_half,
+ -v_inner_c_h + v_one_half,
+ v_one,
+ ],
+ [v_one, -v_outer_c_h + v_one_half, v_one],
+ ]
+ )
- spline_list.append(_Bezier(degrees=[1, 1], control_points=top))
+ for control_points in [
+ right,
+ right_top,
+ bottom,
+ bottom_left,
+ left,
+ top_left,
+ top,
+ bottom_right,
+ ]:
+ spline_list.append(
+ _Bezier(degrees=[1, 1, 1], control_points=control_points)
+ )
- spline_list.append(
- _Bezier(degrees=[1, 1], control_points=bottom_right)
- )
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
- return (spline_list, None)
+ return (splines, derivatives)
diff --git a/splinepy/microstructure/tiles/inverse_cross_3d.py b/splinepy/microstructure/tiles/inverse_cross_3d.py
index c24954702..43e5ed632 100644
--- a/splinepy/microstructure/tiles/inverse_cross_3d.py
+++ b/splinepy/microstructure/tiles/inverse_cross_3d.py
@@ -32,6 +32,16 @@ class InverseCross3D(_TileBase):
]
)
_n_info_per_eval_point = 1
+ # TODO: implemented sensitivities are not correct
+ _sensitivities_implemented = True
+ _closure_directions = ["z_min", "z_max"]
+ _parameter_bounds = [[0.2, 0.3]] * 6 # For default values
+ _parameters_shape = (6, 1)
+ _default_parameter_value = 0.21
+
+ _BOUNDARY_WIDTH_BOUNDS = [0.0, 0.5]
+ _FILLING_HEIGHT_BOUNDS = [0.0, 1.0]
+ _CENTER_EXPANSION_BOUNDS = [0.5, 1.5]
def _closing_tile(
self,
@@ -40,7 +50,7 @@ def _closing_tile(
closure=None,
boundary_width=0.1,
filling_height=0.5,
- seperator_distance=None,
+ separator_distance=0.3,
**kwargs, # noqa ARG002
):
"""Create a closing tile to match with closed surface.
@@ -53,7 +63,7 @@ def _closing_tile(
with of the boundary surrounding branch
filling_height : float
portion of the height that is filled in parametric domain
- seperator_distance : float
+ separator_distance : float
Describes the position of the separator layer in the control point
domain
closure : str
@@ -69,827 +79,951 @@ def _closing_tile(
if closure is None:
raise ValueError("No closing direction given")
- # Set default values
- if seperator_distance is None:
- seperator_distance = 0.3
-
- if parameters is None:
- self._logd("Tile request is not parametrized, setting default 0.2")
- parameters = (
- _np.ones(
- (
- self._evaluation_points.shape[0],
- self._n_info_per_eval_point,
- )
- )
- * 0.2
- )
-
- self.check_params(parameters)
-
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
-
- if not (_np.all(parameters > 0) and _np.all(parameters < 0.5)):
- raise ValueError("Thickness out of range (0, .5)")
-
- if not (0.0 < float(boundary_width) < 0.5):
- raise ValueError("Boundary Width is out of range")
-
- if not (0.0 < float(filling_height) < 1.0):
- raise ValueError("Filling must be in (0,1)")
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
- # Precompute auxiliary values
- inv_filling_height = 1.0 - filling_height
- ctps_mid_height_top = (1 + filling_height) * 0.5
- ctps_mid_height_bottom = 1.0 - ctps_mid_height_top
- center_width = 1.0 - 2 * boundary_width
- r_center = center_width * 0.5
- half_r_center = (r_center + 0.5) * 0.5
- aux_column_width = 0.5 - 2 * (0.5 - seperator_distance)
+ self._check_custom_parameter(
+ boundary_width, "boundary width", self._BOUNDARY_WIDTH_BOUNDS
+ )
+ self._check_custom_parameter(
+ filling_height, "filling height", self._FILLING_HEIGHT_BOUNDS
+ )
- spline_list = []
- if closure == "z_min":
- branch_thickness = parameters.flatten()[5]
- branch_neighbor_x_min_ctps = _np.array(
- [
- [-0.5, -r_center, filling_height],
- [-half_r_center, -r_center, filling_height],
- [-r_center, -r_center, filling_height],
- [-0.5, r_center, filling_height],
- [-half_r_center, r_center, filling_height],
- [-r_center, r_center, filling_height],
- [-0.5, -aux_column_width, ctps_mid_height_top],
- [
- -seperator_distance,
- -aux_column_width,
- ctps_mid_height_top,
- ],
+ splines = []
+
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ # Auxiliary values
+ fill_height_aux = filling_height
+ sep_distance_aux = separator_distance
+ inv_filling_height = 1.0 - filling_height
+ ctps_mid_height_top = (1 + filling_height) * 0.5
+ ctps_mid_height_bottom = 1.0 - ctps_mid_height_top
+ center_width = 1.0 - 2 * boundary_width
+ r_center = center_width * 0.5
+ half_r_center = (r_center + 0.5) * 0.5
+ aux_column_width = 0.5 - 2 * (0.5 - separator_distance)
+ v_zero = 0.0
+ v_one_half = 0.5
+ v_one = 1.0
+ if closure == "z_min":
+ branch_thickness = parameters.flatten()[5]
+ elif closure == "z_max":
+ branch_thickness = parameters.flatten()[4]
+ else:
+ fill_height_aux = 0.0
+ sep_distance_aux = 0.0
+ inv_filling_height = 0.0
+ ctps_mid_height_top = 0.0
+ ctps_mid_height_bottom = 0.0
+ center_width = 0.0
+ r_center = 0.0
+ half_r_center = 0.0
+ aux_column_width = 0.0
+ v_zero, v_one_half, v_one = [0.0] * 3
+ if closure == "z_min":
+ branch_thickness = parameter_sensitivities.flatten()[5]
+ elif closure == "z_max":
+ branch_thickness = parameter_sensitivities.flatten()[4]
+ spline_list = []
+ if closure == "z_min":
+ branch_neighbor_x_min_ctps = _np.array(
[
- -branch_thickness,
- -branch_thickness,
- ctps_mid_height_top,
- ],
- [-0.5, aux_column_width, ctps_mid_height_top],
- [
- -seperator_distance,
- aux_column_width,
- ctps_mid_height_top,
- ],
- [-branch_thickness, branch_thickness, ctps_mid_height_top],
- [-0.5, -aux_column_width, 1.0],
- [-seperator_distance, -aux_column_width, 1.0],
- [-branch_thickness, -branch_thickness, 1.0],
- [-0.5, aux_column_width, 1.0],
- [-seperator_distance, aux_column_width, 1.0],
- [-branch_thickness, branch_thickness, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 1, 2],
- control_points=branch_neighbor_x_min_ctps,
+ [-v_one_half, -r_center, fill_height_aux],
+ [-half_r_center, -r_center, fill_height_aux],
+ [-r_center, -r_center, fill_height_aux],
+ [-v_one_half, r_center, fill_height_aux],
+ [-half_r_center, r_center, fill_height_aux],
+ [-r_center, r_center, fill_height_aux],
+ [-v_one_half, -aux_column_width, ctps_mid_height_top],
+ [
+ -sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [
+ -branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [-v_one_half, aux_column_width, ctps_mid_height_top],
+ [
+ -sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [
+ -branch_thickness,
+ branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [-v_one_half, -aux_column_width, v_one],
+ [-sep_distance_aux, -aux_column_width, v_one],
+ [-branch_thickness, -branch_thickness, v_one],
+ [-v_one_half, aux_column_width, v_one],
+ [-sep_distance_aux, aux_column_width, v_one],
+ [-branch_thickness, branch_thickness, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 1, 2],
+ control_points=branch_neighbor_x_min_ctps,
+ )
)
- )
- branch_neighbor_x_max_ctps = _np.array(
- [
- [r_center, -r_center, filling_height],
- [half_r_center, -r_center, filling_height],
- [0.5, -r_center, filling_height],
- [r_center, r_center, filling_height],
- [half_r_center, r_center, filling_height],
- [0.5, r_center, filling_height],
- [branch_thickness, -branch_thickness, ctps_mid_height_top],
+ branch_neighbor_x_max_ctps = _np.array(
[
- seperator_distance,
- -aux_column_width,
- ctps_mid_height_top,
- ],
- [0.5, -aux_column_width, ctps_mid_height_top],
- [branch_thickness, branch_thickness, ctps_mid_height_top],
- [
- seperator_distance,
- aux_column_width,
- ctps_mid_height_top,
- ],
- [0.5, aux_column_width, ctps_mid_height_top],
- [branch_thickness, -branch_thickness, 1.0],
- [seperator_distance, -aux_column_width, 1.0],
- [0.5, -aux_column_width, 1.0],
- [branch_thickness, branch_thickness, 1.0],
- [seperator_distance, aux_column_width, 1.0],
- [0.5, aux_column_width, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 1, 2],
- control_points=branch_neighbor_x_max_ctps,
+ [r_center, -r_center, fill_height_aux],
+ [half_r_center, -r_center, fill_height_aux],
+ [v_one_half, -r_center, fill_height_aux],
+ [r_center, r_center, fill_height_aux],
+ [half_r_center, r_center, fill_height_aux],
+ [v_one_half, r_center, fill_height_aux],
+ [
+ branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [v_one_half, -aux_column_width, ctps_mid_height_top],
+ [
+ branch_thickness,
+ branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [v_one_half, aux_column_width, ctps_mid_height_top],
+ [branch_thickness, -branch_thickness, v_one],
+ [sep_distance_aux, -aux_column_width, v_one],
+ [v_one_half, -aux_column_width, v_one],
+ [branch_thickness, branch_thickness, v_one],
+ [sep_distance_aux, aux_column_width, v_one],
+ [v_one_half, aux_column_width, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 1, 2],
+ control_points=branch_neighbor_x_max_ctps,
+ )
)
- )
- branch_neighbor_y_min_ctps = _np.array(
- [
- [-r_center, -0.5, filling_height],
- [r_center, -0.5, filling_height],
- [-r_center, -half_r_center, filling_height],
- [r_center, -half_r_center, filling_height],
- [-r_center, -r_center, filling_height],
- [r_center, -r_center, filling_height],
- [-aux_column_width, -0.5, ctps_mid_height_top],
- [aux_column_width, -0.5, ctps_mid_height_top],
+ branch_neighbor_y_min_ctps = _np.array(
[
- -aux_column_width,
- -seperator_distance,
- ctps_mid_height_top,
- ],
- [
- aux_column_width,
- -seperator_distance,
- ctps_mid_height_top,
- ],
- [
- -branch_thickness,
- -branch_thickness,
- ctps_mid_height_top,
- ],
- [branch_thickness, -branch_thickness, ctps_mid_height_top],
- [-aux_column_width, -0.5, 1.0],
- [aux_column_width, -0.5, 1.0],
- [-aux_column_width, -seperator_distance, 1.0],
- [aux_column_width, -seperator_distance, 1.0],
- [-branch_thickness, -branch_thickness, 1.0],
- [branch_thickness, -branch_thickness, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[1, 2, 2],
- control_points=branch_neighbor_y_min_ctps,
+ [-r_center, -v_one_half, fill_height_aux],
+ [r_center, -v_one_half, fill_height_aux],
+ [-r_center, -half_r_center, fill_height_aux],
+ [r_center, -half_r_center, fill_height_aux],
+ [-r_center, -r_center, fill_height_aux],
+ [r_center, -r_center, fill_height_aux],
+ [-aux_column_width, -v_one_half, ctps_mid_height_top],
+ [aux_column_width, -v_one_half, ctps_mid_height_top],
+ [
+ -aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ -branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [-aux_column_width, -v_one_half, v_one],
+ [aux_column_width, -v_one_half, v_one],
+ [-aux_column_width, -sep_distance_aux, v_one],
+ [aux_column_width, -sep_distance_aux, v_one],
+ [-branch_thickness, -branch_thickness, v_one],
+ [branch_thickness, -branch_thickness, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[1, 2, 2],
+ control_points=branch_neighbor_y_min_ctps,
+ )
)
- )
- branch_neighbor_y_max_ctps = _np.array(
- [
- [-r_center, r_center, filling_height],
- [r_center, r_center, filling_height],
- [-r_center, half_r_center, filling_height],
- [r_center, half_r_center, filling_height],
- [-r_center, 0.5, filling_height],
- [r_center, 0.5, filling_height],
- [-branch_thickness, branch_thickness, ctps_mid_height_top],
- [branch_thickness, branch_thickness, ctps_mid_height_top],
+ branch_neighbor_y_max_ctps = _np.array(
[
- -aux_column_width,
- seperator_distance,
- ctps_mid_height_top,
- ],
- [
- aux_column_width,
- seperator_distance,
- ctps_mid_height_top,
- ],
- [-aux_column_width, 0.5, ctps_mid_height_top],
- [aux_column_width, 0.5, ctps_mid_height_top],
- [-branch_thickness, branch_thickness, 1.0],
- [branch_thickness, branch_thickness, 1.0],
- [-aux_column_width, seperator_distance, 1.0],
- [aux_column_width, seperator_distance, 1.0],
- [-aux_column_width, 0.5, 1.0],
- [aux_column_width, 0.5, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[1, 2, 2],
- control_points=branch_neighbor_y_max_ctps,
+ [-r_center, r_center, fill_height_aux],
+ [r_center, r_center, fill_height_aux],
+ [-r_center, half_r_center, fill_height_aux],
+ [r_center, half_r_center, fill_height_aux],
+ [-r_center, v_one_half, fill_height_aux],
+ [r_center, v_one_half, fill_height_aux],
+ [
+ -branch_thickness,
+ branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ branch_thickness,
+ branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ -aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [-aux_column_width, v_one_half, ctps_mid_height_top],
+ [aux_column_width, v_one_half, ctps_mid_height_top],
+ [-branch_thickness, branch_thickness, v_one],
+ [branch_thickness, branch_thickness, v_one],
+ [-aux_column_width, sep_distance_aux, v_one],
+ [aux_column_width, sep_distance_aux, v_one],
+ [-aux_column_width, v_one_half, v_one],
+ [aux_column_width, v_one_half, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[1, 2, 2],
+ control_points=branch_neighbor_y_max_ctps,
+ )
)
- )
- branch_x_min_y_min_ctps = _np.array(
- [
- [-0.5, -0.5, filling_height],
- [-half_r_center, -0.5, filling_height],
- [-r_center, -0.5, filling_height],
- [-0.5, -half_r_center, filling_height],
- [-half_r_center, -half_r_center, filling_height],
- [-r_center, -half_r_center, filling_height],
- [-0.5, -r_center, filling_height],
- [-half_r_center, -r_center, filling_height],
- [-r_center, -r_center, filling_height],
- [-0.5, -0.5, ctps_mid_height_top],
- [-seperator_distance, -0.5, ctps_mid_height_top],
- [-aux_column_width, -0.5, ctps_mid_height_top],
- [-0.5, -seperator_distance, ctps_mid_height_top],
- [
- -seperator_distance,
- -seperator_distance,
- ctps_mid_height_top,
- ],
- [
- -aux_column_width,
- -seperator_distance,
- ctps_mid_height_top,
- ],
- [-0.5, -aux_column_width, ctps_mid_height_top],
+ branch_x_min_y_min_ctps = _np.array(
[
- -seperator_distance,
- -aux_column_width,
- ctps_mid_height_top,
- ],
- [
- -branch_thickness,
- -branch_thickness,
- ctps_mid_height_top,
- ],
- [-0.5, -0.5, 1.0],
- [-seperator_distance, -0.5, 1.0],
- [-aux_column_width, -0.5, 1.0],
- [-0.5, -seperator_distance, 1.0],
- [-seperator_distance, -seperator_distance, 1.0],
- [-aux_column_width, -seperator_distance, 1.0],
- [-0.5, -aux_column_width, 1.0],
- [-seperator_distance, -aux_column_width, 1.0],
- [-branch_thickness, -branch_thickness, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_min_y_min_ctps
+ [-v_one_half, -v_one_half, fill_height_aux],
+ [-half_r_center, -v_one_half, fill_height_aux],
+ [-r_center, -v_one_half, fill_height_aux],
+ [-v_one_half, -half_r_center, fill_height_aux],
+ [-half_r_center, -half_r_center, fill_height_aux],
+ [-r_center, -half_r_center, fill_height_aux],
+ [-v_one_half, -r_center, fill_height_aux],
+ [-half_r_center, -r_center, fill_height_aux],
+ [-r_center, -r_center, fill_height_aux],
+ [-v_one_half, -v_one_half, ctps_mid_height_top],
+ [-sep_distance_aux, -v_one_half, ctps_mid_height_top],
+ [-aux_column_width, -v_one_half, ctps_mid_height_top],
+ [-v_one_half, -sep_distance_aux, ctps_mid_height_top],
+ [
+ -sep_distance_aux,
+ -sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ -aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [-v_one_half, -aux_column_width, ctps_mid_height_top],
+ [
+ -sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [
+ -branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [-v_one_half, -v_one_half, v_one],
+ [-sep_distance_aux, -v_one_half, v_one],
+ [-aux_column_width, -v_one_half, v_one],
+ [-v_one_half, -sep_distance_aux, v_one],
+ [-sep_distance_aux, -sep_distance_aux, v_one],
+ [-aux_column_width, -sep_distance_aux, v_one],
+ [-v_one_half, -aux_column_width, v_one],
+ [-sep_distance_aux, -aux_column_width, v_one],
+ [-branch_thickness, -branch_thickness, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_min_y_min_ctps,
+ )
)
- )
- branch_x_min_y_max_ctps = _np.array(
- [
- [-0.5, r_center, filling_height],
- [-half_r_center, r_center, filling_height],
- [-r_center, r_center, filling_height],
- [-0.5, half_r_center, filling_height],
- [-half_r_center, half_r_center, filling_height],
- [-r_center, half_r_center, filling_height],
- [-0.5, 0.5, filling_height],
- [-half_r_center, 0.5, filling_height],
- [-r_center, 0.5, filling_height],
- [-0.5, aux_column_width, ctps_mid_height_top],
- [
- -seperator_distance,
- aux_column_width,
- ctps_mid_height_top,
- ],
- [-branch_thickness, branch_thickness, ctps_mid_height_top],
- [-0.5, seperator_distance, ctps_mid_height_top],
+ branch_x_min_y_max_ctps = _np.array(
[
- -seperator_distance,
- seperator_distance,
- ctps_mid_height_top,
- ],
- [
- -aux_column_width,
- seperator_distance,
- ctps_mid_height_top,
- ],
- [-0.5, 0.5, ctps_mid_height_top],
- [-seperator_distance, 0.5, ctps_mid_height_top],
- [-aux_column_width, 0.5, ctps_mid_height_top],
- [-0.5, aux_column_width, 1.0],
- [-seperator_distance, aux_column_width, 1.0],
- [-branch_thickness, branch_thickness, 1.0],
- [-0.5, seperator_distance, 1.0],
- [-seperator_distance, seperator_distance, 1.0],
- [-aux_column_width, seperator_distance, 1.0],
- [-0.5, 0.5, 1.0],
- [-seperator_distance, 0.5, 1.0],
- [-aux_column_width, 0.5, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_min_y_max_ctps
+ [-v_one_half, r_center, fill_height_aux],
+ [-half_r_center, r_center, fill_height_aux],
+ [-r_center, r_center, fill_height_aux],
+ [-v_one_half, half_r_center, fill_height_aux],
+ [-half_r_center, half_r_center, fill_height_aux],
+ [-r_center, half_r_center, fill_height_aux],
+ [-v_one_half, v_one_half, fill_height_aux],
+ [-half_r_center, v_one_half, fill_height_aux],
+ [-r_center, v_one_half, fill_height_aux],
+ [-v_one_half, aux_column_width, ctps_mid_height_top],
+ [
+ -sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [
+ -branch_thickness,
+ branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [-v_one_half, sep_distance_aux, ctps_mid_height_top],
+ [
+ -sep_distance_aux,
+ sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ -aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [-v_one_half, v_one_half, ctps_mid_height_top],
+ [-sep_distance_aux, v_one_half, ctps_mid_height_top],
+ [-aux_column_width, v_one_half, ctps_mid_height_top],
+ [-v_one_half, aux_column_width, v_one],
+ [-sep_distance_aux, aux_column_width, v_one],
+ [-branch_thickness, branch_thickness, v_one],
+ [-v_one_half, sep_distance_aux, v_one],
+ [-sep_distance_aux, sep_distance_aux, v_one],
+ [-aux_column_width, sep_distance_aux, v_one],
+ [-v_one_half, v_one_half, v_one],
+ [-sep_distance_aux, v_one_half, v_one],
+ [-aux_column_width, v_one_half, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_min_y_max_ctps,
+ )
)
- )
- branch_x_max_y_min_ctps = _np.array(
- [
- [r_center, -0.5, filling_height],
- [half_r_center, -0.5, filling_height],
- [0.5, -0.5, filling_height],
- [r_center, -half_r_center, filling_height],
- [half_r_center, -half_r_center, filling_height],
- [0.5, -half_r_center, filling_height],
- [r_center, -r_center, filling_height],
- [half_r_center, -r_center, filling_height],
- [0.5, -r_center, filling_height],
- [aux_column_width, -0.5, ctps_mid_height_top],
- [seperator_distance, -0.5, ctps_mid_height_top],
- [0.5, -0.5, ctps_mid_height_top],
- [
- aux_column_width,
- -seperator_distance,
- ctps_mid_height_top,
- ],
- [
- seperator_distance,
- -seperator_distance,
- ctps_mid_height_top,
- ],
- [0.5, -seperator_distance, ctps_mid_height_top],
- [branch_thickness, -branch_thickness, ctps_mid_height_top],
+ branch_x_max_y_min_ctps = _np.array(
[
- seperator_distance,
- -aux_column_width,
- ctps_mid_height_top,
- ],
- [0.5, -aux_column_width, ctps_mid_height_top],
- [aux_column_width, -0.5, 1.0],
- [seperator_distance, -0.5, 1.0],
- [0.5, -0.5, 1.0],
- [aux_column_width, -seperator_distance, 1.0],
- [seperator_distance, -seperator_distance, 1.0],
- [0.5, -seperator_distance, 1.0],
- [branch_thickness, -branch_thickness, 1.0],
- [seperator_distance, -aux_column_width, 1.0],
- [0.5, -aux_column_width, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_max_y_min_ctps
+ [r_center, -v_one_half, fill_height_aux],
+ [half_r_center, -v_one_half, fill_height_aux],
+ [v_one_half, -v_one_half, fill_height_aux],
+ [r_center, -half_r_center, fill_height_aux],
+ [half_r_center, -half_r_center, fill_height_aux],
+ [v_one_half, -half_r_center, fill_height_aux],
+ [r_center, -r_center, fill_height_aux],
+ [half_r_center, -r_center, fill_height_aux],
+ [v_one_half, -r_center, fill_height_aux],
+ [aux_column_width, -v_one_half, ctps_mid_height_top],
+ [sep_distance_aux, -v_one_half, ctps_mid_height_top],
+ [v_one_half, -v_one_half, ctps_mid_height_top],
+ [
+ aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ sep_distance_aux,
+ -sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [v_one_half, -sep_distance_aux, ctps_mid_height_top],
+ [
+ branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [v_one_half, -aux_column_width, ctps_mid_height_top],
+ [aux_column_width, -v_one_half, v_one],
+ [sep_distance_aux, -v_one_half, v_one],
+ [v_one_half, -v_one_half, v_one],
+ [aux_column_width, -sep_distance_aux, v_one],
+ [sep_distance_aux, -sep_distance_aux, v_one],
+ [v_one_half, -sep_distance_aux, v_one],
+ [branch_thickness, -branch_thickness, v_one],
+ [sep_distance_aux, -aux_column_width, v_one],
+ [v_one_half, -aux_column_width, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_max_y_min_ctps,
+ )
)
- )
- branch_x_max_y_max_ctps = _np.array(
- [
- [r_center, r_center, filling_height],
- [half_r_center, r_center, filling_height],
- [0.5, r_center, filling_height],
- [r_center, half_r_center, filling_height],
- [half_r_center, half_r_center, filling_height],
- [0.5, half_r_center, filling_height],
- [r_center, 0.5, filling_height],
- [half_r_center, 0.5, filling_height],
- [0.5, 0.5, filling_height],
- [branch_thickness, branch_thickness, ctps_mid_height_top],
- [
- seperator_distance,
- aux_column_width,
- ctps_mid_height_top,
- ],
- [0.5, aux_column_width, ctps_mid_height_top],
- [
- aux_column_width,
- seperator_distance,
- ctps_mid_height_top,
- ],
+ branch_x_max_y_max_ctps = _np.array(
[
- seperator_distance,
- seperator_distance,
- ctps_mid_height_top,
- ],
- [0.5, seperator_distance, ctps_mid_height_top],
- [aux_column_width, 0.5, ctps_mid_height_top],
- [seperator_distance, 0.5, ctps_mid_height_top],
- [0.5, 0.5, ctps_mid_height_top],
- [branch_thickness, branch_thickness, 1.0],
- [seperator_distance, aux_column_width, 1.0],
- [0.5, aux_column_width, 1.0],
- [aux_column_width, seperator_distance, 1.0],
- [seperator_distance, seperator_distance, 1.0],
- [0.5, seperator_distance, 1.0],
- [aux_column_width, 0.5, 1.0],
- [seperator_distance, 0.5, 1.0],
- [0.5, 0.5, 1.0],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_max_y_max_ctps
+ [r_center, r_center, fill_height_aux],
+ [half_r_center, r_center, fill_height_aux],
+ [v_one_half, r_center, fill_height_aux],
+ [r_center, half_r_center, fill_height_aux],
+ [half_r_center, half_r_center, fill_height_aux],
+ [v_one_half, half_r_center, fill_height_aux],
+ [r_center, v_one_half, fill_height_aux],
+ [half_r_center, v_one_half, fill_height_aux],
+ [v_one_half, v_one_half, fill_height_aux],
+ [
+ branch_thickness,
+ branch_thickness,
+ ctps_mid_height_top,
+ ],
+ [
+ sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_top,
+ ],
+ [v_one_half, aux_column_width, ctps_mid_height_top],
+ [
+ aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [
+ sep_distance_aux,
+ sep_distance_aux,
+ ctps_mid_height_top,
+ ],
+ [v_one_half, sep_distance_aux, ctps_mid_height_top],
+ [aux_column_width, v_one_half, ctps_mid_height_top],
+ [sep_distance_aux, v_one_half, ctps_mid_height_top],
+ [v_one_half, v_one_half, ctps_mid_height_top],
+ [branch_thickness, branch_thickness, v_one],
+ [sep_distance_aux, aux_column_width, v_one],
+ [v_one_half, aux_column_width, v_one],
+ [aux_column_width, sep_distance_aux, v_one],
+ [sep_distance_aux, sep_distance_aux, v_one],
+ [v_one_half, sep_distance_aux, v_one],
+ [aux_column_width, v_one_half, v_one],
+ [sep_distance_aux, v_one_half, v_one],
+ [v_one_half, v_one_half, v_one],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_max_y_max_ctps,
+ )
)
- )
- return (spline_list, None)
-
- elif closure == "z_max":
- branch_thickness = parameters.flatten()[4]
- branch_neighbor_x_min_ctps = _np.array(
- [
- [-0.5, -aux_column_width, 0.0],
- [-seperator_distance, -aux_column_width, 0.0],
- [-branch_thickness, -branch_thickness, 0.0],
- [-0.5, aux_column_width, 0.0],
- [-seperator_distance, aux_column_width, 0.0],
- [-branch_thickness, branch_thickness, 0.0],
- [-0.5, -aux_column_width, ctps_mid_height_bottom],
- [
- -seperator_distance,
- -aux_column_width,
- ctps_mid_height_bottom,
- ],
- [
- -branch_thickness,
- -branch_thickness,
- ctps_mid_height_bottom,
- ],
- [-0.5, aux_column_width, ctps_mid_height_bottom],
+ elif closure == "z_max":
+ branch_neighbor_x_min_ctps = _np.array(
[
- -seperator_distance,
- aux_column_width,
- ctps_mid_height_bottom,
- ],
- [
- -branch_thickness,
- branch_thickness,
- ctps_mid_height_bottom,
- ],
- [-0.5, -r_center, inv_filling_height],
- [-half_r_center, -r_center, inv_filling_height],
- [-r_center, -r_center, inv_filling_height],
- [-0.5, r_center, inv_filling_height],
- [-half_r_center, r_center, inv_filling_height],
- [-r_center, r_center, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 1, 2],
- control_points=branch_neighbor_x_min_ctps,
+ [-v_one_half, -aux_column_width, v_zero],
+ [-sep_distance_aux, -aux_column_width, v_zero],
+ [-branch_thickness, -branch_thickness, v_zero],
+ [-v_one_half, aux_column_width, v_zero],
+ [-sep_distance_aux, aux_column_width, v_zero],
+ [-branch_thickness, branch_thickness, v_zero],
+ [
+ -v_one_half,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -v_one_half,
+ aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -branch_thickness,
+ branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [-v_one_half, -r_center, inv_filling_height],
+ [-half_r_center, -r_center, inv_filling_height],
+ [-r_center, -r_center, inv_filling_height],
+ [-v_one_half, r_center, inv_filling_height],
+ [-half_r_center, r_center, inv_filling_height],
+ [-r_center, r_center, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 1, 2],
+ control_points=branch_neighbor_x_min_ctps,
+ )
)
- )
- branch_neighbor_x_max_ctps = _np.array(
- [
- [branch_thickness, -branch_thickness, 0.0],
- [seperator_distance, -aux_column_width, 0.0],
- [0.5, -aux_column_width, 0.0],
- [branch_thickness, branch_thickness, 0.0],
- [seperator_distance, aux_column_width, 0.0],
- [0.5, aux_column_width, 0.0],
- [
- branch_thickness,
- -branch_thickness,
- ctps_mid_height_bottom,
- ],
+ branch_neighbor_x_max_ctps = _np.array(
[
- seperator_distance,
- -aux_column_width,
- ctps_mid_height_bottom,
- ],
- [0.5, -aux_column_width, ctps_mid_height_bottom],
- [
- branch_thickness,
- branch_thickness,
- ctps_mid_height_bottom,
- ],
- [
- seperator_distance,
- aux_column_width,
- ctps_mid_height_bottom,
- ],
- [0.5, aux_column_width, ctps_mid_height_bottom],
- [r_center, -r_center, inv_filling_height],
- [half_r_center, -r_center, inv_filling_height],
- [0.5, -r_center, inv_filling_height],
- [r_center, r_center, inv_filling_height],
- [half_r_center, r_center, inv_filling_height],
- [0.5, r_center, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 1, 2],
- control_points=branch_neighbor_x_max_ctps,
+ [branch_thickness, -branch_thickness, v_zero],
+ [sep_distance_aux, -aux_column_width, v_zero],
+ [v_one_half, -aux_column_width, v_zero],
+ [branch_thickness, branch_thickness, v_zero],
+ [sep_distance_aux, aux_column_width, v_zero],
+ [v_one_half, aux_column_width, v_zero],
+ [
+ branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ v_one_half,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ branch_thickness,
+ branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [v_one_half, aux_column_width, ctps_mid_height_bottom],
+ [r_center, -r_center, inv_filling_height],
+ [half_r_center, -r_center, inv_filling_height],
+ [v_one_half, -r_center, inv_filling_height],
+ [r_center, r_center, inv_filling_height],
+ [half_r_center, r_center, inv_filling_height],
+ [v_one_half, r_center, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 1, 2],
+ control_points=branch_neighbor_x_max_ctps,
+ )
)
- )
- branch_neighbor_y_min_ctps = _np.array(
- [
- [-aux_column_width, -0.5, 0.0],
- [aux_column_width, -0.5, 0.0],
- [-aux_column_width, -seperator_distance, 0.0],
- [aux_column_width, -seperator_distance, 0.0],
- [-branch_thickness, -branch_thickness, 0.0],
- [branch_thickness, -branch_thickness, 0.0],
- [-aux_column_width, -0.5, ctps_mid_height_bottom],
- [aux_column_width, -0.5, ctps_mid_height_bottom],
- [
- -aux_column_width,
- -seperator_distance,
- ctps_mid_height_bottom,
- ],
+ branch_neighbor_y_min_ctps = _np.array(
[
- aux_column_width,
- -seperator_distance,
- ctps_mid_height_bottom,
- ],
- [
- -branch_thickness,
- -branch_thickness,
- ctps_mid_height_bottom,
- ],
- [
- branch_thickness,
- -branch_thickness,
- ctps_mid_height_bottom,
- ],
- [-r_center, -0.5, inv_filling_height],
- [r_center, -0.5, inv_filling_height],
- [-r_center, -half_r_center, inv_filling_height],
- [r_center, -half_r_center, inv_filling_height],
- [-r_center, -r_center, inv_filling_height],
- [r_center, -r_center, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[1, 2, 2],
- control_points=branch_neighbor_y_min_ctps,
+ [-aux_column_width, -v_one_half, v_zero],
+ [aux_column_width, -v_one_half, v_zero],
+ [-aux_column_width, -sep_distance_aux, v_zero],
+ [aux_column_width, -sep_distance_aux, v_zero],
+ [-branch_thickness, -branch_thickness, v_zero],
+ [branch_thickness, -branch_thickness, v_zero],
+ [
+ -aux_column_width,
+ -v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [
+ aux_column_width,
+ -v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [-r_center, -v_one_half, inv_filling_height],
+ [r_center, -v_one_half, inv_filling_height],
+ [-r_center, -half_r_center, inv_filling_height],
+ [r_center, -half_r_center, inv_filling_height],
+ [-r_center, -r_center, inv_filling_height],
+ [r_center, -r_center, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[1, 2, 2],
+ control_points=branch_neighbor_y_min_ctps,
+ )
)
- )
- branch_neighbor_y_max_ctps = _np.array(
- [
- [-branch_thickness, branch_thickness, 0.0],
- [branch_thickness, branch_thickness, 0.0],
- [-aux_column_width, seperator_distance, 0.0],
- [aux_column_width, seperator_distance, 0.0],
- [-aux_column_width, 0.5, 0.0],
- [aux_column_width, 0.5, 0.0],
+ branch_neighbor_y_max_ctps = _np.array(
[
- -branch_thickness,
- branch_thickness,
- ctps_mid_height_bottom,
- ],
- [
- branch_thickness,
- branch_thickness,
- ctps_mid_height_bottom,
- ],
- [
- -aux_column_width,
- seperator_distance,
- ctps_mid_height_bottom,
- ],
- [
- aux_column_width,
- seperator_distance,
- ctps_mid_height_bottom,
- ],
- [-aux_column_width, 0.5, ctps_mid_height_bottom],
- [aux_column_width, 0.5, ctps_mid_height_bottom],
- [-r_center, r_center, inv_filling_height],
- [r_center, r_center, inv_filling_height],
- [-r_center, half_r_center, inv_filling_height],
- [r_center, half_r_center, inv_filling_height],
- [-r_center, 0.5, inv_filling_height],
- [r_center, 0.5, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[1, 2, 2],
- control_points=branch_neighbor_y_max_ctps,
+ [-branch_thickness, branch_thickness, v_zero],
+ [branch_thickness, branch_thickness, v_zero],
+ [-aux_column_width, sep_distance_aux, v_zero],
+ [aux_column_width, sep_distance_aux, v_zero],
+ [-aux_column_width, v_one_half, v_zero],
+ [aux_column_width, v_one_half, v_zero],
+ [
+ -branch_thickness,
+ branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ branch_thickness,
+ branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [aux_column_width, v_one_half, ctps_mid_height_bottom],
+ [-r_center, r_center, inv_filling_height],
+ [r_center, r_center, inv_filling_height],
+ [-r_center, half_r_center, inv_filling_height],
+ [r_center, half_r_center, inv_filling_height],
+ [-r_center, v_one_half, inv_filling_height],
+ [r_center, v_one_half, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[1, 2, 2],
+ control_points=branch_neighbor_y_max_ctps,
+ )
)
- )
- branch_x_min_y_min_ctps = _np.array(
- [
- [-0.5, -0.5, 0.0],
- [-seperator_distance, -0.5, 0.0],
- [-aux_column_width, -0.5, 0.0],
- [-0.5, -seperator_distance, 0.0],
- [-seperator_distance, -seperator_distance, 0.0],
- [-aux_column_width, -seperator_distance, 0.0],
- [-0.5, -aux_column_width, 0.0],
- [-seperator_distance, -aux_column_width, 0.0],
- [-branch_thickness, -branch_thickness, 0.0],
- [-0.5, -0.5, ctps_mid_height_bottom],
- [-seperator_distance, -0.5, ctps_mid_height_bottom],
- [-aux_column_width, -0.5, ctps_mid_height_bottom],
- [-0.5, -seperator_distance, ctps_mid_height_bottom],
- [
- -seperator_distance,
- -seperator_distance,
- ctps_mid_height_bottom,
- ],
- [
- -aux_column_width,
- -seperator_distance,
- ctps_mid_height_bottom,
- ],
- [-0.5, -aux_column_width, ctps_mid_height_bottom],
- [
- -seperator_distance,
- -aux_column_width,
- ctps_mid_height_bottom,
- ],
+ branch_x_min_y_min_ctps = _np.array(
[
- -branch_thickness,
- -branch_thickness,
- ctps_mid_height_bottom,
- ],
- [-0.5, -0.5, inv_filling_height],
- [-half_r_center, -0.5, inv_filling_height],
- [-r_center, -0.5, inv_filling_height],
- [-0.5, -half_r_center, inv_filling_height],
- [-half_r_center, -half_r_center, inv_filling_height],
- [-r_center, -half_r_center, inv_filling_height],
- [-0.5, -r_center, inv_filling_height],
- [-half_r_center, -r_center, inv_filling_height],
- [-r_center, -r_center, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_min_y_min_ctps
+ [-v_one_half, -v_one_half, v_zero],
+ [-sep_distance_aux, -v_one_half, v_zero],
+ [-aux_column_width, -v_one_half, v_zero],
+ [-v_one_half, -sep_distance_aux, v_zero],
+ [-sep_distance_aux, -sep_distance_aux, v_zero],
+ [-aux_column_width, -sep_distance_aux, v_zero],
+ [-v_one_half, -aux_column_width, v_zero],
+ [-sep_distance_aux, -aux_column_width, v_zero],
+ [-branch_thickness, -branch_thickness, v_zero],
+ [-v_one_half, -v_one_half, ctps_mid_height_bottom],
+ [
+ -sep_distance_aux,
+ -v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ -v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -v_one_half,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -sep_distance_aux,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -v_one_half,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [-v_one_half, -v_one_half, inv_filling_height],
+ [-half_r_center, -v_one_half, inv_filling_height],
+ [-r_center, -v_one_half, inv_filling_height],
+ [-v_one_half, -half_r_center, inv_filling_height],
+ [-half_r_center, -half_r_center, inv_filling_height],
+ [-r_center, -half_r_center, inv_filling_height],
+ [-v_one_half, -r_center, inv_filling_height],
+ [-half_r_center, -r_center, inv_filling_height],
+ [-r_center, -r_center, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_min_y_min_ctps,
+ )
)
- )
- branch_x_max_y_max_ctps = _np.array(
- [
- [branch_thickness, branch_thickness, 0.0],
- [seperator_distance, aux_column_width, 0.0],
- [0.5, aux_column_width, 0.0],
- [aux_column_width, seperator_distance, 0.0],
- [seperator_distance, seperator_distance, 0.0],
- [0.5, seperator_distance, 0.0],
- [aux_column_width, 0.5, 0.0],
- [seperator_distance, 0.5, 0.0],
- [0.5, 0.5, 0.0],
- [
- branch_thickness,
- branch_thickness,
- ctps_mid_height_bottom,
- ],
- [
- seperator_distance,
- aux_column_width,
- ctps_mid_height_bottom,
- ],
- [0.5, aux_column_width, ctps_mid_height_bottom],
+ branch_x_max_y_max_ctps = _np.array(
[
- aux_column_width,
- seperator_distance,
- ctps_mid_height_bottom,
- ],
- [
- seperator_distance,
- seperator_distance,
- ctps_mid_height_bottom,
- ],
- [0.5, seperator_distance, ctps_mid_height_bottom],
- [aux_column_width, 0.5, ctps_mid_height_bottom],
- [seperator_distance, 0.5, ctps_mid_height_bottom],
- [0.5, 0.5, ctps_mid_height_bottom],
- [r_center, r_center, inv_filling_height],
- [half_r_center, r_center, inv_filling_height],
- [0.5, r_center, inv_filling_height],
- [r_center, half_r_center, inv_filling_height],
- [half_r_center, half_r_center, inv_filling_height],
- [0.5, half_r_center, inv_filling_height],
- [r_center, 0.5, inv_filling_height],
- [half_r_center, 0.5, inv_filling_height],
- [0.5, 0.5, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_max_y_max_ctps
+ [branch_thickness, branch_thickness, v_zero],
+ [sep_distance_aux, aux_column_width, v_zero],
+ [v_one_half, aux_column_width, v_zero],
+ [aux_column_width, sep_distance_aux, v_zero],
+ [sep_distance_aux, sep_distance_aux, v_zero],
+ [v_one_half, sep_distance_aux, v_zero],
+ [aux_column_width, v_one_half, v_zero],
+ [sep_distance_aux, v_one_half, v_zero],
+ [v_one_half, v_one_half, v_zero],
+ [
+ branch_thickness,
+ branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [v_one_half, aux_column_width, ctps_mid_height_bottom],
+ [
+ aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [v_one_half, sep_distance_aux, ctps_mid_height_bottom],
+ [aux_column_width, v_one_half, ctps_mid_height_bottom],
+ [sep_distance_aux, v_one_half, ctps_mid_height_bottom],
+ [v_one_half, v_one_half, ctps_mid_height_bottom],
+ [r_center, r_center, inv_filling_height],
+ [half_r_center, r_center, inv_filling_height],
+ [v_one_half, r_center, inv_filling_height],
+ [r_center, half_r_center, inv_filling_height],
+ [half_r_center, half_r_center, inv_filling_height],
+ [v_one_half, half_r_center, inv_filling_height],
+ [r_center, v_one_half, inv_filling_height],
+ [half_r_center, v_one_half, inv_filling_height],
+ [v_one_half, v_one_half, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_max_y_max_ctps,
+ )
)
- )
- branch_x_max_y_min_ctps = _np.array(
- [
- [aux_column_width, -0.5, 0.0],
- [seperator_distance, -0.5, 0.0],
- [0.5, -0.5, 0.0],
- [aux_column_width, -seperator_distance, 0.0],
- [seperator_distance, -seperator_distance, 0.0],
- [0.5, -seperator_distance, 0.0],
- [branch_thickness, -branch_thickness, 0.0],
- [seperator_distance, -aux_column_width, 0.0],
- [0.5, -aux_column_width, 0.0],
- [aux_column_width, -0.5, ctps_mid_height_bottom],
- [seperator_distance, -0.5, ctps_mid_height_bottom],
- [0.5, -0.5, ctps_mid_height_bottom],
- [
- aux_column_width,
- -seperator_distance,
- ctps_mid_height_bottom,
- ],
+ branch_x_max_y_min_ctps = _np.array(
[
- seperator_distance,
- -seperator_distance,
- ctps_mid_height_bottom,
- ],
- [0.5, -seperator_distance, ctps_mid_height_bottom],
- [
- branch_thickness,
- -branch_thickness,
- ctps_mid_height_bottom,
- ],
- [
- seperator_distance,
- -aux_column_width,
- ctps_mid_height_bottom,
- ],
- [0.5, -aux_column_width, ctps_mid_height_bottom],
- [r_center, -0.5, inv_filling_height],
- [half_r_center, -0.5, inv_filling_height],
- [0.5, -0.5, inv_filling_height],
- [r_center, -half_r_center, inv_filling_height],
- [half_r_center, -half_r_center, inv_filling_height],
- [0.5, -half_r_center, inv_filling_height],
- [r_center, -r_center, inv_filling_height],
- [half_r_center, -r_center, inv_filling_height],
- [0.5, -r_center, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_max_y_min_ctps
+ [aux_column_width, -v_one_half, v_zero],
+ [sep_distance_aux, -v_one_half, v_zero],
+ [v_one_half, -v_one_half, v_zero],
+ [aux_column_width, -sep_distance_aux, v_zero],
+ [sep_distance_aux, -sep_distance_aux, v_zero],
+ [v_one_half, -sep_distance_aux, v_zero],
+ [branch_thickness, -branch_thickness, v_zero],
+ [sep_distance_aux, -aux_column_width, v_zero],
+ [v_one_half, -aux_column_width, v_zero],
+ [
+ aux_column_width,
+ -v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ -v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [v_one_half, -v_one_half, ctps_mid_height_bottom],
+ [
+ aux_column_width,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ v_one_half,
+ -sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ branch_thickness,
+ -branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ sep_distance_aux,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ v_one_half,
+ -aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [r_center, -v_one_half, inv_filling_height],
+ [half_r_center, -v_one_half, inv_filling_height],
+ [v_one_half, -v_one_half, inv_filling_height],
+ [r_center, -half_r_center, inv_filling_height],
+ [half_r_center, -half_r_center, inv_filling_height],
+ [v_one_half, -half_r_center, inv_filling_height],
+ [r_center, -r_center, inv_filling_height],
+ [half_r_center, -r_center, inv_filling_height],
+ [v_one_half, -r_center, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_max_y_min_ctps,
+ )
)
- )
- branch_x_min_y_max_ctps = _np.array(
- [
- [-0.5, aux_column_width, 0.0],
- [-seperator_distance, aux_column_width, 0.0],
- [-branch_thickness, branch_thickness, 0.0],
- [-0.5, seperator_distance, 0.0],
- [-seperator_distance, seperator_distance, 0.0],
- [-aux_column_width, seperator_distance, 0.0],
- [-0.5, 0.5, 0.0],
- [-seperator_distance, 0.5, 0.0],
- [-aux_column_width, 0.5, 0.0],
- [-0.5, aux_column_width, ctps_mid_height_bottom],
- [
- -seperator_distance,
- aux_column_width,
- ctps_mid_height_bottom,
- ],
+ branch_x_min_y_max_ctps = _np.array(
[
- -branch_thickness,
- branch_thickness,
- ctps_mid_height_bottom,
- ],
- [-0.5, seperator_distance, ctps_mid_height_bottom],
- [
- -seperator_distance,
- seperator_distance,
- ctps_mid_height_bottom,
- ],
- [
- -aux_column_width,
- seperator_distance,
- ctps_mid_height_bottom,
- ],
- [-0.5, 0.5, ctps_mid_height_bottom],
- [-seperator_distance, 0.5, ctps_mid_height_bottom],
- [-aux_column_width, 0.5, ctps_mid_height_bottom],
- [-0.5, r_center, inv_filling_height],
- [-half_r_center, r_center, inv_filling_height],
- [-r_center, r_center, inv_filling_height],
- [-0.5, half_r_center, inv_filling_height],
- [-half_r_center, half_r_center, inv_filling_height],
- [-r_center, half_r_center, inv_filling_height],
- [-0.5, 0.5, inv_filling_height],
- [-half_r_center, 0.5, inv_filling_height],
- [-r_center, 0.5, inv_filling_height],
- ]
- ) + _np.array([0.5, 0.5, 0.0])
-
- spline_list.append(
- _Bezier(
- degrees=[2, 2, 2], control_points=branch_x_min_y_max_ctps
+ [-v_one_half, aux_column_width, v_zero],
+ [-sep_distance_aux, aux_column_width, v_zero],
+ [-branch_thickness, branch_thickness, v_zero],
+ [-v_one_half, sep_distance_aux, v_zero],
+ [-sep_distance_aux, sep_distance_aux, v_zero],
+ [-aux_column_width, sep_distance_aux, v_zero],
+ [-v_one_half, v_one_half, v_zero],
+ [-sep_distance_aux, v_one_half, v_zero],
+ [-aux_column_width, v_one_half, v_zero],
+ [
+ -v_one_half,
+ aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -sep_distance_aux,
+ aux_column_width,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -branch_thickness,
+ branch_thickness,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -v_one_half,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -sep_distance_aux,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ sep_distance_aux,
+ ctps_mid_height_bottom,
+ ],
+ [-v_one_half, v_one_half, ctps_mid_height_bottom],
+ [
+ -sep_distance_aux,
+ v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [
+ -aux_column_width,
+ v_one_half,
+ ctps_mid_height_bottom,
+ ],
+ [-v_one_half, r_center, inv_filling_height],
+ [-half_r_center, r_center, inv_filling_height],
+ [-r_center, r_center, inv_filling_height],
+ [-v_one_half, half_r_center, inv_filling_height],
+ [-half_r_center, half_r_center, inv_filling_height],
+ [-r_center, half_r_center, inv_filling_height],
+ [-v_one_half, v_one_half, inv_filling_height],
+ [-half_r_center, v_one_half, inv_filling_height],
+ [-r_center, v_one_half, inv_filling_height],
+ ]
+ ) + _np.array([v_one_half, v_one_half, v_zero])
+
+ spline_list.append(
+ _Bezier(
+ degrees=[2, 2, 2],
+ control_points=branch_x_min_y_max_ctps,
+ )
)
- )
+ else:
+ raise ValueError("Corner Type not supported")
+
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
- return (spline_list, None)
- else:
- raise ValueError("Corner Type not supported")
+ return (splines, derivatives)
def create_tile(
self,
parameters=None,
parameter_sensitivities=None,
- seperator_distance=None,
+ separator_distance=0.3,
center_expansion=1.0,
closure=None,
**kwargs, # noqa ARG002
@@ -905,9 +1039,9 @@ def create_tile(
parameters : np.array
only first entry is used, defines the internal radii of the
branches
- seperator_distance : float
+ separator_distance : float
Control point distance to separation layer of biquadratic degrees,
- determines the minimum branch thickness (defaults to 0.4)
+ determines the minimum branch thickness (defaults to 0.3)
center_expansion : float
thickness of center is expanded by a factor (default to 1.0), which
determines the maximum branch thickness
@@ -920,46 +1054,25 @@ def create_tile(
microtile_list : list(splines)
"""
- if not isinstance(center_expansion, float):
- raise ValueError("Invalid Type")
-
- if not ((center_expansion > 0.5) and (center_expansion < 1.5)):
- raise ValueError("Center Expansion must be in (.5, 1.5)")
-
- # Set default values
- if seperator_distance is None:
- seperator_distance = 0.3
-
- if center_expansion is None:
- center_expansion = 1.0
+ self._check_custom_parameter(
+ center_expansion, "center expansion", self._CENTER_EXPANSION_BOUNDS
+ )
# Check if all radii are in allowed range
max_radius = min(0.5, (0.5 / center_expansion))
- max_radius = min(max_radius, seperator_distance)
- min_radius = max(0.5 - seperator_distance, 0)
-
- # set to default if nothing is given
- if parameters is None:
- self._logd("Setting branch thickness to default 0.2")
- parameters = (
- _np.ones(
- (len(self._evaluation_points), self._n_info_per_eval_point)
- )
- * 0.2
- )
-
- if parameter_sensitivities is not None:
- raise NotImplementedError(
- "Derivatives are not implemented for this tile yet"
- )
+ max_radius = min(max_radius, separator_distance)
+ min_radius = max(0.5 - separator_distance, 0)
- self.check_params(parameters)
+ parameters, n_derivatives, derivatives = self._process_input(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ )
if _np.any(parameters < min_radius) or _np.any(
parameters > max_radius
):
raise ValueError(
- f"Radii must be in (0,{max_radius}) for "
+ f"Radii must be in ({min_radius},{max_radius}) for "
f"center_expansion {center_expansion}"
)
@@ -967,649 +1080,715 @@ def create_tile(
return self._closing_tile(
parameters=parameters,
parameter_sensitivities=parameter_sensitivities,
- seperator_distance=seperator_distance,
+ separator_distance=separator_distance,
closure=closure,
**kwargs,
)
- [
- x_min_r,
- x_max_r,
- y_min_r,
- y_max_r,
- z_min_r,
- z_max_r,
- ] = parameters.flatten()
-
- # center radius
- center_r = _np.sum(parameters) / 6.0 * center_expansion
-
- # Auxiliary values for smooothing (mid-branch thickness)
- [
- aux_x_min,
- aux_x_max,
- aux_y_min,
- aux_y_max,
- aux_z_min,
- aux_z_max,
- ] = _np.minimum(parameters.ravel(), center_r)
- # Branch midlength
- hd_center = 0.5 * (0.5 + center_r)
- aux_column_width = 0.5 - 2 * (0.5 - seperator_distance)
-
- # Init return type
- spline_list = []
-
- # Start with branch interconnections
- x_min_y_min = _np.array(
- [
- [-0.5, -0.5, -aux_column_width],
- [-seperator_distance, -0.5, -aux_column_width],
- [-y_min_r, -0.5, -y_min_r],
- [-0.5, -seperator_distance, -aux_column_width],
- [-hd_center, -hd_center, -aux_column_width],
- [-aux_y_min, -hd_center, -aux_y_min],
- [-0.5, -x_min_r, -x_min_r],
- [-hd_center, -aux_x_min, -aux_x_min],
- [-center_r, -center_r, -center_r],
- [-0.5, -0.5, aux_column_width],
- [-seperator_distance, -0.5, aux_column_width],
- [-y_min_r, -0.5, y_min_r],
- [-0.5, -seperator_distance, aux_column_width],
- [-hd_center, -hd_center, aux_column_width],
- [-aux_y_min, -hd_center, aux_y_min],
- [-0.5, -x_min_r, x_min_r],
- [-hd_center, -aux_x_min, aux_x_min],
- [-center_r, -center_r, center_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 1], control_points=x_min_y_min)
- )
+ splines = []
+ for i_derivative in range(n_derivatives + 1):
+ if i_derivative == 0:
+ [
+ x_min_r,
+ x_max_r,
+ y_min_r,
+ y_max_r,
+ z_min_r,
+ z_max_r,
+ ] = parameters.flatten()
+
+ # center radius
+ center_r = _np.sum(parameters) / 6.0 * center_expansion
+
+ # Auxiliary values for smooothing (mid-branch thickness)
+ [
+ aux_x_min,
+ aux_x_max,
+ aux_y_min,
+ aux_y_max,
+ aux_z_min,
+ aux_z_max,
+ ] = _np.minimum(parameters.ravel(), center_r)
+ # Branch midlength
+ hd_center = 0.5 * (0.5 + center_r)
+ aux_column_width = 0.5 - 2 * (0.5 - separator_distance)
+
+ v_one_half = 0.5
+ center_point = _np.array([0.5, 0.5, 0.5])
+
+ sep_distance = separator_distance
+ else:
+ sensitivities_i = parameter_sensitivities[
+ :, 0, i_derivative - 1
+ ]
+ [
+ x_min_r,
+ x_max_r,
+ y_min_r,
+ y_max_r,
+ z_min_r,
+ z_max_r,
+ ] = sensitivities_i
+
+ center_r = _np.mean(sensitivities_i) * center_expansion
+ [
+ aux_x_min,
+ aux_x_max,
+ aux_y_min,
+ aux_y_max,
+ aux_z_min,
+ aux_z_max,
+ ] = _np.where(
+ parameters.ravel()
+ < _np.mean(parameters.ravel()) * center_expansion,
+ sensitivities_i,
+ center_r,
+ )
+ # Branch midlength
+ hd_center = center_r / 2.0
+ aux_column_width = 0.0
+ v_one_half = 0.0
+ center_point = _np.zeros(3)
- x_max_y_min = _np.array(
- [
- [y_min_r, -0.5, -y_min_r],
- [seperator_distance, -0.5, -aux_column_width],
- [0.5, -0.5, -aux_column_width],
- [aux_y_min, -hd_center, -aux_y_min],
- [hd_center, -hd_center, -aux_column_width],
- [0.5, -seperator_distance, -aux_column_width],
- [center_r, -center_r, -center_r],
- [hd_center, -aux_x_max, -aux_x_max],
- [0.5, -x_max_r, -x_max_r],
- [y_min_r, -0.5, y_min_r],
- [seperator_distance, -0.5, aux_column_width],
- [0.5, -0.5, aux_column_width],
- [aux_y_min, -hd_center, aux_y_min],
- [hd_center, -hd_center, aux_column_width],
- [0.5, -seperator_distance, aux_column_width],
- [center_r, -center_r, center_r],
- [hd_center, -aux_x_max, aux_x_max],
- [0.5, -x_max_r, x_max_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 1], control_points=x_max_y_min)
- )
+ sep_distance = 0.0
- x_min_y_max = _np.array(
- [
- [-0.5, x_min_r, -x_min_r],
- [-hd_center, aux_x_min, -aux_x_min],
- [-center_r, center_r, -center_r],
- [-0.5, seperator_distance, -aux_column_width],
- [-hd_center, hd_center, -aux_column_width],
- [-aux_y_max, hd_center, -aux_y_max],
- [-0.5, 0.5, -aux_column_width],
- [-seperator_distance, 0.5, -aux_column_width],
- [-y_max_r, 0.5, -y_max_r],
- [-0.5, x_min_r, x_min_r],
- [-hd_center, aux_x_min, aux_x_min],
- [-center_r, center_r, center_r],
- [-0.5, seperator_distance, aux_column_width],
- [-hd_center, hd_center, aux_column_width],
- [-aux_y_max, hd_center, aux_y_max],
- [-0.5, 0.5, aux_column_width],
- [-seperator_distance, 0.5, aux_column_width],
- [-y_max_r, 0.5, y_max_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 1], control_points=x_min_y_max)
- )
+ # Init return type
+ spline_list = []
- x_max_y_max = _np.array(
- [
- [center_r, center_r, -center_r],
- [hd_center, aux_x_max, -aux_x_max],
- [0.5, x_max_r, -x_max_r],
- [aux_y_max, hd_center, -aux_y_max],
- [hd_center, hd_center, -aux_column_width],
- [0.5, seperator_distance, -aux_column_width],
- [y_max_r, 0.5, -y_max_r],
- [seperator_distance, 0.5, -aux_column_width],
- [0.5, 0.5, -aux_column_width],
- [center_r, center_r, center_r],
- [hd_center, aux_x_max, aux_x_max],
- [0.5, x_max_r, x_max_r],
- [aux_y_max, hd_center, aux_y_max],
- [hd_center, hd_center, aux_column_width],
- [0.5, seperator_distance, aux_column_width],
- [y_max_r, 0.5, y_max_r],
- [seperator_distance, 0.5, aux_column_width],
- [0.5, 0.5, aux_column_width],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 1], control_points=x_max_y_max)
- )
+ # Start with branch interconnections
+ x_min_y_min = (
+ _np.array(
+ [
+ [-v_one_half, -v_one_half, -aux_column_width],
+ [-sep_distance, -v_one_half, -aux_column_width],
+ [-y_min_r, -v_one_half, -y_min_r],
+ [-v_one_half, -sep_distance, -aux_column_width],
+ [-hd_center, -hd_center, -aux_column_width],
+ [-aux_y_min, -hd_center, -aux_y_min],
+ [-v_one_half, -x_min_r, -x_min_r],
+ [-hd_center, -aux_x_min, -aux_x_min],
+ [-center_r, -center_r, -center_r],
+ [-v_one_half, -v_one_half, aux_column_width],
+ [-sep_distance, -v_one_half, aux_column_width],
+ [-y_min_r, -v_one_half, y_min_r],
+ [-v_one_half, -sep_distance, aux_column_width],
+ [-hd_center, -hd_center, aux_column_width],
+ [-aux_y_min, -hd_center, aux_y_min],
+ [-v_one_half, -x_min_r, x_min_r],
+ [-hd_center, -aux_x_min, aux_x_min],
+ [-center_r, -center_r, center_r],
+ ]
+ )
+ + center_point
+ )
- x_min_z_min = _np.array(
- [
- [-0.5, -aux_column_width, -0.5],
- [-seperator_distance, -aux_column_width, -0.5],
- [-z_min_r, -z_min_r, -0.5],
- [-0.5, aux_column_width, -0.5],
- [-seperator_distance, aux_column_width, -0.5],
- [-z_min_r, z_min_r, -0.5],
- [-0.5, -aux_column_width, -seperator_distance],
- [-hd_center, -aux_column_width, -hd_center],
- [-aux_z_min, -aux_z_min, -hd_center],
- [-0.5, aux_column_width, -seperator_distance],
- [-hd_center, aux_column_width, -hd_center],
- [-aux_z_min, aux_z_min, -hd_center],
- [-0.5, -x_min_r, -x_min_r],
- [-hd_center, -aux_x_min, -aux_x_min],
- [-center_r, -center_r, -center_r],
- [-0.5, x_min_r, -x_min_r],
- [-hd_center, aux_x_min, -aux_x_min],
- [-center_r, center_r, -center_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 1, 2], control_points=x_min_z_min)
- )
+ x_max_y_min = (
+ _np.array(
+ [
+ [y_min_r, -v_one_half, -y_min_r],
+ [sep_distance, -v_one_half, -aux_column_width],
+ [v_one_half, -v_one_half, -aux_column_width],
+ [aux_y_min, -hd_center, -aux_y_min],
+ [hd_center, -hd_center, -aux_column_width],
+ [v_one_half, -sep_distance, -aux_column_width],
+ [center_r, -center_r, -center_r],
+ [hd_center, -aux_x_max, -aux_x_max],
+ [v_one_half, -x_max_r, -x_max_r],
+ [y_min_r, -v_one_half, y_min_r],
+ [sep_distance, -v_one_half, aux_column_width],
+ [v_one_half, -v_one_half, aux_column_width],
+ [aux_y_min, -hd_center, aux_y_min],
+ [hd_center, -hd_center, aux_column_width],
+ [v_one_half, -sep_distance, aux_column_width],
+ [center_r, -center_r, center_r],
+ [hd_center, -aux_x_max, aux_x_max],
+ [v_one_half, -x_max_r, x_max_r],
+ ]
+ )
+ + center_point
+ )
- x_max_z_min = _np.array(
- [
- [z_min_r, -z_min_r, -0.5],
- [seperator_distance, -aux_column_width, -0.5],
- [0.5, -aux_column_width, -0.5],
- [z_min_r, z_min_r, -0.5],
- [seperator_distance, aux_column_width, -0.5],
- [0.5, aux_column_width, -0.5],
- [aux_z_min, -aux_z_min, -hd_center],
- [hd_center, -aux_column_width, -hd_center],
- [0.5, -aux_column_width, -seperator_distance],
- [aux_z_min, aux_z_min, -hd_center],
- [hd_center, aux_column_width, -hd_center],
- [0.5, aux_column_width, -seperator_distance],
- [center_r, -center_r, -center_r],
- [hd_center, -aux_x_max, -aux_x_max],
- [0.5, -x_max_r, -x_max_r],
- [center_r, center_r, -center_r],
- [hd_center, aux_x_max, -aux_x_max],
- [0.5, x_max_r, -x_max_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 1, 2], control_points=x_max_z_min)
- )
+ x_min_y_max = (
+ _np.array(
+ [
+ [-v_one_half, x_min_r, -x_min_r],
+ [-hd_center, aux_x_min, -aux_x_min],
+ [-center_r, center_r, -center_r],
+ [-v_one_half, sep_distance, -aux_column_width],
+ [-hd_center, hd_center, -aux_column_width],
+ [-aux_y_max, hd_center, -aux_y_max],
+ [-v_one_half, v_one_half, -aux_column_width],
+ [-sep_distance, v_one_half, -aux_column_width],
+ [-y_max_r, v_one_half, -y_max_r],
+ [-v_one_half, x_min_r, x_min_r],
+ [-hd_center, aux_x_min, aux_x_min],
+ [-center_r, center_r, center_r],
+ [-v_one_half, sep_distance, aux_column_width],
+ [-hd_center, hd_center, aux_column_width],
+ [-aux_y_max, hd_center, aux_y_max],
+ [-v_one_half, v_one_half, aux_column_width],
+ [-sep_distance, v_one_half, aux_column_width],
+ [-y_max_r, v_one_half, y_max_r],
+ ]
+ )
+ + center_point
+ )
- x_min_z_max = _np.array(
- [
- [-0.5, -x_min_r, x_min_r],
- [-hd_center, -aux_x_min, aux_x_min],
- [-center_r, -center_r, center_r],
- [-0.5, x_min_r, x_min_r],
- [-hd_center, aux_x_min, aux_x_min],
- [-center_r, center_r, center_r],
- [-0.5, -aux_column_width, seperator_distance],
- [-hd_center, -aux_column_width, hd_center],
- [-aux_z_max, -aux_z_max, hd_center],
- [-0.5, aux_column_width, seperator_distance],
- [-hd_center, aux_column_width, hd_center],
- [-aux_z_max, aux_z_max, hd_center],
- [-0.5, -aux_column_width, 0.5],
- [-seperator_distance, -aux_column_width, 0.5],
- [-z_max_r, -z_max_r, 0.5],
- [-0.5, aux_column_width, 0.5],
- [-seperator_distance, aux_column_width, 0.5],
- [-z_max_r, z_max_r, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 1, 2], control_points=x_min_z_max)
- )
+ x_max_y_max = (
+ _np.array(
+ [
+ [center_r, center_r, -center_r],
+ [hd_center, aux_x_max, -aux_x_max],
+ [v_one_half, x_max_r, -x_max_r],
+ [aux_y_max, hd_center, -aux_y_max],
+ [hd_center, hd_center, -aux_column_width],
+ [v_one_half, sep_distance, -aux_column_width],
+ [y_max_r, v_one_half, -y_max_r],
+ [sep_distance, v_one_half, -aux_column_width],
+ [v_one_half, v_one_half, -aux_column_width],
+ [center_r, center_r, center_r],
+ [hd_center, aux_x_max, aux_x_max],
+ [v_one_half, x_max_r, x_max_r],
+ [aux_y_max, hd_center, aux_y_max],
+ [hd_center, hd_center, aux_column_width],
+ [v_one_half, sep_distance, aux_column_width],
+ [y_max_r, v_one_half, y_max_r],
+ [sep_distance, v_one_half, aux_column_width],
+ [v_one_half, v_one_half, aux_column_width],
+ ]
+ )
+ + center_point
+ )
- x_max_z_max = _np.array(
- [
- [center_r, -center_r, center_r],
- [hd_center, -aux_x_max, aux_x_max],
- [0.5, -x_max_r, x_max_r],
- [center_r, center_r, center_r],
- [hd_center, aux_x_max, aux_x_max],
- [0.5, x_max_r, x_max_r],
- [aux_z_max, -aux_z_max, hd_center],
- [hd_center, -aux_column_width, hd_center],
- [0.5, -aux_column_width, seperator_distance],
- [aux_z_max, aux_z_max, hd_center],
- [hd_center, aux_column_width, hd_center],
- [0.5, aux_column_width, seperator_distance],
- [z_max_r, -z_max_r, 0.5],
- [seperator_distance, -aux_column_width, 0.5],
- [0.5, -aux_column_width, 0.5],
- [z_max_r, z_max_r, 0.5],
- [seperator_distance, aux_column_width, 0.5],
- [0.5, aux_column_width, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 1, 2], control_points=x_max_z_max)
- )
+ x_min_z_min = (
+ _np.array(
+ [
+ [-v_one_half, -aux_column_width, -v_one_half],
+ [-sep_distance, -aux_column_width, -v_one_half],
+ [-z_min_r, -z_min_r, -v_one_half],
+ [-v_one_half, aux_column_width, -v_one_half],
+ [-sep_distance, aux_column_width, -v_one_half],
+ [-z_min_r, z_min_r, -v_one_half],
+ [-v_one_half, -aux_column_width, -sep_distance],
+ [-hd_center, -aux_column_width, -hd_center],
+ [-aux_z_min, -aux_z_min, -hd_center],
+ [-v_one_half, aux_column_width, -sep_distance],
+ [-hd_center, aux_column_width, -hd_center],
+ [-aux_z_min, aux_z_min, -hd_center],
+ [-v_one_half, -x_min_r, -x_min_r],
+ [-hd_center, -aux_x_min, -aux_x_min],
+ [-center_r, -center_r, -center_r],
+ [-v_one_half, x_min_r, -x_min_r],
+ [-hd_center, aux_x_min, -aux_x_min],
+ [-center_r, center_r, -center_r],
+ ]
+ )
+ + center_point
+ )
- y_min_z_min = _np.array(
- [
- [-aux_column_width, -0.5, -0.5],
- [aux_column_width, -0.5, -0.5],
- [-aux_column_width, -seperator_distance, -0.5],
- [aux_column_width, -seperator_distance, -0.5],
- [-z_min_r, -z_min_r, -0.5],
- [z_min_r, -z_min_r, -0.5],
- [-aux_column_width, -0.5, -seperator_distance],
- [aux_column_width, -0.5, -seperator_distance],
- [-aux_column_width, -hd_center, -hd_center],
- [aux_column_width, -hd_center, -hd_center],
- [-aux_z_min, -aux_z_min, -hd_center],
- [aux_z_min, -aux_z_min, -hd_center],
- [-y_min_r, -0.5, -y_min_r],
- [y_min_r, -0.5, -y_min_r],
- [-aux_y_min, -hd_center, -aux_y_min],
- [aux_y_min, -hd_center, -aux_y_min],
- [-center_r, -center_r, -center_r],
- [center_r, -center_r, -center_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[1, 2, 2], control_points=y_min_z_min)
- )
+ x_max_z_min = (
+ _np.array(
+ [
+ [z_min_r, -z_min_r, -v_one_half],
+ [sep_distance, -aux_column_width, -v_one_half],
+ [v_one_half, -aux_column_width, -v_one_half],
+ [z_min_r, z_min_r, -v_one_half],
+ [sep_distance, aux_column_width, -v_one_half],
+ [v_one_half, aux_column_width, -v_one_half],
+ [aux_z_min, -aux_z_min, -hd_center],
+ [hd_center, -aux_column_width, -hd_center],
+ [v_one_half, -aux_column_width, -sep_distance],
+ [aux_z_min, aux_z_min, -hd_center],
+ [hd_center, aux_column_width, -hd_center],
+ [v_one_half, aux_column_width, -sep_distance],
+ [center_r, -center_r, -center_r],
+ [hd_center, -aux_x_max, -aux_x_max],
+ [v_one_half, -x_max_r, -x_max_r],
+ [center_r, center_r, -center_r],
+ [hd_center, aux_x_max, -aux_x_max],
+ [v_one_half, x_max_r, -x_max_r],
+ ]
+ )
+ + center_point
+ )
- y_max_z_min = _np.array(
- [
- [-z_min_r, z_min_r, -0.5],
- [z_min_r, z_min_r, -0.5],
- [-aux_column_width, seperator_distance, -0.5],
- [aux_column_width, seperator_distance, -0.5],
- [-aux_column_width, 0.5, -0.5],
- [aux_column_width, 0.5, -0.5],
- [-aux_z_min, aux_z_min, -hd_center],
- [aux_z_min, aux_z_min, -hd_center],
- [-aux_column_width, hd_center, -hd_center],
- [aux_column_width, hd_center, -hd_center],
- [-aux_column_width, 0.5, -seperator_distance],
- [aux_column_width, 0.5, -seperator_distance],
- [-center_r, center_r, -center_r],
- [center_r, center_r, -center_r],
- [-aux_y_max, hd_center, -aux_y_max],
- [aux_y_max, hd_center, -aux_y_max],
- [-y_max_r, 0.5, -y_max_r],
- [y_max_r, 0.5, -y_max_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[1, 2, 2], control_points=y_max_z_min)
- )
+ x_min_z_max = (
+ _np.array(
+ [
+ [-v_one_half, -x_min_r, x_min_r],
+ [-hd_center, -aux_x_min, aux_x_min],
+ [-center_r, -center_r, center_r],
+ [-v_one_half, x_min_r, x_min_r],
+ [-hd_center, aux_x_min, aux_x_min],
+ [-center_r, center_r, center_r],
+ [-v_one_half, -aux_column_width, sep_distance],
+ [-hd_center, -aux_column_width, hd_center],
+ [-aux_z_max, -aux_z_max, hd_center],
+ [-v_one_half, aux_column_width, sep_distance],
+ [-hd_center, aux_column_width, hd_center],
+ [-aux_z_max, aux_z_max, hd_center],
+ [-v_one_half, -aux_column_width, v_one_half],
+ [-sep_distance, -aux_column_width, v_one_half],
+ [-z_max_r, -z_max_r, v_one_half],
+ [-v_one_half, aux_column_width, v_one_half],
+ [-sep_distance, aux_column_width, v_one_half],
+ [-z_max_r, z_max_r, v_one_half],
+ ]
+ )
+ + center_point
+ )
- y_min_z_max = _np.array(
- [
- [-y_min_r, -0.5, y_min_r],
- [y_min_r, -0.5, y_min_r],
- [-aux_y_min, -hd_center, aux_y_min],
- [aux_y_min, -hd_center, aux_y_min],
- [-center_r, -center_r, center_r],
- [center_r, -center_r, center_r],
- [-aux_column_width, -0.5, seperator_distance],
- [aux_column_width, -0.5, seperator_distance],
- [-aux_column_width, -hd_center, hd_center],
- [aux_column_width, -hd_center, hd_center],
- [-aux_z_max, -aux_z_max, hd_center],
- [aux_z_max, -aux_z_max, hd_center],
- [-aux_column_width, -0.5, 0.5],
- [aux_column_width, -0.5, 0.5],
- [-aux_column_width, -seperator_distance, 0.5],
- [aux_column_width, -seperator_distance, 0.5],
- [-z_max_r, -z_max_r, 0.5],
- [z_max_r, -z_max_r, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[1, 2, 2], control_points=y_min_z_max)
- )
+ x_max_z_max = (
+ _np.array(
+ [
+ [center_r, -center_r, center_r],
+ [hd_center, -aux_x_max, aux_x_max],
+ [v_one_half, -x_max_r, x_max_r],
+ [center_r, center_r, center_r],
+ [hd_center, aux_x_max, aux_x_max],
+ [v_one_half, x_max_r, x_max_r],
+ [aux_z_max, -aux_z_max, hd_center],
+ [hd_center, -aux_column_width, hd_center],
+ [v_one_half, -aux_column_width, sep_distance],
+ [aux_z_max, aux_z_max, hd_center],
+ [hd_center, aux_column_width, hd_center],
+ [v_one_half, aux_column_width, sep_distance],
+ [z_max_r, -z_max_r, v_one_half],
+ [sep_distance, -aux_column_width, v_one_half],
+ [v_one_half, -aux_column_width, v_one_half],
+ [z_max_r, z_max_r, v_one_half],
+ [sep_distance, aux_column_width, v_one_half],
+ [v_one_half, aux_column_width, v_one_half],
+ ]
+ )
+ + center_point
+ )
- y_max_z_max = _np.array(
- [
- [-center_r, center_r, center_r],
- [center_r, center_r, center_r],
- [-aux_y_max, hd_center, aux_y_max],
- [aux_y_max, hd_center, aux_y_max],
- [-y_max_r, 0.5, y_max_r],
- [y_max_r, 0.5, y_max_r],
- [-aux_z_max, aux_z_max, hd_center],
- [aux_z_max, aux_z_max, hd_center],
- [-aux_column_width, hd_center, hd_center],
- [aux_column_width, hd_center, hd_center],
- [-aux_column_width, 0.5, seperator_distance],
- [aux_column_width, 0.5, seperator_distance],
- [-z_max_r, z_max_r, 0.5],
- [z_max_r, z_max_r, 0.5],
- [-aux_column_width, seperator_distance, 0.5],
- [aux_column_width, seperator_distance, 0.5],
- [-aux_column_width, 0.5, 0.5],
- [aux_column_width, 0.5, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[1, 2, 2], control_points=y_max_z_max)
- )
+ y_min_z_min = (
+ _np.array(
+ [
+ [-aux_column_width, -v_one_half, -v_one_half],
+ [aux_column_width, -v_one_half, -v_one_half],
+ [-aux_column_width, -sep_distance, -v_one_half],
+ [aux_column_width, -sep_distance, -v_one_half],
+ [-z_min_r, -z_min_r, -v_one_half],
+ [z_min_r, -z_min_r, -v_one_half],
+ [-aux_column_width, -v_one_half, -sep_distance],
+ [aux_column_width, -v_one_half, -sep_distance],
+ [-aux_column_width, -hd_center, -hd_center],
+ [aux_column_width, -hd_center, -hd_center],
+ [-aux_z_min, -aux_z_min, -hd_center],
+ [aux_z_min, -aux_z_min, -hd_center],
+ [-y_min_r, -v_one_half, -y_min_r],
+ [y_min_r, -v_one_half, -y_min_r],
+ [-aux_y_min, -hd_center, -aux_y_min],
+ [aux_y_min, -hd_center, -aux_y_min],
+ [-center_r, -center_r, -center_r],
+ [center_r, -center_r, -center_r],
+ ]
+ )
+ + center_point
+ )
- x_min_y_min_z_min = _np.array(
- [
- [-0.5, -0.5, -0.5],
- [-seperator_distance, -0.5, -0.5],
- [-aux_column_width, -0.5, -0.5],
- [-0.5, -seperator_distance, -0.5],
- [-seperator_distance, -seperator_distance, -0.5],
- [-aux_column_width, -seperator_distance, -0.5],
- [-0.5, -aux_column_width, -0.5],
- [-seperator_distance, -aux_column_width, -0.5],
- [-z_min_r, -z_min_r, -0.5],
- [-0.5, -0.5, -seperator_distance],
- [-seperator_distance, -0.5, -seperator_distance],
- [-aux_column_width, -0.5, -seperator_distance],
- [-0.5, -seperator_distance, -seperator_distance],
- [-hd_center, -hd_center, -hd_center],
- [-aux_column_width, -hd_center, -hd_center],
- [-0.5, -aux_column_width, -seperator_distance],
- [-hd_center, -aux_column_width, -hd_center],
- [-aux_z_min, -aux_z_min, -hd_center],
- [-0.5, -0.5, -aux_column_width],
- [-seperator_distance, -0.5, -aux_column_width],
- [-y_min_r, -0.5, -y_min_r],
- [-0.5, -seperator_distance, -aux_column_width],
- [-hd_center, -hd_center, -aux_column_width],
- [-aux_y_min, -hd_center, -aux_y_min],
- [-0.5, -x_min_r, -x_min_r],
- [-hd_center, -aux_x_min, -aux_x_min],
- [-center_r, -center_r, -center_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_min_y_min_z_min)
- )
+ y_max_z_min = (
+ _np.array(
+ [
+ [-z_min_r, z_min_r, -v_one_half],
+ [z_min_r, z_min_r, -v_one_half],
+ [-aux_column_width, sep_distance, -v_one_half],
+ [aux_column_width, sep_distance, -v_one_half],
+ [-aux_column_width, v_one_half, -v_one_half],
+ [aux_column_width, v_one_half, -v_one_half],
+ [-aux_z_min, aux_z_min, -hd_center],
+ [aux_z_min, aux_z_min, -hd_center],
+ [-aux_column_width, hd_center, -hd_center],
+ [aux_column_width, hd_center, -hd_center],
+ [-aux_column_width, v_one_half, -sep_distance],
+ [aux_column_width, v_one_half, -sep_distance],
+ [-center_r, center_r, -center_r],
+ [center_r, center_r, -center_r],
+ [-aux_y_max, hd_center, -aux_y_max],
+ [aux_y_max, hd_center, -aux_y_max],
+ [-y_max_r, v_one_half, -y_max_r],
+ [y_max_r, v_one_half, -y_max_r],
+ ]
+ )
+ + center_point
+ )
- x_max_y_min_z_min = _np.array(
- [
- [aux_column_width, -0.5, -0.5],
- [seperator_distance, -0.5, -0.5],
- [0.5, -0.5, -0.5],
- [aux_column_width, -seperator_distance, -0.5],
- [seperator_distance, -seperator_distance, -0.5],
- [0.5, -seperator_distance, -0.5],
- [z_min_r, -z_min_r, -0.5],
- [seperator_distance, -aux_column_width, -0.5],
- [0.5, -aux_column_width, -0.5],
- [aux_column_width, -0.5, -seperator_distance],
- [seperator_distance, -0.5, -seperator_distance],
- [0.5, -0.5, -seperator_distance],
- [aux_column_width, -hd_center, -hd_center],
- [hd_center, -hd_center, -hd_center],
- [0.5, -seperator_distance, -seperator_distance],
- [aux_z_min, -aux_z_min, -hd_center],
- [hd_center, -aux_column_width, -hd_center],
- [0.5, -aux_column_width, -seperator_distance],
- [y_min_r, -0.5, -y_min_r],
- [seperator_distance, -0.5, -aux_column_width],
- [0.5, -0.5, -aux_column_width],
- [aux_y_min, -hd_center, -aux_y_min],
- [hd_center, -hd_center, -aux_column_width],
- [0.5, -seperator_distance, -aux_column_width],
- [center_r, -center_r, -center_r],
- [hd_center, -aux_x_max, -aux_x_max],
- [0.5, -x_max_r, -x_max_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_max_y_min_z_min)
- )
+ y_min_z_max = (
+ _np.array(
+ [
+ [-y_min_r, -v_one_half, y_min_r],
+ [y_min_r, -v_one_half, y_min_r],
+ [-aux_y_min, -hd_center, aux_y_min],
+ [aux_y_min, -hd_center, aux_y_min],
+ [-center_r, -center_r, center_r],
+ [center_r, -center_r, center_r],
+ [-aux_column_width, -v_one_half, sep_distance],
+ [aux_column_width, -v_one_half, sep_distance],
+ [-aux_column_width, -hd_center, hd_center],
+ [aux_column_width, -hd_center, hd_center],
+ [-aux_z_max, -aux_z_max, hd_center],
+ [aux_z_max, -aux_z_max, hd_center],
+ [-aux_column_width, -v_one_half, v_one_half],
+ [aux_column_width, -v_one_half, v_one_half],
+ [-aux_column_width, -sep_distance, v_one_half],
+ [aux_column_width, -sep_distance, v_one_half],
+ [-z_max_r, -z_max_r, v_one_half],
+ [z_max_r, -z_max_r, v_one_half],
+ ]
+ )
+ + center_point
+ )
- x_min_y_max_z_min = _np.array(
- [
- [-0.5, aux_column_width, -0.5],
- [-seperator_distance, aux_column_width, -0.5],
- [-z_min_r, z_min_r, -0.5],
- [-0.5, seperator_distance, -0.5],
- [-seperator_distance, seperator_distance, -0.5],
- [-aux_column_width, seperator_distance, -0.5],
- [-0.5, 0.5, -0.5],
- [-seperator_distance, 0.5, -0.5],
- [-aux_column_width, 0.5, -0.5],
- [-0.5, aux_column_width, -seperator_distance],
- [-hd_center, aux_column_width, -hd_center],
- [-aux_z_min, aux_z_min, -hd_center],
- [-0.5, seperator_distance, -seperator_distance],
- [-hd_center, hd_center, -hd_center],
- [-aux_column_width, hd_center, -hd_center],
- [-0.5, 0.5, -seperator_distance],
- [-seperator_distance, 0.5, -seperator_distance],
- [-aux_column_width, 0.5, -seperator_distance],
- [-0.5, x_min_r, -x_min_r],
- [-hd_center, aux_x_min, -aux_x_min],
- [-center_r, center_r, -center_r],
- [-0.5, seperator_distance, -aux_column_width],
- [-hd_center, hd_center, -aux_column_width],
- [-aux_y_max, hd_center, -aux_y_max],
- [-0.5, 0.5, -aux_column_width],
- [-seperator_distance, 0.5, -aux_column_width],
- [-y_max_r, 0.5, -y_max_r],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_min_y_max_z_min)
- )
+ y_max_z_max = (
+ _np.array(
+ [
+ [-center_r, center_r, center_r],
+ [center_r, center_r, center_r],
+ [-aux_y_max, hd_center, aux_y_max],
+ [aux_y_max, hd_center, aux_y_max],
+ [-y_max_r, v_one_half, y_max_r],
+ [y_max_r, v_one_half, y_max_r],
+ [-aux_z_max, aux_z_max, hd_center],
+ [aux_z_max, aux_z_max, hd_center],
+ [-aux_column_width, hd_center, hd_center],
+ [aux_column_width, hd_center, hd_center],
+ [-aux_column_width, v_one_half, sep_distance],
+ [aux_column_width, v_one_half, sep_distance],
+ [-z_max_r, z_max_r, v_one_half],
+ [z_max_r, z_max_r, v_one_half],
+ [-aux_column_width, sep_distance, v_one_half],
+ [aux_column_width, sep_distance, v_one_half],
+ [-aux_column_width, v_one_half, v_one_half],
+ [aux_column_width, v_one_half, v_one_half],
+ ]
+ )
+ + center_point
+ )
- x_max_y_max_z_min = _np.array(
- [
- [z_min_r, z_min_r, -0.5],
- [seperator_distance, aux_column_width, -0.5],
- [0.5, aux_column_width, -0.5],
- [aux_column_width, seperator_distance, -0.5],
- [seperator_distance, seperator_distance, -0.5],
- [0.5, seperator_distance, -0.5],
- [aux_column_width, 0.5, -0.5],
- [seperator_distance, 0.5, -0.5],
- [0.5, 0.5, -0.5],
- [aux_z_min, aux_z_min, -hd_center],
- [hd_center, aux_column_width, -hd_center],
- [0.5, aux_column_width, -seperator_distance],
- [aux_column_width, hd_center, -hd_center],
- [hd_center, hd_center, -hd_center],
- [0.5, seperator_distance, -seperator_distance],
- [aux_column_width, 0.5, -seperator_distance],
- [seperator_distance, 0.5, -seperator_distance],
- [0.5, 0.5, -seperator_distance],
- [center_r, center_r, -center_r],
- [hd_center, aux_x_max, -aux_x_max],
- [0.5, x_max_r, -x_max_r],
- [aux_y_max, hd_center, -aux_y_max],
- [hd_center, hd_center, -aux_column_width],
- [0.5, seperator_distance, -aux_column_width],
- [y_max_r, 0.5, -y_max_r],
- [seperator_distance, 0.5, -aux_column_width],
- [0.5, 0.5, -aux_column_width],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_max_y_max_z_min)
- )
+ x_min_y_min_z_min = (
+ _np.array(
+ [
+ [-v_one_half, -v_one_half, -v_one_half],
+ [-sep_distance, -v_one_half, -v_one_half],
+ [-aux_column_width, -v_one_half, -v_one_half],
+ [-v_one_half, -sep_distance, -v_one_half],
+ [
+ -sep_distance,
+ -sep_distance,
+ -v_one_half,
+ ],
+ [-aux_column_width, -sep_distance, -v_one_half],
+ [-v_one_half, -aux_column_width, -v_one_half],
+ [-sep_distance, -aux_column_width, -v_one_half],
+ [-z_min_r, -z_min_r, -v_one_half],
+ [-v_one_half, -v_one_half, -sep_distance],
+ [
+ -sep_distance,
+ -v_one_half,
+ -sep_distance,
+ ],
+ [-aux_column_width, -v_one_half, -sep_distance],
+ [
+ -v_one_half,
+ -sep_distance,
+ -sep_distance,
+ ],
+ [-hd_center, -hd_center, -hd_center],
+ [-aux_column_width, -hd_center, -hd_center],
+ [-v_one_half, -aux_column_width, -sep_distance],
+ [-hd_center, -aux_column_width, -hd_center],
+ [-aux_z_min, -aux_z_min, -hd_center],
+ [-v_one_half, -v_one_half, -aux_column_width],
+ [-sep_distance, -v_one_half, -aux_column_width],
+ [-y_min_r, -v_one_half, -y_min_r],
+ [-v_one_half, -sep_distance, -aux_column_width],
+ [-hd_center, -hd_center, -aux_column_width],
+ [-aux_y_min, -hd_center, -aux_y_min],
+ [-v_one_half, -x_min_r, -x_min_r],
+ [-hd_center, -aux_x_min, -aux_x_min],
+ [-center_r, -center_r, -center_r],
+ ]
+ )
+ + center_point
+ )
- x_min_y_min_z_max = _np.array(
- [
- [-0.5, -0.5, aux_column_width],
- [-seperator_distance, -0.5, aux_column_width],
- [-y_min_r, -0.5, y_min_r],
- [-0.5, -seperator_distance, aux_column_width],
- [-hd_center, -hd_center, aux_column_width],
- [-aux_y_min, -hd_center, aux_y_min],
- [-0.5, -x_min_r, x_min_r],
- [-hd_center, -aux_x_min, aux_x_min],
- [-center_r, -center_r, center_r],
- [-0.5, -0.5, seperator_distance],
- [-seperator_distance, -0.5, seperator_distance],
- [-aux_column_width, -0.5, seperator_distance],
- [-0.5, -seperator_distance, seperator_distance],
- [-hd_center, -hd_center, hd_center],
- [-aux_column_width, -hd_center, hd_center],
- [-0.5, -aux_column_width, seperator_distance],
- [-hd_center, -aux_column_width, hd_center],
- [-aux_z_max, -aux_z_max, hd_center],
- [-0.5, -0.5, 0.5],
- [-seperator_distance, -0.5, 0.5],
- [-aux_column_width, -0.5, 0.5],
- [-0.5, -seperator_distance, 0.5],
- [-seperator_distance, -seperator_distance, 0.5],
- [-aux_column_width, -seperator_distance, 0.5],
- [-0.5, -aux_column_width, 0.5],
- [-seperator_distance, -aux_column_width, 0.5],
- [-z_max_r, -z_max_r, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_min_y_min_z_max)
- )
+ x_max_y_min_z_min = (
+ _np.array(
+ [
+ [aux_column_width, -v_one_half, -v_one_half],
+ [sep_distance, -v_one_half, -v_one_half],
+ [v_one_half, -v_one_half, -v_one_half],
+ [aux_column_width, -sep_distance, -v_one_half],
+ [sep_distance, -sep_distance, -v_one_half],
+ [v_one_half, -sep_distance, -v_one_half],
+ [z_min_r, -z_min_r, -v_one_half],
+ [sep_distance, -aux_column_width, -v_one_half],
+ [v_one_half, -aux_column_width, -v_one_half],
+ [aux_column_width, -v_one_half, -sep_distance],
+ [sep_distance, -v_one_half, -sep_distance],
+ [v_one_half, -v_one_half, -sep_distance],
+ [aux_column_width, -hd_center, -hd_center],
+ [hd_center, -hd_center, -hd_center],
+ [v_one_half, -sep_distance, -sep_distance],
+ [aux_z_min, -aux_z_min, -hd_center],
+ [hd_center, -aux_column_width, -hd_center],
+ [v_one_half, -aux_column_width, -sep_distance],
+ [y_min_r, -v_one_half, -y_min_r],
+ [sep_distance, -v_one_half, -aux_column_width],
+ [v_one_half, -v_one_half, -aux_column_width],
+ [aux_y_min, -hd_center, -aux_y_min],
+ [hd_center, -hd_center, -aux_column_width],
+ [v_one_half, -sep_distance, -aux_column_width],
+ [center_r, -center_r, -center_r],
+ [hd_center, -aux_x_max, -aux_x_max],
+ [v_one_half, -x_max_r, -x_max_r],
+ ]
+ )
+ + center_point
+ )
- x_max_y_min_z_max = _np.array(
- [
- [y_min_r, -0.5, y_min_r],
- [seperator_distance, -0.5, aux_column_width],
- [0.5, -0.5, aux_column_width],
- [aux_y_min, -hd_center, aux_y_min],
- [hd_center, -hd_center, aux_column_width],
- [0.5, -seperator_distance, aux_column_width],
- [center_r, -center_r, center_r],
- [hd_center, -aux_x_max, aux_x_max],
- [0.5, -x_max_r, x_max_r],
- [aux_column_width, -0.5, seperator_distance],
- [seperator_distance, -0.5, seperator_distance],
- [0.5, -0.5, seperator_distance],
- [aux_column_width, -hd_center, hd_center],
- [hd_center, -hd_center, hd_center],
- [0.5, -seperator_distance, seperator_distance],
- [aux_z_max, -aux_z_max, hd_center],
- [hd_center, -aux_column_width, hd_center],
- [0.5, -aux_column_width, seperator_distance],
- [aux_column_width, -0.5, 0.5],
- [seperator_distance, -0.5, 0.5],
- [0.5, -0.5, 0.5],
- [aux_column_width, -seperator_distance, 0.5],
- [seperator_distance, -seperator_distance, 0.5],
- [0.5, -seperator_distance, 0.5],
- [z_max_r, -z_max_r, 0.5],
- [seperator_distance, -aux_column_width, 0.5],
- [0.5, -aux_column_width, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_max_y_min_z_max)
- )
+ x_min_y_max_z_min = (
+ _np.array(
+ [
+ [-v_one_half, aux_column_width, -v_one_half],
+ [-sep_distance, aux_column_width, -v_one_half],
+ [-z_min_r, z_min_r, -v_one_half],
+ [-v_one_half, sep_distance, -v_one_half],
+ [-sep_distance, sep_distance, -v_one_half],
+ [-aux_column_width, sep_distance, -v_one_half],
+ [-v_one_half, v_one_half, -v_one_half],
+ [-sep_distance, v_one_half, -v_one_half],
+ [-aux_column_width, v_one_half, -v_one_half],
+ [-v_one_half, aux_column_width, -sep_distance],
+ [-hd_center, aux_column_width, -hd_center],
+ [-aux_z_min, aux_z_min, -hd_center],
+ [-v_one_half, sep_distance, -sep_distance],
+ [-hd_center, hd_center, -hd_center],
+ [-aux_column_width, hd_center, -hd_center],
+ [-v_one_half, v_one_half, -sep_distance],
+ [-sep_distance, v_one_half, -sep_distance],
+ [-aux_column_width, v_one_half, -sep_distance],
+ [-v_one_half, x_min_r, -x_min_r],
+ [-hd_center, aux_x_min, -aux_x_min],
+ [-center_r, center_r, -center_r],
+ [-v_one_half, sep_distance, -aux_column_width],
+ [-hd_center, hd_center, -aux_column_width],
+ [-aux_y_max, hd_center, -aux_y_max],
+ [-v_one_half, v_one_half, -aux_column_width],
+ [-sep_distance, v_one_half, -aux_column_width],
+ [-y_max_r, v_one_half, -y_max_r],
+ ]
+ )
+ + center_point
+ )
- x_min_y_max_z_max = _np.array(
- [
- [-0.5, x_min_r, x_min_r],
- [-hd_center, aux_x_min, aux_x_min],
- [-center_r, center_r, center_r],
- [-0.5, seperator_distance, aux_column_width],
- [-hd_center, hd_center, aux_column_width],
- [-aux_y_max, hd_center, aux_y_max],
- [-0.5, 0.5, aux_column_width],
- [-seperator_distance, 0.5, aux_column_width],
- [-y_max_r, 0.5, y_max_r],
- [-0.5, aux_column_width, seperator_distance],
- [-hd_center, aux_column_width, hd_center],
- [-aux_z_max, aux_z_max, hd_center],
- [-0.5, seperator_distance, seperator_distance],
- [-hd_center, hd_center, hd_center],
- [-aux_column_width, hd_center, hd_center],
- [-0.5, 0.5, seperator_distance],
- [-seperator_distance, 0.5, seperator_distance],
- [-aux_column_width, 0.5, seperator_distance],
- [-0.5, aux_column_width, 0.5],
- [-seperator_distance, aux_column_width, 0.5],
- [-z_max_r, z_max_r, 0.5],
- [-0.5, seperator_distance, 0.5],
- [-seperator_distance, seperator_distance, 0.5],
- [-aux_column_width, seperator_distance, 0.5],
- [-0.5, 0.5, 0.5],
- [-seperator_distance, 0.5, 0.5],
- [-aux_column_width, 0.5, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_min_y_max_z_max)
- )
+ x_max_y_max_z_min = (
+ _np.array(
+ [
+ [z_min_r, z_min_r, -v_one_half],
+ [sep_distance, aux_column_width, -v_one_half],
+ [v_one_half, aux_column_width, -v_one_half],
+ [aux_column_width, sep_distance, -v_one_half],
+ [sep_distance, sep_distance, -v_one_half],
+ [v_one_half, sep_distance, -v_one_half],
+ [aux_column_width, v_one_half, -v_one_half],
+ [sep_distance, v_one_half, -v_one_half],
+ [v_one_half, v_one_half, -v_one_half],
+ [aux_z_min, aux_z_min, -hd_center],
+ [hd_center, aux_column_width, -hd_center],
+ [v_one_half, aux_column_width, -sep_distance],
+ [aux_column_width, hd_center, -hd_center],
+ [hd_center, hd_center, -hd_center],
+ [v_one_half, sep_distance, -sep_distance],
+ [aux_column_width, v_one_half, -sep_distance],
+ [sep_distance, v_one_half, -sep_distance],
+ [v_one_half, v_one_half, -sep_distance],
+ [center_r, center_r, -center_r],
+ [hd_center, aux_x_max, -aux_x_max],
+ [v_one_half, x_max_r, -x_max_r],
+ [aux_y_max, hd_center, -aux_y_max],
+ [hd_center, hd_center, -aux_column_width],
+ [v_one_half, sep_distance, -aux_column_width],
+ [y_max_r, v_one_half, -y_max_r],
+ [sep_distance, v_one_half, -aux_column_width],
+ [v_one_half, v_one_half, -aux_column_width],
+ ]
+ )
+ + center_point
+ )
- x_max_y_max_z_max = _np.array(
- [
- [center_r, center_r, center_r],
- [hd_center, aux_x_max, aux_x_max],
- [0.5, x_max_r, x_max_r],
- [aux_y_max, hd_center, aux_y_max],
- [hd_center, hd_center, aux_column_width],
- [0.5, seperator_distance, aux_column_width],
- [y_max_r, 0.5, y_max_r],
- [seperator_distance, 0.5, aux_column_width],
- [0.5, 0.5, aux_column_width],
- [aux_z_max, aux_z_max, hd_center],
- [hd_center, aux_column_width, hd_center],
- [0.5, aux_column_width, seperator_distance],
- [aux_column_width, hd_center, hd_center],
- [hd_center, hd_center, hd_center],
- [0.5, seperator_distance, seperator_distance],
- [aux_column_width, 0.5, seperator_distance],
- [seperator_distance, 0.5, seperator_distance],
- [0.5, 0.5, seperator_distance],
- [z_max_r, z_max_r, 0.5],
- [seperator_distance, aux_column_width, 0.5],
- [0.5, aux_column_width, 0.5],
- [aux_column_width, seperator_distance, 0.5],
- [seperator_distance, seperator_distance, 0.5],
- [0.5, seperator_distance, 0.5],
- [aux_column_width, 0.5, 0.5],
- [seperator_distance, 0.5, 0.5],
- [0.5, 0.5, 0.5],
- ]
- ) + _np.array([0.5, 0.5, 0.5])
-
- spline_list.append(
- _Bezier(degrees=[2, 2, 2], control_points=x_max_y_max_z_max)
- )
- return (spline_list, None)
+ x_min_y_min_z_max = (
+ _np.array(
+ [
+ [-v_one_half, -v_one_half, aux_column_width],
+ [-sep_distance, -v_one_half, aux_column_width],
+ [-y_min_r, -v_one_half, y_min_r],
+ [-v_one_half, -sep_distance, aux_column_width],
+ [-hd_center, -hd_center, aux_column_width],
+ [-aux_y_min, -hd_center, aux_y_min],
+ [-v_one_half, -x_min_r, x_min_r],
+ [-hd_center, -aux_x_min, aux_x_min],
+ [-center_r, -center_r, center_r],
+ [-v_one_half, -v_one_half, sep_distance],
+ [-sep_distance, -v_one_half, sep_distance],
+ [-aux_column_width, -v_one_half, sep_distance],
+ [-v_one_half, -sep_distance, sep_distance],
+ [-hd_center, -hd_center, hd_center],
+ [-aux_column_width, -hd_center, hd_center],
+ [-v_one_half, -aux_column_width, sep_distance],
+ [-hd_center, -aux_column_width, hd_center],
+ [-aux_z_max, -aux_z_max, hd_center],
+ [-v_one_half, -v_one_half, v_one_half],
+ [-sep_distance, -v_one_half, v_one_half],
+ [-aux_column_width, -v_one_half, v_one_half],
+ [-v_one_half, -sep_distance, v_one_half],
+ [-sep_distance, -sep_distance, v_one_half],
+ [-aux_column_width, -sep_distance, v_one_half],
+ [-v_one_half, -aux_column_width, v_one_half],
+ [-sep_distance, -aux_column_width, v_one_half],
+ [-z_max_r, -z_max_r, v_one_half],
+ ]
+ )
+ + center_point
+ )
+
+ x_max_y_min_z_max = (
+ _np.array(
+ [
+ [y_min_r, -v_one_half, y_min_r],
+ [sep_distance, -v_one_half, aux_column_width],
+ [v_one_half, -v_one_half, aux_column_width],
+ [aux_y_min, -hd_center, aux_y_min],
+ [hd_center, -hd_center, aux_column_width],
+ [v_one_half, -sep_distance, aux_column_width],
+ [center_r, -center_r, center_r],
+ [hd_center, -aux_x_max, aux_x_max],
+ [v_one_half, -x_max_r, x_max_r],
+ [aux_column_width, -v_one_half, sep_distance],
+ [sep_distance, -v_one_half, sep_distance],
+ [v_one_half, -v_one_half, sep_distance],
+ [aux_column_width, -hd_center, hd_center],
+ [hd_center, -hd_center, hd_center],
+ [v_one_half, -sep_distance, sep_distance],
+ [aux_z_max, -aux_z_max, hd_center],
+ [hd_center, -aux_column_width, hd_center],
+ [v_one_half, -aux_column_width, sep_distance],
+ [aux_column_width, -v_one_half, v_one_half],
+ [sep_distance, -v_one_half, v_one_half],
+ [v_one_half, -v_one_half, v_one_half],
+ [aux_column_width, -sep_distance, v_one_half],
+ [sep_distance, -sep_distance, v_one_half],
+ [v_one_half, -sep_distance, v_one_half],
+ [z_max_r, -z_max_r, v_one_half],
+ [sep_distance, -aux_column_width, v_one_half],
+ [v_one_half, -aux_column_width, v_one_half],
+ ]
+ )
+ + center_point
+ )
+
+ x_min_y_max_z_max = (
+ _np.array(
+ [
+ [-v_one_half, x_min_r, x_min_r],
+ [-hd_center, aux_x_min, aux_x_min],
+ [-center_r, center_r, center_r],
+ [-v_one_half, sep_distance, aux_column_width],
+ [-hd_center, hd_center, aux_column_width],
+ [-aux_y_max, hd_center, aux_y_max],
+ [-v_one_half, v_one_half, aux_column_width],
+ [-sep_distance, v_one_half, aux_column_width],
+ [-y_max_r, v_one_half, y_max_r],
+ [-v_one_half, aux_column_width, sep_distance],
+ [-hd_center, aux_column_width, hd_center],
+ [-aux_z_max, aux_z_max, hd_center],
+ [-v_one_half, sep_distance, sep_distance],
+ [-hd_center, hd_center, hd_center],
+ [-aux_column_width, hd_center, hd_center],
+ [-v_one_half, v_one_half, sep_distance],
+ [-sep_distance, v_one_half, sep_distance],
+ [-aux_column_width, v_one_half, sep_distance],
+ [-v_one_half, aux_column_width, v_one_half],
+ [-sep_distance, aux_column_width, v_one_half],
+ [-z_max_r, z_max_r, v_one_half],
+ [-v_one_half, sep_distance, v_one_half],
+ [-sep_distance, sep_distance, v_one_half],
+ [-aux_column_width, sep_distance, v_one_half],
+ [-v_one_half, v_one_half, v_one_half],
+ [-sep_distance, v_one_half, v_one_half],
+ [-aux_column_width, v_one_half, v_one_half],
+ ]
+ )
+ + center_point
+ )
+
+ x_max_y_max_z_max = (
+ _np.array(
+ [
+ [center_r, center_r, center_r],
+ [hd_center, aux_x_max, aux_x_max],
+ [v_one_half, x_max_r, x_max_r],
+ [aux_y_max, hd_center, aux_y_max],
+ [hd_center, hd_center, aux_column_width],
+ [v_one_half, sep_distance, aux_column_width],
+ [y_max_r, v_one_half, y_max_r],
+ [sep_distance, v_one_half, aux_column_width],
+ [v_one_half, v_one_half, aux_column_width],
+ [aux_z_max, aux_z_max, hd_center],
+ [hd_center, aux_column_width, hd_center],
+ [v_one_half, aux_column_width, sep_distance],
+ [aux_column_width, hd_center, hd_center],
+ [hd_center, hd_center, hd_center],
+ [v_one_half, sep_distance, sep_distance],
+ [aux_column_width, v_one_half, sep_distance],
+ [sep_distance, v_one_half, sep_distance],
+ [v_one_half, v_one_half, sep_distance],
+ [z_max_r, z_max_r, v_one_half],
+ [sep_distance, aux_column_width, v_one_half],
+ [v_one_half, aux_column_width, v_one_half],
+ [aux_column_width, sep_distance, v_one_half],
+ [sep_distance, sep_distance, v_one_half],
+ [v_one_half, sep_distance, v_one_half],
+ [aux_column_width, v_one_half, v_one_half],
+ [sep_distance, v_one_half, v_one_half],
+ [v_one_half, v_one_half, v_one_half],
+ ]
+ )
+ + center_point
+ )
+
+ # Append the control points to the spline list
+ for control_points, degrees in [
+ (x_min_y_min, [2, 2, 1]),
+ (x_max_y_min, [2, 2, 1]),
+ (x_min_y_max, [2, 2, 1]),
+ (x_max_y_max, [2, 2, 1]),
+ (x_min_z_min, [2, 1, 2]),
+ (x_max_z_min, [2, 1, 2]),
+ (x_min_z_max, [2, 1, 2]),
+ (x_max_z_max, [2, 1, 2]),
+ (y_min_z_min, [1, 2, 2]),
+ (y_max_z_min, [1, 2, 2]),
+ (y_min_z_max, [1, 2, 2]),
+ (y_max_z_max, [1, 2, 2]),
+ (x_min_y_min_z_min, [2, 2, 2]),
+ (x_max_y_min_z_min, [2, 2, 2]),
+ (x_min_y_max_z_min, [2, 2, 2]),
+ (x_max_y_max_z_min, [2, 2, 2]),
+ (x_min_y_min_z_max, [2, 2, 2]),
+ (x_max_y_min_z_max, [2, 2, 2]),
+ (x_min_y_max_z_max, [2, 2, 2]),
+ (x_max_y_max_z_max, [2, 2, 2]),
+ ]:
+ spline_list.append(
+ _Bezier(degrees=degrees, control_points=control_points)
+ )
+
+ if i_derivative == 0:
+ splines = spline_list.copy()
+ else:
+ derivatives.append(spline_list)
+ return (splines, derivatives)
diff --git a/splinepy/microstructure/tiles/snappy.py b/splinepy/microstructure/tiles/snappy.py
index dac00bd20..24a910e0d 100644
--- a/splinepy/microstructure/tiles/snappy.py
+++ b/splinepy/microstructure/tiles/snappy.py
@@ -8,6 +8,9 @@ class Snappy(_TileBase):
"""Snap-through tile consisting of a thin truss and a thick truss that
collide into each other.
+ # TODO: currently the tile parameters are not implemented as the parameters variable
+ therefore, no parameter sensitivities are calculated
+
.. raw:: html
Fullscreen.
@@ -20,10 +23,16 @@ class Snappy(_TileBase):
# dummy values - not used
_evaluation_points = _np.array([[0.5, 0.5]])
_n_info_per_eval_point = 1
+ _sensitivities_implemented = False
+ _closure_directions = ["y_min", "y_max"]
+ _parameter_bounds = []
+ _parameters_shape = ()
+
+ _CONTACT_LENGTH_BOUNDS = [0.0, 0.5]
def _closing_tile(
self,
- parameters=None,
+ parameters=None, # noqa: ARG002
parameter_sensitivities=None, # TODO
closure=None,
contact_length=0.1,
@@ -61,8 +70,6 @@ def _closing_tile(
if closure is None:
raise ValueError("No closing direction given")
- self.check_params(parameters)
-
if parameter_sensitivities is not None:
raise NotImplementedError(
"Derivatives are not implemented for this tile yet"
@@ -220,7 +227,6 @@ def _closing_tile(
spline_list.append(
_Bezier(degrees=[3, 1], control_points=spline_10)
)
- return spline_list
elif closure == "y_max":
spline_1 = _np.array(
[
@@ -286,12 +292,13 @@ def _closing_tile(
spline_list.append(
_Bezier(degrees=[3, 1], control_points=spline_5)
)
- return (spline_list, None)
else:
- raise ValueError(
+ raise NotImplementedError(
"Closing tile is only implemented for y-enclosure"
)
+ return (spline_list, None)
+
def create_tile(
self,
parameters=None,
@@ -339,13 +346,16 @@ def create_tile(
"""
for param in [a, b, c, r, contact_length]:
- if not isinstance(param, float):
- raise ValueError(f"Invalid Type, {param} is not float")
+ if not isinstance(param, (int, float)):
+ raise TypeError(
+ f"Invalid Type, {param} is neither int nor float"
+ )
if param < 0:
raise ValueError("Invalid parameter, must be > 0.")
- if not ((contact_length > 0) and (contact_length < 0.49)):
- raise ValueError("The length of a side must be in (0.01, 0.49)")
+ self._check_custom_parameter(
+ contact_length, "contact length", self._CONTACT_LENGTH_BOUNDS
+ )
# Check horizontal parameters
if not ((r + contact_length) < 0.5):
@@ -362,7 +372,7 @@ def create_tile(
if parameters is not None:
raise NotImplementedError(
- "Parametriazation is not implemented for this tile yet"
+ "Parametrization is not implemented for this tile yet"
)
if parameter_sensitivities is not None:
diff --git a/splinepy/microstructure/tiles/tile_base.py b/splinepy/microstructure/tiles/tile_base.py
index 0c4a64100..80df767a0 100644
--- a/splinepy/microstructure/tiles/tile_base.py
+++ b/splinepy/microstructure/tiles/tile_base.py
@@ -6,12 +6,39 @@
class TileBase(_SplinepyBase):
"""
Base class for tile objects
+
+ Attributes
+ ---------------
+ _dim: int
+ Dimension in physical space
+ _para_dim: int
+ Dimension in parametric space
+ _evaluation_points: np.ndarray (2D)
+ Points in parametric space where tile parameters are evaluated. Each parameter
+ is attributed one evaluation point. This is used for the parametrization spline.
+ _n_info_per_eval_point: int
+ Number of tile parameters per evaluation point
+ _sensitivities_implemented: bool
+ Whether sensitivities w.r.t. tile parameters are implemented
+ _closure_directions: list
+ List of directions in which the closure has been implemented
+ _parameter_bounds: list>
+ List of bounds for the tile parameters
+ _parameters_shape: tuple
+ Shape of parameters array
+ _default_parameter_value: float/np.ndarray
+ Default values for all tile parameters
"""
_dim = None
_para_dim = None
_evaluation_points = None
_n_info_per_eval_point = None
+ _sensitivities_implemented = None
+ _closure_directions = None
+ _parameter_bounds = None
+ _parameters_shape = None
+ _default_parameter_value = None
def __init__(self):
if type(self) is TileBase:
@@ -25,8 +52,7 @@ def _raise_if_not_set_else_return(cls, attr_name):
attr = getattr(cls, attr_name, None)
if attr is None and cls is not TileBase:
raise NotImplementedError(
- f"Inherited Tile-types need to provide {attr_name}, see "
- "documentation."
+ f"Inherited Tile-types need to provide {attr_name}, see documentation."
)
return attr
@@ -46,7 +72,21 @@ def evaluation_points(self):
return self._raise_if_not_set_else_return("_evaluation_points")
@property
- def dim(self):
+ def n_info_per_eval_point(cls):
+ """Number of parameters per evaluation point
+
+ Parameters
+ ----------
+ None
+
+ Returns
+ -------
+ n_info : int
+ """
+ return cls._raise_if_not_set_else_return("_n_info_per_eval_point")
+
+ @property
+ def dim(cls):
"""Returns dimensionality in physical space of the Microtile.
Parameters
@@ -57,7 +97,7 @@ def dim(self):
-------
dim : int
"""
- return self._raise_if_not_set_else_return("_dim")
+ return cls._raise_if_not_set_else_return("_dim")
@property
def para_dim(self):
@@ -73,8 +113,82 @@ def para_dim(self):
"""
return self._raise_if_not_set_else_return("_para_dim")
- def check_params(self, params):
- """Checks if the parameters have the correct format and shape
+ @property
+ def sensitivities_implemented(cls):
+ """Returns whether sensitivities are implemented for the microtile
+
+ Parameters
+ ----------
+ None
+
+ Returns
+ -------
+ is_implemented: bool
+ """
+ return cls._raise_if_not_set_else_return("_sensitivities_implemented")
+
+ @property
+ def closure_directions(cls):
+ """Returns the available closure directions of the microtile
+
+ Parameters
+ ----------
+ None
+
+ Returns
+ -------
+ directions: None/list
+ """
+ return cls._closure_directions
+
+ @property
+ def parameter_bounds(self):
+ """Returns the bounds for the microtiles' parameters.
+
+ Depending on the tile, parameter bounds can dynamically change (e.g. Cross2D).
+ Therefore, it is instance-dependent and self instead of cls is used.
+
+ Parameters
+ ----------
+ None
+
+ Returns
+ -------
+ bounds: list>
+ """
+ return self._raise_if_not_set_else_return("_parameter_bounds")
+
+ @property
+ def parameters_shape(cls):
+ """Returns the shape of the microtile's parameters array
+
+ Parameters
+ ----------
+ None
+
+ Returns
+ -------
+ shape: tuple
+ """
+ return cls._raise_if_not_set_else_return("_parameters_shape")
+
+ @property
+ def default_parameter_value(cls):
+ """Returns the default value of the microtile's parameters
+
+ Parameters
+ ----------
+ None
+
+ Returns
+ -------
+ default_value: float/None
+ """
+ return cls._default_parameter_value
+
+ def check_params(self, parameters):
+ """Checks if the parameters have the correct format and shape and are within
+ defined bounds
Parameters
----------
@@ -85,14 +199,14 @@ def check_params(self, params):
-------
True: Boolean
"""
- # check if tuple
-
- if not (isinstance(params, _np.ndarray) and params.ndim == 2):
+ # Check correct format
+ if not (isinstance(parameters, _np.ndarray) and parameters.ndim == 2):
raise TypeError("parameters must be two-dimensional np array")
+ # Check correct shape
if not (
- (self._evaluation_points.shape[0] == params.shape[0])
- and (self._n_info_per_eval_point == params.shape[1])
+ (self._evaluation_points.shape[0] == parameters.shape[0])
+ and (self._n_info_per_eval_point == parameters.shape[1])
):
raise TypeError(
f"Mismatch in parameter size, expected "
@@ -100,6 +214,21 @@ def check_params(self, params):
f"{self._n_info_per_eval_point}"
)
+ # Check if all parameters are within bounds
+ if self._parameter_bounds is not None:
+ bounds = _np.array(self._parameter_bounds)
+ lower_bounds = bounds[:, 0]
+ upper_bounds = bounds[:, 1]
+ within_bounds = (parameters.ravel() > lower_bounds) & (
+ parameters.ravel() < upper_bounds
+ )
+ if not _np.all(within_bounds):
+ out_of_bounds = parameters[~within_bounds.reshape(parameters.shape)]
+ raise ValueError(
+ f"The following parameters are out of bounds: {out_of_bounds}. "
+ f"Expected bounds: lower: {lower_bounds} and upper: {upper_bounds}"
+ )
+
return True
def check_param_derivatives(self, derivatives):
@@ -117,9 +246,7 @@ def check_param_derivatives(self, derivatives):
if derivatives is None:
return False
- if not (
- isinstance(derivatives, _np.ndarray) and derivatives.ndim == 3
- ):
+ if not (isinstance(derivatives, _np.ndarray) and derivatives.ndim == 3):
raise TypeError("parameters must be three-dimensional np array")
if not (
@@ -150,6 +277,74 @@ def create_tile(self, **kwargs):
List of list of splines that represents parameter sensitivities.
If it is not implemented, returns None.
"""
- raise NotImplementedError(
- f"create_tile() not implemented for {type(self)}"
- )
+ raise NotImplementedError(f"create_tile() not implemented for {type(self)}")
+
+ def _process_input(self, parameters, parameter_sensitivities):
+ """Processing input for create_tile and _closing_tile
+
+ Parameters
+ -------------
+ parameters: np.ndarray
+ Tile parameters
+ parameter_sensitivities: np.ndarray
+ Tile parameter sensitivities to be calculated
+
+ Returns
+ ---------
+ parameters: np.ndarray
+ Tile parameters
+ n_derivatives: np.ndarray
+ Number of different derivatives to compute
+ derivatives: list/None
+ Initialized list of derivatives
+ """
+ # Set parameters to default values if not user-given
+ if parameters is None:
+ default_value = self.default_parameter_value
+ self._logd(f"Setting parameters to default values ({default_value})")
+ if isinstance(default_value, float):
+ parameters = _np.full(
+ (len(self.evaluation_points), self.n_info_per_eval_point),
+ default_value,
+ )
+ elif isinstance(default_value, _np.ndarray):
+ parameters = default_value
+
+ # Validity check of parameters and their sensitivities
+ self.check_params(parameters)
+ self.check_param_derivatives(parameter_sensitivities)
+
+ # Initialize list of derivatives
+ if parameter_sensitivities is not None:
+ n_derivatives = parameter_sensitivities.shape[2]
+ derivatives = []
+ else:
+ n_derivatives = 0
+ derivatives = None
+
+ return parameters, n_derivatives, derivatives
+
+ def _check_custom_parameter(self, value, param_name, bounds):
+ """Check if a custom tile parameter (e.g. contact length) is within bounds
+
+ Parameters
+ ------------------
+ value: float
+ Value of the custom parameter
+ param_name: str
+ Name of custom parameter
+ bounds: list
+ List of min. and max. bound
+ """
+
+ if not isinstance(bounds, list):
+ raise TypeError("bounds has to be a list")
+ if len(bounds) != 2:
+ raise ValueError("Bounds must consist of a min. and a max. value")
+ min_bound, max_bound = bounds
+
+ if not isinstance(value, (int, float)):
+ raise ValueError(f"Invalid type for {param_name}")
+
+ if not ((value > min_bound) and (value < max_bound)):
+ raise ValueError(f"{param_name} must be in ({min_bound}, {max_bound})")
diff --git a/splinepy/utils/data.py b/splinepy/utils/data.py
index 4c66e716d..00105c796 100644
--- a/splinepy/utils/data.py
+++ b/splinepy/utils/data.py
@@ -468,7 +468,7 @@ def uniform_query(bounds, resolutions):
# create per-dimension queries
queries_per_dim = []
- for lb, ub, r in zip(lower_b, upper_b, resolutions):
+ for lb, ub, r in zip(lower_b, upper_b, resolutions, strict=True):
queries_per_dim.append(_np.linspace(lb, ub, r))
return cartesian_product(queries_per_dim, reverse=True)
@@ -573,8 +573,7 @@ def __init__(
# can call sample or has a function?
if not self.has_function and not self.is_spline:
raise ValueError(
- "None spline data should at least have an accompanying "
- "function."
+ "None spline data should at least have an accompanying function."
)
def as_vertex_data(self, resolutions=None, on=None):
@@ -595,8 +594,7 @@ def as_vertex_data(self, resolutions=None, on=None):
if self.has_locations and (resolutions is not None or on is not None):
raise ValueError(
- "Location dependent data can't be evaluated with `resolutions`"
- " or `at`."
+ "Location dependent data can't be evaluated with `resolutions` or `at`."
)
# if resolutions is specified, this is not a location query
diff --git a/tests/conftest.py b/tests/conftest.py
index 5043ef971..c1068c716 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -15,7 +15,7 @@ def error_log(*args):
@pytest.fixture
def np_rng():
- return np.random.default_rng()
+ return np.random.default_rng(seed=0)
# query points
@@ -41,6 +41,52 @@ def queries_3D():
]
+# hard-coded values to keep the same for derivative/sensitivity calculations
+@pytest.fixture
+def h_eps():
+ """
+ Perturbation/step size for finite difference evaluation of derivative/sensitivity.
+
+ The value 1e-5 is arbitrary, but is a compromise between:
+ - Being small enough to ensure the finite difference calculation being accurate
+ - Being large enough to avoid round-off error in floating-point arithmetic
+ """
+ return 1e-5
+
+
+@pytest.fixture
+def n_test_points():
+ """
+ Number of random testing points (in parametric domain)
+
+ The number 10 is arbitrary and should ensure to have good test coverage. Increasing
+ this number could yield more thorough tests at the cost of longer runtime.
+ """
+ return 10
+
+
+@pytest.fixture
+def big_perturbation():
+ """Value for perturbation of parameters value
+
+ The number 0.1 is chosen arbitrarily. This value is for testing out of bounds
+ parameter values. It is designed to add to the maximum or subtract from the
+ minimum bound to deliberately make the values out of the bounds."""
+ return 0.1
+
+
+@pytest.fixture
+def fd_derivative_stepsizes_and_weights():
+ """Stepsizes and weights for the calculation of the derivative using finite
+ differences. Using fourth-order accurate centered scheme.
+
+ Returns
+ -------
+ stepsizes_and_weights, denominator: dict
+ """
+ return {-2: 1 / 12, -1: -8 / 12, 1: 8 / 12, 2: -1 / 12}
+
+
# initializing a spline should be a test itself, so provide `dict_spline`
# this is "iga-book"'s fig 2.15.
@pytest.fixture
@@ -222,7 +268,9 @@ def _raster(bounds, resolutions):
pts = np.meshgrid(
*[
np.linspace(lo, up, re)
- for lo, up, re in zip(l_bounds, u_bounds, resolutions)
+ for lo, up, re in zip(
+ l_bounds, u_bounds, resolutions, strict=True
+ )
],
indexing="ij",
)
@@ -270,7 +318,7 @@ def _are_splines_equal(a, b, print_=False):
return False
for req_prop in a.required_properties:
if req_prop == "knot_vectors":
- for aa, bb in zip(a.knot_vectors, b.knot_vectors):
+ for aa, bb in zip(a.knot_vectors, b.knot_vectors, strict=True):
if not np.allclose(aa.numpy(), bb.numpy()):
if print_:
error_log("a.kvs", a.kvs)
@@ -292,7 +340,7 @@ def _are_items_close(a, b):
"""returns True if items in a and b are close"""
all_close = True
- for i, (aa, bb) in enumerate(zip(a, b)):
+ for i, (aa, bb) in enumerate(zip(a, b, strict=True)):
if not all(np.isclose(aa, bb)):
# print to inform
error_log(f"elements in index-{i} are not close")
@@ -312,7 +360,7 @@ def _are_items_same(a, b):
"""returns True if items in a and b are same"""
all_same = True
- for i, (aa, bb) in enumerate(zip(a, b)):
+ for i, (aa, bb) in enumerate(zip(a, b, strict=True)):
if aa != bb:
# print to inform
error_log(f"element in index-{i} are not same")
@@ -332,8 +380,7 @@ def _are_stripped_lines_same(a, b, ignore_order=False):
"""returns True if items in a and b same, preceding and tailing whitespaces
are ignored and strings are joined"""
all_same = True
-
- for i, (line_a, line_b) in enumerate(zip(a, b)):
+ for i, (line_a, line_b) in enumerate(zip(a, b, strict=True)):
# check stripped string
stripped_a, stripped_b = line_a.strip(), line_b.strip()
diff --git a/tests/data/mfem_cartesian_2d.mesh b/tests/data/mfem_cartesian_2d.mesh
index b70d4a28a..746ffe2b6 100644
--- a/tests/data/mfem_cartesian_2d.mesh
+++ b/tests/data/mfem_cartesian_2d.mesh
@@ -85,3 +85,4 @@ controlpoints_cartesian
2.0 0.0 1.0
1.0 1.0 1.0
2.0 1.0 1.0
+
diff --git a/tests/data/mfem_cartesian_3d.mesh b/tests/data/mfem_cartesian_3d.mesh
index 389d3928d..b6bc475cb 100644
--- a/tests/data/mfem_cartesian_3d.mesh
+++ b/tests/data/mfem_cartesian_3d.mesh
@@ -147,3 +147,4 @@ controlpoints_cartesian
2.0 0.0 1.0 1.0
1.0 1.0 1.0 1.0
2.0 1.0 1.0 1.0
+
diff --git a/tests/helpme/test_create.py b/tests/helpme/test_create.py
index 265f3c103..8ec877be2 100644
--- a/tests/helpme/test_create.py
+++ b/tests/helpme/test_create.py
@@ -1,5 +1,6 @@
import numpy as np
import pytest
+from gustaf.utils import arr
import splinepy
@@ -181,7 +182,7 @@ def check_parametric_view(spline, conform):
# same knot_vectors
if spline.has_knot_vectors:
- for p_kv, kv in zip(p_spl.kvs, spline.kvs):
+ for p_kv, kv in zip(p_spl.kvs, spline.kvs, strict=True):
assert np.allclose(p_kv, kv)
# same weights
@@ -193,7 +194,9 @@ def check_parametric_view(spline, conform):
assert not any(p_spl.ds - 1)
# same unique knots - implies same p_bounds
- for p_ukv, ukv in zip(p_spl.unique_knots, spline.unique_knots):
+ for p_ukv, ukv in zip(
+ p_spl.unique_knots, spline.unique_knots, strict=True
+ ):
assert np.allclose(p_ukv, ukv)
spl = request.getfixturevalue(splinetype)
@@ -343,3 +346,308 @@ def test_determinant_spline(
det_spl.evaluate(queries=rnd_queries).ravel(),
np.linalg.det(sp_i.jacobian(queries=rnd_queries)),
), f"{sp_i.whatami} at index {idx} failed determinant spline"
+
+
+### TESTS FOR SWEEPING ###
+
+
+# test the basic functionality of the swept-function
+def test_swept_basic_functionality():
+ cross_section = splinepy.NURBS(
+ degrees=[2, 1],
+ knot_vectors=[
+ [0, 0, 0, 1, 1, 1],
+ [0, 0, 1, 1],
+ ],
+ control_points=[
+ [-1.0, 0.0],
+ [-1.0, 1.0],
+ [0.0, 1.0],
+ [-2.0, 0.0],
+ [-2.0, 2.0],
+ [0.0, 2.0],
+ ],
+ weights=[
+ [1.0],
+ [2**-0.5],
+ [1.0],
+ [1.0],
+ [2**-0.5],
+ [1.0],
+ ],
+ )
+ trajectory = splinepy.BSpline(
+ degrees=[3],
+ control_points=[[0, 0], [1, 2], [2, 3], [3, 3]],
+ knot_vectors=[[0, 0, 0, 0, 1, 1, 1, 1]],
+ )
+
+ # create result --> 3D body should be created
+ result = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="parametric",
+ )
+
+ # test result's type
+ assert result is not None
+ assert result.is_rational
+
+ # test invalid input
+ invalid_trajectory = "invalid_trajectory"
+ with pytest.raises(TypeError):
+ splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=invalid_trajectory,
+ anchor="auto",
+ )
+
+ # test result's shape
+ assert (
+ result.control_points.shape[0]
+ == cross_section.control_points.shape[0]
+ * trajectory.control_points.shape[0]
+ )
+
+ # test if result is 3D
+ assert result.dim == 3
+
+ # test if result's degrees are correct
+ assert np.allclose(
+ result.degrees,
+ [
+ cross_section.degrees[0],
+ cross_section.degrees[1],
+ trajectory.degrees[0],
+ ],
+ )
+
+ # test if result's knot vectors are correct
+ assert np.allclose(
+ result.knot_vectors[0], cross_section.knot_vectors[0]
+ ), "Knot vector of first cross-section dimension does not match."
+ assert np.allclose(
+ result.knot_vectors[1], cross_section.knot_vectors[1]
+ ), "Knot vector of second cross-section dimension does not match."
+ assert np.allclose(
+ result.knot_vectors[2], trajectory.knot_vectors[0]
+ ), "Knot vector of trajectory does not match."
+
+
+# create linear swept surface and compare it to extruded surface
+def test_swept_to_extruded():
+
+ cross_section = splinepy.NURBS(
+ degrees=[2],
+ control_points=[[-0.5, -1 / 3], [0, 2 / 3], [0.5, -1 / 3]],
+ weights=[1, 0.5, 1],
+ knot_vectors=[[0, 0, 0, 1, 1, 1]],
+ )
+ trajectory = splinepy.NURBS(
+ degrees=[1],
+ control_points=[[0, 0, 0], [0, 0, 3]],
+ weights=[1, 1],
+ knot_vectors=[[0, 0, 1, 1]],
+ )
+
+ result = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="parametric",
+ rotation_adaption=np.pi / 2,
+ )
+ extruded_result = splinepy.helpme.create.extruded(cross_section, [0, 0, 3])
+ assert np.allclose(result.control_points, extruded_result.control_points)
+
+
+# check if cross-section's control points are always placed in the correct angle
+def test_swept_control_point_placing(np_rng):
+
+ cross_section = splinepy.BSpline(
+ degrees=[2],
+ control_points=[[0, 0], [0.5, 1], [1, 0]],
+ knot_vectors=[[0, 0, 0, 1, 1, 1]],
+ )
+
+ trajectory = splinepy.BSpline(
+ degrees=[3],
+ control_points=[[0, 0, 0], [1, 0, 1], [0, 0, 2], [0, 0, 3]],
+ knot_vectors=[[0, 0, 0, 0, 1, 1, 1, 1]],
+ )
+ result = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="parametric",
+ )
+
+ def calculate_cs_normal_vector(cs_cp, res_cp, rand):
+
+ # take the control points of the chosen cross-section
+ taken_cs_cp = res_cp[
+ rand * len(cs_cp) : rand * len(cs_cp) + len(cs_cp)
+ ]
+ P1 = taken_cs_cp[0]
+ P2 = taken_cs_cp[1]
+ P3 = taken_cs_cp[2]
+
+ # calculate normal vector of cross-section
+ v1 = P2 - P1
+ v2 = P3 - P1
+ return np.cross(v1, v2)
+
+ cs_cp = cross_section.control_points
+ res_cp = result.control_points
+
+ # choose id of cross-section to take from result
+ rand = np_rng.integers(0, len(res_cp) / len(cs_cp), 1)[0]
+
+ normal_vector = calculate_cs_normal_vector(cs_cp, res_cp, rand)
+
+ # evaluate trajectory parameter value at the position of the cross-section
+ rand_traj_pos = trajectory.greville_abscissae()[rand]
+ # calculate tangent vector of trajectory at the position of the cross-section
+ rand_traj_tangent = trajectory.derivative([rand_traj_pos], 1).ravel()
+
+ # check if normal vector is parallel to tangent vector
+ # --> then transformation of cross-section is correct
+ assert np.allclose(np.cross(rand_traj_tangent, normal_vector), 0)
+
+ ## TEST ALSO WITH CUSTOM NORMAL VECTOR ##
+
+ # make sure that the angle between trajectory's tangent and cross-section's
+ # normal vector is always the same
+ custom_normal = np.array([1, 0, 1])
+
+ angle_of_custom_cs_normal = np.arctan2(custom_normal[2], custom_normal[0])
+ # calculate rotation matrix for cross-section normal vector
+ R = arr.rotation_matrix_around_axis(
+ axis=[0, 1, 0], rotation=angle_of_custom_cs_normal, degree=False
+ )
+ # in sweeping, the cross-section is rotated, we mimic this here
+ test_normal = np.matmul(R, custom_normal)
+
+ start_traj_tang = trajectory.derivative([[0]], 1).ravel()
+ angle_at_start = np.arccos(
+ np.dot(start_traj_tang, test_normal)
+ / (np.linalg.norm(start_traj_tang) * np.linalg.norm(test_normal))
+ )
+
+ result_with_cus_normal = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ cross_section_normal=custom_normal,
+ anchor="auto",
+ )
+
+ result_with_cus_normal_cps = result_with_cus_normal.control_points
+ normal_vector_custom_version = (
+ calculate_cs_normal_vector(cs_cp, result_with_cus_normal_cps, rand)
+ * -1
+ )
+
+ angle_at_rand = np.arccos(
+ np.dot(rand_traj_tangent, normal_vector_custom_version)
+ / (
+ np.linalg.norm(rand_traj_tangent)
+ * np.linalg.norm(normal_vector_custom_version)
+ )
+ )
+
+ assert np.allclose(angle_at_start, angle_at_rand)
+
+
+# check if cross-section's center lays on the trajectory
+def test_swept_cross_section_centering(np_rng):
+
+ cross_section = splinepy.BSpline(
+ degrees=[2],
+ control_points=[[0, 0], [0.5, 1], [1, 0]],
+ knot_vectors=[[0, 0, 0, 1, 1, 1]],
+ )
+ trajectory = splinepy.BSpline(
+ degrees=[3],
+ control_points=[[0, 0, 0], [1, 2, 0], [2, 3, 0], [3, 3, 0]],
+ knot_vectors=[[0, 0, 0, 0, 1, 1, 1, 1]],
+ )
+ result = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="parametric",
+ )
+
+ # choose random parameter value of trajectory
+ r_par_val = np_rng.random(1)
+ # evaluate swept spline at the chosen position of the trajectory
+ # --> cross-section parameter value 0.5 ensures that the center of the
+ # cross-section is evaluated
+ coords = result.evaluate([[0.5, r_par_val[0]]]).ravel()
+ # evaluate trajectory at the chosen position of the trajectory
+ ref_coords = trajectory.evaluate([r_par_val]).ravel()
+
+ assert np.allclose(coords, ref_coords)
+
+
+def test_swept_anchor_modes():
+ cross_section = splinepy.helpme.create.circle(0.55).nurbs
+ cross_section.control_points[:, 0] *= 1.2
+ cross_section.control_points[:, 1] *= 0.8
+ cross_section.control_points[1] += np.array([0.9, -0.15])
+ cross_section.control_points[2] += np.array([0.45, 0.55])
+ cross_section.control_points[5] += np.array([-0.35, -0.45])
+ cross_section.weights[1] *= 0.25
+ cross_section.weights[2] *= 0.45
+ cross_section.weights[5] *= 0.5
+
+ trajectory = splinepy.BSpline(
+ degrees=[1],
+ control_points=[[0, 0, 0], [0, 0, 2]],
+ knot_vectors=[[0, 0, 1, 1]],
+ )
+
+ swept_parametric = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="parametric",
+ )
+ swept_control_box = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="control_box",
+ )
+ swept_geometry_box = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="geometry_box",
+ )
+ swept_auto = splinepy.helpme.create.swept(
+ cross_section=cross_section,
+ trajectory=trajectory,
+ anchor="auto",
+ )
+
+ assert np.allclose(
+ swept_auto.control_points, swept_geometry_box.control_points
+ )
+ assert not np.allclose(
+ swept_parametric.control_points, swept_geometry_box.control_points
+ )
+ assert not np.allclose(
+ swept_control_box.control_points, swept_geometry_box.control_points
+ )
+
+ n_section_cps = cross_section.control_points.shape[0]
+ diff_control_vs_geometry = (
+ swept_control_box.control_points[:n_section_cps]
+ - swept_geometry_box.control_points[:n_section_cps]
+ )
+ diff_parametric_vs_geometry = (
+ swept_parametric.control_points[:n_section_cps]
+ - swept_geometry_box.control_points[:n_section_cps]
+ )
+
+ assert np.allclose(diff_control_vs_geometry, diff_control_vs_geometry[0])
+ assert np.allclose(
+ diff_parametric_vs_geometry, diff_parametric_vs_geometry[0]
+ )
+ assert not np.allclose(diff_control_vs_geometry[0], 0.0)
+ assert not np.allclose(diff_parametric_vs_geometry[0], 0.0)
diff --git a/tests/helpme/test_integrate.py b/tests/helpme/test_integrate.py
index 9dc287e63..ee2444c7f 100644
--- a/tests/helpme/test_integrate.py
+++ b/tests/helpme/test_integrate.py
@@ -34,20 +34,20 @@ def test_volume_integration_embedded(np_rng):
Test volume integration for splines using numerical integration of the
Jacobi-Determinant
"""
- # Test 1D -> 2D
+ # Test 1D -> 2D volume integration for Bezier
expected_result = 2.0**1.5
bezier = splinepy.Bezier(degrees=[1], control_points=[[0, 0], [2, 2]])
assert np.allclose(bezier.integrate.volume(), expected_result)
- # test for other types same spline
+ # For same curve, test other spline types
assert np.allclose(bezier.bspline.integrate.volume(), expected_result)
assert np.allclose(
bezier.rationalbezier.integrate.volume(), expected_result
)
assert np.allclose(bezier.nurbs.integrate.volume(), expected_result)
- # Check if equal after refinement
+ # Check if volume is equal after degree elevation
bezier.elevate_degrees([0, 0, 0])
assert np.allclose(bezier.integrate.volume(), expected_result)
@@ -177,6 +177,7 @@ def test_assertions(np_rng):
def test_function_integration(np_rng):
col1_factor = 2
+ # Define vector-valued constant function
def volume_function(x):
vf = np.ones((len(x), 2))
# scale it with a factor to get a different value
@@ -186,12 +187,11 @@ def volume_function(x):
bezier = splinepy.Bezier(
degrees=[1, 2], control_points=np_rng.random((6, 2))
)
-
+ # Test function integration for constant functions
assert np.allclose(
[bezier.integrate.volume(), col1_factor * bezier.integrate.volume()],
bezier.integrate.parametric_function(volume_function),
)
-
# try bsplines
bspline = bezier.bspline
assert np.allclose(
@@ -200,6 +200,59 @@ def volume_function(x):
)
+def test_transformation_class(np_rng):
+ """Test element transformation of single patch"""
+ # Create quadratic spline
+ spline = splinepy.BSpline(
+ degrees=[2, 2],
+ knot_vectors=[[0, 0, 0, 1, 1, 1], [0, 0, 0, 1, 1, 1]],
+ control_points=splinepy.utils.data.cartesian_product(
+ [np.linspace(0, 1, 3), np.linspace(0, 1, 3)]
+ ),
+ )
+
+ # Randomly insert knots along both parametric dimensions
+ spline.insert_knots(0, np_rng.random(2))
+ spline.insert_knots(1, np_rng.random(2))
+
+ # Create transformation class for spline
+ trafo = splinepy.helpme.integrate.Transformation(spline)
+
+ # Check whether element quadrature points lie inside element
+ ukvs = spline.unique_knots
+ trafo.compute_all_element_quad_points()
+ # Check quadrature points of each element
+ for element_id, quad_points in enumerate(trafo.all_quad_points):
+ grid_id = trafo.get_element_grid_id(element_id)
+ # Extract the corners of the current element
+ element_corners = [
+ ukv[grid_dim_id : grid_dim_id + 2]
+ for ukv, grid_dim_id in zip(ukvs, grid_id, strict=True)
+ ]
+ # Check if quadrature points lie within element
+ for dim, corners in enumerate(element_corners):
+ assert np.all(
+ (quad_points[:, dim] > corners[0])
+ & (quad_points[:, dim] < corners[1])
+ ), f"Quadrature points do not lie within element for dimension {dim}"
+
+ # For given spline, all Jacobians should be identity matrix
+ eye = np.eye(spline.para_dim)
+ trafo.compute_all_element_jacobian_inverses()
+ for element_jacobians in trafo.all_jacobians:
+ for jacobian_at_quad_point in element_jacobians:
+ assert np.allclose(
+ eye, jacobian_at_quad_point
+ ), "All Jacobians should be identity matrix"
+
+ # For created spline, all determinants should equal one
+ trafo.compute_all_element_jacobian_determinants()
+ assert np.allclose(
+ trafo.all_jacobian_determinants,
+ np.ones_like(trafo.all_jacobian_determinants),
+ ), "All Jacobians' determinants should be equal to one"
+
+
def test_physical_function_integration(np_rng):
# Analytical integral of y*(5-y) over [0,1]x[0,5] rectangle
integral_analytical = 125 / 6
diff --git a/tests/io/test_cats.py b/tests/io/test_cats.py
index 46d835cbf..dd06cda7a 100644
--- a/tests/io/test_cats.py
+++ b/tests/io/test_cats.py
@@ -259,6 +259,7 @@ def test_cats_import(to_tmpf, are_splines_equal):
for a, b in zip(
multipatch_geometry,
multipatch_geometry_loaded,
+ strict=True,
)
)
@@ -276,5 +277,6 @@ def test_cats_import(to_tmpf, are_splines_equal):
for a, b in zip(
multipatch_geometry,
multipatch_geometry_loaded,
+ strict=True,
)
)
diff --git a/tests/io/test_gismo.py b/tests/io/test_gismo.py
index 4376f41d0..80ae3531c 100644
--- a/tests/io/test_gismo.py
+++ b/tests/io/test_gismo.py
@@ -160,10 +160,13 @@ def test_gismo_export_2D(
labeled_boundaries=False,
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_noindent_nolabels_ascii_2d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_noindent_nolabels_ascii_2d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -183,10 +186,13 @@ def test_gismo_export_2D_indented(
labeled_boundaries=False,
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_indent_nolabels_ascii_2d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_indent_nolabels_ascii_2d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -207,10 +213,13 @@ def test_gismo_export_2D_labels(
labeled_boundaries=True,
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_noindent_labels_ascii_2d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_noindent_labels_ascii_2d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -230,10 +239,13 @@ def test_gismo_export_2D_labels_indented(
labeled_boundaries=True,
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_indent_labels_ascii_2d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_indent_labels_ascii_2d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -254,10 +266,13 @@ def test_gismo_export_3D(
labeled_boundaries=False,
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_noindent_nolabels_ascii_3d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_noindent_nolabels_ascii_3d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -324,10 +339,13 @@ def test_gismo_export_additional_blocks(
additional_blocks=additional_blocks.to_list(),
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_additional_blocks.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_additional_blocks.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -347,10 +365,13 @@ def test_gismo_export_3D_indented(
labeled_boundaries=False,
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__)
- + "/../data/gismo_indent_nolabels_ascii_3d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__)
+ + "/../data/gismo_indent_nolabels_ascii_3d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -399,6 +420,7 @@ def test_gismo_import(to_tmpf, are_splines_equal):
for a, b in zip(
multipatch_geometry.patches,
multipatch_geometry_loaded.patches,
+ strict=True,
)
)
@@ -425,6 +447,7 @@ def test_gismo_import(to_tmpf, are_splines_equal):
for a, b in zip(
multipatch_geometry.patches,
multipatch_geometry_loaded.patches,
+ strict=True,
)
)
@@ -505,6 +528,7 @@ def test_gismo_import_with_options(to_tmpf, are_splines_equal):
for a, b in zip(
multipatch_geometry.patches,
multipatch_geometry_loaded.patches,
+ strict=True,
)
)
@@ -552,10 +576,13 @@ def test_gismo_io_binary(to_tmpf, are_stripped_lines_same, are_splines_equal):
gismo_options_loaded,
) = splinepy.io.gismo.load(tmpf, load_options=True)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(os.path.dirname(__file__))
- + "/data/gismo_noindent_nolabels_b64_3d.xml"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(os.path.dirname(__file__))
+ + "/data/gismo_noindent_nolabels_b64_3d.xml"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -565,6 +592,7 @@ def test_gismo_io_binary(to_tmpf, are_stripped_lines_same, are_splines_equal):
for a, b in zip(
multipatch_geometry.patches,
multipatch_geometry_loaded.patches,
+ strict=True,
)
)
diff --git a/tests/io/test_iges.py b/tests/io/test_iges.py
index 7b3fb2be5..6aed23afb 100644
--- a/tests/io/test_iges.py
+++ b/tests/io/test_iges.py
@@ -56,5 +56,5 @@ def test_iges_round_trip_bsplines(to_tmpf, are_splines_equal):
assert all(
are_splines_equal(a, b)
- for a, b in zip(splines_in_3d, list_of_splines_loaded)
+ for a, b in zip(splines_in_3d, list_of_splines_loaded, strict=True)
)
diff --git a/tests/io/test_irit.py b/tests/io/test_irit.py
index ea28d8c6e..be56418ec 100644
--- a/tests/io/test_irit.py
+++ b/tests/io/test_irit.py
@@ -25,5 +25,7 @@ def test_irit_export_import(
list_of_splines_loaded = splinepy.io.irit.load(tmpf)
assert all(
are_splines_equal(a, b)
- for a, b in zip(list_of_splines, list_of_splines_loaded)
+ for a, b in zip(
+ list_of_splines, list_of_splines_loaded, strict=True
+ )
)
diff --git a/tests/io/test_json.py b/tests/io/test_json.py
index e4571655e..8016da122 100644
--- a/tests/io/test_json.py
+++ b/tests/io/test_json.py
@@ -43,7 +43,9 @@ def test_json_import(to_tmpf, are_splines_equal):
list_of_splines_loaded = splinepy.io.json.load(tmpf)
assert all(
are_splines_equal(a, b)
- for a, b in zip(list_of_splines, list_of_splines_loaded)
+ for a, b in zip(
+ list_of_splines, list_of_splines_loaded, strict=True
+ )
)
# Test Import export with non base64 encoding
@@ -53,5 +55,7 @@ def test_json_import(to_tmpf, are_splines_equal):
list_of_splines_loaded = splinepy.io.json.load(tmpf)
assert all(
are_splines_equal(a, b)
- for a, b in zip(list_of_splines, list_of_splines_loaded)
+ for a, b in zip(
+ list_of_splines, list_of_splines_loaded, strict=True
+ )
)
diff --git a/tests/io/test_mfem_export.py b/tests/io/test_mfem_export.py
index 5c2544a94..4617a340f 100644
--- a/tests/io/test_mfem_export.py
+++ b/tests/io/test_mfem_export.py
@@ -43,9 +43,12 @@ def test_mfem_export(to_tmpf, are_stripped_lines_same):
tmpf, [bez_el0, bsp_el2, nur_el3, rbz_el1]
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__) + "/../data/mfem_cartesian_2d.mesh"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__) + "/../data/mfem_cartesian_2d.mesh"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
@@ -123,9 +126,12 @@ def test_mfem_export(to_tmpf, are_stripped_lines_same):
tmpf, [bez_el0, bsp_el2, nur_el3, rbz_el1]
)
- with open(tmpf) as tmp_read, open(
- os.path.dirname(__file__) + "/../data/mfem_cartesian_3d.mesh"
- ) as base_file:
+ with (
+ open(tmpf) as tmp_read,
+ open(
+ os.path.dirname(__file__) + "/../data/mfem_cartesian_3d.mesh"
+ ) as base_file,
+ ):
assert are_stripped_lines_same(
base_file.readlines(), tmp_read.readlines(), True
)
diff --git a/tests/io/test_npz.py b/tests/io/test_npz.py
index 7a16f194e..600f14e47 100644
--- a/tests/io/test_npz.py
+++ b/tests/io/test_npz.py
@@ -43,5 +43,7 @@ def test_npz_io(to_tmpf, are_splines_equal):
list_of_splines_loaded = splinepy.io.npz.load(tmpf + ".npz")
assert all(
are_splines_equal(a, b)
- for a, b in zip(list_of_splines, list_of_splines_loaded)
+ for a, b in zip(
+ list_of_splines, list_of_splines_loaded, strict=True
+ )
)
diff --git a/tests/test_bezier_extraction.py b/tests/test_bezier_extraction.py
index 49c9cd5ae..5fb137118 100644
--- a/tests/test_bezier_extraction.py
+++ b/tests/test_bezier_extraction.py
@@ -52,7 +52,7 @@ def test_extraction_matrices(splinetype, np_rng, request):
n_matrices = spline.knot_insertion_matrix(beziers=True)
beziers_n = spline.extract_bezier_patches()
- for m, b in zip(n_matrices, beziers_n):
+ for m, b in zip(n_matrices, beziers_n, strict=True):
# Test matrices m against spline ctps
if "nurbs" in splinetype:
assert np.allclose(b.weights, m @ spline.weights)
diff --git a/tests/test_bezier_operations.py b/tests/test_bezier_operations.py
index 5afc97c80..4cb53cf2e 100644
--- a/tests/test_bezier_operations.py
+++ b/tests/test_bezier_operations.py
@@ -98,7 +98,7 @@ def test_composition_sensitivities_on_bsplines(bspline_2p2d):
composed_der_ctps = []
beziers = []
- for bez, mat in zip(extract_beziers, extraction_matrices):
+ for bez, mat in zip(extract_beziers, extraction_matrices, strict=True):
# Composition
composed, derivatives = bez.compose(
inner_function, compute_sensitivities=True
@@ -118,7 +118,7 @@ def test_composition_sensitivities_on_bsplines(bspline_2p2d):
# Extract Beziers
extract_beziers_dx = bspline_dx.extract_bezier_patches()
for bez, bez_dx, comps in zip(
- beziers, extract_beziers_dx, composed_der_ctps
+ beziers, extract_beziers_dx, composed_der_ctps, strict=True
):
# Compose finite differences spline
composed_dx = bez_dx.compose(inner_function)
diff --git a/tests/test_knot_vectors.py b/tests/test_knot_vectors.py
index 329d165b5..9d9af3457 100644
--- a/tests/test_knot_vectors.py
+++ b/tests/test_knot_vectors.py
@@ -12,7 +12,7 @@ def test_knot_vectors(splinetype, request):
copy_knot_vectors = spline.knot_vectors[:]
unique_knots = [np.unique(ckvs) for ckvs in copy_knot_vectors]
- for uk, uk_fct in zip(unique_knots, spline.unique_knots):
+ for uk, uk_fct in zip(unique_knots, spline.unique_knots, strict=True):
assert np.allclose(uk, uk_fct)
# test knot_multiplicities
@@ -20,7 +20,9 @@ def test_knot_vectors(splinetype, request):
np.unique(ckvs, return_counts=True) for ckvs in copy_knot_vectors
]
- for m_u, m_fct in zip(multiplicity, spline.knot_multiplicities):
+ for m_u, m_fct in zip(
+ multiplicity, spline.knot_multiplicities, strict=True
+ ):
assert np.allclose(m_u[1], m_fct)
# test knot_vector creation
@@ -28,5 +30,6 @@ def test_knot_vectors(splinetype, request):
spline.unique_knots,
spline.knot_multiplicities,
spline.knot_vectors,
+ strict=True,
):
- assert np.allclose(np.array(spl_kv), np.repeat(u_kv, kn_m))
+ assert np.allclose(spl_kv.numpy(), np.repeat(u_kv, kn_m))
diff --git a/tests/test_kv_manipulation.py b/tests/test_kv_manipulation.py
index b3c7d63da..04516d5aa 100644
--- a/tests/test_kv_manipulation.py
+++ b/tests/test_kv_manipulation.py
@@ -196,7 +196,7 @@ def test_uniform_refine():
# compute what it should be
n_elem2_ref = 1
- for uk, nk in zip(unique_knots1, n_knots):
+ for uk, nk in zip(unique_knots1, n_knots, strict=True):
n_elem2_ref *= (len(uk) - 1) * (nk + 1)
assert n_elem2_ref == n_elem2
diff --git a/tests/test_microstructure.py b/tests/test_microstructure.py
new file mode 100644
index 000000000..2b6713adf
--- /dev/null
+++ b/tests/test_microstructure.py
@@ -0,0 +1,210 @@
+import numpy as np
+from pytest import mark, skip
+
+import splinepy.microstructure as ms
+from splinepy.helpme.create import box
+from splinepy.helpme.integrate import volume
+
+all_tile_classes = list(ms.tiles.everything().values())
+# Tile classes where closure should be tested
+tile_classes_with_closure = [
+ tile_class
+ for tile_class in all_tile_classes
+ if tile_class._closure_directions is not None
+]
+
+# Fixed auxiliary variables specific to microstructure testing
+TILING = [2, 2, 2]
+BOX_DIMENSIONS = [1, 1, 1]
+EPS = 1e-7
+
+# TODO(#458): the following tiles fail the closure test
+CLOSURE_FAILS = {
+ ms.tiles.InverseCross3D: "closure is special: the generated tile is the inverse "
+ + "geometry of the closure tile of the Cross3D-tile, hence it itself does not fill"
+ + " the whole unit cube.",
+}
+# TODO: the following tiles fail the macro-sensitivity testing
+MACRO_FAILS = {
+ ms.tiles.Chi: "currently macro-sensitivity tests fail for the Chi-tile."
+}
+
+
+@mark.parametrize("tile_class", tile_classes_with_closure)
+def test_closing_face(tile_class):
+ """Check if closing face is working
+
+ Parameters
+ ---------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile
+ """
+
+ # Skip tile if it doesn't support closure
+ if tile_class._closure_directions is None:
+ skip(
+ f"Tile {tile_class.__name__} does not have a closure implementation. Skip"
+ )
+
+ # TODO: right now skip tiles which have faulty closures
+ if tile_class in CLOSURE_FAILS:
+ reason = CLOSURE_FAILS[tile_class]
+ skip(
+ f"Known issue: skip closure test for {tile_class.__name__}, "
+ f"reason: {reason}"
+ )
+
+ def check_if_closed(multipatch, closure_direction):
+ """Helper function to see if multipatch has a closing surface
+
+ Parameters
+ ----------
+ multipatch: splinepy Multipatch
+ Microstructure multipatch
+ closure_direction: str
+ Direction in which the closure has been applied
+ """
+ direction_index_dict = {"x": 0, "y": 1, "z": 2}
+ direction_index = direction_index_dict[closure_direction]
+
+ def min_identifier(points):
+ return points[:, direction_index] < EPS
+
+ def max_identifier(points):
+ return (
+ points[:, direction_index]
+ > BOX_DIMENSIONS[direction_index] - EPS
+ )
+
+ # create min- and max-boundaries of the multipatch using the identifiers
+ multipatch.boundary_from_function(min_identifier, boundary_id=2)
+ multipatch.boundary_from_function(max_identifier, boundary_id=3)
+
+ min_patches = multipatch.boundary_multipatch(2)
+ max_patches = multipatch.boundary_multipatch(3)
+
+ # Check if the closing surface has a surface area of 1
+ face_min_area = sum([volume(patch) for patch in min_patches.patches])
+ face_max_area = sum([volume(patch) for patch in max_patches.patches])
+
+ assert face_min_area > 1.0 - EPS, (
+ f"The closure of the {closure_direction}_min surface is not complete. "
+ f"Expected area of 1, instead got {face_min_area}"
+ )
+ assert face_max_area > 1.0 - EPS, (
+ f"The closure of the {closure_direction}_max surface is not complete. "
+ f"Expected area of 1, instead got {face_max_area}"
+ )
+
+ tile_creator = tile_class()
+ generator = ms.microstructure.Microstructure(
+ deformation_function=box(*BOX_DIMENSIONS[: tile_creator._dim]),
+ microtile=tile_creator,
+ tiling=TILING[: tile_creator._dim],
+ )
+ # Go through all implemented closure direction
+ closure_directions = {
+ directionname[0] for directionname in tile_creator._closure_directions
+ }
+ for closure_direction in closure_directions:
+ multipatch = generator.create(closing_face=closure_direction)
+ check_if_closed(multipatch, closure_direction)
+
+
+@mark.parametrize("tile_class", all_tile_classes)
+def test_macro_sensitivities(tile_class, np_rng, h_eps, n_test_points):
+ """Testing the correctness of the derivatives of the whole microstructure w.r.t.
+ the deformation function's control points. It is tested by evaluating the derivative
+ obtained via finite differences. The values are evaluated at random points.
+
+ Parameters
+ ----------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile
+ np_rng: numpy.random._generator.Generator
+ Default random number generator
+ h_eps: float
+ Perturbation size for finite difference evaluation. Defined in conftest.py
+ n_test_points: int
+ Number of testing points in the parametric domain. Defined in conftest.py
+ """
+
+ # TODO: right now skip tiles which cause errors
+ if tile_class in MACRO_FAILS:
+ reason = MACRO_FAILS[tile_class]
+ skip(
+ f"Known issue: skip macro-senstivity test for {tile_class.__name__}, "
+ f"reason: {reason}"
+ )
+
+ tile_creator = tile_class()
+ deformation_function_orig = box(*BOX_DIMENSIONS[: tile_creator._dim])
+ generator = ms.microstructure.Microstructure(
+ deformation_function=deformation_function_orig,
+ microtile=tile_creator,
+ tiling=TILING[: tile_creator._dim],
+ )
+ multipatch = generator.create(macro_sensitivities=True)
+ dim = multipatch.dim
+ n_cps = deformation_function_orig.cps.shape[0]
+
+ # Set evaluation points as random spots in the parametric space
+ eval_points = np_rng.random((n_test_points, tile_creator._para_dim))
+ microstructure_orig_evaluations = [
+ patch.evaluate(eval_points) for patch in multipatch.patches
+ ]
+ n_patches = len(multipatch.patches)
+
+ # Go through derivatives of every deformation function's control point
+ for ii_ctps in range(n_cps):
+ # Gradient through finite differences
+ deformation_function_perturbed = deformation_function_orig.copy()
+ deformation_function_perturbed.cps[ii_ctps, :] += h_eps
+ generator.deformation_function = deformation_function_perturbed
+ multipatch_perturbed = generator.create()
+ microstructure_perturbed_evaluations = [
+ patch.evaluate(eval_points)
+ for patch in multipatch_perturbed.patches
+ ]
+ # Evaluate finite difference gradient
+ fd_sensitivity = [
+ (patch_perturbed - patch_orig) / h_eps
+ for patch_perturbed, patch_orig in zip(
+ microstructure_perturbed_evaluations,
+ microstructure_orig_evaluations,
+ strict=True,
+ )
+ ]
+
+ # Go through each direction
+ for jj_dim in range(dim):
+ deriv_orig = multipatch.fields[ii_ctps * dim + jj_dim]
+ deriv_evaluations = [
+ patch.evaluate(eval_points) for patch in deriv_orig.patches
+ ]
+ for k_patch, patch_deriv_implemented, patch_deriv_fd in zip(
+ range(n_patches),
+ deriv_evaluations,
+ fd_sensitivity,
+ strict=True,
+ ):
+ # Verify derivative shapes
+ assert patch_deriv_implemented.shape[1] == dim, (
+ "The derivative at "
+ + f"patch {k_patch} has the wrong dimensions."
+ )
+ # Assert correctness of sensitivity
+ assert np.allclose(
+ patch_deriv_implemented[:, jj_dim],
+ patch_deriv_fd[:, jj_dim],
+ ), (
+ "Implemented derivative calculation for tile "
+ + f"{tile_class}, at patch {k_patch + 1}/{n_patches} does not "
+ + "match the derivative obtained using Finite Differences at "
+ + "the following evaluation points:\n"
+ + str(eval_points)
+ + "\nImplemented derivative:\n"
+ + str(patch_deriv_implemented[:, jj_dim])
+ + "\nFinite difference derivative:\n"
+ + str(patch_deriv_fd[:, jj_dim])
+ )
diff --git a/tests/test_microtiles.py b/tests/test_microtiles.py
new file mode 100644
index 000000000..52d71af8b
--- /dev/null
+++ b/tests/test_microtiles.py
@@ -0,0 +1,462 @@
+from inspect import getfullargspec
+
+import numpy as np
+from pytest import mark, raises, skip
+
+import splinepy.microstructure as ms
+from splinepy.utils.data import cartesian_product as _cartesian_product
+
+# Tolerance value for checking control points
+EPS = 1e-8
+
+all_tile_classes = list(ms.tiles.everything().values())
+# Tile classes where closure should be tested
+tile_classes_with_closure = [
+ tile_class
+ for tile_class in all_tile_classes
+ if tile_class._closure_directions is not None
+]
+# Tile classes where sensitivities should be tested
+tile_classes_with_sensitivities = [
+ tile_class
+ for tile_class in all_tile_classes
+ if tile_class._sensitivities_implemented
+]
+
+# Skip certain tile classes for parameters testing
+skip_tiles = {
+ ms.tiles.EllipsVoid: "control points easily lie outside unitcube",
+ ms.tiles.Snappy: "has no 'parameters' implemented",
+}
+
+
+def check_control_points(tile_patches):
+ """Helper function. Check if all of tile's control points all lie within unit
+ square/cube. The tolerance is defined by EPS"""
+ # Go through all patches
+ for tile_patch in tile_patches:
+ cps = tile_patch.control_points
+ valid_cp_indices = (cps >= 0.0 - EPS) & (cps <= 1.0 + EPS)
+ assert np.all(valid_cp_indices), (
+ "Control points of tile must lie inside the unit square/cube. "
+ + f"Found points outside bounds: {cps[~(valid_cp_indices)]}"
+ )
+
+
+def make_bounds_feasible(bounds):
+ """Helper function. Bounds are understood as open set of min. and max. values.
+ Therefore, convert bounds to open set of these values.
+
+ Parameters
+ ------------
+ bounds: list>
+ Values of bounds
+
+ Returns
+ ----------
+ feasible_bounds: np.ndarray
+ Values of bounds
+ """
+ feasible_bounds = [
+ [min_value + EPS, max_value - EPS] for min_value, max_value in bounds
+ ]
+ return np.array(feasible_bounds)
+
+
+@mark.parametrize("tile_class", all_tile_classes)
+def test_tile_class(tile_class):
+ """Checks if all tile classes have the appropriate members and functions.
+
+ Parameters
+ ---------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile
+ """
+ # Create instance of class
+ tile_instance = tile_class()
+ tile_name = tile_class.__name__
+
+ required_class_variables = {
+ "_para_dim": int,
+ "_dim": int,
+ "_evaluation_points": np.ndarray,
+ "_n_info_per_eval_point": int,
+ "_sensitivities_implemented": bool,
+ "_parameter_bounds": list,
+ "_parameters_shape": tuple,
+ }
+
+ # Get tile class' objects
+ members = [
+ attr for attr in dir(tile_instance) if not attr.startswith("__")
+ ]
+
+ # Class must have function create_tile()
+ assert hasattr(
+ tile_instance, "create_tile"
+ ), f"Tile class {tile_name} must have create_tile() method"
+
+ # Tile must be able to take parameters and sensitivities as input
+ create_parameters = getfullargspec(tile_instance.create_tile).args
+ for required_param in ["parameters", "parameter_sensitivities"]:
+ assert required_param in create_parameters, (
+ f"{tile_name}.create_tile() must have '{required_param}' as an "
+ "input parameter"
+ )
+
+ # Ensure closure can be handled correctly
+ if "closure" in create_parameters:
+ assert "_closure_directions" in members, (
+ f"Tile class {tile_name} has closure ability. The available closure "
+ + "directions are missing"
+ )
+ assert hasattr(
+ tile_instance, "_closing_tile"
+ ), f"Tile class {tile_name} has closure ability but no _closing_tile() function"
+
+ # Check if tile class has all required variables and they are the correct type
+ for required_variable, var_type in required_class_variables.items():
+ assert (
+ required_variable in members
+ ), f"Tile class {tile_name} needs to have member variable '{required_variable}'"
+ assert isinstance(
+ getattr(tile_instance, required_variable), var_type
+ ), (
+ f"Variable {required_variable} must be of type {var_type.__name__}, "
+ f"but found type {type(getattr(tile_instance, required_variable)).__name__}"
+ )
+
+ # Check default parameter value if there is one
+ if tile_instance._parameters_shape != ():
+ # Assert that there is a default value
+ assert hasattr(
+ tile_instance, "_default_parameter_value"
+ ), f'{tile_name} must have "_default_parameter_value" as a class attribute.'
+ # Check the default value's type
+ default_value = tile_instance._default_parameter_value
+ if isinstance(default_value, np.ndarray):
+ # Check the dimensions
+ assert default_value.shape == tile_instance._parameters_shape, (
+ f"Default parameter values for tile {tile_name} has the wrong"
+ " dimensions"
+ )
+ # Check if default values are within bounds
+ default_value = default_value.ravel()
+ elif not isinstance(default_value, float):
+ raise ValueError(
+ f"Default parameter value for tile {tile_name} must either be "
+ "a float or a numpy array"
+ )
+
+ # Check if default values are within bounds
+ parameter_bounds = np.asarray(tile_instance._parameter_bounds)
+ lower_bounds = parameter_bounds[:, 0]
+ upper_bounds = parameter_bounds[:, 1]
+ assert np.all(
+ (default_value > lower_bounds) & (default_value < upper_bounds)
+ ), f"Default parameter value of tile {tile_name} is not within bounds"
+
+
+@mark.parametrize("tile_class", all_tile_classes)
+def test_tile_bounds(tile_class):
+ """Test if tile is still in unit cube at the bounds. Checks default and also
+ non-default parameter values.
+
+ Parameters
+ ---------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile
+ """
+ tile_creator = tile_class()
+ # Create tile with default parameters
+ tile_patches, _ = tile_creator.create_tile()
+ check_control_points(tile_patches)
+
+ # Skip certain classes for testing
+ if tile_class in skip_tiles:
+ skip(
+ "Known issue: skip bound test for non-default parameter values for tile "
+ f"{tile_class.__name__}. Reason: {skip_tiles[tile_class]}"
+ )
+
+ # Go through all extremes of parameters and ensure that also they create
+ # tiles within unit square/cube
+ feasible_parameter_bounds = make_bounds_feasible(
+ tile_creator._parameter_bounds
+ )
+ all_parameter_bounds = _cartesian_product(feasible_parameter_bounds)
+ for parameter_extremes in all_parameter_bounds:
+ tile_patches, _ = tile_creator.create_tile(
+ parameters=parameter_extremes.reshape(
+ tile_creator._parameters_shape
+ )
+ )
+ check_control_points(tile_patches)
+
+
+@mark.parametrize("tile_class", tile_classes_with_closure)
+def test_tile_closure(tile_class):
+ """Check if closing tiles also lie in unit cube.
+
+ Parameters
+ ---------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile
+ """
+ tile_name = tile_class.__name__
+
+ # Skip tile if if does not support closure
+ if tile_class._closure_directions is None:
+ skip(f"Tile {tile_name} does not have a closure implementation. Skip")
+ tile_creator = tile_class()
+ # Go through all implemented closure directions
+ for closure_direction in tile_creator._closure_directions:
+ tile_patches, sensitivities = tile_creator.create_tile(
+ closure=closure_direction
+ )
+ assert sensitivities is None, (
+ f"Expected sensitivities to be None for closure {closure_direction} "
+ + f"when no sensitivities are requested, got {sensitivities}"
+ )
+
+ check_control_points(tile_patches)
+
+ # Also check non-default parameters
+ # Skip certain classes for testing
+ if tile_class in skip_tiles:
+ skip(
+ "Known issue: skip closure test for non-default parameter for tile "
+ f"{tile_name}. Reason: {skip_tiles[tile_class]}"
+ )
+
+ # Go through all extremes of parameters and ensure that also they create
+ # tiles within unit square/cube
+ feasible_parameter_bounds = make_bounds_feasible(
+ tile_creator._parameter_bounds
+ )
+ all_parameter_bounds = _cartesian_product(feasible_parameter_bounds)
+ # Go through all implemented closure directions
+ for closure_direction in tile_creator._closure_directions:
+ for parameter_extremes in all_parameter_bounds:
+ tile_patches, _ = tile_creator.create_tile(
+ parameters=parameter_extremes.reshape(
+ tile_creator._parameters_shape
+ ),
+ closure=closure_direction,
+ )
+ check_control_points(tile_patches)
+
+
+@mark.parametrize("tile_class", tile_classes_with_sensitivities)
+def test_tile_derivatives(
+ tile_class,
+ np_rng,
+ h_eps,
+ n_test_points,
+ fd_derivative_stepsizes_and_weights,
+):
+ """Testing the correctness of the tile derivatives using Finite Differences.
+ This includes every closure and no closure, every parameter and every patch
+ by evaluating at random points and for random parameters.
+
+ Parameters
+ ---------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile
+ np_rng: numpy.random._generator.Generator
+ Default random number generator
+ h_eps: float
+ Perturbation size for finite difference evaluation. Defined in conftest.py
+ n_test_points: int
+ Number of testing points in the parametric domain. Defined in conftest.py
+ fd_derivative_stepsizes_and_weights: dict
+ Stepsizes and weights for finite difference scheme. Defined in conftest.py
+ """
+ tile_creator = tile_class()
+ # Skip test if tile class has no implemented sensitivities
+ if not tile_creator._sensitivities_implemented:
+ skip(f"Tile {tile_class.__name__} has no sensitivities implemented")
+
+ def generate_random_parameters(tile_creator, np_rng):
+ """Generate random parameters within bounds"""
+ parameter_bounds = np.array(tile_creator._parameter_bounds)
+ parameters = parameter_bounds[:, 0] + np_rng.random(
+ len(parameter_bounds)
+ ) * np.ptp(parameter_bounds, axis=1)
+ return parameters.reshape(tile_creator._parameters_shape)
+
+ parameters = generate_random_parameters(tile_creator, np_rng)
+
+ # Test no closure as well as ...
+ closure_directions = [None]
+ # ... every closure implemented
+ if tile_creator._closure_directions is not None:
+ closure_directions += tile_creator._closure_directions
+
+ # Retrieve shape values of parameters
+ n_eval_points = tile_creator._evaluation_points.shape[0]
+ n_info_per_eval_point = tile_creator._n_info_per_eval_point
+
+ def derivative_finite_difference_evaluation(
+ tile_creator, parameters, i_parameter, closure, eval_points, n_patches
+ ):
+ """Compute the derivative using fourth-order accurate centered finite
+ differences
+
+ Parameters
+ ------------
+ tile_creator: instance of microtile
+ Microtile class
+ parameters: np.ndarray
+ Tile parameter values
+ i_parameter: int
+ Index of parameter, on which the FD derivative calculation should be
+ performed on
+ closure: None/str
+ Closure direction of tile
+ eval_points: np.ndarray
+ Evaluation points on where to evaluate the derivative on
+ n_patches: int
+ Number of patches of tile
+ """
+ # Initialize array for FD evaluation
+ fd_sensitivities = np.zeros(
+ (n_patches, len(eval_points), tile_creator.dim)
+ )
+
+ # Go through the
+ for stepsize, weighting in fd_derivative_stepsizes_and_weights.items():
+ # Perturb parameter with respective stepsize
+ parameters_perturbed = parameters.copy()
+ parameters_perturbed[:, i_parameter] += stepsize * h_eps
+ # Create patches with perturbed parameter value
+ splines_perturbed, _ = tile_creator.create_tile(
+ parameters=parameters_perturbed, closure=closure
+ )
+ fd_sensitivities += np.array(
+ [
+ weighting / h_eps * spl.evaluate(eval_points)
+ for spl in splines_perturbed
+ ]
+ )
+
+ return fd_sensitivities
+
+ # Test each closure direction
+ for closure in closure_directions:
+ # Evaluate tile with given parameter and closure configuration
+ splines_orig, _ = tile_creator.create_tile(
+ parameters=parameters, closure=closure
+ )
+ n_patches = len(splines_orig)
+ # Set evaluation points as random spots in the parametric space
+ eval_points = np_rng.random((n_test_points, splines_orig[0].para_dim))
+ # Go through all the parameters individually
+ for i_parameter in range(n_info_per_eval_point):
+ # Get implemented derivatives w.r.t. one parameter
+ parameter_sensitivities = np.zeros(
+ (n_eval_points, n_info_per_eval_point, 1)
+ )
+ parameter_sensitivities[:, i_parameter, :] = 1
+ _, derivatives = tile_creator.create_tile(
+ parameters=parameters,
+ parameter_sensitivities=parameter_sensitivities,
+ closure=closure,
+ )
+ deriv_evaluations = [
+ deriv.evaluate(eval_points) for deriv in derivatives[0]
+ ]
+ # Perform finite difference evaluation
+ fd_sensitivities = derivative_finite_difference_evaluation(
+ tile_creator,
+ parameters,
+ i_parameter,
+ closure,
+ eval_points,
+ n_patches,
+ )
+ # Check every patch
+ for i_patch, deriv_orig, deriv_fd in zip(
+ range(n_patches),
+ deriv_evaluations,
+ fd_sensitivities,
+ strict=True,
+ ):
+ message = (
+ f"Implemented derivative calculation for tile class {tile_class} "
+ f"with closure {closure}, parameter {i_parameter + 1}/"
+ f"{n_info_per_eval_point} at patch {i_patch + 1}/{n_patches} does"
+ " not match the derivative obtained using Finite Differences"
+ f" at the following evaluation points:\n {eval_points}\n"
+ "Implemented derivative:\n{deriv_orig}\n"
+ f"Finite Difference derivative:\n{deriv_fd}"
+ )
+ assert np.allclose(deriv_orig, deriv_fd), message
+
+
+@mark.parametrize("tile_class", all_tile_classes)
+def test_invalid_parameter_values(tile_class, big_perturbation):
+ """Testing whether the tile class correctly raises an error if invalid parameters
+ are given. Current tests include too low or too high parameter values and wrong
+ shapes of the parameter array.
+
+ Parameters
+ ----------
+ tile_class: tile class in splinepy.microstructure.tiles
+ Microtile class
+ """
+ tile_creator = tile_class()
+ # For certain tiles skip tests
+ if len(tile_creator._parameter_bounds) == 0:
+ skip(
+ f"Skip check for invalid parameters for tile {tile_class.__name__} "
+ "since there are no parameter bounds implemented for this tile"
+ )
+
+ parameter_bounds = np.asarray(tile_creator._parameter_bounds)
+
+ # Check if tile class correctly raises an error if parameter values are too low
+ parameters_too_low = (
+ parameter_bounds[:, 0].reshape(tile_creator._parameters_shape)
+ - big_perturbation
+ )
+ with raises(ValueError) as exc_info_low:
+ tile_creator.create_tile(parameters=parameters_too_low)
+ # Check if the exception message calls TileBase.check_params()
+ assert "The following parameters are out of bounds: " in str(
+ exc_info_low.value
+ ), (
+ f"Tile class {tile_class.__name__} must call TileBase.check_params() and raise",
+ " a ValueError if parameters values are too low",
+ )
+
+ # Check the same if parameter values are too high
+ parameters_too_high = (
+ parameter_bounds[:, 1].reshape(tile_creator._parameters_shape)
+ + big_perturbation
+ )
+ with raises(ValueError) as exc_info_high:
+ tile_creator.create_tile(parameters=parameters_too_high)
+ # Check if the exception message calls TileBase.check_params()
+ assert "The following parameters are out of bounds: " in str(
+ exc_info_high.value
+ ), (
+ f"Tile class {tile_class.__name__} must call TileBase.check_params() and raise",
+ " a ValueError if parameters values are too high",
+ )
+
+ # Test if error is correctly thrown if the parameter shape is incompatible
+ # Take parameters in the middle of the bounds and double the array size
+ parameters_middle = np.mean(parameter_bounds, axis=1).reshape(
+ tile_creator._parameters_shape
+ )
+ parameters_middle = np.tile(parameters_middle, [2, 1])
+ # Check if the error is correctly raised
+ with raises(TypeError) as exc_info_size:
+ tile_creator.create_tile(parameters=parameters_middle)
+ assert "Mismatch in parameter size, expected" in str(
+ exc_info_size.value
+ ), (
+ f"Tile class {tile_class.__name__} must call TileBase.check_params() and raise",
+ " a TypeError if the given parameters have the wrong shape",
+ )
diff --git a/tests/test_multipatch.py b/tests/test_multipatch.py
index b2ad9cc38..51390a23a 100644
--- a/tests/test_multipatch.py
+++ b/tests/test_multipatch.py
@@ -207,11 +207,11 @@ def test_interfaces_and_boundaries(are_splines_equal):
bmp_1 = multipatch.boundary_multipatch(1)
assert len(bmp_1.patches) == 2
boundary_1 = []
- for i_patch, i_face in zip(*multipatch.boundaries[0]):
+ for i_patch, i_face in zip(*multipatch.boundaries[0], strict=True):
boundary_1.append(
*multipatch.patches[i_patch].extract.boundaries([i_face])
)
- for patch_0, patch_1 in zip(boundary_1, bmp_1.patches):
+ for patch_0, patch_1 in zip(boundary_1, bmp_1.patches, strict=True):
assert are_splines_equal(patch_0, patch_1)
assert len(multipatch.boundary_patch_ids(8)) == 0
diff --git a/tests/test_normalize_knot_vectors.py b/tests/test_normalize_knot_vectors.py
index ced5ab685..494a3a6db 100644
--- a/tests/test_normalize_knot_vectors.py
+++ b/tests/test_normalize_knot_vectors.py
@@ -14,7 +14,9 @@ def test_bspline_normalize_knot_vectors(bspline_2p2d):
# normalize
bspline.normalize_knot_vectors()
- for i, (ref_kv, kv) in enumerate(zip(ref, bspline.knot_vectors)):
+ for i, (ref_kv, kv) in enumerate(
+ zip(ref, bspline.knot_vectors, strict=True)
+ ):
assert np.allclose(ref_kv, kv), f"{i}. para dim failed to normalize"
@@ -31,5 +33,7 @@ def test_nurbs_normalize_knot_vectors(nurbs_2p2d):
# normalize
nurbs.normalize_knot_vectors()
- for i, (ref_kv, kv) in enumerate(zip(ref, nurbs.knot_vectors)):
+ for i, (ref_kv, kv) in enumerate(
+ zip(ref, nurbs.knot_vectors, strict=True)
+ ):
assert np.allclose(ref_kv, kv), f"{i}. para dim failed to normalize"