Skip to content

Commit 6df31fb

Browse files
Merge pull request #295 from HydrogenSulfate/add_darcy2d
Add darcy2d
2 parents 6e963c7 + 1b14fc3 commit 6df31fb

File tree

6 files changed

+247
-0
lines changed

6 files changed

+247
-0
lines changed

docs/images/darcy2d/darcy2d_v2.png

154 KB
Loading

docs/zh/api/equation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
- Laplace
1010
- NavierStokes
1111
- NormalDotVec
12+
- Poisson
1213
show_root_heading: false
1314
heading_level: 3

examples/darcy/darcy2d_v2.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import numpy as np
16+
17+
import ppsci
18+
from ppsci.utils import config
19+
from ppsci.utils import logger
20+
21+
if __name__ == "__main__":
22+
args = config.parse_args()
23+
# set random seed for reproducibility
24+
ppsci.utils.misc.set_random_seed(42)
25+
# set output directory
26+
output_dir = "./output_darcy2d" if not args.output_dir else args.output_dir
27+
# initialize logger
28+
logger.init_logger("ppsci", f"{output_dir}/train.log", "info")
29+
30+
# set model
31+
model = ppsci.arch.MLP(("x", "y"), ("p",), 5, 20, "tanh", False, False)
32+
33+
# set equation
34+
equation = {"Poisson": ppsci.equation.Poisson(2)}
35+
36+
# set geometry
37+
geom = {"rect": ppsci.geometry.Rectangle((0.0, 0.0), (1.0, 1.0))}
38+
39+
# set dataloader config
40+
ITERS_PER_EPOCH = 1
41+
train_dataloader_cfg = {
42+
"dataset": "IterableNamedArrayDataset",
43+
"iters_per_epoch": ITERS_PER_EPOCH,
44+
}
45+
46+
NPOINT_PDE = 99**2
47+
NPOINT_TOP = 101
48+
NPOINT_BOTTOM = 101
49+
NPOINT_LEFT = 99
50+
NPOINT_RIGHT = 99
51+
52+
# set constraint
53+
def poisson_ref_compute_func(_in):
54+
return (
55+
-8.0
56+
* (np.pi**2)
57+
* np.sin(2.0 * np.pi * _in["x"])
58+
* np.cos(2.0 * np.pi * _in["y"])
59+
)
60+
61+
pde_constraint = ppsci.constraint.InteriorConstraint(
62+
equation["Poisson"].equations,
63+
{"poisson": poisson_ref_compute_func},
64+
geom["rect"],
65+
{**train_dataloader_cfg, "batch_size": NPOINT_PDE},
66+
ppsci.loss.MSELoss("sum"),
67+
evenly=True,
68+
name="EQ",
69+
)
70+
bc_top = ppsci.constraint.BoundaryConstraint(
71+
{"p": lambda out: out["p"]},
72+
{
73+
"p": lambda _in: np.sin(2.0 * np.pi * _in["x"])
74+
* np.cos(2.0 * np.pi * _in["y"])
75+
},
76+
geom["rect"],
77+
{**train_dataloader_cfg, "batch_size": NPOINT_TOP},
78+
ppsci.loss.MSELoss("sum"),
79+
criteria=lambda x, y: np.isclose(y, 1.0),
80+
name="BC_top",
81+
)
82+
bc_bottom = ppsci.constraint.BoundaryConstraint(
83+
{"p": lambda out: out["p"]},
84+
{
85+
"p": lambda _in: np.sin(2.0 * np.pi * _in["x"])
86+
* np.cos(2.0 * np.pi * _in["y"])
87+
},
88+
geom["rect"],
89+
{**train_dataloader_cfg, "batch_size": NPOINT_BOTTOM},
90+
ppsci.loss.MSELoss("sum"),
91+
criteria=lambda x, y: np.isclose(y, 0.0),
92+
name="BC_bottom",
93+
)
94+
bc_left = ppsci.constraint.BoundaryConstraint(
95+
{"p": lambda out: out["p"]},
96+
{
97+
"p": lambda _in: np.sin(2.0 * np.pi * _in["x"])
98+
* np.cos(2.0 * np.pi * _in["y"])
99+
},
100+
geom["rect"],
101+
{**train_dataloader_cfg, "batch_size": NPOINT_LEFT},
102+
ppsci.loss.MSELoss("sum"),
103+
criteria=lambda x, y: np.isclose(x, 0.0),
104+
name="BC_left",
105+
)
106+
bc_right = ppsci.constraint.BoundaryConstraint(
107+
{"p": lambda out: out["p"]},
108+
{
109+
"p": lambda _in: np.sin(2.0 * np.pi * _in["x"])
110+
* np.cos(2.0 * np.pi * _in["y"])
111+
},
112+
geom["rect"],
113+
{**train_dataloader_cfg, "batch_size": NPOINT_RIGHT},
114+
ppsci.loss.MSELoss("sum"),
115+
criteria=lambda x, y: np.isclose(x, 1.0),
116+
name="BC_right",
117+
)
118+
# wrap constraints together
119+
constraint = {
120+
pde_constraint.name: pde_constraint,
121+
bc_top.name: bc_top,
122+
bc_bottom.name: bc_bottom,
123+
bc_left.name: bc_left,
124+
bc_right.name: bc_right,
125+
}
126+
127+
# set training hyper-parameters
128+
epochs = 10000 if not args.epochs else args.epochs
129+
130+
# set optimizer
131+
optimizer = ppsci.optimizer.Adam(1e-3)((model,))
132+
133+
# set validator
134+
NPOINTS_EVAL = NPOINT_PDE
135+
residual_validator = ppsci.validate.GeometryValidator(
136+
equation["Poisson"].equations,
137+
{"poisson": poisson_ref_compute_func},
138+
geom["rect"],
139+
{
140+
"dataset": "NamedArrayDataset",
141+
"total_size": NPOINTS_EVAL,
142+
"batch_size": 8192,
143+
"sampler": {"name": "BatchSampler"},
144+
},
145+
ppsci.loss.MSELoss("sum"),
146+
evenly=True,
147+
metric={"MSE": ppsci.metric.MSE()},
148+
name="Residual",
149+
)
150+
validator = {residual_validator.name: residual_validator}
151+
152+
# set visualizer(optional)
153+
# manually collate input data for visualization,
154+
NPOINT_BC = NPOINT_TOP + NPOINT_BOTTOM + NPOINT_LEFT + NPOINT_RIGHT
155+
vis_points = geom["rect"].sample_interior(NPOINT_PDE + NPOINT_BC, evenly=True)
156+
visualizer = {
157+
"visulzie_u_v": ppsci.visualize.VisualizerVtu(
158+
vis_points,
159+
{"p": lambda d: d["p"]},
160+
prefix="result_u_v",
161+
)
162+
}
163+
164+
# initialize solver
165+
solver = ppsci.solver.Solver(
166+
model,
167+
constraint,
168+
output_dir,
169+
optimizer,
170+
None,
171+
epochs,
172+
ITERS_PER_EPOCH,
173+
eval_during_train=True,
174+
eval_freq=200,
175+
equation=equation,
176+
geom=geom,
177+
validator=validator,
178+
visualizer=visualizer,
179+
)
180+
# train model
181+
solver.train()
182+
# evaluate after finished training
183+
solver.eval()
184+
# visualize prediction after finished training
185+
solver.visualize()
186+
187+
# directly evaluate pretrained model(optional)
188+
logger.init_logger("ppsci", f"{output_dir}/eval.log", "info")
189+
solver = ppsci.solver.Solver(
190+
model,
191+
constraint,
192+
output_dir,
193+
equation=equation,
194+
geom=geom,
195+
validator=validator,
196+
visualizer=visualizer,
197+
pretrained_model_path=f"{output_dir}/checkpoints/latest",
198+
)
199+
solver.eval()
200+
# visualize prediction for pretrained model(optional)
201+
solver.visualize()

