This benchmark simulates a 2D cross-sectional example that models excavation in rock in two days ($\text{1.728}\cdot\text{10}^5$ s) under two-phase flow conditions. The 2D domain is a cross-section perpendicular to the tunnel axis, with a size of $140 \times 140 \textrm{m}^2$; the coordinates of the tunnel centre are (0,-857) m; the tunnel radius is 6.5 m. Only one quarter of the domain is used for the simulation, which has a duration of 2.5 days. The mesh is generated by this script and is shown in the figure below:
Liquid (water) density depends linearly on the liquid pressure. Gas density follows the ideal gas law. Phase properties are as follows:
| Property | Value | Unit |
|---|---|---|
| Solid density | 2000 | kg/m$^3$ |
| Liquid density | $1000+4\cdot10^{-10}(p_L-10^5)$ | kg/m$^3$ |
| Liquid viscosity | $10^{-3}$ | Pa$\cdot$s |
| Air molar mass | 0.002016 | kg/mol |
| Gas viscosity | $9\cdot 10^{-6}$ | Pa$\cdot$s |
The relative permeability for each phase is defined as follows:
Liquid phase: van Genuchten model with the following parameter values:
| Property | Value | Unit |
|---|---|---|
| Residual liquid saturation | 0.1 | - |
| Residual gas saturation | 0.1 | - |
| Exponent | 0.2 | - |
Gas phase: van Genuchten-Mualem model with the following parameter values:
| Property | Value | Unit |
|---|---|---|
| Residual liquid saturation | 0.6 | - |
| Residual gas saturation | 0.0 | - |
| Exponent | 0.2 | - |
The van Genuchten saturation-capillary function is applied using the following parameter values:
| Property | Value | Unit |
|---|---|---|
| Residual liquid saturation | 0.01 | - |
| Residual gas saturation | 0.01 | - |
| Exponent | 0.2 | - |
| Entry pressure | 48.0 | MPa |
The remaining porous-medium properties are listed in the following table:
| Property | Value | Unit |
|---|---|---|
| Porosity | 0.1 | - |
| Intrinsic permeability | $10^{-21}$ | m$^2$ |
| Biot’s constant | 1.0 | - |
| Bishop (saturation cutoff) | 0.99 | - |
Simulations are run with purely elastic deformation and with elasto-plastic deformation. For the elasto-plastic case we use the modified Mohr–Coulomb constitutive law (Mohr–Coulomb Abbo-Sloan). Mechanical properties are:
| Property | Value | Unit |
|---|---|---|
| Young’s modulus | 6.5 | GPa |
| Poisson’s ratio | 0.3 | - |
| Cohesion | 5 | MPa |
| Friction angle | 25.0 | degree |
| Dilatancy angle | 2.0 | degree |
| Transition angle | 25.0 | degree |
The initial capillary pressure is $10^4$ Pa. The initial gas pressure is set from a hydraulic steady-state condition:
$$ p^g_0= 10^5 - 9.81\rho_L y \quad\text{(Pa)}, $$with $\rho_L$ the liquid density and $y$ the vertical coordinate. The total initial stresses are:
For the fluid field, there is no flux on the left, bottom, and right boundaries. On the left and bottom boundaries, the displacement in the normal direction is fixed and the tangential traction component increment is zero. On the right boundary, the traction increment is zero. The remaining boundary conditions are listed below:
| Boundary | Variable | Type | Value | Unit |
|---|---|---|---|---|
| Top | Capillary pressure | Dirichlet | 1000 | Pa |
| Arc | Capillary pressure | Dirichlet | TimeDecayDirichlet |
Pa |
| (lower limit: $2.3850105160885438\cdot 10^8$) | Pa | |||
| Top | Gas pressure | Dirichlet | $8.50717\cdot 10^6$ | Pa |
| Arc | Gas pressure | Dirichlet | TimeDecayDirichlet (lower limit: $10^5$) |
Pa |
| Top | Deformation | Normal traction | -20.4$\cdot 10^{6}$ | Pa |
| Arc | Deformation | Release nodal force | - | - |
Note: the capillary pressure lower limit corresponds to a saturation value of 0.65.
The time-decay function for the boundary conditions TimeDecayDirichlet and ReleaseNodalForce is
import os…
(click to toggle)
import os
from pathlib import Path
import gmsh
import matplotlib.pyplot as plt
import numpy as np
import ogstools as ot
from mesh import MeshGeneratorout_dir = Path(os.environ.get("OGS_TESTRUNNER_OUT_DIR", "_out"))…
(click to toggle)
out_dir = Path(os.environ.get("OGS_TESTRUNNER_OUT_DIR", "_out"))
if not out_dir.exists():
out_dir.mkdir(parents=True)
mesh_dir = Path(out_dir, "Mesh")point_a = (6.5, -857.0, 0)…
(click to toggle)
point_a = (6.5, -857.0, 0)
point_b = (70.0, -857.0, 0)
radius_tunnel = 6.5
points = np.asarray(
[
[x, -857, 0]
for x in [
radius_tunnel,
radius_tunnel + 1,
radius_tunnel + 2.5,
radius_tunnel + 3.5,
radius_tunnel + 8.5,
]
]
)
labels = [f"r = {point[0]:.1f} m" for i, point in enumerate(points)]
saturation = ot.variables.Scalar(
data_name="saturation",
output_name="Saturation",
data_unit="",
output_unit="",
)
pg_interpolated = ot.variables.Scalar(
data_name="gas_pressure_interpolated",
output_name="Gas pressure",
data_unit="Pa",
output_unit="MPa",
)
pc_interpolated = ot.variables.Scalar(
data_name="capillary_pressure_interpolated",
output_name="capillary pressure",
data_unit="Pa",
output_unit="MPa",
)
pl_interpolated = ot.variables.Scalar(
data_name="liquid_pressure_interpolated",
output_name="Liquid pressure",
data_unit="Pa",
output_unit="MPa",
)
pls_strain = ot.variables.Scalar(
data_name="epsilon_pls",
output_name="Equivalent plastic strain",
data_unit="",
output_unit="",
)
mohr_coulomb = {
"Cohesion": 5e6, # Large number for fast run
"FrictionAngle": 25.0,
"DilatancyAngle": 2.0,
"TransitionAngle": 25.0,
"TensionCutOffParameter": 0.5,
}
output_variable_names = [
"displacement",
"sigma",
"gas_pressure",
"capillary_pressure",
"saturation",
]
comparison_atols = {
"displacement": 1e-9,
"sigma": 1e-6,
"gas_pressure": 1e-9,
"capillary_pressure": 1e-9,
"saturation": 1e-6,
}# Compare the obtained results with the reference results…
(click to toggle)
# Compare the obtained results with the reference results
def check_profile(profile, reference_file_name):
reference_profile = np.load(reference_file_name)
for variable_name in output_variable_names:
atol = comparison_atols[variable_name]
data = profile[variable_name]
expected_data = reference_profile[variable_name]
np.testing.assert_allclose(data, expected_data, atol=atol, rtol=1e-6)
print("Test passed.")if not gmsh.isInitialized():…
(click to toggle)
if not gmsh.isInitialized():
gmsh.initialize()
gmsh.model.add("Mesh")
mesh_generator = MeshGenerator(
gmsh_model=gmsh.model,
min_edge_length=1.0,
max_edge_length=12.0,
quad_zone_factor=0.25,
n_side=15,
)
mesh_generator.generate_meshes(out_dir=mesh_dir, order=2)
gmsh.finalize()Info : Meshing 1D...
Info : [ 0%] Meshing curve 1 (Circle)
Info : [ 20%] Meshing curve 2 (Circle)
Info : [ 30%] Meshing curve 3 (Line)
Info : [ 40%] Meshing curve 4 (Line)
Info : [ 50%] Meshing curve 5 (Line)
Info : [ 60%] Meshing curve 6 (Line)
Info : [ 70%] Meshing curve 7 (Line)
Info : [ 80%] Meshing curve 8 (Line)
Info : [ 90%] Meshing curve 9 (Line)
Info : [100%] Meshing curve 10 (Line)
Info : Done meshing 1D (Wall 0.00238915s, CPU 0.002685s)
Info : Meshing 2D...
Info : [ 0%] Meshing surface 1 (Transfinite)
Info : [ 40%] Meshing surface 2 (Plane, Delaunay)
Info : [ 70%] Meshing surface 3 (Plane, Delaunay)
Info : Done meshing 2D (Wall 0.0032666s, CPU 0.003284s)
Info : 597 nodes 972 elements
Info : Writing '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/domain.msh'...
Info : Done writing '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/domain.msh'
domain: 687 cells
physical_group_arc: 19 cells
physical_group_left: 26 cells
physical_group_bottom: 26 cells
physical_group_top: 6 cells
physical_group_right: 6 cells
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a510>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Reordering nodes...
info: Method: Reversing order of nodes unless it is considered correct by the OGS6 standard, i.e. such that det(J) > 0, where J is the Jacobian of the global-to-local coordinate transformation.
info: Corrected 687 elements.
info: VTU file written.
Create quadratic mesh for /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/domain.vtu
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Create a quadratic order mesh
info: Save the new mesh into a file
Create quadratic mesh for /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/arc.vtu
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Create a quadratic order mesh
info: Save the new mesh into a file
Create quadratic mesh for /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/right.vtu
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Create a quadratic order mesh
info: Save the new mesh into a file
Create quadratic mesh for /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/bottom.vtu
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Create a quadratic order mesh
info: Save the new mesh into a file
Create quadratic mesh for /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/left.vtu
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Create a quadratic order mesh
info: Save the new mesh into a file
Create quadratic mesh for /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/Mesh/top.vtu
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Create a quadratic order mesh
info: Save the new mesh into a file
OGS_BIN_PATH: None .
OGS wheel: ModuleSpec(name='ogs', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f0d5713a270>, origin='/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs/__init__.py', submodule_search_locations=['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/site-packages/ogs']) .
OGS in PATH: ['/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs', '/var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/bin/ogs'] .
Warning: Too many occurrences of 'ogs' found in PATH.
Please remove OGS from PATH.
info: Mesh reading time: 0.00192913 s
info: MeshNodeSearcher construction time: 6.1161e-05 s
info: identifySubdomainMesh(): identifySubdomainMeshNodes took 9.8087e-05 s
info: identifySubdomainMesh(): identifySubdomainMeshElements took 0.000276345 s
info: identifySubdomainMesh(): identifySubdomainMeshNodes took 3.054e-06 s
info: identifySubdomainMesh(): identifySubdomainMeshElements took 3.352e-05 s
info: identifySubdomainMesh(): identifySubdomainMeshNodes took 3.255e-06 s
info: identifySubdomainMesh(): identifySubdomainMeshElements took 3.5794e-05 s
info: identifySubdomainMesh(): identifySubdomainMeshNodes took 3.345e-06 s
info: identifySubdomainMesh(): identifySubdomainMeshElements took 3.4201e-05 s
info: identifySubdomainMesh(): identifySubdomainMeshNodes took 8.71e-07 s
info: identifySubdomainMesh(): identifySubdomainMeshElements took 3.2799e-05 s
info: identifySubdomainMesh(): identifySubdomainMeshNodes took 5.71e-07 s
info: identifySubdomainMesh(): identifySubdomainMeshElements took 3.2779e-05 s
info: identifySubdomains time: 0.000581361 s
info: writing time: 0.00204157 s
info: Entire run time: 0.00475194 s
def remove_plastic_model(prj):…
(click to toggle)
def remove_plastic_model(prj):
prj.remove_element("./processes/process/constitutive_relation[type='MFront']")
prj.remove_element(
"./processes/process/secondary_variables/secondary_variable[@internal_name='EquivalentPlasticStrain']"
)
prj.remove_element("./time_loop/output/variables/variable[7]")def runBenchmark(…
(click to toggle)
def runBenchmark(
project_file,
out_dir,
output_prefix,
mesh_dir,
use_taylor_hood=True,
plastic_model=None,
ogs_path=None,
):
prj = ot.Project(
input_file=project_file,
output_file=Path(out_dir, f"{output_prefix}.prj"),
OMP_NUM_THREADS=4,
OGS_ASM_THREADS=4,
)
if use_taylor_hood:
xpath_var = './process_variables/process_variable[name="displacement"]/'
prj.replace_text(
2,
xpath=xpath_var + "order",
)
if plastic_model:
print("Use plastic model")
for key, value in plastic_model.items():
prj.replace_text(value, f"./parameters/parameter[name='{key}']/value")
else:
print("Use elastic model")
prj.add_block(
blocktag="constitutive_relation",
parent_xpath="./processes/process",
taglist=["type", "youngs_modulus", "poissons_ratio"],
textlist=["LinearElasticIsotropic", "E", "nu"],
)
remove_plastic_model(prj)
prj.replace_text(
output_prefix,
xpath="./time_loop/output/prefix",
)
prj.write_input()
prj.run_model(
logfile=Path(out_dir, "log.txt"),
path=ogs_path,
args=f"-o {out_dir} -m {mesh_dir}",
)
print(f"Output prefix is {output_prefix}")
return Path(out_dir, f"{output_prefix}.pvd")def contour_plot(mesh_data, variables, cmap="jet", file_name=None):…
(click to toggle)
def contour_plot(mesh_data, variables, cmap="jet", file_name=None):
fig, axs = plt.subplots(2, 2, figsize=(8, 6), sharex=True, sharey=True)
axs_flatten = axs.flatten()
for ax, variable in zip(axs_flatten, variables, strict=True):
ot.plot.contourf(
mesh_data,
variable,
fig=fig,
ax=ax,
fontsize=8,
cmap=cmap,
)
fig.tight_layout()
if file_name:
plt.savefig(file_name, dpi=320)class PlotProfile:…
(click to toggle)
class PlotProfile:
def __init__(self, profile_e, profile_pls):
self.xs = profile_e["Distance"] + 6.5
self.profile_e = profile_e
self.profile_pls = profile_pls
def get_data(self, variable_name):
if variable_name == "sigma_xx":
return (
self.profile_e["sigma"][:, 0] * 1e-6,
self.profile_pls["sigma"][:, 0] * 1e-6,
)
if variable_name == "sigma_yy":
return (
self.profile_e["sigma"][:, 1] * 1e-6,
self.profile_pls["sigma"][:, 1] * 1e-6,
)
scaling = 1e-6 if "pressure" in variable_name else 1.0
return (
self.profile_e[variable_name] * scaling,
self.profile_pls[variable_name] * scaling,
)
def plot(self, variable_names, y_labels):
fig, axs = plt.subplots(1, 2, figsize=(10, 4), sharey=False)
for ax, variable_name, y_label in zip(
axs, variable_names, y_labels, strict=True
):
data_e, data_pls = self.get_data(variable_name)
ax.plot(self.xs, data_e, color="C0", label="elastic")
ax.plot(self.xs, data_pls, color="C7", label="plastic")
ax.set_xlabel("x / m")
ax.set_ylabel(y_label)
ax.grid()
ax.legend()
fig.tight_layout()
plt.show()class VariableVariations:…
(click to toggle)
class VariableVariations:
def __init__(self, point_data_e, point_data_pls):
self.point_data_e = point_data_e
self.point_data_pls = point_data_pls
self.labels_e = (np.array(labels) + " (elastic)").tolist()
self.labels_pls = (np.array(labels) + " (plastic)").tolist()
def plot(self, variables):
fig, axs = plt.subplots(1, 2, figsize=(12, 4))
for ax, variable in zip(axs, variables, strict=True):
ot.plot.line(
self.point_data_e,
"time",
variable,
labels=self.labels_e,
linestyle="dashed",
ax=ax,
fontsize=11,
linewidth=0.5,
)
ot.plot.line(
self.point_data_pls,
"time",
variable,
labels=self.labels_pls,
ax=ax,
fontsize=11,
linewidth=0.5,
)
ax.grid()
ax.legend(loc="center left", bbox_to_anchor=(1, 0.5))
fig.tight_layout()
plt.show()pvd = runBenchmark(…
(click to toggle)
pvd = runBenchmark(
project_file="excavation_th2m.prj",
out_dir=out_dir,
output_prefix="excavation_th2m_e",
mesh_dir=mesh_dir,
)Use elastic model
Project file written to output.
Simulation: /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/excavation_th2m_e.prj
Status: finished successfully.
Execution took 30.104228258132935 s
Output prefix is excavation_th2m_e
ms_e = ot.MeshSeries(pvd).scale(time=("s", "d"))
ms_e_last = ms_e[-1]The following figures illustrate the distributions of displacements and stresses at the end of the simulation.
contour_plot(…
(click to toggle)
contour_plot(
ms_e_last,
[
ot.variables.displacement["x"],
ot.variables.displacement["y"],
ot.variables.stress["xx"],
ot.variables.stress["yy"],
],
)
The following figures illustrate the distributions of gas pressure, liquid pressure, capillary pressure and saturation at the end of the simulation.
contour_plot(…
(click to toggle)
contour_plot(
ms_e_last,
[saturation, pc_interpolated, pg_interpolated, pl_interpolated],
cmap="coolwarm",
)
x_profile_e = ms_e_last.sample_over_line(point_a, point_b, resolution=55)…
(click to toggle)
x_profile_e = ms_e_last.sample_over_line(point_a, point_b, resolution=55)
## Write the reference results.
# fields = {name: x_profile_e[name] for name in output_variable_names}
# np.savez("reference_profile_e.npz", **fields)
check_profile(x_profile_e, "reference_profile_e.npz")Test passed.
pvd_pls = runBenchmark(…
(click to toggle)
pvd_pls = runBenchmark(
project_file="excavation_th2m.prj",
out_dir=out_dir,
output_prefix="excavation_th2m_pls",
mesh_dir=mesh_dir,
plastic_model=mohr_coulomb,
)Use plastic model
Project file written to output.
Simulation: /var/lib/gitlab-runner/builds/Sbm-BZZt4/1/ogs/build/release-all/Tests/Data/TH2M/ExcavationTH2M/excavation_th2m/excavation_th2m_pls.prj
Status: finished successfully.
Execution took 63.93568778038025 s
Output prefix is excavation_th2m_pls
ms_pls = ot.MeshSeries(pvd_pls).scale(time=("s", "d"))
ms_pls_last = ms_pls[-1]The following figures illustrate the distributions of displacement, horizontal stress, and equivalent plastic strain at the end of the simulation. In comparison with elastic deformation, displacement and stress exhibit noticeable changes.
contour_plot(…
(click to toggle)
contour_plot(
ms_pls_last,
[
ot.variables.displacement["x"],
ot.variables.displacement["y"],
ot.variables.stress["xx"],
pls_strain,
],
)
The following figures illustrate the distributions of gas pressure, liquid pressure, capillary pressure and saturation at the end of the simulation. In contrast to elastic deformation, these variables are also modified.
contour_plot(…
(click to toggle)
contour_plot(
ms_pls_last,
[saturation, pc_interpolated, pg_interpolated, pl_interpolated],
cmap="coolwarm",
)
x_profile_pls = ms_pls_last.sample_over_line(point_a, point_b, resolution=55)…
(click to toggle)
x_profile_pls = ms_pls_last.sample_over_line(point_a, point_b, resolution=55)
## Write the reference results.
# fields = {name: x_profile_pls[name] for name in output_variable_names}
# np.savez("reference_profile_pls.npz", **fields)
check_profile(x_profile_pls, "reference_profile_pls.npz")Test passed.
The left figure below illustrates the equivalent plastic strain profile at the bottom boundary, while the right figure illustrates the equivalent plastic strain variations at selected bottom points. From the latter, we observe that the largest equivalent plastic strain occurs at the position closest to the tunnel surface.
fig, ax = plt.subplots(1, 2, figsize=(10, 4))…
(click to toggle)
fig, ax = plt.subplots(1, 2, figsize=(10, 4))
ax[0].plot(x_profile_pls["Distance"] + 6.5, x_profile_pls["epsilon_pls"], color="C0")
ax[0].set_xlabel("x / m")
ax[0].set_ylabel("Equivalent plastic strain")
ax[0].set_title("Profile at the bottom")
ax[0].grid()
ms_pts_pls = ot.MeshSeries.extract_probe(ms_pls, points)
ot.plot.line(
ms_pts_pls,
"time",
pls_strain,
labels=labels,
# linestyle="dashed",
ax=ax[1],
fontsize=11,
linewidth=0.5,
)
ax[1].set_title("Variations at the selected bottom points")
fig.tight_layout()
plt.show()
In this section, the results obtained using elastic deformation and elasto-plastic deformation are compared.
plot_profile = PlotProfile(x_profile_e, x_profile_pls)The following figures present the profiles of horizontal stress, $\sigma_{xx}$, and vertical stress, $\sigma_{yy}$ along the bottom boundary. The stress variations near the tunnel are clearly significant.
plot_profile.plot(…
(click to toggle)
plot_profile.plot(
["sigma_xx", "sigma_yy"],
[r"Stress $\sigma_{xx}$ /MPa", r"Stress $\sigma_{yy}$ /MPa"],
)
The following figures show the profiles of gas pressure and liquid pressure along the bottom boundary. The application of the plastic model results in a substantial change in the gas pressure.
plot_profile.plot(…
(click to toggle)
plot_profile.plot(
["gas_pressure_interpolated", "liquid_pressure_interpolated"],
["Gas pressure /MPa", "Liquid pressure /MPa"],
)
The following figures show the profiles of capillary pressure and saturation along the bottom boundary. Using the plastic model results in a slight change in the saturation.
plot_profile.plot(…
(click to toggle)
plot_profile.plot(
["capillary_pressure_interpolated", "saturation"],
["Capillary pressure /MPa", "Saturation"],
)
ms_pts_e = ot.MeshSeries.extract_probe(ms_e, points)
vv = VariableVariations(ms_pts_e, ms_pts_pls)The figures below illustrate the variations in horizontal displacement (left) and gas pressure (right). It is evident that the application of the plastic model leads to reductions in both parameters.
vv.plot([ot.variables.displacement["x"], pg_interpolated])
The figures below illustrate the variations in horizontal stress (left) and vertical stress (right). This stress comparison further confirms that the application of the plastic model leads to significant alterations in the stress results.
vv.plot([ot.variables.stress["xx"], ot.variables.stress["yy"]])
The figures below illustrate the variations in capillary pressure (left) and saturation (right). The significant changes in these variables occur in the region near the tunnel.
vv.plot([pc_interpolated, saturation])
This benchmark is conducted using both elastic and elasto-plastic models and Taylor-Hood elements. The results demonstrate the influence of the elasto-plastic model on the simulation outcomes. To tailor the run for shorter computation time, a coarse mesh is generated and a large cohesion value is assigned to the plastic model to reduce non-linear iterations. Adjustments to the mesh element density and cohesion can be made directly within this notebook.
This article was written by Wenqing Wang. If you are missing something or you find an error please let us know.
Generated with Hugo 0.147.9
in CI job 683680
|
Last revision: November 10, 2025