Skip to content

Commit 8b8eae6

Browse files
[Feature] Replace python funcion with sympy expression (#507)
* add sympy2func * fix node * fix var name * fix implementation * add sympy to func module * add type hint and clean code * update unitest for N-S equation with sympy-base 'nu' * delete redundant sympy2func.py * remove sympy to function code from expression.py to sym_to_func.py * update type hint in expression * update code * update code * update code * refine sym_to_func.py * replace sympy PDE for biharmonic and laplace * refine sym_to_func.py * fix bug in _cvt_to_key * refine sym_to_func and expression code * add euler_beam static code(WIP, can not running, to be debug) * wip code * temporary code(need to be refined) * update solver code * replace more pdes with sympy * simplify code in solver * update code * rename 'normal_dot_vel' to 'normal_dot_vec' * fix bug * update unitest * remove redundant unitest * remove unnecessary code * remove unnecessary more code * use DETACH_FUNC_NAME instead of 'detach' * add derivatives for sdf function * replace .diff.diff with .diff(, 2) * support exporting expression to .dot and .png file for visualizing and DEBUG * remove compute_sdf_derivatives for next PR * refine docstring of ppsci/data/dataset/array_dataset.py * remove sdf_derivatives code in geometry for next PR * remove print code in solver * rename sympy_to_function to lambdify and add it in ppsci.* * rename for test files * rename sym_to_func.py to symbolic.py * update linear_init_ and conv_init_ to kaiming style * refine probability document * change list to tuple * update docstrings of equations * larger atol to 1e-7 for test_linear_elasticity * fix seed to 42 for test_linear_elasticity --------- Co-authored-by: PuQing <[email protected]>
1 parent 3724732 commit 8b8eae6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1217
-2222
lines changed

docs/zh/api/probability.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Probability(概率编程) 模块
2+
13
::: ppsci.probability
24
handler: python
35
options:

docs/zh/api/utils.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919
- load_checkpoint
2020
- load_pretrain
2121
- save_checkpoint
22+
- lambdify
2223
show_root_heading: false
2324
heading_level: 3

examples/aneurysm/aneurysm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def inlet_w_ref_func(_in):
132132
)
133133
igc_outlet = ppsci.constraint.IntegralConstraint(
134134
equation["NormalDotVec"].equations,
135-
{"normal_dot_vel": 2.54},
135+
{"normal_dot_vec": 2.54},
136136
geom["outlet_geo"],
137137
{
138138
**train_dataloader_cfg,
@@ -141,12 +141,12 @@ def inlet_w_ref_func(_in):
141141
"integral_batch_size": 310,
142142
},
143143
ppsci.loss.IntegralLoss("sum"),
144-
weight_dict={"normal_dot_vel": 0.1},
144+
weight_dict={"normal_dot_vec": 0.1},
145145
name="igc_outlet",
146146
)
147147
igc_integral = ppsci.constraint.IntegralConstraint(
148148
equation["NormalDotVec"].equations,
149-
{"normal_dot_vel": -2.54},
149+
{"normal_dot_vec": -2.54},
150150
geom["integral_geo"],
151151
{
152152
**train_dataloader_cfg,
@@ -155,7 +155,7 @@ def inlet_w_ref_func(_in):
155155
"integral_batch_size": 310,
156156
},
157157
ppsci.loss.IntegralLoss("sum"),
158-
weight_dict={"normal_dot_vel": 0.1},
158+
weight_dict={"normal_dot_vec": 0.1},
159159
name="igc_integral",
160160
)
161161
# wrap constraints together

