tfgt 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tfgt-0.1.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pan Guojun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
tfgt-0.1.0/MANIFEST.in ADDED
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ recursive-include tfgt *.py
4
+
tfgt-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: tfgt
3
+ Version: 0.1.0
4
+ Summary: Topological Free-energy Gradient Theory toolkit for fluid-topology computation with NS++ topological forcing.
5
+ Home-page: https://github.com/panguojun/tfgt
6
+ Author: Pan Guojun
7
+ Author-email: Pan Guojun <18858146@qq.com>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://github.com/panguojun/tfgt
10
+ Project-URL: Repository, https://github.com/panguojun/tfgt
11
+ Project-URL: Documentation, https://github.com/panguojun/tfgt#readme
12
+ Project-URL: Bug Reports, https://github.com/panguojun/tfgt/issues
13
+ Keywords: fluid,topology,navier-stokes,thermodynamics,free-energy,scientific-computing,numpy
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Topic :: Scientific/Engineering :: Physics
18
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
19
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Operating System :: OS Independent
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy>=1.22
31
+ Provides-Extra: dev
32
+ Requires-Dist: build>=1.2.0; extra == "dev"
33
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
34
+ Requires-Dist: twine>=5.0.0; extra == "dev"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # TFGT
41
+
42
+ TFGT (`tfgt`) is a Python package for fluid-topology computation based on the
43
+ Topological Free-energy Gradient Theory.
44
+
45
+ Core modeling identity:
46
+
47
+ ```text
48
+ f_top = -lambda * grad(F_top)
49
+ ```
50
+
51
+ This equivalent topological force can be injected into an NS++ momentum model:
52
+
53
+ ```text
54
+ rho * Du/Dt = -grad(p) + div(tau) - lambda * grad(F_top)
55
+ ```
56
+
57
+ ## Theory Snapshot
58
+
59
+ This package is initialized from the research note:
60
+
61
+ `C:\Users\18858\Desktop\MD_2026-04-28_10-09-36_668.md`
62
+
63
+ Canonical baseline parameters implemented here:
64
+
65
+ - `lambda0 = 4*pi*alpha`
66
+ - `E0 = 0.026 eV`
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ pip install tfgt
72
+ ```
73
+
74
+ From source:
75
+
76
+ ```bash
77
+ pip install .
78
+ ```
79
+
80
+ ## Quick Start
81
+
82
+ ```python
83
+ import numpy as np
84
+ from tfgt import TFGTParameters, topological_force, nspp_rhs, topological_activity_index
85
+
86
+ # Build a synthetic free-energy field F_top on a 2D grid.
87
+ x = np.linspace(-1.0, 1.0, 64)
88
+ y = np.linspace(-1.0, 1.0, 64)
89
+ xx, yy = np.meshgrid(x, y, indexing="ij")
90
+ F_top = np.exp(-6.0 * (xx**2 + yy**2))
91
+
92
+ params = TFGTParameters()
93
+ force = topological_force(F_top, lambda_top=params.lambda0, spacing=(x[1] - x[0], y[1] - y[0]))
94
+
95
+ rho = 1.0
96
+ pressure_gradient = np.zeros_like(force)
97
+ tau_divergence = np.zeros_like(force)
98
+ velocity = np.zeros_like(force)
99
+
100
+ dudt = nspp_rhs(
101
+ velocity=velocity,
102
+ rho=rho,
103
+ pressure_gradient=pressure_gradient,
104
+ tau_divergence=tau_divergence,
105
+ f_top=F_top,
106
+ lambda_top=params.lambda0,
107
+ spacing=(x[1] - x[0], y[1] - y[0]),
108
+ )
109
+
110
+ print("dudt shape:", dudt.shape)
111
+ print("TAI:", topological_activity_index(F_top, lambda_top=params.lambda0))
112
+ ```
113
+
114
+ ## API
115
+
116
+ - `TFGTParameters`: canonical parameter container (`alpha`, `lambda0`, `E0`)
117
+ - `gradient_nd`, `laplacian_nd`: finite-difference scalar field operators
118
+ - `topological_force`: equivalent topology force from free-energy field
119
+ - `nspp_acceleration`, `nspp_rhs`: NS++ helper terms
120
+ - `vorticity_2d`, `helicity_density_3d`, `enstrophy_2d`, `topological_activity_index`
121
+
122
+ ## Build and Publish
123
+
124
+ Install dev tooling:
125
+
126
+ ```bash
127
+ pip install -e .[dev]
128
+ ```
129
+
130
+ Run tests:
131
+
132
+ ```bash
133
+ pytest -q
134
+ ```
135
+
136
+ Build package:
137
+
138
+ ```bash
139
+ python -m build
140
+ ```
141
+
142
+ Validate artifacts:
143
+
144
+ ```bash
145
+ python -m twine check dist/*
146
+ ```
147
+
148
+ Upload:
149
+
150
+ ```bash
151
+ python -m twine upload dist/*
152
+ ```
153
+
154
+ ## Scientific Scope
155
+
156
+ `tfgt` currently provides a computational core and reference utilities for
157
+ fluid-topology workflows. It does not claim experimental validation by itself.
158
+ Use this library together with your own data, calibration, and falsifiability
159
+ protocols.
160
+
161
+ ## License
162
+
163
+ MIT License.
164
+
tfgt-0.1.0/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # TFGT
2
+
3
+ TFGT (`tfgt`) is a Python package for fluid-topology computation based on the
4
+ Topological Free-energy Gradient Theory.
5
+
6
+ Core modeling identity:
7
+
8
+ ```text
9
+ f_top = -lambda * grad(F_top)
10
+ ```
11
+
12
+ This equivalent topological force can be injected into an NS++ momentum model:
13
+
14
+ ```text
15
+ rho * Du/Dt = -grad(p) + div(tau) - lambda * grad(F_top)
16
+ ```
17
+
18
+ ## Theory Snapshot
19
+
20
+ This package is initialized from the research note:
21
+
22
+ `C:\Users\18858\Desktop\MD_2026-04-28_10-09-36_668.md`
23
+
24
+ Canonical baseline parameters implemented here:
25
+
26
+ - `lambda0 = 4*pi*alpha`
27
+ - `E0 = 0.026 eV`
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install tfgt
33
+ ```
34
+
35
+ From source:
36
+
37
+ ```bash
38
+ pip install .
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ```python
44
+ import numpy as np
45
+ from tfgt import TFGTParameters, topological_force, nspp_rhs, topological_activity_index
46
+
47
+ # Build a synthetic free-energy field F_top on a 2D grid.
48
+ x = np.linspace(-1.0, 1.0, 64)
49
+ y = np.linspace(-1.0, 1.0, 64)
50
+ xx, yy = np.meshgrid(x, y, indexing="ij")
51
+ F_top = np.exp(-6.0 * (xx**2 + yy**2))
52
+
53
+ params = TFGTParameters()
54
+ force = topological_force(F_top, lambda_top=params.lambda0, spacing=(x[1] - x[0], y[1] - y[0]))
55
+
56
+ rho = 1.0
57
+ pressure_gradient = np.zeros_like(force)
58
+ tau_divergence = np.zeros_like(force)
59
+ velocity = np.zeros_like(force)
60
+
61
+ dudt = nspp_rhs(
62
+ velocity=velocity,
63
+ rho=rho,
64
+ pressure_gradient=pressure_gradient,
65
+ tau_divergence=tau_divergence,
66
+ f_top=F_top,
67
+ lambda_top=params.lambda0,
68
+ spacing=(x[1] - x[0], y[1] - y[0]),
69
+ )
70
+
71
+ print("dudt shape:", dudt.shape)
72
+ print("TAI:", topological_activity_index(F_top, lambda_top=params.lambda0))
73
+ ```
74
+
75
+ ## API
76
+
77
+ - `TFGTParameters`: canonical parameter container (`alpha`, `lambda0`, `E0`)
78
+ - `gradient_nd`, `laplacian_nd`: finite-difference scalar field operators
79
+ - `topological_force`: equivalent topology force from free-energy field
80
+ - `nspp_acceleration`, `nspp_rhs`: NS++ helper terms
81
+ - `vorticity_2d`, `helicity_density_3d`, `enstrophy_2d`, `topological_activity_index`
82
+
83
+ ## Build and Publish
84
+
85
+ Install dev tooling:
86
+
87
+ ```bash
88
+ pip install -e .[dev]
89
+ ```
90
+
91
+ Run tests:
92
+
93
+ ```bash
94
+ pytest -q
95
+ ```
96
+
97
+ Build package:
98
+
99
+ ```bash
100
+ python -m build
101
+ ```
102
+
103
+ Validate artifacts:
104
+
105
+ ```bash
106
+ python -m twine check dist/*
107
+ ```
108
+
109
+ Upload:
110
+
111
+ ```bash
112
+ python -m twine upload dist/*
113
+ ```
114
+
115
+ ## Scientific Scope
116
+
117
+ `tfgt` currently provides a computational core and reference utilities for
118
+ fluid-topology workflows. It does not claim experimental validation by itself.
119
+ Use this library together with your own data, calibration, and falsifiability
120
+ protocols.
121
+
122
+ ## License
123
+
124
+ MIT License.
125
+
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tfgt"
7
+ version = "0.1.0"
8
+ description = "Topological Free-energy Gradient Theory toolkit for fluid-topology computation with NS++ topological forcing."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Pan Guojun", email = "18858146@qq.com" }
14
+ ]
15
+ keywords = [
16
+ "fluid",
17
+ "topology",
18
+ "navier-stokes",
19
+ "thermodynamics",
20
+ "free-energy",
21
+ "scientific-computing",
22
+ "numpy"
23
+ ]
24
+ classifiers = [
25
+ "Development Status :: 3 - Alpha",
26
+ "Intended Audience :: Developers",
27
+ "Intended Audience :: Science/Research",
28
+ "Topic :: Scientific/Engineering :: Physics",
29
+ "Topic :: Scientific/Engineering :: Mathematics",
30
+ "Topic :: Scientific/Engineering :: Information Analysis",
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.9",
33
+ "Programming Language :: Python :: 3.10",
34
+ "Programming Language :: Python :: 3.11",
35
+ "Programming Language :: Python :: 3.12",
36
+ "Programming Language :: Python :: 3.13",
37
+ "Operating System :: OS Independent"
38
+ ]
39
+ dependencies = [
40
+ "numpy>=1.22"
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ dev = [
45
+ "build>=1.2.0",
46
+ "pytest>=8.0.0",
47
+ "twine>=5.0.0"
48
+ ]
49
+
50
+ [project.urls]
51
+ Homepage = "https://github.com/panguojun/tfgt"
52
+ Repository = "https://github.com/panguojun/tfgt"
53
+ Documentation = "https://github.com/panguojun/tfgt#readme"
54
+ "Bug Reports" = "https://github.com/panguojun/tfgt/issues"
55
+
56
+ [tool.setuptools]
57
+ include-package-data = true
58
+
59
+ [tool.setuptools.packages.find]
60
+ include = ["tfgt*"]
tfgt-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
tfgt-0.1.0/setup.py ADDED
@@ -0,0 +1,24 @@
1
+ from setuptools import setup, find_packages
2
+
3
+
4
+ setup(
5
+ name="tfgt",
6
+ version="0.1.0",
7
+ packages=find_packages(),
8
+ include_package_data=True,
9
+ description=(
10
+ "Topological Free-energy Gradient Theory toolkit for fluid-topology "
11
+ "computation with NS++ topological forcing."
12
+ ),
13
+ long_description=open("README.md", encoding="utf-8").read(),
14
+ long_description_content_type="text/markdown",
15
+ author="Pan Guojun",
16
+ author_email="18858146@qq.com",
17
+ url="https://github.com/panguojun/tfgt",
18
+ python_requires=">=3.9",
19
+ classifiers=[
20
+ "Programming Language :: Python :: 3",
21
+ "Operating System :: OS Independent",
22
+ "Topic :: Scientific/Engineering :: Physics",
23
+ ],
24
+ )
@@ -0,0 +1,41 @@
1
+ import numpy as np
2
+
3
+ from tfgt import TFGTParameters, nspp_rhs, topological_force, topological_activity_index
4
+
5
+
6
+ def test_topological_force_shape() -> None:
7
+ x = np.linspace(-1.0, 1.0, 32)
8
+ y = np.linspace(-1.0, 1.0, 24)
9
+ xx, yy = np.meshgrid(x, y, indexing="ij")
10
+ f_top = xx**2 + yy**2
11
+ force = topological_force(f_top, spacing=(x[1] - x[0], y[1] - y[0]))
12
+ assert force.shape == (2, 32, 24)
13
+
14
+
15
+ def test_nspp_rhs_shape() -> None:
16
+ n = 16
17
+ f_top = np.random.default_rng(123).normal(size=(n, n))
18
+ velocity = np.zeros((2, n, n), dtype=float)
19
+ zero = np.zeros_like(velocity)
20
+ params = TFGTParameters()
21
+
22
+ rhs = nspp_rhs(
23
+ velocity=velocity,
24
+ rho=1.0,
25
+ pressure_gradient=zero,
26
+ tau_divergence=zero,
27
+ f_top=f_top,
28
+ lambda_top=params.lambda0,
29
+ spacing=1.0,
30
+ )
31
+ assert rhs.shape == velocity.shape
32
+
33
+
34
+ def test_topological_activity_index_positive() -> None:
35
+ x = np.linspace(-2.0, 2.0, 20)
36
+ y = np.linspace(-2.0, 2.0, 20)
37
+ xx, yy = np.meshgrid(x, y, indexing="ij")
38
+ f_top = np.exp(-(xx * xx + yy * yy))
39
+ value = topological_activity_index(f_top)
40
+ assert value > 0.0
41
+
@@ -0,0 +1,36 @@
1
+ """
2
+ TFGT: Topological Free-energy Gradient Theory toolkit.
3
+
4
+ Core equation implemented in this package:
5
+ f_top = -lambda * grad(F_top)
6
+ """
7
+
8
+ from .constants import TFGTParameters, alpha_default, lambda0_default, e0_default_ev
9
+ from .fields import gradient_nd, laplacian_nd
10
+ from .forces import topological_force
11
+ from .nspp import nspp_acceleration, nspp_rhs
12
+ from .metrics import (
13
+ vorticity_2d,
14
+ helicity_density_3d,
15
+ enstrophy_2d,
16
+ topological_activity_index,
17
+ )
18
+
19
+ __all__ = [
20
+ "TFGTParameters",
21
+ "alpha_default",
22
+ "lambda0_default",
23
+ "e0_default_ev",
24
+ "gradient_nd",
25
+ "laplacian_nd",
26
+ "topological_force",
27
+ "nspp_acceleration",
28
+ "nspp_rhs",
29
+ "vorticity_2d",
30
+ "helicity_density_3d",
31
+ "enstrophy_2d",
32
+ "topological_activity_index",
33
+ ]
34
+
35
+ __version__ = "0.1.0"
36
+
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ import math
5
+
6
+ alpha_default: float = 1.0 / 137.035999084
7
+ e0_default_ev: float = 0.026
8
+ lambda0_default: float = 4.0 * math.pi * alpha_default
9
+
10
+ EV_TO_J = 1.602176634e-19
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class TFGTParameters:
15
+ """
16
+ Canonical TFGT parameters.
17
+
18
+ The baseline matches the initial research note:
19
+ lambda_0 ~ 4*pi*alpha
20
+ E0 = 0.026 eV
21
+ """
22
+
23
+ alpha: float = alpha_default
24
+ e0_ev: float = e0_default_ev
25
+
26
+ @property
27
+ def lambda0(self) -> float:
28
+ return 4.0 * math.pi * self.alpha
29
+
30
+ @property
31
+ def e0_joule(self) -> float:
32
+ return self.e0_ev * EV_TO_J
33
+
@@ -0,0 +1,39 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Iterable, Sequence
4
+ import numpy as np
5
+
6
+ ArrayLike = np.ndarray
7
+
8
+
9
+ def _normalize_spacing(ndim: int, spacing: float | Sequence[float]) -> tuple[float, ...]:
10
+ if isinstance(spacing, (int, float)):
11
+ return (float(spacing),) * ndim
12
+ s = tuple(float(v) for v in spacing)
13
+ if len(s) != ndim:
14
+ raise ValueError(f"spacing length ({len(s)}) must equal ndim ({ndim})")
15
+ return s
16
+
17
+
18
+ def gradient_nd(field: ArrayLike, spacing: float | Sequence[float] = 1.0) -> list[np.ndarray]:
19
+ """
20
+ Return grad(field) for an N-D scalar field using finite differences.
21
+ """
22
+ arr = np.asarray(field, dtype=float)
23
+ ds = _normalize_spacing(arr.ndim, spacing)
24
+ return list(np.gradient(arr, *ds, edge_order=2))
25
+
26
+
27
+ def laplacian_nd(field: ArrayLike, spacing: float | Sequence[float] = 1.0) -> np.ndarray:
28
+ """
29
+ Return the N-D Laplacian sum_i d2(field)/dx_i^2 from central differences.
30
+ """
31
+ arr = np.asarray(field, dtype=float)
32
+ ds = _normalize_spacing(arr.ndim, spacing)
33
+ grad = np.gradient(arr, *ds, edge_order=2)
34
+ lap = np.zeros_like(arr, dtype=float)
35
+ for axis, (g, d) in enumerate(zip(grad, ds)):
36
+ dgi = np.gradient(g, d, axis=axis, edge_order=2)
37
+ lap += dgi
38
+ return lap
39
+
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Sequence
4
+ import numpy as np
5
+
6
+ from .constants import lambda0_default
7
+ from .fields import gradient_nd
8
+
9
+
10
+ def topological_force(
11
+ f_top: np.ndarray,
12
+ *,
13
+ lambda_top: float = lambda0_default,
14
+ spacing: float | Sequence[float] = 1.0,
15
+ ) -> np.ndarray:
16
+ """
17
+ Compute equivalent topological force field:
18
+ f = -lambda_top * grad(F_top)
19
+
20
+ Returns an array with shape (ndim, ...).
21
+ """
22
+ grad_f = gradient_nd(f_top, spacing=spacing)
23
+ return -float(lambda_top) * np.stack(grad_f, axis=0)
24
+
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Sequence
4
+ import numpy as np
5
+
6
+ from .fields import gradient_nd
7
+ from .forces import topological_force
8
+ from .constants import lambda0_default
9
+
10
+
11
+ def vorticity_2d(velocity: np.ndarray, spacing: float | Sequence[float] = 1.0) -> np.ndarray:
12
+ """
13
+ Return scalar vorticity for 2D velocity field [u, v]:
14
+ omega_z = dv/dx - du/dy
15
+ """
16
+ vel = np.asarray(velocity, dtype=float)
17
+ if vel.ndim != 3 or vel.shape[0] != 2:
18
+ raise ValueError("velocity must have shape (2, nx, ny)")
19
+
20
+ u, v = vel[0], vel[1]
21
+ if isinstance(spacing, (int, float)):
22
+ dx = dy = float(spacing)
23
+ else:
24
+ dx, dy = spacing
25
+
26
+ du_dy = np.gradient(u, dy, axis=1, edge_order=2)
27
+ dv_dx = np.gradient(v, dx, axis=0, edge_order=2)
28
+ return dv_dx - du_dy
29
+
30
+
31
+ def helicity_density_3d(velocity: np.ndarray, spacing: float | Sequence[float] = 1.0) -> np.ndarray:
32
+ """
33
+ Return helicity density h = u . (curl u) for 3D velocity field [u, v, w].
34
+ """
35
+ vel = np.asarray(velocity, dtype=float)
36
+ if vel.ndim != 4 or vel.shape[0] != 3:
37
+ raise ValueError("velocity must have shape (3, nx, ny, nz)")
38
+
39
+ u, v, w = vel
40
+ if isinstance(spacing, (int, float)):
41
+ dx = dy = dz = float(spacing)
42
+ else:
43
+ dx, dy, dz = spacing
44
+
45
+ du_dy = np.gradient(u, dy, axis=1, edge_order=2)
46
+ du_dz = np.gradient(u, dz, axis=2, edge_order=2)
47
+ dv_dx = np.gradient(v, dx, axis=0, edge_order=2)
48
+ dv_dz = np.gradient(v, dz, axis=2, edge_order=2)
49
+ dw_dx = np.gradient(w, dx, axis=0, edge_order=2)
50
+ dw_dy = np.gradient(w, dy, axis=1, edge_order=2)
51
+
52
+ curl_x = dw_dy - dv_dz
53
+ curl_y = du_dz - dw_dx
54
+ curl_z = dv_dx - du_dy
55
+ return u * curl_x + v * curl_y + w * curl_z
56
+
57
+
58
+ def enstrophy_2d(velocity: np.ndarray, spacing: float | Sequence[float] = 1.0) -> float:
59
+ """
60
+ Return integral-like enstrophy proxy in 2D:
61
+ E = 0.5 * mean(omega^2)
62
+ """
63
+ omega = vorticity_2d(velocity, spacing=spacing)
64
+ return 0.5 * float(np.mean(omega * omega))
65
+
66
+
67
+ def topological_activity_index(
68
+ f_top: np.ndarray,
69
+ *,
70
+ lambda_top: float = lambda0_default,
71
+ spacing: float | Sequence[float] = 1.0,
72
+ ) -> float:
73
+ """
74
+ A compact scalar intensity for topology-driven forcing:
75
+ TAI = mean(||-lambda*grad(F_top)||_2)
76
+ """
77
+ force = topological_force(f_top, lambda_top=lambda_top, spacing=spacing)
78
+ mag = np.linalg.norm(force, axis=0)
79
+ return float(np.mean(mag))
80
+
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Sequence
4
+ import numpy as np
5
+
6
+ from .forces import topological_force
7
+
8
+
9
+ def nspp_acceleration(
10
+ rho: float | np.ndarray,
11
+ pressure_gradient: np.ndarray,
12
+ tau_divergence: np.ndarray,
13
+ f_top: np.ndarray,
14
+ *,
15
+ lambda_top: float,
16
+ spacing: float | Sequence[float] = 1.0,
17
+ ) -> np.ndarray:
18
+ """
19
+ NS++ acceleration term:
20
+ Du/Dt = (-grad(p) + div(tau) - lambda*grad(F_top)) / rho
21
+
22
+ The first axis of pressure_gradient and tau_divergence is vector dimension.
23
+ """
24
+ rho_arr = np.asarray(rho, dtype=float)
25
+ p_grad = np.asarray(pressure_gradient, dtype=float)
26
+ tau_div = np.asarray(tau_divergence, dtype=float)
27
+ f_eq = topological_force(f_top, lambda_top=lambda_top, spacing=spacing)
28
+ if p_grad.shape != tau_div.shape or p_grad.shape != f_eq.shape:
29
+ raise ValueError(
30
+ "pressure_gradient, tau_divergence and topological force must share shape"
31
+ )
32
+ return (-p_grad + tau_div + f_eq) / rho_arr
33
+
34
+
35
+ def nspp_rhs(
36
+ velocity: np.ndarray,
37
+ rho: float | np.ndarray,
38
+ pressure_gradient: np.ndarray,
39
+ tau_divergence: np.ndarray,
40
+ f_top: np.ndarray,
41
+ *,
42
+ lambda_top: float,
43
+ spacing: float | Sequence[float] = 1.0,
44
+ ) -> np.ndarray:
45
+ """
46
+ Simple explicit RHS helper:
47
+ dU/dt = NS++ acceleration
48
+
49
+ This function is solver-agnostic and intended to be plugged into user time
50
+ integrators (Euler/RK/IMEX/etc.).
51
+ """
52
+ _ = np.asarray(velocity, dtype=float)
53
+ return nspp_acceleration(
54
+ rho=rho,
55
+ pressure_gradient=pressure_gradient,
56
+ tau_divergence=tau_divergence,
57
+ f_top=f_top,
58
+ lambda_top=lambda_top,
59
+ spacing=spacing,
60
+ )
61
+
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: tfgt
3
+ Version: 0.1.0
4
+ Summary: Topological Free-energy Gradient Theory toolkit for fluid-topology computation with NS++ topological forcing.
5
+ Home-page: https://github.com/panguojun/tfgt
6
+ Author: Pan Guojun
7
+ Author-email: Pan Guojun <18858146@qq.com>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://github.com/panguojun/tfgt
10
+ Project-URL: Repository, https://github.com/panguojun/tfgt
11
+ Project-URL: Documentation, https://github.com/panguojun/tfgt#readme
12
+ Project-URL: Bug Reports, https://github.com/panguojun/tfgt/issues
13
+ Keywords: fluid,topology,navier-stokes,thermodynamics,free-energy,scientific-computing,numpy
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Topic :: Scientific/Engineering :: Physics
18
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
19
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Operating System :: OS Independent
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy>=1.22
31
+ Provides-Extra: dev
32
+ Requires-Dist: build>=1.2.0; extra == "dev"
33
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
34
+ Requires-Dist: twine>=5.0.0; extra == "dev"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # TFGT
41
+
42
+ TFGT (`tfgt`) is a Python package for fluid-topology computation based on the
43
+ Topological Free-energy Gradient Theory.
44
+
45
+ Core modeling identity:
46
+
47
+ ```text
48
+ f_top = -lambda * grad(F_top)
49
+ ```
50
+
51
+ This equivalent topological force can be injected into an NS++ momentum model:
52
+
53
+ ```text
54
+ rho * Du/Dt = -grad(p) + div(tau) - lambda * grad(F_top)
55
+ ```
56
+
57
+ ## Theory Snapshot
58
+
59
+ This package is initialized from the research note:
60
+
61
+ `C:\Users\18858\Desktop\MD_2026-04-28_10-09-36_668.md`
62
+
63
+ Canonical baseline parameters implemented here:
64
+
65
+ - `lambda0 = 4*pi*alpha`
66
+ - `E0 = 0.026 eV`
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ pip install tfgt
72
+ ```
73
+
74
+ From source:
75
+
76
+ ```bash
77
+ pip install .
78
+ ```
79
+
80
+ ## Quick Start
81
+
82
+ ```python
83
+ import numpy as np
84
+ from tfgt import TFGTParameters, topological_force, nspp_rhs, topological_activity_index
85
+
86
+ # Build a synthetic free-energy field F_top on a 2D grid.
87
+ x = np.linspace(-1.0, 1.0, 64)
88
+ y = np.linspace(-1.0, 1.0, 64)
89
+ xx, yy = np.meshgrid(x, y, indexing="ij")
90
+ F_top = np.exp(-6.0 * (xx**2 + yy**2))
91
+
92
+ params = TFGTParameters()
93
+ force = topological_force(F_top, lambda_top=params.lambda0, spacing=(x[1] - x[0], y[1] - y[0]))
94
+
95
+ rho = 1.0
96
+ pressure_gradient = np.zeros_like(force)
97
+ tau_divergence = np.zeros_like(force)
98
+ velocity = np.zeros_like(force)
99
+
100
+ dudt = nspp_rhs(
101
+ velocity=velocity,
102
+ rho=rho,
103
+ pressure_gradient=pressure_gradient,
104
+ tau_divergence=tau_divergence,
105
+ f_top=F_top,
106
+ lambda_top=params.lambda0,
107
+ spacing=(x[1] - x[0], y[1] - y[0]),
108
+ )
109
+
110
+ print("dudt shape:", dudt.shape)
111
+ print("TAI:", topological_activity_index(F_top, lambda_top=params.lambda0))
112
+ ```
113
+
114
+ ## API
115
+
116
+ - `TFGTParameters`: canonical parameter container (`alpha`, `lambda0`, `E0`)
117
+ - `gradient_nd`, `laplacian_nd`: finite-difference scalar field operators
118
+ - `topological_force`: equivalent topology force from free-energy field
119
+ - `nspp_acceleration`, `nspp_rhs`: NS++ helper terms
120
+ - `vorticity_2d`, `helicity_density_3d`, `enstrophy_2d`, `topological_activity_index`
121
+
122
+ ## Build and Publish
123
+
124
+ Install dev tooling:
125
+
126
+ ```bash
127
+ pip install -e .[dev]
128
+ ```
129
+
130
+ Run tests:
131
+
132
+ ```bash
133
+ pytest -q
134
+ ```
135
+
136
+ Build package:
137
+
138
+ ```bash
139
+ python -m build
140
+ ```
141
+
142
+ Validate artifacts:
143
+
144
+ ```bash
145
+ python -m twine check dist/*
146
+ ```
147
+
148
+ Upload:
149
+
150
+ ```bash
151
+ python -m twine upload dist/*
152
+ ```
153
+
154
+ ## Scientific Scope
155
+
156
+ `tfgt` currently provides a computational core and reference utilities for
157
+ fluid-topology workflows. It does not claim experimental validation by itself.
158
+ Use this library together with your own data, calibration, and falsifiability
159
+ protocols.
160
+
161
+ ## License
162
+
163
+ MIT License.
164
+
@@ -0,0 +1,17 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ setup.py
6
+ tests/test_tfgt_core.py
7
+ tfgt/__init__.py
8
+ tfgt/constants.py
9
+ tfgt/fields.py
10
+ tfgt/forces.py
11
+ tfgt/metrics.py
12
+ tfgt/nspp.py
13
+ tfgt.egg-info/PKG-INFO
14
+ tfgt.egg-info/SOURCES.txt
15
+ tfgt.egg-info/dependency_links.txt
16
+ tfgt.egg-info/requires.txt
17
+ tfgt.egg-info/top_level.txt
@@ -0,0 +1,6 @@
1
+ numpy>=1.22
2
+
3
+ [dev]
4
+ build>=1.2.0
5
+ pytest>=8.0.0
6
+ twine>=5.0.0
@@ -0,0 +1 @@
1
+ tfgt