Skip to content

Commit 61d0085

Browse files
authored
Merge pull request #29 from JXRepo/Jun_2025_10_26
Finished updating docstring in Kanapy/src /kanapy/
2 parents cbb4b8b + 7106b58 commit 61d0085

File tree

14 files changed

+4269
-947
lines changed

14 files changed

+4269
-947
lines changed

src/kanapy/core/api.py

Lines changed: 563 additions & 132 deletions
Large diffs are not rendered by default.

src/kanapy/core/cli.py

Lines changed: 112 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,23 @@ def main(ctx):
1818
@main.command(name='gui')
1919
@click.pass_context
2020
def gui(ctx):
21-
""" Start Kanapy's GUI (experimental alpha-version). """
21+
"""
22+
Start Kanapy's graphical user interface (experimental alpha version)
23+
24+
This function initializes and launches the Kanapy GUI using Tkinter.
25+
It creates a main application window with multiple tabs for different
26+
RVE generation modes, such as particle-based and cuboid-based RVEs.
27+
28+
Parameters
29+
----------
30+
ctx : object
31+
Execution context (reserved for CLI or application integration)
32+
33+
Notes
34+
-----
35+
- This GUI version is experimental and intended for testing only
36+
- Requires `matplotlib` and `tkinter` libraries
37+
"""
2238
import matplotlib.pyplot as plt
2339
import tkinter as tk
2440
import tkinter.font as tkFont
@@ -54,7 +70,26 @@ def gui(ctx):
5470
@click.option('--no_texture', default=False)
5571
@click.pass_context
5672
def tests(ctx, no_texture: bool):
57-
""" Runs unittests built within kanapy."""
73+
"""
74+
Run Kanapy's internal unittests
75+
76+
Executes the built-in test suite for Kanapy using pytest.
77+
Depending on the `no_texture` flag, it either runs a subset of tests
78+
or all available tests in the `tests` directory.
79+
80+
Parameters
81+
----------
82+
ctx : object
83+
Execution context (reserved for CLI or internal use)
84+
no_texture : bool
85+
If True, run tests excluding texture-related modules;
86+
if False, run the full test suite
87+
88+
Notes
89+
-----
90+
- Must be executed from the root directory of the Kanapy installation
91+
- Temporary dump files generated during testing are automatically removed
92+
"""
5893
click.echo('Will only work in root directory of kanapy installation.')
5994
cwd = os.getcwd()
6095
if no_texture:
@@ -73,16 +108,40 @@ def tests(ctx, no_texture: bool):
73108
@main.command(name='readDocs')
74109
@click.pass_context
75110
def docs(ctx):
76-
"""Open webpage with Kanapy documentation."""
111+
"""
112+
Open the Kanapy documentation webpage
113+
114+
Launches the default web browser and navigates to the official
115+
Kanapy documentation page hosted on GitHub Pages.
116+
117+
Parameters
118+
----------
119+
ctx : object
120+
Execution context (reserved for CLI or internal use)
121+
"""
77122
webbrowser.open("https://icams.github.io/Kanapy/")
78123

79124

80125
@main.command(name='copyExamples')
81126
@click.pass_context
82127
def download_subdir(ctx):
83128
"""
84-
Download examples from Kanapy's GitHub repository.
129+
Download example files from Kanapy's GitHub repository
130+
131+
Fetches the latest Kanapy repository archive from GitHub,
132+
extracts the `examples` subdirectory, and saves it to the local
133+
working directory as `kanapy_examples`.
85134
135+
Parameters
136+
----------
137+
ctx : object
138+
Execution context (reserved for CLI or internal use)
139+
140+
Notes
141+
-----
142+
- Requires an active internet connection
143+
- Downloads from the `master` branch of the Kanapy repository
144+
- Automatically creates the output directory if it does not exist
86145
"""
87146
zip_url = f"https://github.com/ICAMS/kanapy/archive/refs/heads/master.zip"
88147
output_dir = os.path.join(os.getcwd(), 'kanapy_examples')
@@ -113,12 +172,42 @@ def download_subdir(ctx):
113172
@main.command(name='setupMTEX')
114173
@click.pass_context
115174
def setup_mtex(ctx):
116-
""" Starts Matlab engine and initializes MTEX."""
175+
"""
176+
Start the MATLAB engine and initialize MTEX
177+
178+
Launches the MATLAB engine from Python and sets up the
179+
MTEX toolbox environment for crystallographic computations.
180+
181+
Parameters
182+
----------
183+
ctx : object
184+
Execution context (reserved for CLI or internal use)
185+
186+
Notes
187+
-----
188+
- Requires MATLAB and the MTEX toolbox to be installed
189+
- Calls `setPaths()` to configure MATLAB path settings
190+
"""
117191
setPaths()
118192