examples/bracket/bracket.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,15 @@
127127
support_interior_constraint = ppsci.constraint.InteriorConstraint(
128128
equation["LinearElasticity"].equations,
129129
{
130-
"equilibrium_x": 0,
131-
"equilibrium_y": 0,
132-
"equilibrium_z": 0,
133130
"stress_disp_xx": 0,
134131
"stress_disp_yy": 0,
135132
"stress_disp_zz": 0,
136133
"stress_disp_xy": 0,
137134
"stress_disp_xz": 0,
138135
"stress_disp_yz": 0,
136+
"equilibrium_x": 0,
137+
"equilibrium_y": 0,
138+
"equilibrium_z": 0,
139139
},
140140
geom["geo"],
141141
{**train_dataloader_cfg, "batch_size": 2048},
@@ -149,30 +149,30 @@
149149
& (z < BOUNDS_SUPPORT_Z[1])
150150
),
151151
weight_dict={
152-
"equilibrium_x": "sdf",
153-
"equilibrium_y": "sdf",
154-
"equilibrium_z": "sdf",
155152
"stress_disp_xx": "sdf",
156153
"stress_disp_yy": "sdf",
157154
"stress_disp_zz": "sdf",
158155
"stress_disp_xy": "sdf",
159156
"stress_disp_xz": "sdf",
160157
"stress_disp_yz": "sdf",
158+
"equilibrium_x": "sdf",
159+
"equilibrium_y": "sdf",
160+
"equilibrium_z": "sdf",
161161
},
162162
name="support_interior",
163163
)
164164
bracket_interior_constraint = ppsci.constraint.InteriorConstraint(
165165
equation["LinearElasticity"].equations,
166166
{
167-
"equilibrium_x": 0,
168-
"equilibrium_y": 0,
169-
"equilibrium_z": 0,
170167
"stress_disp_xx": 0,
171168
"stress_disp_yy": 0,
172169
"stress_disp_zz": 0,
173170
"stress_disp_xy": 0,
174171
"stress_disp_xz": 0,
175172
"stress_disp_yz": 0,
173+
"equilibrium_x": 0,
174+
"equilibrium_y": 0,
175+
"equilibrium_z": 0,
176176
},
177177
geom["geo"],
178178
{**train_dataloader_cfg, "batch_size": 1024},
@@ -186,15 +186,15 @@
186186
& (z < BOUNDS_BRACKET_Z[1])
187187
),
188188
weight_dict={
189-
"equilibrium_x": "sdf",
190-
"equilibrium_y": "sdf",
191-
"equilibrium_z": "sdf",
192189
"stress_disp_xx": "sdf",
193190
"stress_disp_yy": "sdf",
194191
"stress_disp_zz": "sdf",
195192
"stress_disp_xy": "sdf",
196193
"stress_disp_xz": "sdf",
197194
"stress_disp_yz": "sdf",
195+
"equilibrium_x": "sdf",
196+
"equilibrium_y": "sdf",
197+
"equilibrium_z": "sdf",
198198
},
199199
name="bracket_interior",
200200
)

examples/laplace/laplace2d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
EVAL_FREQ = 200
3030

3131
# set output directory
32-
OUTPUT_DIR = "./output/laplace2d" if not args.output_dir else args.output_dir
32+
OUTPUT_DIR = "./output_laplace2d" if not args.output_dir else args.output_dir
3333
logger.init_logger("ppsci", f"{OUTPUT_DIR}/train.log", "info")
3434

3535
# set model

examples/pipe/poiseuille_flow.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@ def output_trans_p(input, out):
133133

134134
# set euqation
135135
equation = {
136-
"NavierStokes": ppsci.equation.NavierStokes(
137-
nu=lambda out: out["nu"], rho=RHO, dim=2, time=False
138-
)
136+
"NavierStokes": ppsci.equation.NavierStokes(nu="nu", rho=RHO, dim=2, time=False)
139137
}
140138

141139
# set constraint

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ nav:
8787
- ppsci.validate: zh/api/validate.md
8888
- ppsci.visualize: zh/api/visualize.md
8989
- ppsci.experimental: zh/api/experimental.md
90+
- ppsci.probability: zh/api/probability.md
9091
- 使用指南: zh/user_guide.md
9192
- 开发与复现指南:
9293
- 开发指南: zh/development.md

ppsci/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from ppsci.utils.checker import run_check # isort:skip
3131
from ppsci.utils.checker import run_check_mesh # isort:skip
32+
from ppsci.utils import lambdify # isort:skip
3233

3334
__all__ = [
3435
"arch",
@@ -47,4 +48,5 @@
4748
"experimental",
4849
"run_check",
4950
"run_check_mesh",
51+
"lambdify",
5052
]

ppsci/constraint/boundary_constraint.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import numpy as np
2525
import sympy
26-
from sympy.parsing import sympy_parser as sp_parser
2726
from typing_extensions import Literal
2827

