PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
problem.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -------------------------------------------
3# Copyright (c) 2021 - 2026 Prashant K. Jha
4# -------------------------------------------
5# PeriDEM https://github.com/prashjha/PeriDEM
6#
7# Distributed under the Boost Software License, Version 1.0. (See accompanying
8# file LICENSE)
9
10"""Single rectangular particle pulled diagonally.
11
12The south-west corner is fixed and the north-east corner is pulled at a
13constant rate. The deck is built in Python and the mesh is generated in the
14calling process, so no ``.msh`` file is read or written.
15"""
16
17from __future__ import annotations
18
19import os
20import sys
21from pathlib import Path
22
23HERE = Path(__file__).resolve().parent
24for _p in HERE.parents:
25 if (_p / "examples" / "peridem_env.py").is_file():
26 sys.path.insert(0, str(_p / "examples"))
27 break
28import peridem_env # noqa: F401,E402
29
30import peridem # noqa: E402
31from peridem import Deck, Geometry # noqa: E402
32from peridem.deck import MeshSpec, to_G # noqa: E402
33
34SIDE = 0.01
35MESH_SIZE = 0.0002
36HORIZON = 0.00032
37DENSITY = 1200.0
38K = 216000.0
39NU = 0.25
40GC = 500.0
41
42FINAL_TIME = 0.01
43NUM_STEPS = 20000
44PULL_RATE = 0.01
45
46TAGS = ["Displacement", "Velocity", "Force", "Force_Density", "Damage_Z",
47 "Damage", "Nodal_Volume", "Zone_ID", "Particle_ID", "Fixity",
48 "Force_Fixity", "Theta"]
49
50
51def build_deck(output_path: str | os.PathLike[str] = "runs/", *,
52 final_time: float = FINAL_TIME, num_steps: int = NUM_STEPS,
53 output_interval: int = 2000, mesh_size: float = MESH_SIZE,
54 horizon: float = HORIZON,
55 tags: list[str] | None = None) -> Deck:
56 d = Deck(dim=2, t_final=final_time, n_steps=num_steps,
57 particle_sim_type="Single_Particle")
58 d.set_comment("Single-particle rectangle: uniform in-process mesh; fixed "
59 "SW corner, linear pull on NE, set up in Python")
60 d.set_output(output_path, tags=tags or TAGS, interval=output_interval,
61 debug=1, tag_pp="1", pvd_collection=True)
62
63 # The uniform mesh is generated in memory and no file is read.
64 d.add_particle_type(Geometry("rectangle", [0.0, 0.0, 0.0, SIDE, SIDE, 0.0]),
65 MeshSpec(size=mesh_size, info="uniform"))
66 d.add_material(horizon=horizon, density=DENSITY, K=K,
67 G=to_G(E=peridem.to_E(K, NU), nu=NU), Gc=GC,
68 influence_fn_type=1)
69
70 corner = 0.2 * SIDE
71 hold = Geometry("rectangle", [0.0, 0.0, 0.0, corner, corner, 0.0])
72 pull = Geometry("rectangle",
73 [SIDE - corner, SIDE - corner, 0.0, SIDE, SIDE, 0.0])
74 d.add_displacement_bc(region=hold, direction=[1, 2],
75 time_fn_type="constant", time_fn_params=[0.0],
76 spatial_fn_type="constant", zero_displacement=True)
77 d.add_displacement_bc(region=pull, direction=[1, 2],
78 time_fn_type="linear", time_fn_params=[PULL_RATE],
79 spatial_fn_type="constant")
80
81 d.set_test("test_peridynamics")
82 return d
83
84
85def main(argv: list[str] | None = None) -> int:
86 import argparse
87
88 p = argparse.ArgumentParser(description=__doc__)
89 p.add_argument("-o", "--output", default=str(HERE / "runs_py"))
90 p.add_argument("--final-time", type=float, default=FINAL_TIME)
91 p.add_argument("--num-steps", type=int, default=NUM_STEPS)
92 p.add_argument("--output-interval", type=int, default=2000)
93 p.add_argument("--mesh-size", type=float, default=MESH_SIZE)
94 p.add_argument("--nthreads", type=int,
95 default=int(os.environ.get("NTHREADS", "4")))
96 p.add_argument("--snapshot", metavar="PNG", default=None)
97 p.add_argument("--write-deck", metavar="PATH", default=None)
98 args = p.parse_args(argv)
99
100 out = Path(args.output).resolve()
101 d = build_deck(str(out) + "/", final_time=args.final_time,
102 num_steps=args.num_steps,
103 output_interval=args.output_interval,
104 mesh_size=args.mesh_size)
105 if args.write_deck:
106 print(d.write(args.write_deck))
107 return 0
108
109 out.mkdir(parents=True, exist_ok=True)
110 peridem.init(n_threads=args.nthreads)
111 sim = d.run(workdir=HERE)
112 if peridem.mpi_rank() != 0:
113 return 0
114 u = sim.displacement
115 print(f"done: nodes={sim.n_nodes} step={sim.step_index} t={sim.time:g}")
116 print(f"max |u| = {float(abs(u).max()):.6e}")
117 if args.snapshot:
118 print(peridem.snapshot(peridem.last_vtu(out), args.snapshot,
119 color="|Displacement|",
120 title="rectangle: |u| at final time"))
121 print(f"VTU under {out}")
122 return 0
123
124
125if __name__ == "__main__":
126 raise SystemExit(main())
Deck build_deck(str|os.PathLike[str] output_path="runs/out/", *str preset="short", float|None final_time=None, int|None num_steps=None, int|None output_interval=None, float omega=OMEGA, str|os.PathLike[str] mesh_dir=MESH_DIR, str|os.PathLike[str] csv=CSV)
Definition problem.py:132