bsplyne 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bsplyne/__init__.py +55 -0
- bsplyne/b_spline.py +2464 -0
- bsplyne/b_spline_basis.py +1000 -0
- bsplyne/geometries_in_3D.py +1193 -0
- bsplyne/multi_patch_b_spline.py +1731 -0
- bsplyne/my_wide_product.py +209 -0
- bsplyne/parallel_utils.py +378 -0
- bsplyne/save_utils.py +141 -0
- bsplyne-1.0.0.dist-info/METADATA +91 -0
- bsplyne-1.0.0.dist-info/RECORD +13 -0
- bsplyne-1.0.0.dist-info/WHEEL +5 -0
- bsplyne-1.0.0.dist-info/licenses/LICENSE.txt +70 -0
- bsplyne-1.0.0.dist-info/top_level.txt +1 -0
bsplyne/save_utils.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import meshio as io
|
|
3
|
+
from typing import Iterable
|
|
4
|
+
from functools import reduce
|
|
5
|
+
import os
|
|
6
|
+
import xml
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def writePVD(fileName: str, groups: dict[str, dict]):
|
|
10
|
+
"""
|
|
11
|
+
Writes a Paraview Data (PVD) file that references multiple VTK files.
|
|
12
|
+
|
|
13
|
+
Creates an XML-based PVD file that collects and organizes multiple VTK files into groups,
|
|
14
|
+
allowing visualization of multi-part, time-series data in Paraview.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
fileName : str
|
|
19
|
+
Base name for the mesh files (without numbers and extension)
|
|
20
|
+
groups : dict[str, dict]
|
|
21
|
+
Nested dictionary specifying file groups with format:
|
|
22
|
+
{"group_name": {"ext": "file_extension", "npart": num_parts, "nstep": num_timesteps}}
|
|
23
|
+
|
|
24
|
+
Notes
|
|
25
|
+
-----
|
|
26
|
+
VTK files must follow naming pattern: {fileName}_{group}_{part}_{timestep}.{ext}
|
|
27
|
+
Example: for fileName="mesh", group="fluid", part=1, timestep=5, ext="vtu":
|
|
28
|
+
mesh_fluid_1_5.vtu
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
None
|
|
33
|
+
"""
|
|
34
|
+
rep, fname = os.path.split(fileName)
|
|
35
|
+
pvd = xml.dom.minidom.Document()
|
|
36
|
+
pvd_root = pvd.createElementNS("VTK", "VTKFile")
|
|
37
|
+
pvd_root.setAttribute("type", "Collection")
|
|
38
|
+
pvd_root.setAttribute("version", "0.1")
|
|
39
|
+
pvd_root.setAttribute("byte_order", "LittleEndian")
|
|
40
|
+
pvd.appendChild(pvd_root)
|
|
41
|
+
collection = pvd.createElementNS("VTK", "Collection")
|
|
42
|
+
pvd_root.appendChild(collection)
|
|
43
|
+
for name, grp in groups.items():
|
|
44
|
+
for jp in range(grp["npart"]):
|
|
45
|
+
for js in range(grp["nstep"]):
|
|
46
|
+
dataSet = pvd.createElementNS("VTK", "DataSet")
|
|
47
|
+
dataSet.setAttribute("timestep", str(js))
|
|
48
|
+
dataSet.setAttribute("group", name)
|
|
49
|
+
dataSet.setAttribute("part", str(jp))
|
|
50
|
+
dataSet.setAttribute("file", f"{fname}_{name}_{jp}_{js}.{grp['ext']}")
|
|
51
|
+
dataSet.setAttribute("name", f"{name}_{jp}")
|
|
52
|
+
collection.appendChild(dataSet)
|
|
53
|
+
outFile = open(fileName + ".pvd", "w")
|
|
54
|
+
pvd.writexml(outFile, newl="\n")
|
|
55
|
+
print("VTK: " + fileName + ".pvd written")
|
|
56
|
+
outFile.close()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def merge_meshes(meshes: Iterable[io.Mesh]) -> io.Mesh:
|
|
60
|
+
"""
|
|
61
|
+
Merges multiple meshio.Mesh objects into a single mesh.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
meshes : Iterable[io.Mesh]
|
|
66
|
+
An iterable of meshio.Mesh objects to merge.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
io.Mesh
|
|
71
|
+
A single meshio.Mesh object containing the merged meshes with combined
|
|
72
|
+
vertices, cells and point data.
|
|
73
|
+
"""
|
|
74
|
+
vertices = np.vstack([m.points for m in meshes])
|
|
75
|
+
all_cell_types = reduce(lambda a, b: a & b, [m.cells_dict.keys() for m in meshes])
|
|
76
|
+
cells = {}
|
|
77
|
+
for cell_type in all_cell_types:
|
|
78
|
+
counter = 0
|
|
79
|
+
cell = []
|
|
80
|
+
for m in meshes:
|
|
81
|
+
if cell_type in m.cells_dict:
|
|
82
|
+
cell.append(m.cells_dict[cell_type] + counter)
|
|
83
|
+
counter += m.points.shape[0]
|
|
84
|
+
cells[cell_type] = np.vstack(cell)
|
|
85
|
+
point_data_names = reduce(lambda a, b: a & b, [m.point_data.keys() for m in meshes])
|
|
86
|
+
point_datas = {}
|
|
87
|
+
for point_data_name in point_data_names:
|
|
88
|
+
for m in meshes:
|
|
89
|
+
if point_data_name in m.point_data:
|
|
90
|
+
shape = m.point_data[point_data_name].shape[1:] # type: ignore
|
|
91
|
+
break
|
|
92
|
+
point_data = []
|
|
93
|
+
for m in meshes:
|
|
94
|
+
if point_data_name in m.point_data:
|
|
95
|
+
point_data.append(m.point_data[point_data_name])
|
|
96
|
+
else:
|
|
97
|
+
point_data.append(np.zeros((m.points.shape[0], *shape)))
|
|
98
|
+
point_datas[point_data_name] = np.concatenate(point_data, axis=0)
|
|
99
|
+
return io.Mesh(vertices, cells, point_data=point_datas)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def merge_saves(
|
|
103
|
+
path: str, name: str, nb_patchs: int, nb_steps: int, group_names: list[str]
|
|
104
|
+
) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Merge multiple mesh files and save the merged results.
|
|
107
|
+
|
|
108
|
+
This function reads multiple mesh files for each group and time step,
|
|
109
|
+
merges them into a single mesh, and writes the merged mesh to a new file.
|
|
110
|
+
It also generates a PVD file to describe the collection of merged meshes.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
path : str
|
|
115
|
+
The directory path where the mesh files are located.
|
|
116
|
+
name : str
|
|
117
|
+
The base name of the mesh files.
|
|
118
|
+
nb_patchs : int
|
|
119
|
+
The number of patches to merge for each group and time step.
|
|
120
|
+
nb_steps : int
|
|
121
|
+
The number of time steps for which meshes are available.
|
|
122
|
+
group_names : list[str]
|
|
123
|
+
A list of group names to process.
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
None
|
|
128
|
+
"""
|
|
129
|
+
filename = os.path.join(path, name)
|
|
130
|
+
filename_out = filename + "_merged"
|
|
131
|
+
groups = {}
|
|
132
|
+
for group_name in group_names:
|
|
133
|
+
groups[group_name] = {"ext": "vtu", "npart": 1, "nstep": nb_steps}
|
|
134
|
+
for step in range(nb_steps):
|
|
135
|
+
merge_meshes(
|
|
136
|
+
[
|
|
137
|
+
io.read(f"{filename}_{group_name}_{p}_{step}.vtu")
|
|
138
|
+
for p in range(nb_patchs)
|
|
139
|
+
]
|
|
140
|
+
).write(f"{filename_out}_{group_name}_0_{step}.vtu")
|
|
141
|
+
writePVD(filename_out, groups)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bsplyne
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A package for N dimensions B-splines.
|
|
5
|
+
Home-page: https://github.com/Dorian210/bsplyne
|
|
6
|
+
Author: Dorian Bichet
|
|
7
|
+
Author-email: dbichet@insa-toulouse.fr
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: License :: OSI Approved :: CEA CNRS Inria Logiciel Libre License, version 2.1 (CeCILL-2.1)
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE.txt
|
|
13
|
+
Requires-Dist: numpy
|
|
14
|
+
Requires-Dist: numba
|
|
15
|
+
Requires-Dist: scipy
|
|
16
|
+
Requires-Dist: matplotlib
|
|
17
|
+
Requires-Dist: meshio
|
|
18
|
+
Requires-Dist: tqdm
|
|
19
|
+
Dynamic: author
|
|
20
|
+
Dynamic: author-email
|
|
21
|
+
Dynamic: classifier
|
|
22
|
+
Dynamic: description
|
|
23
|
+
Dynamic: description-content-type
|
|
24
|
+
Dynamic: home-page
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
Dynamic: requires-dist
|
|
27
|
+
Dynamic: summary
|
|
28
|
+
|
|
29
|
+
# bsplyne
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src=docs/logo.png width="500" />
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
**bsplyne** is a Python library for working with N-dimensional B-splines. It implements the Cox-de Boor algorithm for basis evaluation, order elevation, knot insertion, and provides a connectivity class for multi-patch structures. Additionally, it includes visualization tools with export capabilities to Paraview.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
Since **bsplyne** is not yet on PyPI, you can install it locally as follows:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/Dorian210/bsplyne
|
|
43
|
+
cd bsplyne
|
|
44
|
+
pip install -e .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Dependencies
|
|
48
|
+
Make sure you have the following dependencies installed:
|
|
49
|
+
- `numpy`
|
|
50
|
+
- `numba`
|
|
51
|
+
- `scipy`
|
|
52
|
+
- `matplotlib`
|
|
53
|
+
- `meshio`
|
|
54
|
+
- `tqdm`
|
|
55
|
+
|
|
56
|
+
## Main Modules
|
|
57
|
+
|
|
58
|
+
- **BSplineBasis**
|
|
59
|
+
Implements B-spline basis function evaluation using the Cox-de Boor recursion formula.
|
|
60
|
+
|
|
61
|
+
- **BSpline**
|
|
62
|
+
Provides methods for creating and manipulating N-dimensional B-splines, including order elevation and knot insertion.
|
|
63
|
+
|
|
64
|
+
- **MultiPatchBSplineConnectivity**
|
|
65
|
+
Manages the connectivity between multiple N-dimensional B-spline patches.
|
|
66
|
+
|
|
67
|
+
- **CouplesBSplineBorder** (less documented)
|
|
68
|
+
Handles coupling between B-spline borders.
|
|
69
|
+
|
|
70
|
+
## Examples
|
|
71
|
+
|
|
72
|
+
Several example scripts demonstrating the usage of **bsplyne** can be found in the `examples/` directory. These scripts cover:
|
|
73
|
+
- Basis evaluation on a curved line
|
|
74
|
+
- Plotting with Matplotlib
|
|
75
|
+
- Order elevation
|
|
76
|
+
- Knot insertion
|
|
77
|
+
- Surface examples
|
|
78
|
+
- Exporting to Paraview
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
The full API documentation is available in the `docs/` directory of the project or via the [online documentation portal](https://dorian210.github.io/bsplyne/).
|
|
83
|
+
|
|
84
|
+
## Contributions
|
|
85
|
+
|
|
86
|
+
At the moment, I am not actively reviewing contributions. However, if you encounter issues or have suggestions, feel free to open an issue.
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
This project is licensed under the [CeCILL License](LICENSE.txt).
|
|
91
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
bsplyne/__init__.py,sha256=sajGBdm1-pu6iMgD-G_nimXrbXZsXwrJT6bjA_JyLO8,1899
|
|
2
|
+
bsplyne/b_spline.py,sha256=CJYIS_kAJFOy1ay7kIOACyX1j20BkT9TRn1t1j8WkGU,110105
|
|
3
|
+
bsplyne/b_spline_basis.py,sha256=J4vrGx-WcW7suZDJzvLr3zDQyGCCLAZlMbzuGeQ1fZ4,35315
|
|
4
|
+
bsplyne/geometries_in_3D.py,sha256=krQPNZEg-PZCTnlhd1YrJjwCwv7R9T7oAxxlZJms_Zs,36519
|
|
5
|
+
bsplyne/multi_patch_b_spline.py,sha256=4lsxS3m7EV_igfzOBjCKaB7Pd8pxI-ZHyLmnQRP4NhQ,75925
|
|
6
|
+
bsplyne/my_wide_product.py,sha256=JqFy2s3ks0wKf4iq22NyzrZo-3Uo7ita-r6fGcGEfEE,5678
|
|
7
|
+
bsplyne/parallel_utils.py,sha256=M0Tuy8wA3AYltsnr_iYOnREWRGZnPxavq9cpWaEC_lU,15326
|
|
8
|
+
bsplyne/save_utils.py,sha256=p-gDHTAU4Fr8iI_yPfdrMHtEF6bOlgkm8b4yHxA5qtw,5023
|
|
9
|
+
bsplyne-1.0.0.dist-info/licenses/LICENSE.txt,sha256=NuJeFieCkXCWPQlUUkzn5TrngzZmXp09-Q8fk15_r6A,3196
|
|
10
|
+
bsplyne-1.0.0.dist-info/METADATA,sha256=5Gb889Dpk_bkCi3Pgds_5EintBhxWTNCREE7C4bNjkY,2690
|
|
11
|
+
bsplyne-1.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
12
|
+
bsplyne-1.0.0.dist-info/top_level.txt,sha256=Mwj9pTQb41GC_guOzmpvMcdkXeeAIWF6VtZcXghgx0c,8
|
|
13
|
+
bsplyne-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
|
|
2
|
+
CeCILL FREE SOFTWARE LICENSE AGREEMENT
|
|
3
|
+
|
|
4
|
+
Version 2.1 dated 2013-06-21
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Notice
|
|
8
|
+
|
|
9
|
+
This Agreement is a Free Software license agreement that is the result
|
|
10
|
+
of discussions between its authors in order to ensure compliance with
|
|
11
|
+
the two main principles guiding its drafting:
|
|
12
|
+
|
|
13
|
+
* firstly, compliance with the principles governing the distribution
|
|
14
|
+
of Free Software: access to source code, broad rights granted to users,
|
|
15
|
+
* secondly, the election of a governing law, French law, with which it
|
|
16
|
+
is conformant, both as regards the law of torts and intellectual
|
|
17
|
+
property law, and the protection that it offers to both authors and
|
|
18
|
+
holders of the economic rights over software.
|
|
19
|
+
|
|
20
|
+
The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
|
|
21
|
+
license are:
|
|
22
|
+
|
|
23
|
+
Commissariat à l'énergie atomique et aux énergies alternatives - CEA, a
|
|
24
|
+
public scientific, technical and industrial research establishment,
|
|
25
|
+
having its principal place of business at 25 rue Leblanc, immeuble Le
|
|
26
|
+
Ponant D, 75015 Paris, France.
|
|
27
|
+
|
|
28
|
+
Centre National de la Recherche Scientifique - CNRS, a public scientific
|
|
29
|
+
and technological establishment, having its principal place of business
|
|
30
|
+
at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
|
|
31
|
+
|
|
32
|
+
Institut National de Recherche en Informatique et en Automatique -
|
|
33
|
+
Inria, a public scientific and technological establishment, having its
|
|
34
|
+
principal place of business at Domaine de Voluceau, Rocquencourt, BP
|
|
35
|
+
105, 78153 Le Chesnay cedex, France.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
Preamble
|
|
39
|
+
|
|
40
|
+
The purpose of this Free Software license agreement is to grant users
|
|
41
|
+
the right to modify and redistribute the software governed by this
|
|
42
|
+
license within the framework of an open source distribution model.
|
|
43
|
+
|
|
44
|
+
The exercising of this right is conditional upon certain obligations for
|
|
45
|
+
users so as to preserve this status for all subsequent redistributions.
|
|
46
|
+
|
|
47
|
+
In consideration of access to the source code and the rights to copy,
|
|
48
|
+
modify and redistribute granted by the license, users are provided only
|
|
49
|
+
with a limited warranty and the software's author, the holder of the
|
|
50
|
+
economic rights, and the successive licensors only have limited liability.
|
|
51
|
+
|
|
52
|
+
In this respect, the risks associated with loading, using, modifying
|
|
53
|
+
and/or developing or reproducing the software by the user are brought to
|
|
54
|
+
the user's attention, given its Free Software status, which may make it
|
|
55
|
+
complicated to use, with the result that its use is reserved for
|
|
56
|
+
developers and experienced professionals having in-depth computer
|
|
57
|
+
knowledge. Users are therefore encouraged to load and test the
|
|
58
|
+
suitability of the software as regards their requirements in conditions
|
|
59
|
+
enabling the security of their systems and/or data to be ensured and,
|
|
60
|
+
more generally, to use and operate it in the same conditions of
|
|
61
|
+
security. This Agreement may be freely reproduced and published,
|
|
62
|
+
provided it is not altered, and that no provisions are either added or
|
|
63
|
+
removed herefrom.
|
|
64
|
+
|
|
65
|
+
This Agreement may apply to any or all software for which the holder of
|
|
66
|
+
the economic rights decides to submit the use thereof to its provisions.
|
|
67
|
+
|
|
68
|
+
Frequently asked questions can be found on the official website of the
|
|
69
|
+
CeCILL licenses family (http://www.cecill.info/index.en.html) for any
|
|
70
|
+
necessary clarification.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bsplyne
|