2928
from ppsci import geometry
@@ -86,14 +85,12 @@ def __init__(
8685
weight_dict: Optional[Dict[str, Union[float, Callable]]] = None,
8786
name: str = "BC",
8887
):
89-
self.output_expr = output_expr
90-
for label_name, expr in self.output_expr.items():
91-
if isinstance(expr, str):
92-
self.output_expr[label_name] = sp_parser.parse_expr(expr)
93-
9488
self.label_dict = label_dict
9589
self.input_keys = geom.dim_keys
96-
self.output_keys = list(label_dict.keys())
90+
self.output_keys = tuple(label_dict.keys())
91+
self.output_expr = {
92+
k: v for k, v in output_expr.items() if k in self.output_keys
93+
}
9794
# "area" will be kept in "output_dict" for computation.
9895
if isinstance(geom, geometry.Mesh):
9996
self.output_keys += ["area"]
@@ -137,9 +134,6 @@ def __init__(
137134
weight = {key: np.ones_like(next(iter(label.values()))) for key in label}
138135
if weight_dict is not None:
139136
for key, value in weight_dict.items():
140-
if isinstance(value, str):
141-
value = sp_parser.parse_expr(value)
142-
143137
if isinstance(value, (int, float)):
144138
weight[key] = np.full_like(next(iter(label.values())), value)
145139
elif isinstance(value, sympy.Basic):

ppsci/constraint/initial_constraint.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import numpy as np
2525
import sympy
26-
from sympy.parsing import sympy_parser as sp_parser
2726
from typing_extensions import Literal
2827

2928
from ppsci import geometry
@@ -89,14 +88,12 @@ def __init__(
8988
weight_dict: Optional[Dict[str, Callable]] = None,
9089
name: str = "IC",
9190
):
92-
self.output_expr = output_expr
93-
for label_name, expr in self.output_expr.items():
94-
if isinstance(expr, str):
95-
self.output_expr[label_name] = sp_parser.parse_expr(expr)
96-
9791
self.label_dict = label_dict
9892
self.input_keys = geom.dim_keys
99-
self.output_keys = list(label_dict.keys())
93+
self.output_keys = tuple(label_dict.keys())
94+
self.output_expr = {
95+
k: v for k, v in output_expr.items() if k in self.output_keys
96+
}
10097
# "area" will be kept in "output_dict" for computation.
10198
if isinstance(geom.geometry, geometry.Mesh):
10299
self.output_keys += ["area"]
@@ -117,8 +114,6 @@ def __init__(
117114
# prepare label
118115
label = {}
119116
for key, value in label_dict.items():
120-
if isinstance(value, str):
121-
value = sp_parser.parse_expr(value)
122117
if isinstance(value, (int, float)):
123118
label[key] = np.full_like(next(iter(input.values())), value)
124119
elif isinstance(value, sympy.Basic):
@@ -142,8 +137,6 @@ def __init__(
142137
weight = {key: np.ones_like(next(iter(label.values()))) for key in label}
143138
if weight_dict is not None:
144139
for key, value in weight_dict.items():
145-
if isinstance(value, str):
146-
value = sp_parser.parse_expr(value)
147140
if isinstance(value, (int, float)):
148141
weight[key] = np.full_like(next(iter(label.values())), value)
149142
elif isinstance(value, sympy.Basic):

ppsci/constraint/integral_constraint.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import numpy as np
2525
import paddle
2626
import sympy
27-
from sympy.parsing import sympy_parser as sp_parser
2827
from typing_extensions import Literal
2928

3029
from ppsci import geometry
@@ -86,14 +85,12 @@ def __init__(
8685
weight_dict: Optional[Dict[str, Callable]] = None,
8786
name: str = "IgC",
8887
):
89-
self.output_expr = output_expr
90-
for label_name, expr in self.output_expr.items():
91-
if isinstance(expr, str):
92-
self.output_expr[label_name] = sp_parser.parse_expr(expr)
93-
9488
self.label_dict = label_dict
9589
self.input_keys = geom.dim_keys
96-
self.output_keys = list(label_dict.keys())
90+
self.output_keys = tuple(label_dict.keys())
91+
self.output_expr = {
92+
k: v for k, v in output_expr.items() if k in self.output_keys
93+
}
9794
# "area" will be kept in "output_dict" for computation.
9895
if isinstance(geom, geometry.Mesh):
9996
self.output_keys += ["area"]
@@ -149,9 +146,6 @@ def __init__(
149146
weight = {key: np.ones_like(next(iter(label.values()))) for key in label}
150147
if weight_dict is not None:
151148
for key, value in weight_dict.items():
152-
if isinstance(value, str):
153-
value = sp_parser.parse_expr(value)
154-
155149
if isinstance(value, (int, float)):
156150
weight[key] = np.full_like(next(iter(label.values())), value)
157151
elif isinstance(value, sympy.Basic):

ppsci/constraint/interior_constraint.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import numpy as np
2525
import sympy
26-
from sympy.parsing import sympy_parser as sp_parser
2726
from typing_extensions import Literal
2827

2928
from ppsci import geometry
@@ -86,14 +85,12 @@ def __init__(
8685
weight_dict: Optional[Dict[str, Union[Callable, float]]] = None,
8786
name: str = "EQ",
8887
):
89-
self.output_expr = output_expr
90-
for label_name, expr in self.output_expr.items():
91-
if isinstance(expr, str):
92-
self.output_expr[label_name] = sp_parser.parse_expr(expr)
93-
9488
self.label_dict = label_dict
9589
self.input_keys = geom.dim_keys
96-
self.output_keys = list(label_dict.keys())
90+
self.output_keys = tuple(label_dict.keys())
91+
self.output_expr = {
92+
k: v for k, v in output_expr.items() if k in self.output_keys
93+
}
9794
# "area" will be kept in "output_dict" for computation.
9895
if isinstance(geom, geometry.Mesh):
9996
self.output_keys += ["area"]
@@ -114,8 +111,6 @@ def __init__(
114111
# prepare label
115112
label = {}
116113
for key, value in label_dict.items():
117-
if isinstance(value, str):
118-
value = sp_parser.parse_expr(value)
119114
if isinstance(value, (int, float)):
120115
label[key] = np.full_like(next(iter(input.values())), value)
121116
elif isinstance(value, sympy.Basic):

ppsci/constraint/periodic_constraint.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import numpy as np
2525
import paddle
2626
import sympy
27-
from sympy.parsing import sympy_parser as sp_parser
2827
from typing_extensions import Literal
2928

3029
from ppsci import geometry
@@ -73,13 +72,11 @@ def __init__(
7372
weight_dict: Optional[Dict[str, Callable]] = None,
7473
name: str = "PeriodicBC",
7574
):
76-
self.output_expr = output_expr
77-
for label_name, expr in self.output_expr.items():
78-
if isinstance(expr, str):
79-
self.output_expr[label_name] = sp_parser.parse_expr(expr)
80-
8175
self.input_keys = geom.dim_keys
82-
self.output_keys = list(output_expr.keys())
76+
self.output_keys = tuple(output_expr.keys())
77+
self.output_expr = {
78+
k: v for k, v in output_expr.items() if k in self.output_keys
79+
}
8380
# "area" will be kept in "output_dict" for computation.
8481
if isinstance(geom, geometry.Mesh):
8582
self.output_keys += ["area"]
@@ -143,9 +140,6 @@ def __init__(
143140
weight = {key: np.ones_like(next(iter(label.values()))) for key in label}
144141
if weight_dict is not None:
145142
for key, value in weight_dict.items():
146-
if isinstance(value, str):
147-
value = sp_parser.parse_expr(value)
148-
149143
if isinstance(value, (int, float)):
150144
weight[key] = np.full_like(next(iter(label.values())), value)
151145
elif isinstance(value, sympy.Basic):

ppsci/constraint/supervised_constraint.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,20 @@ def __init__(
6060
output_expr: Optional[Dict[str, Callable]] = None,
6161
name: str = "Sup",
6262
):
63-
self.output_expr = output_expr
64-
6563
# build dataset
6664
_dataset = dataset.build_dataset(dataloader_cfg["dataset"])
6765

6866
self.input_keys = _dataset.input_keys
6967
self.output_keys = (
70-
list(output_expr.keys()) if output_expr is not None else _dataset.label_keys
68+
tuple(output_expr.keys())
69+
if output_expr is not None
70+
else _dataset.label_keys
7171
)
7272

73+
self.output_expr = output_expr
7374
if self.output_expr is None:
7475
self.output_expr = {
75-
key: lambda out, k=key: out[k] for key in self.output_keys
76+
key: (lambda out, k=key: out[k]) for key in self.output_keys
7677
}
7778

7879
# construct dataloader with dataset and dataloader_cfg

ppsci/data/dataset/array_dataset.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ class NamedArrayDataset(io.Dataset):
2929
Args:
3030
input (Dict[str, np.ndarray]): Input dict.
3131
label (Dict[str, np.ndarray]): Label dict.
32-
weight (Optional[Dict[str, np.ndarray]], optional): Weight dict.
33-
transforms (Optional[vision.Compose], optional): Compose object contains sample wise
34-
transform(s).
32+
weight (Optional[Dict[str, np.ndarray]]): Weight dict. Defaults to None.
33+
transforms (Optional[vision.Compose]): Compose object contains sample wise
34+
transform(s). Defaults to None.
3535
3636
Examples:
3737
>>> import ppsci

0 commit comments

Comments
 (0)