119193

120194
def chkVersion(matlab):
121-
""" Read the version of Matlab"""
195+
"""
196+
Read the installed MATLAB version from a version string
197+
198+
Parses the given MATLAB version string to extract the release year
199+
(e.g., 'R2023a' → 2023). If the version cannot be determined, returns None.
200+
201+
Parameters
202+
----------
203+
matlab : str
204+
String containing MATLAB version information
205+
206+
Returns
207+
-------
208+
int or None
209+
MATLAB release year if successfully parsed, otherwise None
210+
"""
122211
ind = matlab.find('R20')
123212
if ind < 0:
124213
version = None
@@ -132,7 +221,23 @@ def chkVersion(matlab):
132221

133222

134223
def setPaths():
135-
""" Starts matlab engine, after installation if required, and initializes MTEX.
224+
"""
225+
Start the MATLAB engine and initialize the MTEX environment
226+
227+
Checks if the MATLAB engine for Python is installed and installs it if missing.
228+
Then initializes the MATLAB engine and MTEX toolbox for use with Kanapy.
229+
230+
Raises
231+
------
232+
ModuleNotFoundError
233+
If `kanapy-mtex` or MATLAB are not installed,
234+
or if the MATLAB engine installation fails
235+
236+
Notes
237+
-----
238+
- Requires MATLAB 2025a or later
239+
- Automatically installs the `matlabengine` package if not found
240+
- Configures Kanapy for texture analysis by running `init_engine.py`
136241
"""
137242
try:
138243
from kanapy_mtex import ROOT_DIR

src/kanapy/core/collisions.py

Lines changed: 94 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,30 @@
44

55
def collision_routine(E1, E2):
66
"""
7-
Calls the method :meth:'collide_detect' to determine whether the given two ellipsoid objects overlap using
8-
the Algebraic separation condition developed by W. Wang et al. A detailed description is provided
9-
therein.
10-
11-
Also calls the :meth:`collision_react` to evaluate the response after collision.
12-
13-
:param E1: Ellipsoid :math:`i`
14-
:type E1: object :obj:`Ellipsoid`
15-
:param E2: Ellipsoid :math:`j`
16-
:type E2: object :obj:`Ellipsoid`
17-
18-
.. note:: 1. If both the particles to be tested for overlap are spheres, then the bounding sphere hierarchy is
19-
sufficient to determine whether they overlap.
20-
2. Else, if either of them is an ellipsoid, then their coefficients, positions & rotation matrices are
21-
used to determine whether they overlap.
7+
Detect and handle collision between two ellipsoid objects
8+
9+
Uses the algebraic separation condition by W. Wang et al. to detect overlap
10+
between two ellipsoids, and if a collision occurs, computes the contact
11+
response via the `collision_react` method.
12+
13+
Parameters
14+
----------
15+
E1 : Ellipsoid
16+
First ellipsoid object (particle i)
17+
E2 : Ellipsoid
18+
Second ellipsoid object (particle j)
19+
20+
Returns
21+
-------
22+
bool
23+
True if overlap (collision) is detected, False otherwise
24+
25+
Notes
26+
-----
27+
- If both particles are spheres, the bounding sphere hierarchy alone
28+
suffices to detect collision.
29+
- If either particle is an ellipsoid, their coefficients, positions,
30+
and rotation matrices are used in the overlap test.
2231
"""
2332

2433
# call the collision detection algorithm
@@ -31,44 +40,45 @@ def collision_routine(E1, E2):
3140

3241

3342
def collision_react(ell1, ell2):
34-
r"""
35-
Evaluates and modifies the magnitude and direction of the ellipsoid's velocity after collision.
36-
37-
:param ell1: Ellipsoid :math:`i`
38-
:type ell1: object :obj:`Ellipsoid`
39-
:param ell2: Ellipsoid :math:`j`
40-
:type ell2: object :obj:`Ellipsoid`
41-
42-
.. note:: Consider two ellipsoids :math:`i, j` at collision. Let them occupy certain positions in space
43-
defined by the position vectors :math:`\mathbf{r}^{i}, \mathbf{r}^{j}` and have certain
44-
velocities represented by :math:`\mathbf{v}^{i}, \mathbf{v}^{j}` respectively. The objective
45-
is to find the velocity vectors after collision. The elevation angle :math:`\phi` between
46-
the ellipsoids is determined by,
47-
48-
.. image:: /figs/elevation_ell.png
49-
:width: 200px
50-
:height: 45px
51-
:align: center
52-
53-
where :math:`dx, dy, dz` are defined as the distance between the two ellipsoid centers along
54-
:math:`x, y, z` directions given by,
55-
56-
.. image:: /figs/dist_ell.png
57-
:width: 110px
58-
:height: 75px
59-
:align: center
60-
61-
Depending on the magnitudes of :math:`dx, dz` as projected on the :math:`x-z` plane, the angle
62-
:math:`\Theta` is computed.
63-
The angles :math:`\Theta` and :math:`\phi` determine the in-plane and out-of-plane directions along which
64-
the ellipsoid :math:`i` would bounce back after collision. Thus, the updated velocity vector components
65-
along the :math:`x, y, z` directions are determined by,
66-
67-
.. image:: /figs/velocities_ell.png
68-
:width: 180px
69-
:height: 80px
70-
:align: center
71-
43+
"""
44+
Evaluates and modifies the magnitude and direction of the ellipsoid's velocity after collision
45+
46+
Parameters
47+
----------
48+
ell1 : Ellipsoid
49+
Ellipsoid i
50+
ell2 : Ellipsoid
51+
Ellipsoid j
52+
53+
Notes
54+
-----
55+
Consider two ellipsoids i, j at collision. Let them occupy certain positions in space
56+
defined by the position vectors r^i, r^j and have certain velocities represented by v^i, v^j
57+
respectively. The objective is to find the velocity vectors after collision. The elevation angle φ
58+
between the ellipsoids is determined by:
59+
60+
.. image:: /figs/elevation_ell.png
61+
:width: 200px
62+
:height: 45px
63+
:align: center
64+
65+
where dx, dy, dz are defined as the distance between the two ellipsoid centers along
66+
x, y, z directions given by:
67+
68+
.. image:: /figs/dist_ell.png
69+
:width: 110px
70+
:height: 75px
71+
:align: center
72+
73+
Depending on the magnitudes of dx, dz as projected on the x-z plane, the angle Θ is computed.
74+
The angles Θ and φ determine the in-plane and out-of-plane directions along which
75+
ellipsoid i would bounce back after collision. Thus, the updated velocity vector components
76+
along the x, y, z directions are determined by:
77+
78+
.. image:: /figs/velocities_ell.png
79+
:width: 180px
80+
:height: 80px
81+
:align: center
7282
"""
7383
cdir = ell1.get_pos() - ell2.get_pos()
7484
dst = np.linalg.norm(cdir)
@@ -87,24 +97,37 @@ def collision_react(ell1, ell2):
8797

