Skip to content

Commit fcb277c

Browse files
1want2sleepUnityLikerHydrogenSulfate
authored
【PPSCI Doc No.66-74】 (#829)
* ppsci.equation.PDE.parameters/state_dict/set_state_dict api fix * ppsci.equation.PDE.parameters/state_dict/set_state_dict api fix * fix api docs in the timedomain * fix api docs of timedomain * fix api docs of timedomain --------- Co-authored-by: krp <2934631798@qq.com> Co-authored-by: HydrogenSulfate <490868991@qq.com>
1 parent 52c949f commit fcb277c

File tree

1 file changed

+197
-16
lines changed

1 file changed

+197
-16
lines changed

ppsci/geometry/timedomain.py

Lines changed: 197 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from __future__ import annotations
2020

2121
import itertools
22+
from typing import Callable
23+
from typing import Dict
2224
from typing import Optional
2325
from typing import Tuple
2426

@@ -60,17 +62,37 @@ def __init__(
6062
self.t0 = t0
6163
self.t1 = t1
6264
self.time_step = time_step
63-
self.timestamps = np.array(
64-
timestamps, dtype=paddle.get_default_dtype()
65-
).reshape([-1])
65+
if timestamps is None:
66+
self.timestamps = None
67+
else:
68+
self.timestamps = np.array(
69+
timestamps, dtype=paddle.get_default_dtype()
70+
).reshape([-1])
6671
if time_step is not None:
6772
if time_step <= 0:
6873
raise ValueError(f"time_step({time_step}) must be larger than 0.")
6974
self.num_timestamps = int(np.ceil((t1 - t0) / time_step)) + 1
7075
elif timestamps is not None:
7176
self.num_timestamps = len(timestamps)
7277

73-
def on_initial(self, t):
78+
def on_initial(self, t: np.ndarray):
79+
"""Check if a specific time is on the initial time point.
80+
81+
Args:
82+
t (np.ndarray): The time to be checked.
83+
84+
Returns:
85+
bool: True or False for whether the specific time is on the initial time point.
86+
87+
Examples:
88+
>>> import paddle
89+
>>> import ppsci
90+
>>> geom = ppsci.geometry.TimeDomain(0, 1)
91+
>>> T = [0, 0.01, 0.126, 0.2, 0.3]
92+
>>> check = geom.on_initial(T)
93+
>>> print(check)
94+
[ True False False False False]
95+
"""
7496
return np.isclose(t, self.t0).flatten()
7597

7698

@@ -110,11 +132,26 @@ def boundary_normal(self, x):
110132
normal = self.geometry.boundary_normal(x[:, 1:])
111133
return np.hstack((x[:, :1], normal))
112134

113-
def uniform_points(self, n, boundary=True):
135+
def uniform_points(self, n: int, boundary: bool = True):
114136
"""Uniform points on the spatial-temporal domain.
115-
116137
Geometry volume ~ bbox.
117138
Time volume ~ diam.
139+
140+
Args:
141+
n (int): The total number of sample points to be generated.
142+
boundary (bool): Indicates whether boundary points are included, default is True.
143+
144+
Returns:
145+
np.ndarray: a set of spatial-temporal coordinate points 'tx' that represent sample points evenly distributed within the spatial-temporal domain.
146+
147+
Examples:
148+
>>> import ppsci
149+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1, 0.001)
150+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
151+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
152+
>>> ts = time_geom.uniform_points(1000)
153+
>>> print(ts.shape)
154+
(1000, 3)
118155
"""
119156
if self.timedomain.time_step is not None:
120157
# exclude start time t0
@@ -163,7 +200,30 @@ def uniform_points(self, n, boundary=True):
163200
tx = tx[:n]
164201
return tx
165202

166-
def random_points(self, n, random="pseudo", criteria=None):
203+
def random_points(
204+
self, n: int, random: str = "pseudo", criteria: Optional[Callable] = None
205+
):
206+
"""Generate random points on the spatial-temporal domain.
207+
208+
Args:
209+
n (int): The total number of random points to generate.
210+
random (string): Specifies the way to generate random points, default is "pseudo" , which means that a pseudo-random number generator is used.
211+
criteria (Optional[Callable]): A method that filters on the generated random points, defualt is None.
212+
213+
Returns:
214+
np.ndarray: A set of random spatial-temporal points.
215+
216+
Examples:
217+
>>> import ppsci
218+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1, 0.001)
219+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
220+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
221+
>>> ts = time_geom.random_points(1000)
222+
>>> print(ts.shape)
223+
(1000, 3)
224+
"""
225+
if self.timedomain.time_step is None and self.timedomain.timestamps is None:
226+
raise ValueError("Either time_step or timestamps must be provided.")
167227
# time evenly and geometry random, if time_step if specified
168228
if self.timedomain.time_step is not None:
169229
nt = int(np.ceil(self.timedomain.diam / self.timedomain.time_step))
@@ -287,11 +347,26 @@ def random_points(self, n, random="pseudo", criteria=None):
287347
t = np.random.permutation(t)
288348
return np.hstack((t, x))
289349

290-
def uniform_boundary_points(self, n, criteria=None):
350+
def uniform_boundary_points(self, n: int, criteria: Optional[Callable] = None):
291351
"""Uniform boundary points on the spatial-temporal domain.
292-
293352
Geometry surface area ~ bbox.
294353
Time surface area ~ diam.
354+
355+
Args:
356+
n (int): The total number of boundary points on the spatial-temporal domain to be generated that are evenly distributed across geometry boundaries.
357+
criteria (Optional[Callable]): Used to filter the generated boundary points, only points that meet certain conditions are retained. Default is None.
358+
359+
Returns:
360+
np.ndarray: A set of point coordinates evenly distributed across geometry boundaries on the spatial-temporal domain.
361+
362+
Examples:
363+
>>> import ppsci
364+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1)
365+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
366+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
367+
>>> ts = time_geom.uniform_boundary_points(1000)
368+
>>> print(ts.shape)
369+
(1000, 3)
295370
"""
296371
if self.geometry.ndim == 1:
297372
nx = 2
@@ -350,7 +425,30 @@ def uniform_boundary_points(self, n, criteria=None):
350425
tx = tx[:n]
351426
return tx
352427

353-
def random_boundary_points(self, n, random="pseudo", criteria=None):
428+
def random_boundary_points(
429+
self, n: int, random: str = "pseudo", criteria: Optional[Callable] = None
430+
):
431+
"""Random boundary points on the spatial-temporal domain.
432+
433+
Args:
434+
n (int): The total number of spatial-temporal points generated on a given geometry boundary.
435+
random (string): Controls the way to generate random points. Default is "pseudo".
436+
criteria (Optional[Callable]): Used to filter the generated boundary points, only points that meet certain conditions are retained. Default is None.
437+
438+
Returns:
439+
np.ndarray: A set of point coordinates randomly distributed across geometry boundaries on the spatial-temporal domain.
440+
441+
Examples:
442+
>>> import ppsci
443+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1, 0.001)
444+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
445+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
446+
>>> ts = time_geom.random_boundary_points(1000)
447+
>>> print(ts.shape)
448+
(1000, 3)
449+
"""
450+
if self.timedomain.time_step is None and self.timedomain.timestamps is None:
451+
raise ValueError("Either time_step or timestamps must be provided.")
354452
if self.timedomain.time_step is not None:
355453
# exclude start time t0
356454
nt = int(np.ceil(self.timedomain.diam / self.timedomain.time_step))
@@ -523,19 +621,78 @@ def random_boundary_points(self, n, random="pseudo", criteria=None):
523621
else:
524622
return t_x
525623

526-
def uniform_initial_points(self, n):
624+
def uniform_initial_points(self, n: int):
625+
"""Generate evenly distributed point coordinates on the spatial-temporal domain at the initial moment.
626+
627+
Args:
628+
n (int): The total number of generated points.
629+
630+
Returns:
631+
np.ndarray: A set of point coordinates evenly distributed on the spatial-temporal domain at the initial moment.
632+
633+
Examples:
634+
>>> import ppsci
635+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1)
636+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
637+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
638+
>>> ts = time_geom.uniform_initial_points(1000)
639+
>>> print(ts.shape)
640+
(1000, 3)
641+
"""
527642
x = self.geometry.uniform_points(n, True)
528643
t = self.timedomain.t0
529644
if len(x) > n:
530645
x = x[:n]
531646
return np.hstack((np.full([n, 1], t, dtype=paddle.get_default_dtype()), x))
532647

533-
def random_initial_points(self, n, random="pseudo"):
648+
def random_initial_points(self, n: int, random: str = "pseudo"):
649+
"""Generate randomly distributed point coordinates on the spatial-temporal domain at the initial moment.
650+
651+
Args:
652+
n (int): The total number of generated points.
653+
random (string): Controls the way to generate random points. Default is "pseudo".
654+
655+
Returns:
656+
np.ndarray: A set of point coordinates randomly distributed on the spatial-temporal domain at the initial moment.
657+
658+
Examples:
659+
>>> import ppsci
660+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1)
661+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
662+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
663+
>>> ts = time_geom.random_initial_points(1000)
664+
>>> print(ts.shape)
665+
(1000, 3)
666+
"""
534667
x = self.geometry.random_points(n, random=random)
535668
t = self.timedomain.t0
536669
return np.hstack((np.full([n, 1], t, dtype=paddle.get_default_dtype()), x))
537670

538-
def periodic_point(self, x, component):
671+
def periodic_point(self, x: Dict[str, np.ndarray], component: int):
672+
"""process given point coordinates to satisfy the periodic boundary conditions of the geometry.
673+
674+
Args:
675+
x (Dict[str, np.ndarray]): Contains the coordinates and timestamps of the points. It represents the coordinates of the point to be processed.
676+
component (int): Specifies the components or dimensions of specific spatial coordinates that are periodically processed.
677+
678+
Returns:
679+
Dict[str, np.ndarray] : contains the original timestamps and the coordinates of the spatial point after periodic processing.
680+
681+
Examples:
682+
>>> import ppsci
683+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1, 0.1)
684+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
685+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
686+
>>> ts = time_geom.sample_boundary(1000)
687+
>>> result = time_geom.periodic_point(ts, 0)
688+
>>> for k,v in result.items():
689+
... print(k, v.shape)
690+
t (1000, 1)
691+
x (1000, 1)
692+
y (1000, 1)
693+
normal_x (1000, 1)
694+
normal_y (1000, 1)
695+
"""
539696
xp = self.geometry.periodic_point(x, component)
540697
txp = {"t": x["t"], **xp}
541698
return txp
@@ -544,11 +701,35 @@ def sample_initial_interior(
544701
self,
545702
n: int,
546703
random: str = "pseudo",
547-
criteria=None,
548-
evenly=False,
704+
criteria: Optional[Callable] = None,
705+
evenly: bool = False,
549706
compute_sdf_derivatives: bool = False,
550707
):
551-
"""Sample random points in the time-geometry and return those meet criteria."""
708+
"""Sample random points in the time-geometry and return those meet criteria.
709+
710+
Args:
711+
n (int): The total number of interior points generated.
712+
random (string): The method used to specify the initial point of generation. Default is "pseudo".
713+
criteria (Optional[Callable]): Used to filter the generated interior points, only points that meet certain conditions are retained. Default is None.
714+
evenly (bool): Indicates whether the initial points are generated evenly. Default is False.
715+
compute_sdf_derivatives (bool): Indicates whether to calculate the derivative of signed distance function or not. Default is False.
716+
717+
Returns:
718+
np.ndarray: Contains the coordinates of the initial internal point generated, as well as the potentially computed signed distance function and its derivative.
719+
720+
Examples:
721+
>>> import ppsci
722+
>>> timedomain = ppsci.geometry.TimeDomain(0, 1)
723+
>>> geom = ppsci.geometry.Rectangle((0, 0), (1, 1))
724+
>>> time_geom = ppsci.geometry.TimeXGeometry(timedomain, geom)
725+
>>> ts = time_geom.sample_initial_interior(1000)
726+
>>> for k,v in ts.items():
727+
... print(k, v.shape)
728+
t (1000, 1)
729+
x (1000, 1)
730+
y (1000, 1)
731+
sdf (1000, 1)
732+
"""
552733
x = np.empty(shape=(n, self.ndim), dtype=paddle.get_default_dtype())
553734
_size, _ntry, _nsuc = 0, 0, 0
554735
while _size < n:

0 commit comments

Comments
 (0)