ppsci/equation/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from ppsci.equation.pde import Laplace
2020
from ppsci.equation.pde import NavierStokes
2121
from ppsci.equation.pde import NormalDotVec
22+
from ppsci.equation.pde import Poisson
2223
from ppsci.equation.pde import Vibration
2324
from ppsci.utils import logger
2425
from ppsci.utils import misc
@@ -29,6 +30,7 @@
2930
"Laplace",
3031
"NavierStokes",
3132
"NormalDotVec",
33+
"Poisson",
3234
"Vibration",
3335
"build_equation",
3436
]

ppsci/equation/pde/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from ppsci.equation.pde.laplace import Laplace
1818
from ppsci.equation.pde.navier_stokes import NavierStokes
1919
from ppsci.equation.pde.normal_dot_vec import NormalDotVec
20+
from ppsci.equation.pde.poisson import Poisson
2021
from ppsci.equation.pde.viv import Vibration
2122

2223
__all__ = [
@@ -25,5 +26,6 @@
2526
"Laplace",
2627
"NavierStokes",
2728
"NormalDotVec",
29+
"Poisson",
2830
"Vibration",
2931
]

ppsci/equation/pde/poisson.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from ppsci.autodiff import hessian
16+
from ppsci.equation.pde import base
17+
18+
19+
class Poisson(base.PDE):
20+
"""Poisson
21+
22+
Args:
23+
dim (int): Dimension of equation.
24+
25+
Examples:
26+
>>> import ppsci
27+
>>> pde = ppsci.equation.Poisson(2)
28+
"""
29+
30+
def __init__(self, dim: int):
31+
super().__init__()
32+
self.dim = dim
33+
34+
def poisson_compute_func(out):
35+
invars = ("x", "y", "z")[: self.dim]
36+
poisson = 0
37+
for invar in invars:
38+
poisson += hessian(out["p"], out[invar])
39+
return poisson
40+
41+
self.add_equation("poisson", poisson_compute_func)

0 commit comments

Comments
 (0)