8898

8999
def collide_detect(coef_i, coef_j, r_i, r_j, A_i, A_j):
90-
r"""Implementation of Algebraic separation condition developed by
91-
W. Wang et al. 2001 for overlap detection between two static ellipsoids.
92-
Kudos to ChatGPT for support with translation from C++ code.
93-
94-
:param coef_i: Coefficients of ellipsoid :math:`i`
95-
:type coef_i: numpy array
96-
:param coef_j: Coefficients of ellipsoid :math:`j`
97-
:type coef_j: numpy array
98-
:param r_i: Position of ellipsoid :math:`i`
99-
:type r_i: numpy array
100-
:param r_j: Position of ellipsoid :math:`j`
101-
:type r_j: numpy array
102-
:param A_i: Rotation matrix of ellipsoid :math:`i`
103-
:type A_i: numpy array
104-
:param A_j: Rotation matrix of ellipsoid :math:`j`
105-
:type A_j: numpy array
106-
:returns: **True** if ellipsoids :math:`i, j` overlap, else **False**
107-
:rtype: boolean
100+
"""
101+
Determines overlap between two static ellipsoids using the Algebraic Separation Condition
102+
developed by W. Wang et al., 2001. This function implements the method for two ellipsoids
103+
with given coefficients, positions, and rotation matrices
104+
105+
Parameters
106+
----------
107+
coef_i : numpy array
108+
Coefficients of ellipsoid i
109+
coef_j : numpy array
110+
Coefficients of ellipsoid j
111+
r_i : numpy array
112+
Position vector of ellipsoid i
113+
r_j : numpy array
114+
Position vector of ellipsoid j
115+
A_i : numpy array
116+
Rotation matrix of ellipsoid i
117+
A_j : numpy array
118+
Rotation matrix of ellipsoid j
119+
120+
Returns
121+
-------
122+
bool
123+
True if ellipsoids i and j overlap, False otherwise
124+
125+
Notes
126+
-----
127+
The method calculates the characteristic polynomial based on the ellipsoid coefficients
128+
and rigid body transformations. Roots of this polynomial are used with the Algebraic
129+
Separation Condition to determine whether the ellipsoids intersect. Real roots with
130+
negative values are analyzed to establish the overlap.
108131
"""
109132
SMALL = 1.e-12
110133

0 commit comments

Comments
 (0)