From 2cef61799ed0228020c06778d59a09565b19488a Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 11:09:11 +0200
Subject: [PATCH 1/8] [ci,nb] Refactored notebook testrunner.
nb2hugo not required anymore.
special frontmatter in ipynb notebooks not required anymore, use regular
toml-frontmatter
---
Tests/Data/Notebooks/testrunner.py | 125 ++++++++++-------------------
1 file changed, 43 insertions(+), 82 deletions(-)
diff --git a/Tests/Data/Notebooks/testrunner.py b/Tests/Data/Notebooks/testrunner.py
index 27710943c0b..94af163cdf6 100644
--- a/Tests/Data/Notebooks/testrunner.py
+++ b/Tests/Data/Notebooks/testrunner.py
@@ -11,61 +11,48 @@
import toml
from pathlib import Path
import jupytext
+import subprocess
def save_to_website(exec_notebook_file, web_path):
- from nb2hugo.writer import HugoWriter
-
- output_path = "docs/benchmarks"
+ output_path_arg = ""
notebook = nbformat.read(exec_notebook_file, as_version=4)
first_cell = notebook.cells[0]
- if is_jupytext:
- if "Tests/Data" not in exec_notebook_file:
- output_path = str(Path(exec_notebook_file).parent.parent)
- else:
- lines = first_cell.source.splitlines()
- toml_begin = lines.index("+++")
- toml_end = max(loc for loc, val in enumerate(lines) if val == "+++")
- toml_lines = lines[toml_begin + 1 : toml_end]
- parsed_frontmatter = toml.loads("\n".join(toml_lines))
- output_path = (
- Path(build_dir)
- / Path("web/content")
- / Path(output_path)
- / Path(parsed_frontmatter["web_subsection"])
- )
- elif first_cell.cell_type == "raw":
+ if "Tests/Data" in exec_notebook_file:
lines = first_cell.source.splitlines()
- last_line = lines[-1]
- if "" not in last_line:
- print(
- f"Warning: {exec_notebook_file} does not contain '' as the "
- "last line in the RAW cell!"
- )
- parsed_frontmatter = toml.loads("\n".join(lines[:-1]))
- if "web_subsection" not in parsed_frontmatter:
- print(
- f"Error: {exec_notebook_file} frontmatter does not contain "
- "'web_subsection'!"
- )
- output_path = os.path.join(output_path, parsed_frontmatter["web_subsection"])
- output_path = Path(build_dir) / (Path("web/content") / Path(output_path))
- else:
- print(
- f"Warning: {exec_notebook_file} does not contain a RAW cell as its first "
- "cell!"
+ toml_begin = lines.index("+++")
+ toml_end = max(loc for loc, val in enumerate(lines) if val == "+++")
+ toml_lines = lines[toml_begin + 1 : toml_end]
+ parsed_frontmatter = toml.loads("\n".join(toml_lines))
+ output_path = (
+ Path(build_dir)
+ / Path("web/content/docs/benchmarks")
+ / Path(parsed_frontmatter["web_subsection"])
+ )
+ output_path_arg = (
+ f"--output-dir={Path(output_path) / Path(exec_notebook_file).stem}"
)
- output_path = os.path.join(output_path, "notebooks")
- writer = HugoWriter()
- writer.convert(
- exec_notebook_file,
- web_path,
- output_path,
- os.path.join(
- os.path.dirname(os.path.abspath(__file__)),
- "nbconvert_templates/collapsed.md.j2",
- ),
+
+ template = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "nbconvert_templates/collapsed.md.j2",
)
+ subprocess.run(
+ [
+ "jupyter",
+ "nbconvert",
+ "--to",
+ "markdown",
+ f"--template-file={template}",
+ "--output=index",
+ output_path_arg,
+ exec_notebook_file,
+ ]
+ )
+
+ if not "Tests/Data" in exec_notebook_file:
+ return
+
for subfolder in ["figures", "images"]:
figures_path = os.path.abspath(
os.path.join(os.path.dirname(notebook_file_path), subfolder)
@@ -140,7 +127,7 @@ def save_to_website(exec_notebook_file, web_path):
nb = nbformat.read(f, as_version=4)
ep = ExecutePreprocessor(kernel_name="python3")
- # 1. Run the notebook
+ # Run the notebook
print(f"[Start] {notebook_filename}")
start = timer()
try:
@@ -162,15 +149,7 @@ def save_to_website(exec_notebook_file, web_path):
pass
end = timer()
- # 2. Instantiate the exporter. We use the `classic` template for now; we'll get
- # into more details later about how to customize the exporter further.
- html_exporter = HTMLExporter()
- html_exporter.template_name = "classic"
-
- # 3. Process the notebook we loaded earlier
- (body, resources) = html_exporter.from_notebook_node(nb)
-
- # 4. Write new notebook
+ # Write new notebook
with open(convert_notebook_file, "w", encoding="utf-8") as f:
repo = "https://gitlab.opengeosys.org/ogs/ogs"
branch = "master"
@@ -180,17 +159,14 @@ def save_to_website(exec_notebook_file, web_path):
# Modify metadata
meta_cell = nb["cells"][0]
- if is_jupytext:
- if meta_cell.source.startswith("---"):
- print(
- f"Error: {notebook_filename} frontmatter is not in TOML format! Use +++ delimitiers!"
- )
- success = False
- meta_cell.source = meta_cell.source.replace(
- "+++\n", "+++\nnotebook = true\n", 1
+ if meta_cell.source.startswith("---"):
+ print(
+ f"Error: {notebook_filename} frontmatter is not in TOML format! Use +++ delimitiers!"
)
- else:
- meta_cell.source = f"notebook = true\n{meta_cell.source}"
+ success = False
+ meta_cell.source = meta_cell.source.replace(
+ "+++\n", "+++\nnotebook = true\n", 1
+ )
# Insert Jupyter header with notebook source and binderhub link
binder_link = f"https://mybinder.org/v2/gh/bilke/binder-ogs-requirements/master?urlpath=git-pull%3Frepo={repo}%26urlpath=lab/tree/ogs/{notebook_file_path_relative}%26branch={branch}"
@@ -236,21 +212,6 @@ def save_to_website(exec_notebook_file, web_path):
first_markdown_cell.source = text + first_markdown_cell.source
nbformat.write(nb, f)
- # 5. Symlink images or figures subfolder
- for subfolder in ["figures", "images"]:
- figures_path = os.path.abspath(
- os.path.join(os.path.dirname(notebook_file_path), subfolder)
- )
- symlink_figures_path = os.path.join(notebook_output_path, subfolder)
- if os.path.exists(figures_path) and not os.path.exists(
- symlink_figures_path
- ):
- print(
- f"{subfolder} folder detected, symlink {figures_path} to "
- f"{symlink_figures_path}"
- )
- os.symlink(figures_path, symlink_figures_path)
-
status_string = ""
if notebook_success:
status_string += "[Passed] "
From 3f7236bf17205b73ff84c7ced789181b7aa749cf Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 11:20:54 +0200
Subject: [PATCH 2/8] [web] Update docs for toml frontmatter in notebooks.
---
.../documentation/jupyter-docs/index.md | 35 ++++++++++---------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/web/content/docs/devguide/documentation/jupyter-docs/index.md b/web/content/docs/devguide/documentation/jupyter-docs/index.md
index 15c3c23bf4a..a645379353a 100644
--- a/web/content/docs/devguide/documentation/jupyter-docs/index.md
+++ b/web/content/docs/devguide/documentation/jupyter-docs/index.md
@@ -35,14 +35,15 @@ If you use additional images put them into the `my-page`-folder.
If the notebook result should appear as a page on the web documentation a frontmatter with some meta information (similar to [regular web pages]({{< ref "web-docs.md" >}})) is required as the first cell in the notebook:
- Add a new cell and move it to the first position in the notebook
-- Change the cell type to `raw`!
-- Add meta information, conclude with a end-of-file marker (``) e.g.:
+- Cell type needs to be `markdown` or `raw`
+- Add meta information e.g.:
```md
+ +++
title = "BHE Meshing"
date = "2023-08-18"
author = "Joy Brato Shil, Haibing Shao"
-
+ +++
```
---
@@ -101,10 +102,24 @@ web_subsection = "small-deformations" # required for notebooks in Tests/Data onl
- Frontmatter needs to be in [TOML](https://toml.io)-format.
- For notebooks describing benchmarks `web_subsection` needs to be set to a sub-folder in [web/content/docs/benchmarks](https://gitlab.opengeosys.org/ogs/ogs/-/tree/master/web/content/docs/benchmarks) (if not set the notebook page will not be linked from navigation bar / benchmark gallery on the web page).
- If you edit a Markdown-based notebook with Jupyter and the Jupytext extension please don't add the two newlines but make sure that the frontmatter has its own cell (not mixed with markdown content).
-- For (deprecated) `.ipynb`-based notebooks the frontmatter has to given as a `raw`-cell containing a special ``-marker. See existing notebooks (e.g. [SimpleMechanics.ipynb](https://gitlab.opengeosys.org/ogs/ogs/-/blob/master/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb)) for reference.
+- For (deprecated) `.ipynb`-based notebooks the frontmatter needs to be given in the first cell. See existing notebooks (e.g. [SimpleMechanics.ipynb](https://gitlab.opengeosys.org/ogs/ogs/-/blob/master/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb)) for reference.
### Notebook setup
+The first cell after the frontmatter needs to be a `markdown`-cell!
+
+#### Markdown cells
+
+- HTML inside Markdown cells may be used for specific reasons (e.g. better image formatting).
+- For notebooks in `Tests/Data` only: Static images e.g. for the gallery image or to be used in Markdown cells have to be located in either `images`- or `figures`-subdirectories beneath the Notebook file! Otherwise they will not show up on the web site.
+ - For image captions add a title in quotation marks after the image path, e.g.
+
+ ```md
+ ![Alt text](figures/my_image.png "This will be the image caption.")
+ ```
+
+ - Please note that in merge request web previews static images are not shown at all.
+
#### Python cells
- Do not use machine-specific or absolute paths! See the following example to set up notebook output paths:
@@ -136,18 +151,6 @@ web_subsection = "small-deformations" # required for notebooks in Tests/Data onl
- Do not write anything into the source directories. Use an `out_dir` as above.
- Assume that `ogs` and other tools are in the `PATH`.
-#### Markdown cells
-
-- Do not use HTML inside Markdown blocks.
-- Static images e.g. for the gallery image or to be used in Markdown cells have to be located in either `images`- or `figures`-subdirectories beneath the Notebook file! Otherwise they will not show up in the web site.
- - For image captions add a title in quotation marks after the image path, e.g.
-
- ```md
- ![Alt text](figures/my_image.png "This will be the image caption.")
- ```
-
- - Please note that in merge request web previews static images are not shown at all.
-
### Execution environment
In CI the notebooks are executed with all dependencies installed into a virtual environment in the build directory. The installed packages are defined in `Test/Data/requirements.txt`. The same setup can be enabled locally by setting the CMake option `OGS_USE_PIP=ON`. E.g.
From ef617dde5e611c2929a9fa3413b46237d82ea1ce Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 11:31:20 +0200
Subject: [PATCH 3/8] [nb] Update notebooks to use regular toml frontmatter.
---
.../ssd-cube.ipynb | 9 +-
.../SeabedResponse/Stationary_waves.ipynb | 33 ++++---
..._Disc_with_hole_convergence_analysis.ipynb | 63 ++++++------
.../Mechanics/Linear/SimpleMechanics.ipynb | 9 +-
Tests/Data/Mechanics/PLLC/PLLC.ipynb | 7 +-
Tests/Data/Notebooks/SimplePETSc.ipynb | 7 +-
.../Notebooks/thermo-osmosis.run-skip.ipynb | 15 +--
.../DiffusionSorptionDecay.ipynb | 51 +++++-----
.../MultiLayerDiffusion.ipynb | 47 ++++-----
.../DecayChain/DecayChain.ipynb | 61 ++++++------
.../performance_measurements.ipynb | 98 ++++++++++++++-----
.../RadionuclidesMigration.ipynb | 43 ++++----
.../LiquidFlow/AxiSymTheis/axisym_theis.ipynb | 91 +++++------------
.../BlockingConductingFracture.ipynb | 31 +++---
.../HeatPipe/heatpipe.ipynb | 54 +++++-----
.../TwoPhaseFlowPrho/MoMaS/MoMaS.ipynb | 3 +-
.../Kregime_Propagating_jupyter.ipynb | 71 +++++++-------
.../sen_shear.ipynb | 53 +++++-----
.../beam_jupyter_notebook/beam.ipynb | 43 ++++----
.../Kregime_Static_jupyter.ipynb | 61 ++++++------
.../surfing_pyvista.ipynb | 23 ++---
.../PhaseField/tpb_jupyter_notebook/TPB.ipynb | 49 +++++-----
Tests/Data/TH2M/H/diffusion/diffusion.ipynb | 13 +--
.../phase_appearance.ipynb | 17 ++--
Tests/Data/TH2M/H2/mcWhorter/mcWhorter.ipynb | 15 +--
.../ogs-jupyter-lab-h2m-2d-liakopoulos.ipynb | 41 ++++----
.../TH2M/TH/Ogata-Banks/Ogata-Banks.ipynb | 25 ++---
.../confined_gas_compression.ipynb | 23 ++---
Tests/Data/TH2M/TH2/heatpipe/heatpipe.ipynb | 25 ++---
.../SaturatedPointheatsource.ipynb | 33 ++++---
30 files changed, 571 insertions(+), 543 deletions(-)
diff --git a/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb b/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb
index b77bc7d1d80..fe9adb84908 100644
--- a/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb
+++ b/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb
@@ -5,12 +5,13 @@
"id": "34c87f77-b604-4200-b102-da8290ef81b3",
"metadata": {},
"source": [
+ "+++\n",
"title = \"SteadyStateDiffusion Cube Test\"\n",
"date = \"2021-11-09\"\n",
"author = \"Lars Bilke\"\n",
"web_subsection = \"elliptic\"\n",
"draft = true\n",
- "\n"
+ "+++\n"
]
},
{
@@ -44,7 +45,7 @@
"if \"CI\" in os.environ:\n",
" pv.set_jupyter_backend(\"static\")\n",
"else:\n",
- " pv.set_jupyter_backend(\"client\")"
+ " pv.set_jupyter_backend(\"client\")\n"
]
},
{
@@ -57,7 +58,7 @@
"outputs": [],
"source": [
"resolution = \"2e4\"\n",
- "! ogs cube_{resolution}.prj -o {out_dir} > {out_dir}/log.txt"
+ "! ogs cube_{resolution}.prj -o {out_dir} > {out_dir}/log.txt\n"
]
},
{
@@ -88,7 +89,7 @@
"\n",
"plotter = pv.Plotter(notebook=True)\n",
"plotter.add_mesh(mesh, scalars=\"v\") # pressure\n",
- "plotter.show()"
+ "plotter.show()\n"
]
}
],
diff --git a/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb b/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb
index a7d6399627e..1dc7b1fd727 100644
--- a/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb
+++ b/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb
@@ -5,11 +5,12 @@
"id": "09d7a481-d07d-465f-8f3b-a098b650295d",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Seabed response to water waves\"\n",
"date = \"2023-01-11\"\n",
"author = \"Linda Günther\"\n",
"web_subsection = \"hydro-mechanics\"\n",
- ""
+ "+++\n"
]
},
{
@@ -188,7 +189,7 @@
"\n",
"import pyvista as pv\n",
"pv.set_plot_theme(\"document\")\n",
- "pv.set_jupyter_backend(\"static\")"
+ "pv.set_jupyter_backend(\"static\")\n"
]
},
{
@@ -231,7 +232,7 @@
" sig_xx_rel = np.real(((-2*(m-1)*lam*theta + 2*lam*(1+m*theta)*lam*z)*B1*np.exp(-lam*z) - 2*lam*B2*np.exp(-lam*z) + ((m-1)*(xi_2-lam**2) - 2*lam**2)*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.cos(lam*x))\n",
" sig_zz_rel = np.real(((-2*(m+1)*lam*theta - 2*lam*(1+m*theta)*lam*z)*B1*np.exp(-lam*z) + 2*lam*B2*np.exp(-lam*z) + ((m-1)*(xi_2-lam**2) + 2*xi_2)*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.cos(lam*x))\n",
" sig_xz_rel = np.real(((-2*lam*(1+m*theta)*lam*z-2*lam*theta)*B1*np.exp(-lam*z) + 2*lam*B2*np.exp(-lam*z) + 2*np.sqrt(xi_2)*lam*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.sin(lam*x))\n",
- " return p_rel, sig_xx_rel, sig_zz_rel, sig_xz_rel"
+ " return p_rel, sig_xx_rel, sig_zz_rel, sig_xz_rel\n"
]
},
{
@@ -286,7 +287,7 @@
"#ax[1].plot(compute_pressure_and_stresses(t,0,y)[2]+compute_pressure_and_stresses(t,0,y)[0], -y_rel, linestyle = \"--\", color = colors[1], label = \"$\\\\sigma_{yy}$/$\\\\alpha\\\\tilde{p}$\") # Total vertical stress\n",
"ax[1].plot(compute_pressure_and_stresses(t,0,y)[3], -y_rel, color = colors[4], label = r\"$\\sigma'_{xy}/(\\alpha\\tilde{p})$\")\n",
"ax[1].set_xlabel(r\"$\\sigma'/(\\alpha\\tilde{p})$\")\n",
- "ax[1].legend();"
+ "ax[1].legend();\n"
]
},
{
@@ -338,7 +339,7 @@
"\n",
" \n",
"ax[0].set_title(\"Pore pressure over time\")\n",
- "ax[1].set_title(\"Effective stresses over time\");"
+ "ax[1].set_title(\"Effective stresses over time\");\n"
]
},
{
@@ -390,7 +391,7 @@
"ax[0][1].set_title(\"$\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\")\n",
"ax[1][1].set_title(\"$\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\")\n",
"ax[1][0].set_title(\"$\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\")\n",
- "fig.tight_layout();"
+ "fig.tight_layout();\n"
]
},
{
@@ -437,7 +438,7 @@
"\n",
"# out_dir will contain all data we produce\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
- "os.makedirs(out_dir, exist_ok=True)"
+ "os.makedirs(out_dir, exist_ok=True)\n"
]
},
{
@@ -579,7 +580,7 @@
}
],
"source": [
- "generate_mesh_axb(200,100,25,45,1.07)"
+ "generate_mesh_axb(200,100,25,45,1.07)\n"
]
},
{
@@ -591,7 +592,7 @@
},
"outputs": [],
"source": [
- "input_file = f\"{out_dir}/square_200x100.msh\""
+ "input_file = f\"{out_dir}/square_200x100.msh\"\n"
]
},
{
@@ -642,7 +643,7 @@
],
"source": [
"!msh2vtu --ogs {input_file}\n",
- "assert _exit_code == 0"
+ "assert _exit_code == 0\n"
]
},
{
@@ -686,7 +687,7 @@
"\n",
"plotter.show_bounds(ticks=\"outside\", xlabel=\"x / m\", ylabel=\"y / m\")\n",
"plotter.view_xy()\n",
- "plotter.show()"
+ "plotter.show()\n"
]
},
{
@@ -755,7 +756,7 @@
},
"outputs": [],
"source": [
- "from ogs6py import ogs"
+ "from ogs6py import ogs\n"
]
},
{
@@ -836,7 +837,7 @@
" else:\n",
" f_rel[stress_idx][pt_idx] = f_abs[stress_idx][pt_idx] / sigma_ana\n",
" \n",
- " return f_abs, f_rel"
+ " return f_abs, f_rel\n"
]
},
{
@@ -859,7 +860,7 @@
"source": [
"model = ogs.OGS(INPUT_FILE=\"seabed_response_200x100.prj\", PROJECT_FILE=\"seabed_response_200x100.prj\")\n",
"model.run_model(logfile=f\"{out_dir}/out.txt\",\n",
- " args=f\"-o {out_dir} -m {out_dir}\")"
+ " args=f\"-o {out_dir} -m {out_dir}\")\n"
]
},
{
@@ -902,7 +903,7 @@
"plotter.show_bounds(ticks=\"outside\", xlabel = \"x / m\", ylabel = \"y / m\")\n",
"plotter.add_axes()\n",
"plotter.view_xy()\n",
- "plotter.show()"
+ "plotter.show()\n"
]
},
{
@@ -993,7 +994,7 @@
" ax[idx_1][idx_2].grid(True)\n",
" ax[idx_1][idx_2].set_ylabel(\"$y$ / $L$\")\n",
" ax[idx_1][0].set_xlim(-1.1, 1.1)\n",
- " ax[idx_1][idx_2].legend()"
+ " ax[idx_1][idx_2].legend()\n"
]
},
{
diff --git a/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb b/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb
index d5ff704aebc..8ead903b5f0 100644
--- a/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb
+++ b/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb
@@ -1,15 +1,16 @@
{
"cells": [
{
- "cell_type": "raw",
+ "cell_type": "markdown",
"id": "bb0907b4-4e26-4c4e-ab1f-22b5330cb1d2",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Linear elasticity: disc with hole convergence study\"\n",
"date = \"2022-09-15\"\n",
"author = \"Linda Günther, Sophia Einspänner, Robert Habel, Christoph Lehmann and Thomas Nagel\"\n",
"web_subsection = \"small-deformations\"\n",
- ""
+ "+++"
]
},
{
@@ -97,7 +98,7 @@
"plt.rcParams[\"axes.spines.left\"] = True\n",
"plt.rcParams[\"axes.spines.bottom\"] = True\n",
"plt.rcParams[\"axes.axisbelow\"] = True\n",
- "plt.rcParams[\"figure.figsize\"] = (8, 6)"
+ "plt.rcParams[\"figure.figsize\"] = (8, 6)\n"
]
},
{
@@ -117,7 +118,7 @@
"# ATTENTION: We assume that this notebook is executed in the directory where\n",
"# it is stored. Otherwise this notebook might not work!\n",
"out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"out\")\n",
- "os.makedirs(out_dir, exist_ok=True)"
+ "os.makedirs(out_dir, exist_ok=True)\n"
]
},
{
@@ -137,7 +138,7 @@
"STUDY_indices = [8, 16, 24, 40, 60, 80, 240]\n",
"\n",
"# With this parameter the length of one axis of the square plate is defined\n",
- "STUDY_mesh_size = 20"
+ "STUDY_mesh_size = 20\n"
]
},
{
@@ -273,7 +274,7 @@
"def resample_mesh_to_240_resolution(idx):\n",
" mesh_fine = read_last_timestep_mesh(240)\n",
" mesh_coarse = read_last_timestep_mesh(idx)\n",
- " return mesh_fine.sample(mesh_coarse)"
+ " return mesh_fine.sample(mesh_coarse)\n"
]
},
{
@@ -311,7 +312,7 @@
},
"outputs": [],
"source": [
- "import mesh_quarter_of_rectangle_with_hole"
+ "import mesh_quarter_of_rectangle_with_hole\n"
]
},
{
@@ -541,7 +542,7 @@
" NR=idx,\n",
" Nr=idx,\n",
" P=1,\n",
- " )"
+ " )\n"
]
},
{
@@ -568,7 +569,7 @@
"source": [
"for idx in STUDY_indices:\n",
" input_file = f\"{out_dir}/disc_with_hole_idx_is_{idx}.msh\"\n",
- " ! msh2vtu -r --ogs -o {out_dir}/disc_with_hole_idx_is_{idx} {input_file}"
+ " ! msh2vtu -r --ogs -o {out_dir}/disc_with_hole_idx_is_{idx} {input_file}\n"
]
},
{
@@ -604,7 +605,7 @@
"import pyvista as pv\n",
"\n",
"pv.set_plot_theme(\"document\")\n",
- "pv.set_jupyter_backend(\"static\")"
+ "pv.set_jupyter_backend(\"static\")\n"
]
},
{
@@ -647,7 +648,7 @@
"p.camera.zoom(1.3)\n",
"p.window_size = [1000, 500]\n",
"\n",
- "p.show()"
+ "p.show()\n"
]
},
{
@@ -671,7 +672,7 @@
"outputs": [],
"source": [
"from ogs6py import ogs\n",
- "import shutil"
+ "import shutil\n"
]
},
{
@@ -716,7 +717,7 @@
" prj_path = os.path.join(out_dir, prj_file)\n",
"\n",
" model = ogs.OGS(INPUT_FILE=prj_path, PROJECT_FILE=prj_path)\n",
- " model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")"
+ " model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")\n"
]
},
{
@@ -806,7 +807,7 @@
" * np.sin(2 * np.pi * theta / 180)\n",
" )\n",
" * np.heaviside(r + 1e-7 - a, 1)\n",
- " )"
+ " )\n"
]
},
{
@@ -909,7 +910,7 @@
" # only a single 4-vector will be converted\n",
" return vec4_to_mat3x3polar_single(vec4, xs, ys)\n",
" else:\n",
- " return vec4_to_mat3x3polar_multi(vec4, xs, ys)"
+ " return vec4_to_mat3x3polar_multi(vec4, xs, ys)\n"
]
},
{
@@ -936,7 +937,7 @@
" STUDY_num_result_meshes_by_index[idx] = mesh\n",
"\n",
"\n",
- "read_simulation_result_meshes()"
+ "read_simulation_result_meshes()\n"
]
},
{
@@ -964,7 +965,7 @@
" STUDY_num_result_xaxis_meshes_by_index[idx] = line_mesh\n",
"\n",
"\n",
- "compute_xaxis_meshes()"
+ "compute_xaxis_meshes()\n"
]
},
{
@@ -992,7 +993,7 @@
" STUDY_num_result_yaxis_meshes_by_index[idx] = line_mesh\n",
"\n",
"\n",
- "compute_yaxis_meshes()"
+ "compute_yaxis_meshes()\n"
]
},
{
@@ -1021,7 +1022,7 @@
" STUDY_num_result_diagonal_meshes_by_index[idx] = line_mesh\n",
"\n",
"\n",
- "compute_diagonal_meshes()"
+ "compute_diagonal_meshes()\n"
]
},
{
@@ -1239,7 +1240,7 @@
" fig.tight_layout()\n",
"\n",
"\n",
- "plot_stress_distribution_along_xaxis()"
+ "plot_stress_distribution_along_xaxis()\n"
]
},
{
@@ -1328,7 +1329,7 @@
},
"outputs": [],
"source": [
- "from vtkmodules.vtkFiltersParallel import vtkIntegrateAttributes"
+ "from vtkmodules.vtkFiltersParallel import vtkIntegrateAttributes\n"
]
},
{
@@ -1349,7 +1350,7 @@
" integrator.Update()\n",
" return pv.wrap(\n",
" integrator.GetOutputDataObject(0)\n",
- " ) # that is an entire mesh with one point and one cell"
+ " ) # that is an entire mesh with one point and one cell\n"
]
},
{
@@ -1376,7 +1377,7 @@
" l2_tt = np.sqrt(sum(list_tt))\n",
" l2_rt = np.sqrt(sum(list_rt))\n",
"\n",
- " return l2_rr, l2_tt, l2_rt"
+ " return l2_rr, l2_tt, l2_rt\n"
]
},
{
@@ -1406,7 +1407,7 @@
" l2_x = np.sqrt(sum(list_x))\n",
" l2_y = np.sqrt(sum(list_y))\n",
"\n",
- " return l2_x, l2_y"
+ " return l2_x, l2_y\n"
]
},
{
@@ -1430,7 +1431,7 @@
" l2_rt = np.linalg.norm(sig_rt_240 - sig_rt)\n",
"\n",
" points = sig_rr.shape[0]\n",
- " return l2_rr / np.sqrt(points), l2_tt / np.sqrt(points), l2_rt / np.sqrt(points)"
+ " return l2_rr / np.sqrt(points), l2_tt / np.sqrt(points), l2_rt / np.sqrt(points)\n"
]
},
{
@@ -1461,7 +1462,7 @@
" l2_x = np.linalg.norm(dis_x_240 - dis_x)\n",
" l2_y = np.linalg.norm(dis_y_240 - dis_y)\n",
"\n",
- " return l2_x / np.sqrt(points), l2_y / np.sqrt(points)"
+ " return l2_x / np.sqrt(points), l2_y / np.sqrt(points)\n"
]
},
{
@@ -1501,7 +1502,7 @@
" L2_tt = np.sqrt(integration_result_mesh.point_data[\"diff_tt_squared\"][0])\n",
" L2_rt = np.sqrt(integration_result_mesh.point_data[\"diff_rt_squared\"][0])\n",
"\n",
- " return L2_rr, L2_tt, L2_rt"
+ " return L2_rr, L2_tt, L2_rt\n"
]
},
{
@@ -1541,7 +1542,7 @@
" L2_x = np.sqrt(integration_result_mesh.point_data[\"diff_x_squared\"][0])\n",
" L2_y = np.sqrt(integration_result_mesh.point_data[\"diff_y_squared\"][0])\n",
"\n",
- " return L2_x, L2_y"
+ " return L2_x, L2_y\n"
]
},
{
@@ -1607,7 +1608,7 @@
" size[idx] = compute_cell_size(idx, mesh_coarse)\n",
"\n",
"\n",
- "compute_error_norms()"
+ "compute_error_norms()\n"
]
},
{
@@ -1631,7 +1632,7 @@
" y_ = xs[0] ** slope\n",
" ys = y0 / y_ * xs**slope\n",
" ax.plot(xs, ys, color=\"black\")\n",
- " ax.text(xs[-1] * 1.05, ys[-1], slope)"
+ " ax.text(xs[-1] * 1.05, ys[-1], slope)\n"
]
},
{
@@ -1739,7 +1740,7 @@
"for i in range(3):\n",
" ax[i].legend()\n",
" ax[i].set_xlabel(\"h / cm\")\n",
- " ax[i].loglog(base=10)"
+ " ax[i].loglog(base=10)\n"
]
},
{
diff --git a/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb b/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb
index bce8e212961..82e57b38535 100644
--- a/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb
+++ b/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb
@@ -5,11 +5,12 @@
"id": "96f29a77",
"metadata": {},
"source": [
+ "+++\n",
"title = \"SimpleMechanics\"\n",
"date = \"2021-09-10\"\n",
"author = \"Lars Bilke, Jörg Buchwald\"\n",
"web_subsection = \"small-deformations\"\n",
- ""
+ "+++\n"
]
},
{
@@ -31,7 +32,7 @@
"\n",
"out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"_out\")\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -172,7 +173,7 @@
"\n",
"from datetime import datetime\n",
"\n",
- "print(datetime.now())"
+ "print(datetime.now())\n"
]
},
{
@@ -255,7 +256,7 @@
")\n",
"plt.legend()\n",
"plt.xlabel(\"t\")\n",
- "plt.ylabel(\"u\")"
+ "plt.ylabel(\"u\")\n"
]
},
{
diff --git a/Tests/Data/Mechanics/PLLC/PLLC.ipynb b/Tests/Data/Mechanics/PLLC/PLLC.ipynb
index ee751646246..a503be3c990 100644
--- a/Tests/Data/Mechanics/PLLC/PLLC.ipynb
+++ b/Tests/Data/Mechanics/PLLC/PLLC.ipynb
@@ -5,11 +5,12 @@
"id": "bb0907b4-4e26-4c4e-ab1f-22b5330cb1d2",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Power Law Linear Creep\"\n",
"date = \"2023-01-02\"\n",
"author = \"Florian Zill\"\n",
"web_subsection = \"small-deformations\"\n",
- ""
+ "+++\n"
]
},
{
@@ -77,7 +78,7 @@
" \"DeVries 1988 100\": (100, \"s\", [[4.95, 9.6768E-05], [6.77, 0.000292896], [7.46, 0.000324], [8.55, 0.000664416], [8.92, 0.00091584], [8.98, 0.0009936], [9.91, 0.00124416], [10.1, 0.00139968], [10.22, 0.00093312], [10.27, 0.00132192], [12.1, 0.00216], [12.3, 0.00409536], [12.35, 0.00320544], [12.37, 0.00292032], [12.39, 0.00253152], [12.4, 0.0026784], [12.46, 0.0025056], [12.49, 0.00347328], [13.57, 0.00273024], [13.78, 0.00242784], [14.7, 0.00482112], [16.87, 0.0095904], [17.2, 0.0123552], [19.96, 0.030672]]),\n",
" \"DeVries 1988 200\": (200, \"s\", [[3.47, 0.00117504], [4.71, 0.0032832], [6.67, 0.0104544], [6.78, 0.0132192], [9.86, 0.214272]]),\n",
" \"Berest 2015 14.3\": (14.3, \"P\", [[0.09909639, 8.944207E-08], [0.19575886, 1.4118213E-07], [0.29452325, 1.4118213E-07], [0.49411031, 9.799173E-08]]),\n",
- " \"Berest 2017 7.8\": (7.8, \"P\", [[0.19575886,2.2285256E-07], [0.19575886,9.505469E-08], [0.19754389,2.5947583E-07], [0.19754389,2.647936E-08], [0.39379426,4.9162047E-07], [0.39738509,6.801413E-08], [0.59247161,4.0957628E-07], [0.59247161,5.7241269E-07], [0.59787408,1.0735864E-07], [1.0591736,1.11804208E-06]])}"
+ " \"Berest 2017 7.8\": (7.8, \"P\", [[0.19575886,2.2285256E-07], [0.19575886,9.505469E-08], [0.19754389,2.5947583E-07], [0.19754389,2.647936E-08], [0.39379426,4.9162047E-07], [0.39738509,6.801413E-08], [0.59247161,4.0957628E-07], [0.59247161,5.7241269E-07], [0.59787408,1.0735864E-07], [1.0591736,1.11804208E-06]])}\n"
]
},
{
@@ -106,7 +107,7 @@
"sref = 1. # MPa\n",
"BGRa = lambda sig, T: A1 * np.exp(-Q1/(8.3145*(273.15+T))) * np.power(sig/sref,5.)\n",
"PLLC = lambda sig, T: A1 * np.exp(-Q1/(8.3145*(273.15+T))) * np.power(sig/sref,5.) + \\\n",
- " A2 * np.exp(-Q2/(8.3145*(273.15+T))) * sig/sref / np.power(dGrain, 3) / (273.15+T)"
+ " A2 * np.exp(-Q2/(8.3145*(273.15+T))) * sig/sref / np.power(dGrain, 3) / (273.15+T)\n"
]
},
{
diff --git a/Tests/Data/Notebooks/SimplePETSc.ipynb b/Tests/Data/Notebooks/SimplePETSc.ipynb
index f3990b10e54..59993379282 100644
--- a/Tests/Data/Notebooks/SimplePETSc.ipynb
+++ b/Tests/Data/Notebooks/SimplePETSc.ipynb
@@ -5,11 +5,12 @@
"id": "bb0907b4-4e26-4c4e-ab1f-22b5330cb1d2",
"metadata": {},
"source": [
+ "+++\n",
"title = \"SimplePETSc\"\n",
"date = \"2021-11-09\"\n",
"author = \"Lars Bilke\"\n",
"web_subsection = \"elliptic\"\n",
- ""
+ "+++\n"
]
},
{
@@ -42,7 +43,7 @@
"! mpirun -np 2 ogs {prj_file} > out.txt\n",
"\n",
"from datetime import datetime\n",
- "print(datetime.now())"
+ "print(datetime.now())\n"
]
},
{
@@ -87,7 +88,7 @@
"plt.plot(time, pressure_linear[\"pt1\"], \"r-\", label=\"pt1 linear interpolated\")\n",
"plt.legend()\n",
"plt.xlabel(\"t\")\n",
- "plt.ylabel(\"p\")"
+ "plt.ylabel(\"p\")\n"
]
}
],
diff --git a/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb b/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb
index 43ce56d5cfa..ea37258df64 100644
--- a/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb
+++ b/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb
@@ -4,12 +4,13 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Jörg Buchwald\"\n",
"date = \"2022-05-27T12:39:58+01:00\"\n",
"title = \"Thermo-Osmosis in a one-dimensional column\"\n",
"weight = 70\n",
"web_subsection = \"thermo-hydro-mechanics\"\n",
- ""
+ "+++\n"
]
},
{
@@ -79,7 +80,7 @@
" if \"M\" in model:\n",
" resp[model][var] = f.get_set_data(f\"{var}_interpolated\",pointsetarray=r)\n",
" else:\n",
- " resp[model][var] = f.get_set_data(f\"{var}\",pointsetarray=r)"
+ " resp[model][var] = f.get_set_data(f\"{var}\",pointsetarray=r)\n"
]
},
{
@@ -103,7 +104,7 @@
"aTO = zhou_solution_thermo_osmosis.ANASOL(0,50,100)\n",
"aNoTO = zhou_solution_thermo_osmosis.ANASOL(0,50,100)\n",
"aNoTO.Sw = 0\n",
- "t=7.2e6"
+ "t=7.2e6\n"
]
},
{
@@ -145,7 +146,7 @@
"plt.xlim([0,20])\n",
"plt.ylabel(\"$T$ / K\")\n",
"plt.legend()\n",
- "plt.title(\"temperature\");"
+ "plt.title(\"temperature\");\n"
]
},
{
@@ -175,7 +176,7 @@
"plt.ylabel(\"$p$ / Pa\")\n",
"plt.xlim([0,20])\n",
"plt.legend()\n",
- "plt.title(\"pressure\");"
+ "plt.title(\"pressure\");\n"
]
},
{
@@ -210,7 +211,7 @@
"plt.xlim([0,20])\n",
"plt.ylabel(\"$\\Delta T$ / K\")\n",
"plt.legend()\n",
- "plt.title(\"temperature\");"
+ "plt.title(\"temperature\");\n"
]
},
{
@@ -238,7 +239,7 @@
"plt.ylabel(\"$\\Delta p$ / Pa\")\n",
"plt.xlim([0,20])\n",
"plt.legend()\n",
- "plt.title(\"pressure\");"
+ "plt.title(\"pressure\");\n"
]
},
{
diff --git a/Tests/Data/Parabolic/ComponentTransport/DiffusionSorptionDecay/DiffusionSorptionDecay.ipynb b/Tests/Data/Parabolic/ComponentTransport/DiffusionSorptionDecay/DiffusionSorptionDecay.ipynb
index 9b42ac7ae0a..6009d52b2ec 100644
--- a/Tests/Data/Parabolic/ComponentTransport/DiffusionSorptionDecay/DiffusionSorptionDecay.ipynb
+++ b/Tests/Data/Parabolic/ComponentTransport/DiffusionSorptionDecay/DiffusionSorptionDecay.ipynb
@@ -5,27 +5,12 @@
"id": "f4d3389f-6a41-4c88-aa25-971c9a277d60",
"metadata": {},
"source": [
+ "+++\n",
"title = \"(Advection-)diffusion-sorption-decay problem\"\n",
"date = \"2022-03-09\"\n",
"author = \"Renchao Lu, Jaime Garibay-Rodriguez, Lars Bilke, Christoph Lehmann, Haibing Shao\"\n",
"web_subsection = \"hydro-component\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "78389cc7",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import ogs6py\n",
- "import vtuIO\n",
- "import numpy as np\n",
- "from scipy import special\n",
- "import matplotlib.pyplot as plt\n",
- "from matplotlib.pyplot import cm"
+ "+++\n"
]
},
{
@@ -134,6 +119,22 @@
"Here the concentration profiles are illustrated at $t$ = 10$^3$, 10$^4$, 10$^5$, and 10$^6$ years."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "78389cc7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import ogs6py\n",
+ "import vtuIO\n",
+ "import numpy as np\n",
+ "from scipy import special\n",
+ "import matplotlib.pyplot as plt\n",
+ "from matplotlib.pyplot import cm\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 2,
@@ -178,7 +179,7 @@
"for t in time*3.1536e7: #unit conversion from year to second\n",
" c_t = c_inlet/2*(np.exp(-x*(alpha*R/Dp)**0.5)*special.erfc(x/2*(R/Dp/t)**0.5-(alpha*t)**0.5) \\\n",
" + np.exp(x*(alpha*R/Dp)**0.5)*special.erfc(x/2*(R/Dp/t)**0.5+(alpha*t)**0.5))\n",
- " c = np.vstack([c, c_t])"
+ " c = np.vstack([c, c_t])\n"
]
},
{
@@ -230,7 +231,7 @@
" ax.xaxis.grid(color='gray', linestyle='dashed')\n",
" ax.yaxis.grid(color='gray', linestyle='dashed')\n",
" \n",
- "plot_analytical_solutions() "
+ "plot_analytical_solutions() \n"
]
},
{
@@ -318,7 +319,7 @@
" ax.xaxis.grid(color='gray', linestyle='dashed')\n",
" ax.yaxis.grid(color='gray', linestyle='dashed')\n",
" \n",
- "plot_simulation_results() "
+ "plot_simulation_results() \n"
]
},
{
@@ -352,7 +353,7 @@
" c_sim = pvdfile.read_set_data(t*3.1536e7, 'Cs', data_type=\"point\", pointsetarray=[(i,0,0) for i in x])\n",
" \n",
" l2_norm_error_t = np.log10(np.sum((c_sim - c_ext)**2)**0.5)\n",
- " l2_norm_error = np.vstack([l2_norm_error, l2_norm_error_t])"
+ " l2_norm_error = np.vstack([l2_norm_error, l2_norm_error_t])\n"
]
},
{
@@ -375,7 +376,7 @@
" marker='o', zorder=10, clip_on=False)\n",
" \n",
" ax.xaxis.grid(color='gray', linestyle='dashed')\n",
- " ax.yaxis.grid(color='gray', linestyle='dashed')"
+ " ax.yaxis.grid(color='gray', linestyle='dashed')\n"
]
},
{
@@ -396,7 +397,7 @@
}
],
"source": [
- "plot_l2_norm_error()"
+ "plot_l2_norm_error()\n"
]
},
{
@@ -585,7 +586,7 @@
" c_t = c0*H(x, t) + M(x, t)\n",
" c = np.vstack([c, c_t])\n",
"\n",
- "plot_analytical_solutions()"
+ "plot_analytical_solutions()\n"
]
},
{
@@ -646,7 +647,7 @@
"pvdfile = vtuIO.PVDIO(f\"{out_dir}/{prj_name}.pvd\", dim=1)\n",
"\n",
"#Plot simulation results\n",
- "plot_simulation_results() "
+ "plot_simulation_results() \n"
]
},
{
diff --git a/Tests/Data/Parabolic/ComponentTransport/MultiLayerDiffusion/MultiLayerDiffusion.ipynb b/Tests/Data/Parabolic/ComponentTransport/MultiLayerDiffusion/MultiLayerDiffusion.ipynb
index 19f81af003a..3c7ff3f3cc8 100644
--- a/Tests/Data/Parabolic/ComponentTransport/MultiLayerDiffusion/MultiLayerDiffusion.ipynb
+++ b/Tests/Data/Parabolic/ComponentTransport/MultiLayerDiffusion/MultiLayerDiffusion.ipynb
@@ -5,29 +5,12 @@
"id": "e758cbb0",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Two-layer diffusion problem\"\n",
"date = \"2022-03-09\"\n",
"author = \"Renchao Lu, Dmitri Naumov, Lars Bilke, Christoph Lehmann, Haibing Shao\"\n",
"web_subsection = \"hydro-component\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "6a13a295",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import ogs6py\n",
- "import vtuIO\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "from scipy import special\n",
- "import matplotlib.pyplot as plt\n",
- "from matplotlib.pyplot import cm\n",
- "from IPython.display import Image"
+ "+++\n"
]
},
{
@@ -112,6 +95,24 @@
"\n"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "6a13a295",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import ogs6py\n",
+ "import vtuIO\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from scipy import special\n",
+ "import matplotlib.pyplot as plt\n",
+ "from matplotlib.pyplot import cm\n",
+ "from IPython.display import Image\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 2,
@@ -165,7 +166,7 @@
" ax.xaxis.grid(color='gray', linestyle='dashed')\n",
" ax.yaxis.grid(color='gray', linestyle='dashed')\n",
" \n",
- "plot_analytical_solutions()"
+ "plot_analytical_solutions()\n"
]
},
{
@@ -260,7 +261,7 @@
" ax.xaxis.grid(color='gray', linestyle='dashed')\n",
" ax.yaxis.grid(color='gray', linestyle='dashed')\n",
" \n",
- "plot_simulation_results() "
+ "plot_simulation_results() \n"
]
},
{
@@ -310,7 +311,7 @@
],
"source": [
"from IPython.display import display, Image\n",
- "display(Image(filename=f\"./sketch_molar_flux_calculation.jpg\", width=400))"
+ "display(Image(filename=f\"./sketch_molar_flux_calculation.jpg\", width=400))\n"
]
},
{
@@ -366,7 +367,7 @@
" ax.xaxis.grid(color='gray', linestyle='dashed')\n",
" ax.yaxis.grid(color='gray', linestyle='dashed')\n",
" \n",
- "plot_molar_flux() "
+ "plot_molar_flux() \n"
]
},
{
diff --git a/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/DecayChain.ipynb b/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/DecayChain.ipynb
index 5b1a621f315..3efb977da1e 100644
--- a/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/DecayChain.ipynb
+++ b/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/DecayChain.ipynb
@@ -5,34 +5,12 @@
"id": "f4d3389f-6a41-4c88-aa25-971c9a277d60",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Decay-chain problem\"\n",
"date = \"2022-08-05\"\n",
"author = \"Renchao Lu, Christoph Behrens, Dmitri Naumov, Haibing Shao\"\n",
"web_subsection = \"reactive-transport\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "78389cc7",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import time\n",
- "\n",
- "import ogs6py\n",
- "import vtuIO\n",
- "\n",
- "import numpy as np\n",
- "from scipy import special\n",
- "\n",
- "import h5py\n",
- "\n",
- "import matplotlib.pyplot as plt\n",
- "from matplotlib.pyplot import cm\n",
- "from IPython.display import display, Image"
+ "+++\n"
]
},
{
@@ -59,6 +37,29 @@
"This benchmark is meant to model the migration of radionuclides in the Curium-247 decay chain through a semi-infinite porous column. The diagram below maps the Curium-247 decay chain which contains 6 radionuclides before ending with Actinium-227."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "78389cc7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import time\n",
+ "\n",
+ "import ogs6py\n",
+ "import vtuIO\n",
+ "\n",
+ "import numpy as np\n",
+ "from scipy import special\n",
+ "\n",
+ "import h5py\n",
+ "\n",
+ "import matplotlib.pyplot as plt\n",
+ "from matplotlib.pyplot import cm\n",
+ "from IPython.display import display, Image\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 3,
@@ -81,7 +82,7 @@
}
],
"source": [
- "display(Image(filename=f\"chains.png\", width=600))"
+ "display(Image(filename=f\"chains.png\", width=600))\n"
]
},
{
@@ -299,7 +300,7 @@
"ax.legend(frameon=False, loc='upper right', numpoints=1, fontsize=12, ncol=1)\n",
" \n",
"ax.xaxis.grid(color='gray', linestyle='dashed')\n",
- "ax.yaxis.grid(color='gray', linestyle='dashed')"
+ "ax.yaxis.grid(color='gray', linestyle='dashed')\n"
]
},
{
@@ -440,7 +441,7 @@
"ax2.legend(bbox_to_anchor=(1.04,1), loc=\"upper left\", numpoints=1, fontsize=12, ncol=1)\n",
" \n",
"ax2.xaxis.grid(color='gray', linestyle='dashed')\n",
- "ax2.yaxis.grid(color='gray', linestyle='dashed')"
+ "ax2.yaxis.grid(color='gray', linestyle='dashed')\n"
]
},
{
@@ -590,7 +591,7 @@
"ax.legend(bbox_to_anchor=(1.04,1), loc=\"upper left\", numpoints=1, fontsize=12, ncol=1)\n",
" \n",
"ax.xaxis.grid(color='gray', linestyle='dashed')\n",
- "ax.yaxis.grid(color='gray', linestyle='dashed')"
+ "ax.yaxis.grid(color='gray', linestyle='dashed')\n"
]
},
{
@@ -676,7 +677,7 @@
"ax.bar(list(runtime.keys())[:2], list(runtime.values())[:2], width=0.5, zorder=3)\n",
"\n",
"for i in range(0, 2):\n",
- " ax.annotate(list(runtime.values())[i],(i,list(runtime.values())[i]+50), ha=\"center\")"
+ " ax.annotate(list(runtime.values())[i],(i,list(runtime.values())[i]+50), ha=\"center\")\n"
]
},
{
@@ -732,7 +733,7 @@
"ax.bar(list(runtime.keys())[1:], list(runtime.values())[1:], width=0.5, zorder=3)\n",
"\n",
"for i in range(1, 4):\n",
- " ax.annotate(list(runtime.values())[i],(i-1,list(runtime.values())[i]+2), ha=\"center\")"
+ " ax.annotate(list(runtime.values())[i],(i-1,list(runtime.values())[i]+2), ha=\"center\")\n"
]
},
{
diff --git a/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/GlobalImplicitApproach/performance_measurements.ipynb b/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/GlobalImplicitApproach/performance_measurements.ipynb
index 086214a7281..21f979062c4 100644
--- a/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/GlobalImplicitApproach/performance_measurements.ipynb
+++ b/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/DecayChain/GlobalImplicitApproach/performance_measurements.ipynb
@@ -1,10 +1,32 @@
{
"cells": [
+ {
+ "cell_type": "raw",
+ "id": "791cdfb3",
+ "metadata": {},
+ "source": [
+ "+++\n",
+ "title = \"Performance measurements for RTP\"\n",
+ "date = \"2023-08-18\"\n",
+ "author = \"Christoph Lehmann\"\n",
+ "+++\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "97389d70",
+ "metadata": {},
+ "source": [
+ "Not shown on the website. Added via [!4730](https://gitlab.opengeosys.org/ogs/ogs/-/merge_requests/4730)."
+ ]
+ },
{
"cell_type": "code",
"execution_count": 1,
"id": "dd267901-843a-4f53-b161-421cce229047",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"from ogs6py.log_parser.log_parser import parse_file\n",
@@ -29,7 +51,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -101,7 +124,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -136,7 +160,9 @@
"cell_type": "code",
"execution_count": 6,
"id": "e94565dc-eab8-4b04-93db-38872403c8f9",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [
{
"name": "stdout",
@@ -184,7 +210,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -350,7 +377,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -383,7 +411,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -431,7 +460,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -445,7 +475,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -487,7 +518,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -519,7 +551,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -569,7 +602,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -643,7 +677,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -662,7 +697,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -715,7 +751,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -729,7 +766,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -759,7 +797,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -807,7 +846,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -830,7 +870,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -881,7 +922,9 @@
"cell_type": "code",
"execution_count": 22,
"id": "13bf177b-1f11-45f7-bfa8-ca91beeee4b6",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"computes = []\n",
@@ -918,7 +961,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -938,7 +982,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [
{
@@ -976,7 +1021,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -999,7 +1045,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -1022,7 +1069,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
diff --git a/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/RadionuclidesMigration/RadionuclidesMigration.ipynb b/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/RadionuclidesMigration/RadionuclidesMigration.ipynb
index 157063e0ca1..2cb28d76af7 100644
--- a/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/RadionuclidesMigration/RadionuclidesMigration.ipynb
+++ b/Tests/Data/Parabolic/ComponentTransport/ReactiveTransport/RadionuclidesMigration/RadionuclidesMigration.ipynb
@@ -5,27 +5,12 @@
"id": "f4d3389f-6a41-4c88-aa25-971c9a277d60",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Radionuclides migration in Opalinus clay\"\n",
"date = \"2022-05-13\"\n",
"author = \"Jaime Garibay-Rodriguez, Chaofan Chen, Haibing Shao, Lars Bilke, Olaf Kolditz, Vanessa Montoya, Renchao Lu\"\n",
"web_subsection = \"reactive-transport\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "78389cc7",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import ogs6py\n",
- "import vtuIO\n",
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "from matplotlib.pyplot import cm\n",
- "import time"
+ "+++\n"
]
},
{
@@ -160,6 +145,22 @@
"The simulation takes approximately 23 hrs. to complete when t = 1e6 years. Therefore, only the first 50 time-steps are simulated in this notebook. To run the full simulation, the time loop parameters can be easily adapted."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "78389cc7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import ogs6py\n",
+ "import vtuIO\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "from matplotlib.pyplot import cm\n",
+ "import time\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 2,
@@ -188,7 +189,7 @@
"! ogs {prj_name} -o {out_dir} > {out_dir}/outCs.txt\n",
"\n",
"tf = time.time()\n",
- "print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ "print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -243,7 +244,7 @@
"ax.set_xlabel(\"x [m]\")\n",
"ax.set_yscale('log')\n",
"ax.legend()\n",
- "plt.tight_layout()"
+ "plt.tight_layout()\n"
]
},
{
@@ -310,7 +311,7 @@
"! ogs {prj_name} -o {out_dir} > {out_dir}/outU.txt\n",
"\n",
"tf = time.time()\n",
- "print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ "print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -365,7 +366,7 @@
"ax.set_xlabel(\"x [m]\")\n",
"ax.set_yscale('log')\n",
"ax.legend()\n",
- "plt.tight_layout()"
+ "plt.tight_layout()\n"
]
},
{
diff --git a/Tests/Data/Parabolic/LiquidFlow/AxiSymTheis/axisym_theis.ipynb b/Tests/Data/Parabolic/LiquidFlow/AxiSymTheis/axisym_theis.ipynb
index 299d6d6fed5..162e72fd356 100644
--- a/Tests/Data/Parabolic/LiquidFlow/AxiSymTheis/axisym_theis.ipynb
+++ b/Tests/Data/Parabolic/LiquidFlow/AxiSymTheis/axisym_theis.ipynb
@@ -5,11 +5,22 @@
"id": "ac287b2f",
"metadata": {},
"source": [
+ "+++\n",
"title = \"H process: Theis solution (Pumping well)\"\n",
"date = \"2022-08-24\"\n",
"author = \"Wenqing Wang, Olaf Kolditz\"\n",
"web_subsection = \"liquid-flow\"\n",
- ""
+ "+++\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7d9d7741",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ ""
]
},
{
@@ -29,7 +40,7 @@
"import vtk\n",
"from vtk.util.numpy_support import vtk_to_numpy\n",
"import matplotlib.tri as tri\n",
- "import time"
+ "import time\n"
]
},
{
@@ -49,65 +60,7 @@
"title = \"H process: Theis solution (Pumping well)\"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "688250b6",
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "execution_count": 3,
- "metadata": {
- "image/png": {
- "height": 100,
- "width": 150
- }
- },
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Image(filename = fig_dir + \"ogs-jupyter-lab.png\", width=150, height=100)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "d2ff19ce",
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "execution_count": 4,
- "metadata": {
- "image/png": {
- "height": 100,
- "width": 150
- }
- },
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Image(filename = fig_dir + \"h-tet-1.png\", width=150, height=100)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -253,7 +206,7 @@
"plt.ylabel(r'$s\\;/\\;\\mathrm{m}$')\n",
"plt.legend()\n",
"plt.grid()\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -298,7 +251,7 @@
"plt.ylabel(r'$hydraulic head\\;/\\;\\mathrm{m}$')\n",
"plt.legend()\n",
"plt.grid()\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -364,7 +317,7 @@
"source": [
"mesh = pv.read(vtu_name)\n",
"print(\"inspecting vtu-file\")\n",
- "mesh"
+ "mesh\n"
]
},
{
@@ -416,7 +369,7 @@
"triang = tri.Triangulation(x[:,0], x[:,1])\n",
"#plt.triplot(triang, 'go-', lw=1.0)\n",
"plt.triplot(triang,lw=0.2)\n",
- "plt.tricontour(triang, pressure, 16)"
+ "plt.tricontour(triang, pressure, 16)\n"
]
},
{
@@ -450,7 +403,7 @@
"print(f\"ogs {prj_file} > log.txt\")\n",
"! ogs {prj_file} -o {out_dir} > {out_dir}/log.txt\n",
"tf = time.time()\n",
- "print(\"computation time: \", round(tf - t0, 2), \" s.\")"
+ "print(\"computation time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -515,7 +468,7 @@
"plt.legend()\n",
"plt.grid()\n",
"#plt.savefig(\"theis.png\")\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -569,7 +522,7 @@
"ax[1].text(5,0.7,caption,ha='left')\n",
"\n",
"##plt.savefig(\"theis-ana+num.png\")\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -588,7 +541,7 @@
],
"source": [
"import time\n",
- "print(time.ctime())"
+ "print(time.ctime())\n"
]
},
{
diff --git a/Tests/Data/Parabolic/LiquidFlow/BlockingConductingFracture/BlockingConductingFracture.ipynb b/Tests/Data/Parabolic/LiquidFlow/BlockingConductingFracture/BlockingConductingFracture.ipynb
index 0892905fe13..83e0b556e1c 100644
--- a/Tests/Data/Parabolic/LiquidFlow/BlockingConductingFracture/BlockingConductingFracture.ipynb
+++ b/Tests/Data/Parabolic/LiquidFlow/BlockingConductingFracture/BlockingConductingFracture.ipynb
@@ -5,11 +5,12 @@
"id": "c65efb9d",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Liquid flow in blocking and conducting fractures\"\n",
"date = \"2023-08-05\"\n",
"author = \"Mehran Ghasbeh\"\n",
"web_subsection = \"liquid-flow\"\n",
- ""
+ "+++\n"
]
},
{
@@ -71,7 +72,7 @@
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"import matplotlib.tri as tri\n",
- "import plot_settings"
+ "import plot_settings\n"
]
},
{
@@ -90,7 +91,7 @@
"\n",
"model_lf = OGS(\n",
" INPUT_FILE=\"block_conduct_frac.prj\", PROJECT_FILE=\"block_conduct_frac.prj\"\n",
- ")"
+ ")\n"
]
},
{
@@ -112,7 +113,7 @@
"# Run the analysis\n",
"model_lf.run_model(\n",
" logfile=os.path.join(out_dir, \"block_conduct_frac.txt\"), args=f\"-o {out_dir}\"\n",
- ")"
+ ")\n"
]
},
{
@@ -132,7 +133,7 @@
],
"source": [
"# Access VTU/PVD files, outputted by OpenGeoSys FEM Solver.\n",
- "vtufile = vtuIO.VTUIO(\"fracture_block_conduct_ts_1_t_1.000000.vtu\", dim=2)"
+ "vtufile = vtuIO.VTUIO(\"fracture_block_conduct_ts_1_t_1.000000.vtu\", dim=2)\n"
]
},
{
@@ -153,7 +154,7 @@
"source": [
"# Get the nodal coordinates from vtufilhe porous media include e\n",
"x = vtufile.points[:, 0]\n",
- "y = vtufile.points[:, 1]"
+ "y = vtufile.points[:, 1]\n"
]
},
{
@@ -164,7 +165,7 @@
"outputs": [],
"source": [
"# Triangulation# Post-Processing (Pressure Field in Conducting and Blocking Fracture)\n",
- "triang = tri.Triangulation(x, y)"
+ "triang = tri.Triangulation(x, y)\n"
]
},
{
@@ -177,7 +178,7 @@
"# Get the pressure field from vtufile\n",
"field = vtufile.get_point_field(\"pressure\")\n",
"# Convert the pressure field from Pa to kPa\n",
- "field = field / 1000.0"
+ "field = field / 1000.0\n"
]
},
{
@@ -191,7 +192,7 @@
"fieldx = vtufile.get_point_field(\"v\").T[0]\n",
"fieldy = vtufile.get_point_field(\"v\").T[1]\n",
"fieldx = vtufile.get_point_field(\"v\").T[0]\n",
- "fieldy = vtufile.get_point_field(\"v\").T[1]"
+ "fieldy = vtufile.get_point_field(\"v\").T[1]\n"
]
},
{
@@ -235,7 +236,7 @@
" ax[i].set_aspect(\"equal\")\n",
" ax[i].set_ylabel(\"$y$ / m\")\n",
" ax[i].set_xlabel(\"$x$ / m\")\n",
- "fig.tight_layout()"
+ "fig.tight_layout()\n"
]
},
{
@@ -275,7 +276,7 @@
" ax[i].set_aspect(\"equal\")\n",
" ax[i].set_ylabel(\"$y$ / m\")\n",
" ax[i].set_xlabel(\"$x$ / m\")\n",
- "fig.tight_layout()"
+ "fig.tight_layout()\n"
]
},
{
@@ -286,7 +287,7 @@
"outputs": [],
"source": [
"# Calculate the magnitude of the velocity vector fieldlevels = np.linspace(np.min(field), np.max(field), 58)\n",
- "vmag = np.sqrt(fieldx**2.0 + fieldy**2.0)"
+ "vmag = np.sqrt(fieldx**2.0 + fieldy**2.0)\n"
]
},
{
@@ -339,7 +340,7 @@
" ax[i].set_aspect(\"equal\")\n",
" ax[i].set_ylabel(\"$y$ / m\")\n",
" ax[i].set_xlabel(\"$x$ / m\")\n",
- " fig.tight_layout()"
+ " fig.tight_layout()\n"
]
},
{
@@ -360,7 +361,7 @@
"source": [
"pvd_frac = vtuIO.PVDIO(\"fracture_block_conduct.pvd\", dim=2)\n",
"line_05 = [(0.5, i, 0) for i in np.linspace(start=0.0, stop=1.0, num=500)]\n",
- "lines = {\"@ x=0.5\": line_05}"
+ "lines = {\"@ x=0.5\": line_05}\n"
]
},
{
@@ -417,7 +418,7 @@
" ax[1].legend()\n",
" ax[1].set_xlabel(\"$y$ / m\")\n",
" ax[1].set_ylabel(\"$|v|$ / m/s\")\n",
- " fig.tight_layout()"
+ " fig.tight_layout()\n"
]
},
{
diff --git a/Tests/Data/Parabolic/ThermalTwoPhaseFlowPP/HeatPipe/heatpipe.ipynb b/Tests/Data/Parabolic/ThermalTwoPhaseFlowPP/HeatPipe/heatpipe.ipynb
index 340ae3aad10..3b5de6bf68a 100644
--- a/Tests/Data/Parabolic/ThermalTwoPhaseFlowPP/HeatPipe/heatpipe.ipynb
+++ b/Tests/Data/Parabolic/ThermalTwoPhaseFlowPP/HeatPipe/heatpipe.ipynb
@@ -4,29 +4,12 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Boyan Meng and Yonghui Huang\"\n",
"date = \"2022-07-01\"\n",
"title = \"Heat pipe problem\"\n",
"web_subsection = \"thermal-two-phase-flow\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import vtuIO\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "from mpl_toolkits.axes_grid1.inset_locator import (inset_axes, InsetPosition, mark_inset)\n",
- "from IPython.display import display, Image\n",
- "\n",
- "plt.rcParams['legend.fontsize']=20\n",
- "plt.rcParams['font.size'] = 20"
+ "+++\n"
]
},
{
@@ -72,7 +55,8 @@
}
],
"source": [
- "display(Image(filename=f\"./model_domain.jpg\", width=1000))"
+ "from IPython.display import display, Image\n",
+ "display(Image(filename=f\"./model_domain.jpg\", width=1000))\n"
]
},
{
@@ -125,6 +109,24 @@
"In the CTEST-small, the comparison is made for the time of 10000 seconds. The profiles of saturation and temperature are plotted below."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "e483f1b7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import vtuIO\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "from mpl_toolkits.axes_grid1.inset_locator import (inset_axes, InsetPosition, mark_inset)\n",
+ "\n",
+ "plt.rcParams['legend.fontsize']=20\n",
+ "plt.rcParams['font.size'] = 20\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 3,
@@ -161,7 +163,7 @@
"ax[1].set_ylabel('$T$ / K') \n",
"ax[0].set_title('saturation') \n",
"ax[1].set_title('temperature')\n",
- "fig.tight_layout()"
+ "fig.tight_layout()\n"
]
},
{
@@ -206,7 +208,7 @@
"ax[0].set_ylim([0,1])\n",
"ax[0].set_title('saturation') \n",
"ax[1].set_title('temperature')\n",
- "fig.tight_layout()"
+ "fig.tight_layout()\n"
]
},
{
@@ -234,7 +236,7 @@
"resp = {}\n",
"resp[0] = f.get_set_data(\"saturation\",pointsetarray=r)\n",
"resp[1] = f.get_set_data(\"temperature\",pointsetarray=r)\n",
- "resp[2] = f.get_set_data(\"gas_pressure\",pointsetarray=r) "
+ "resp[2] = f.get_set_data(\"gas_pressure\",pointsetarray=r) \n"
]
},
{
@@ -300,7 +302,7 @@
"ax2.plot(x, soln['saturation'], lw=1.5, label=\"semianalytical\")\n",
"ax2.set_xlim(1.57,1.63)\n",
"ax2.set_ylim(0,0.1)\n",
- "ax2.set_yticks(np.arange(0,0.15,0.05))"
+ "ax2.set_yticks(np.arange(0,0.15,0.05))\n"
]
},
{
@@ -337,7 +339,7 @@
"ax[1].set_title('Absolute error')\n",
"ax[2].set_title('Relative error')\n",
"ax[0].legend()\n",
- "fig.tight_layout()"
+ "fig.tight_layout()\n"
]
},
{
@@ -374,7 +376,7 @@
"ax[1].set_title('Absolute error')\n",
"ax[2].set_title('Relative error')\n",
"ax[0].legend()\n",
- "fig.tight_layout()"
+ "fig.tight_layout()\n"
]
},
{
diff --git a/Tests/Data/Parabolic/TwoPhaseFlowPrho/MoMaS/MoMaS.ipynb b/Tests/Data/Parabolic/TwoPhaseFlowPrho/MoMaS/MoMaS.ipynb
index 199a836e17c..99cea696633 100644
--- a/Tests/Data/Parabolic/TwoPhaseFlowPrho/MoMaS/MoMaS.ipynb
+++ b/Tests/Data/Parabolic/TwoPhaseFlowPrho/MoMaS/MoMaS.ipynb
@@ -4,11 +4,12 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"title = \"MoMaS Benchmark\"\n",
"date = \"2022-10-24\"\n",
"author = \"Yonghui Huang, Falko Vehling\"\n",
"web_subsection = \"two-phase-flow\"\n",
- ""
+ "+++\n"
]
},
{
diff --git a/Tests/Data/PhaseField/Kregime_Propagating_jupyter_notebook/Kregime_Propagating_jupyter.ipynb b/Tests/Data/PhaseField/Kregime_Propagating_jupyter_notebook/Kregime_Propagating_jupyter.ipynb
index 909ce675ccd..dd8f3cfb8ad 100644
--- a/Tests/Data/PhaseField/Kregime_Propagating_jupyter_notebook/Kregime_Propagating_jupyter.ipynb
+++ b/Tests/Data/PhaseField/Kregime_Propagating_jupyter_notebook/Kregime_Propagating_jupyter.ipynb
@@ -4,33 +4,12 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Mostafa Mollaali, Keita Yoshioka\"\n",
"date = \"2023-03-03\"\n",
"title = \"Hydraulic Fracturing in the Toughness-Dominated Regime\"\n",
"web_subsection = \"phase-field\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "from ogs6py import ogs\n",
- "import numpy as np\n",
- "import ogs6py\n",
- "import matplotlib.pyplot as plt\n",
- "import time\n",
- "import math\n",
- "import gmsh\n",
- "import os\n",
- "from ogstools.msh2vtu import run \n",
- "import argparse\n",
- "import re\n",
- "\n",
- "pi = math.pi\n",
- "plt.rcParams[\"text.usetex\"] = True"
+ "+++\n"
]
},
{
@@ -146,6 +125,28 @@
"| _Initial crack length_ | 0.1 | $2a_0$ |"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ogs6py import ogs\n",
+ "import numpy as np\n",
+ "import ogs6py\n",
+ "import matplotlib.pyplot as plt\n",
+ "import time\n",
+ "import math\n",
+ "import gmsh\n",
+ "import os\n",
+ "from ogstools.msh2vtu import run \n",
+ "import argparse\n",
+ "import re\n",
+ "\n",
+ "pi = math.pi\n",
+ "plt.rcParams[\"text.usetex\"] = True\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 2,
@@ -158,7 +159,7 @@
"h = 0.01\n",
"a0 = 0.05 # half of the initial crack length\n",
"\n",
- "phasefield_model = \"AT1\" # AT1/AT2"
+ "phasefield_model = \"AT1\" # AT1/AT2\n"
]
},
{
@@ -179,7 +180,7 @@
"meshname = \"mesh_full_pf\"\n",
"\n",
"out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"_out\")\n",
- "os.makedirs(out_dir, exist_ok=True)"
+ "os.makedirs(out_dir, exist_ok=True)\n"
]
},
{
@@ -284,7 +285,7 @@
" output_file = f\"{out_dir}/\" + meshname + \".msh\"\n",
" gmsh.model.mesh.generate(dim2)\n",
" gmsh.write(output_file)\n",
- " gmsh.finalize()"
+ " gmsh.finalize()\n"
]
},
{
@@ -315,7 +316,7 @@
" phase_field[node_id] = 0.0\n",
"\n",
" mesh.point_data[\"phase-field\"] = phase_field\n",
- " mesh.save(f\"{out_dir}/mesh_full_pf_OGS_pf_ic.vtu\")"
+ " mesh.save(f\"{out_dir}/mesh_full_pf_OGS_pf_ic.vtu\")\n"
]
},
{
@@ -370,7 +371,7 @@
" print(\">>> OGS started execution ... <<<\")\n",
" ! ogs {out_dir}/{prj_name} -o {out_dir} > {out_dir}/log.txt\n",
" tf = time.time()\n",
- " print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ " print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -443,7 +444,7 @@
}
],
"source": [
- "Hydraulic_Fracturing_Toughness_Dominated_numerical(h, phasefield_model)"
+ "Hydraulic_Fracturing_Toughness_Dominated_numerical(h, phasefield_model)\n"
]
},
{
@@ -501,7 +502,7 @@
"pressure_analytical = Analytical_solution(phasefield_model, h)[1]\n",
"length_analytical = Analytical_solution(phasefield_model, h)[2]\n",
"Gc_ref = Analytical_solution(phasefield_model, h)[3]\n",
- "P_c = Analytical_solution(phasefield_model, h)[4]"
+ "P_c = Analytical_solution(phasefield_model, h)[4]\n"
]
},
{
@@ -606,7 +607,7 @@
")\n",
"plt.grid(linestyle=\"dashed\")\n",
"legend = plt.legend(loc=\"upper right\")\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -651,7 +652,7 @@
" r\"$\\frac{|p_\\mathrm{num}-{p}_\\mathrm{ana}|}{{p}_\\mathrm{num}}\\times 100\\%$\",\n",
" fontsize=14,\n",
")\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -702,7 +703,7 @@
"import pyvista as pv\n",
"\n",
"pv.set_plot_theme(\"document\")\n",
- "pv.set_jupyter_backend(\"static\")"
+ "pv.set_jupyter_backend(\"static\")\n"
]
},
{
@@ -750,7 +751,7 @@
" plotter.view_xy()\n",
" plotter.write_frame()\n",
"\n",
- "plotter.close()"
+ "plotter.close()\n"
]
},
{
@@ -810,7 +811,7 @@
"plotter.view_xy()\n",
"plotter.camera.zoom(1.5)\n",
"plotter.window_size = [1000, 500]\n",
- "plotter.show()"
+ "plotter.show()\n"
]
},
{
diff --git a/Tests/Data/PhaseField/PForthotropy_jupyter_notebook/sen_shear.ipynb b/Tests/Data/PhaseField/PForthotropy_jupyter_notebook/sen_shear.ipynb
index 27365c10e36..81ea7ba8d32 100644
--- a/Tests/Data/PhaseField/PForthotropy_jupyter_notebook/sen_shear.ipynb
+++ b/Tests/Data/PhaseField/PForthotropy_jupyter_notebook/sen_shear.ipynb
@@ -5,30 +5,12 @@
"id": "90c995c2",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Vahid Ziaei-Rad, Mostafa Mollaali\"\n",
"date = \"2022-12-15\"\n",
"title = \"Pre-notched shear test\"\n",
"web_subsection = \"phase-field\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "41d0a5bc",
- "metadata": {},
- "outputs": [],
- "source": [
- "from ogs6py import ogs\n",
- "import os\n",
- "import shutil\n",
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "import pyvista as pv\n",
- "import time\n",
- "import pandas as pd\n",
- "from xml.dom import minidom\n",
- "from types import MethodType"
+ "+++\n"
]
},
{
@@ -59,6 +41,25 @@
"## Two helper functions"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "41d0a5bc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ogs6py import ogs\n",
+ "import os\n",
+ "import shutil\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import pyvista as pv\n",
+ "import time\n",
+ "import pandas as pd\n",
+ "from xml.dom import minidom\n",
+ "from types import MethodType\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -85,7 +86,7 @@
"def set_timestepping(model,repeat_list, delta_t_list):\n",
" model.remove_element(xpath='./time_loop/processes/process/time_stepping/timesteps/pair')\n",
" for i in range(len(repeat_list)):\n",
- " model.add_block(blocktag = 'pair',parent_xpath='./time_loop/processes/process/time_stepping/timesteps', taglist = ['repeat', 'delta_t'], textlist = [repeat_list[i], delta_t_list[i]])"
+ " model.add_block(blocktag = 'pair',parent_xpath='./time_loop/processes/process/time_stepping/timesteps', taglist = ['repeat', 'delta_t'], textlist = [repeat_list[i], delta_t_list[i]])\n"
]
},
{
@@ -165,7 +166,7 @@
" print(\" > OGS started execution - \")\n",
" ! ogs {out_dir}/{prj_name} -o {output_dir} >> {logfile}\n",
" tf = time.time()\n",
- " print(\" > OGS terminated execution. Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ " print(\" > OGS terminated execution. Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -223,7 +224,7 @@
"# With the AT2 model, we are verifying two different anisotropic models, namely, orthotropic volumetric-deviatoric and orthotropic no-tension:\n",
"# For more details of each model, please see the reference of Ziaei Rad et al., 2022.\n",
"for b in [\"OrthoMasonry\", \"OrthoVolDev\"]:\n",
- " ogs_ortho(\"AT2\", b, length_scale = ls, bc_displacement = disp, repeat_list=['1'], delta_t_list=['1.e-2'], ncores = mpi_cores)"
+ " ogs_ortho(\"AT2\", b, length_scale = ls, bc_displacement = disp, repeat_list=['1'], delta_t_list=['1.e-2'], ncores = mpi_cores)\n"
]
},
{
@@ -281,7 +282,7 @@
" plotter.view_xy()\n",
" plotter.write_frame()\n",
"\n",
- "plotter.close()"
+ "plotter.close()\n"
]
},
{
@@ -319,7 +320,7 @@
"p.view_xy()\n",
"p.camera.zoom(1.)\n",
"p.window_size = [800,400]\n",
- "p.show()"
+ "p.show()\n"
]
},
{
@@ -390,7 +391,7 @@
"ax.set_ylabel('$F_y [N]$',fontsize =18)\n",
"plt.legend(fontsize =18, ncol = 2)\n",
"ax.axhline(y = 0, color = 'black',linewidth=1) \n",
- "ax.axvline(x = 0, color = 'black',linewidth=1)"
+ "ax.axvline(x = 0, color = 'black',linewidth=1)\n"
]
},
{
diff --git a/Tests/Data/PhaseField/beam_jupyter_notebook/beam.ipynb b/Tests/Data/PhaseField/beam_jupyter_notebook/beam.ipynb
index 5635174b7bb..a6eaa167e28 100644
--- a/Tests/Data/PhaseField/beam_jupyter_notebook/beam.ipynb
+++ b/Tests/Data/PhaseField/beam_jupyter_notebook/beam.ipynb
@@ -5,29 +5,12 @@
"id": "90c995c2",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Matthes Kantzenbach, Keita Yoshioka, Mostafa Mollaali\"\n",
"date = \"2022-11-28\"\n",
"title = \"Beam\"\n",
"web_subsection = \"phase-field\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "41d0a5bc",
- "metadata": {},
- "outputs": [],
- "source": [
- "from ogs6py import ogs\n",
- "import os\n",
- "import ogs6py\n",
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "import pyvista as pv\n",
- "import time\n",
- "from xml.dom import minidom\n",
- "from types import MethodType"
+ "+++\n"
]
},
{
@@ -62,6 +45,24 @@
"## Define some helper functions"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "41d0a5bc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ogs6py import ogs\n",
+ "import os\n",
+ "import ogs6py\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import pyvista as pv\n",
+ "import time\n",
+ "from xml.dom import minidom\n",
+ "from types import MethodType\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -88,7 +89,7 @@
"def set_timestepping(model,repeat_list, delta_t_list):\n",
" model.remove_element(xpath='./time_loop/processes/process/time_stepping/timesteps/pair')\n",
" for i in range(len(repeat_list)):\n",
- " model.add_block(blocktag = 'pair',parent_xpath='./time_loop/processes/process/time_stepping/timesteps', taglist = ['repeat', 'delta_t'], textlist = [repeat_list[i], delta_t_list[i]])"
+ " model.add_block(blocktag = 'pair',parent_xpath='./time_loop/processes/process/time_stepping/timesteps', taglist = ['repeat', 'delta_t'], textlist = [repeat_list[i], delta_t_list[i]])\n"
]
},
{
@@ -164,7 +165,7 @@
" print(\" > OGS started execution ...\")\n",
" ! mpirun -n 3 ogs {out_dir}/{prj_name} -o {output_dir} >> {logfile}\n",
" tf = time.time()\n",
- " print(\" > OGS terminated execution. Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ " print(\" > OGS terminated execution. Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
diff --git a/Tests/Data/PhaseField/kregime_jupyter_notebook/Kregime_Static_jupyter.ipynb b/Tests/Data/PhaseField/kregime_jupyter_notebook/Kregime_Static_jupyter.ipynb
index 08302a697c9..0b364fb9812 100644
--- a/Tests/Data/PhaseField/kregime_jupyter_notebook/Kregime_Static_jupyter.ipynb
+++ b/Tests/Data/PhaseField/kregime_jupyter_notebook/Kregime_Static_jupyter.ipynb
@@ -4,30 +4,12 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Mostafa Mollaali, Keita Yoshioka\"\n",
"date = \"2022-12-06\"\n",
"title = \"Static fracture opening under a constant pressure – Sneddon solution\"\n",
"web_subsection = \"phase-field\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [],
- "source": [
- "from ogs6py import ogs\n",
- "import numpy as np\n",
- "import ogs6py\n",
- "import matplotlib.pyplot as plt\n",
- "import time\n",
- "import math\n",
- "import gmsh\n",
- "import os\n",
- "\n",
- "pi = math.pi\n",
- "plt.rcParams[\"text.usetex\"] = True"
+ "+++\n"
]
},
{
@@ -92,6 +74,25 @@
"| _Initial crack length_ | 0.2 | $2a_0$ |"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ogs6py import ogs\n",
+ "import numpy as np\n",
+ "import ogs6py\n",
+ "import matplotlib.pyplot as plt\n",
+ "import time\n",
+ "import math\n",
+ "import gmsh\n",
+ "import os\n",
+ "\n",
+ "pi = math.pi\n",
+ "plt.rcParams[\"text.usetex\"] = True\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 10,
@@ -111,7 +112,7 @@
" 2 * (round(3.0 * a0 / h)) + 1\n",
") # number of slices for calcute width of fracture\n",
"\n",
- "phasefield_model = \"AT1\""
+ "phasefield_model = \"AT1\"\n"
]
},
{
@@ -121,7 +122,7 @@
"outputs": [],
"source": [
"h_list = [0.01] # list of mesh sizes (h)\n",
- "# h_list =[0.01, 0.005, 0.0025] # list of mesh sizes (h), for mesh sensitivity"
+ "# h_list =[0.01, 0.005, 0.0025] # list of mesh sizes (h), for mesh sensitivity\n"
]
},
{
@@ -142,7 +143,7 @@
"meshname = \"mesh_full_pf\"\n",
"\n",
"out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"_out\")\n",
- "os.makedirs(out_dir, exist_ok=True)"
+ "os.makedirs(out_dir, exist_ok=True)\n"
]
},
{
@@ -240,7 +241,7 @@
" output_file = f\"{out_dir}/\" + meshname + \".msh\"\n",
" gmsh.model.mesh.generate(dim2)\n",
" gmsh.write(output_file)\n",
- " gmsh.finalize()"
+ " gmsh.finalize()\n"
]
},
{
@@ -271,7 +272,7 @@
" phase_field[node_id] = 0.0\n",
"\n",
" mesh.point_data[\"phase-field\"] = phase_field\n",
- " mesh.save(f\"{out_dir}/mesh_full_pf_OGS_pf_ic.vtu\")"
+ " mesh.save(f\"{out_dir}/mesh_full_pf_OGS_pf_ic.vtu\")\n"
]
},
{
@@ -315,7 +316,7 @@
" print(\">>> OGS started execution ... <<<\")\n",
" !ogs {out_dir}/{prj_name} -o {out_dir} > {out_dir}/log.txt\n",
" tf = time.time()\n",
- " print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ " print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -341,7 +342,7 @@
],
"source": [
"for h_j in h_list:\n",
- " sneddon_numerical(h=h_j)"
+ " sneddon_numerical(h=h_j)\n"
]
},
{
@@ -426,7 +427,7 @@
" (point[0] - point_a[0]) ** 2 + (point[1] - point_a[1]) ** 2\n",
" ) ** 0.5 - dist_a_b / 2\n",
"\n",
- " return r_i, width_line"
+ " return r_i, width_line\n"
]
},
{
@@ -456,7 +457,7 @@
" 2 * a_eff * (1 - nu**2) * P / E * math.sqrt(1.0 - ((x[i]) / (a_eff)) ** 2)\n",
" )\n",
"\n",
- " return x, uy, a_eff"
+ " return x, uy, a_eff\n"
]
},
{
@@ -534,7 +535,7 @@
"plt.title(\"%s\" % phasefield_model)\n",
"\n",
"legend = plt.legend(bbox_to_anchor=(1.04, 1), loc=\"upper left\")\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
diff --git a/Tests/Data/PhaseField/surfing_jupyter_notebook/surfing_pyvista.ipynb b/Tests/Data/PhaseField/surfing_jupyter_notebook/surfing_pyvista.ipynb
index c07dad1c05e..e1da2db3749 100644
--- a/Tests/Data/PhaseField/surfing_jupyter_notebook/surfing_pyvista.ipynb
+++ b/Tests/Data/PhaseField/surfing_jupyter_notebook/surfing_pyvista.ipynb
@@ -4,11 +4,12 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Mostafa Mollaali, Keita Yoshioka\"\n",
"date = \"2022-06-28\"\n",
"title = \"Surfing boundary\"\n",
"web_subsection = \"phase-field\"\n",
- ""
+ "+++\n"
]
},
{
@@ -161,7 +162,7 @@
"G_i = 2.7\n",
"ls = 2*h\n",
"# We set ls=2h in our simulation\n",
- "phasefield_model='AT1'# AT1 and AT2 "
+ "phasefield_model='AT1'# AT1 and AT2 \n"
]
},
{
@@ -184,7 +185,7 @@
"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -213,7 +214,7 @@
"source": [
"# https://www.opengeosys.org/docs/tools/meshing/structured-mesh-generation/\n",
"! generateStructuredMesh -o {out_dir}/surfing_quad_1x2.vtu -e quad --lx 2 --nx {round(2/h)+1} --ly 1 --ny {round(1/h)+1}\n",
- "! NodeReordering -i {out_dir}/surfing_quad_1x2.vtu -o {out_dir}/surfing_quad_1x2_NR.vtu"
+ "! NodeReordering -i {out_dir}/surfing_quad_1x2.vtu -o {out_dir}/surfing_quad_1x2_NR.vtu\n"
]
},
{
@@ -272,7 +273,7 @@
"p.view_xy()\n",
"p.camera.zoom(1.5)\n",
"p.window_size = [800,400]\n",
- "p.show()"
+ "p.show()\n"
]
},
{
@@ -313,7 +314,7 @@
"! ogs {out_dir}/{prj_name} -o {out_dir} > {out_dir}/log.txt\n",
"\n",
"tf = time.time()\n",
- "print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ "print(\">>> OGS terminated execution <<< Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -355,7 +356,7 @@
"if phasefield_model=='AT1':\n",
" G_eff=G_i*(1+3*h/(8*ls))\n",
"elif phasefield_model=='AT2':\n",
- " G_eff= G_i*(1+h/(2*ls))"
+ " G_eff= G_i*(1+h/(2*ls))\n"
]
},
{
@@ -529,7 +530,7 @@
" G_theta += mean_value*area\n",
" G_theta_time[t][1]= G_theta\n",
" G_theta_time[t][0]= time_value\n",
- "mesh.save(f\"{out_dir}/surfing_Post_Processing.vtu\")"
+ "mesh.save(f\"{out_dir}/surfing_Post_Processing.vtu\")\n"
]
},
{
@@ -584,7 +585,7 @@
"plt.xlim(-0.05,0.8)\n",
"# plt.ylim(0,4)\n",
"legend = plt.legend(loc='upper right')\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -656,7 +657,7 @@
" plotter.view_xy()\n",
" plotter.write_frame()\n",
"\n",
- "plotter.close()"
+ "plotter.close()\n"
]
},
{
@@ -707,7 +708,7 @@
"p.view_xy()\n",
"p.camera.zoom(1.5)\n",
"p.window_size = [800,400]\n",
- "p.show()"
+ "p.show()\n"
]
},
{
diff --git a/Tests/Data/PhaseField/tpb_jupyter_notebook/TPB.ipynb b/Tests/Data/PhaseField/tpb_jupyter_notebook/TPB.ipynb
index 5f0f880eb8f..d68470ca65a 100644
--- a/Tests/Data/PhaseField/tpb_jupyter_notebook/TPB.ipynb
+++ b/Tests/Data/PhaseField/tpb_jupyter_notebook/TPB.ipynb
@@ -5,30 +5,12 @@
"id": "90c995c2",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Tao You, Keita Yoshioka, Mostafa Mollaali\"\n",
"date = \"2022-11-28\"\n",
"title = \"Three point bending test\"\n",
"web_subsection = \"phase-field\"\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "41d0a5bc",
- "metadata": {},
- "outputs": [],
- "source": [
- "from ogs6py import ogs\n",
- "import os\n",
- "import shutil\n",
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "import pyvista as pv\n",
- "import time\n",
- "import pandas as pd\n",
- "from xml.dom import minidom\n",
- "from types import MethodType"
+ "+++\n"
]
},
{
@@ -58,6 +40,25 @@
"## Define some helper functions"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "41d0a5bc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ogs6py import ogs\n",
+ "import os\n",
+ "import shutil\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import pyvista as pv\n",
+ "import time\n",
+ "import pandas as pd\n",
+ "from xml.dom import minidom\n",
+ "from types import MethodType\n"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 2,
@@ -83,7 +84,7 @@
"def set_timestepping(model,repeat_list, delta_t_list):\n",
" model.remove_element(xpath='./time_loop/processes/process/time_stepping/timesteps/pair')\n",
" for i in range(len(repeat_list)):\n",
- " model.add_block(blocktag = 'pair',parent_xpath='./time_loop/processes/process/time_stepping/timesteps', taglist = ['repeat', 'delta_t'], textlist = [repeat_list[i], delta_t_list[i]])"
+ " model.add_block(blocktag = 'pair',parent_xpath='./time_loop/processes/process/time_stepping/timesteps', taglist = ['repeat', 'delta_t'], textlist = [repeat_list[i], delta_t_list[i]])\n"
]
},
{
@@ -156,7 +157,7 @@
" print(\" > OGS started execution ...\")\n",
" ! ogs {out_dir}/{prj_name} -o {output_dir} >> {logfile}\n",
" tf = time.time()\n",
- " print(\" > OGS terminated execution. Elapsed time: \", round(tf - t0, 2), \" s.\")"
+ " print(\" > OGS terminated execution. Elapsed time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -302,7 +303,7 @@
"source": [
"# Load experimental data\n",
"data_lower = pd.read_csv(f\"figures/experiment_data_lower_limit.csv\") \n",
- "data_upper = pd.read_csv(f\"figures/experiment_data_upper_limit.csv\") "
+ "data_upper = pd.read_csv(f\"figures/experiment_data_upper_limit.csv\") \n"
]
},
{
@@ -356,7 +357,7 @@
"ax.axhline(y = 0, color = 'black',linewidth=1)\n",
"ax.axvline(x = 0, color = 'black',linewidth=1)\n",
"plt.fill_between(data_upper.iloc[:,0],0,data_upper.iloc[:,1], facecolor='green', alpha=0.3)\n",
- "plt.fill_between(data_lower.iloc[:,0],0,data_lower.iloc[:,1], facecolor='white', alpha=1)"
+ "plt.fill_between(data_lower.iloc[:,0],0,data_lower.iloc[:,1], facecolor='white', alpha=1)\n"
]
},
{
diff --git a/Tests/Data/TH2M/H/diffusion/diffusion.ipynb b/Tests/Data/TH2M/H/diffusion/diffusion.ipynb
index 36c88960456..53c065378e2 100644
--- a/Tests/Data/TH2M/H/diffusion/diffusion.ipynb
+++ b/Tests/Data/TH2M/H/diffusion/diffusion.ipynb
@@ -5,6 +5,7 @@
"id": "94e3d277",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Gas Diffusion\"\n",
"date = \"2022-10-19\"\n",
"author = \"Norbert Grunwald\"\n",
@@ -12,7 +13,7 @@
"web_subsection = \"th2m\"\n",
"coupling = \"h\"\n",
"weight = 1\n",
- ""
+ "+++\n"
]
},
{
@@ -97,7 +98,7 @@
"\n",
"# Boundary and initial concentration\n",
"c_b = concentration(1. - (beta_c*H*pGR_b))\n",
- "c_i = concentration(1. - (beta_c*H*pGR_i))"
+ "c_i = concentration(1. - (beta_c*H*pGR_i))\n"
]
},
{
@@ -119,7 +120,7 @@
"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -148,7 +149,7 @@
"model.write_input()\n",
"\n",
"# Run OGS\n",
- "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m .\")"
+ "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m .\")\n"
]
},
{
@@ -160,7 +161,7 @@
"source": [
" #Colors\n",
"cls1 = ['#4a001e', '#731331', '#9f2945', '#cc415a', '#e06e85', '#ed9ab0']\n",
- "cls2 = ['#0b194c', '#163670', '#265191', '#2f74b3', '#5d94cb', '#92b2de']"
+ "cls2 = ['#0b194c', '#163670', '#265191', '#2f74b3', '#5d94cb', '#92b2de']\n"
]
},
{
@@ -187,7 +188,7 @@
"x_axis=[(i,0,0) for i in length]\n",
"\n",
"# Discrete locations for c vs. t plots\n",
- "location = [0.01,0.05,0.1,0.2,0.5,1.0]"
+ "location = [0.01,0.05,0.1,0.2,0.5,1.0]\n"
]
},
{
diff --git a/Tests/Data/TH2M/H2/dissolution_diffusion/phase_appearance.ipynb b/Tests/Data/TH2M/H2/dissolution_diffusion/phase_appearance.ipynb
index fa00151d8ff..cc0dc6c45ac 100644
--- a/Tests/Data/TH2M/H2/dissolution_diffusion/phase_appearance.ipynb
+++ b/Tests/Data/TH2M/H2/dissolution_diffusion/phase_appearance.ipynb
@@ -5,6 +5,7 @@
"id": "4d4c5b87",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Phase Appearance/Disappearance\"\n",
"date = \"2022-10-19\"\n",
"author = \"Norbert Grunwald\"\n",
@@ -12,7 +13,7 @@
"web_subsection = \"th2m\"\n",
"coupling = \"h2\"\n",
"weight = 3\n",
- ""
+ "+++\n"
]
},
{
@@ -82,7 +83,7 @@
"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -129,7 +130,7 @@
"model.write_input()\n",
"\n",
"# Run OGS\n",
- "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m .\")"
+ "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m .\")\n"
]
},
{
@@ -140,7 +141,7 @@
"outputs": [],
"source": [
" #Colors\n",
- "cls=['#e6191d','#337fb8','#4eae4c','#984ea3','#984ea3','#feff32']"
+ "cls=['#e6191d','#337fb8','#4eae4c','#984ea3','#984ea3','#feff32']\n"
]
},
{
@@ -162,7 +163,7 @@
"\n",
"num_results= [1.-saturation['A'], gas_pressure['A'], liquid_pressure['A']]\n",
"\n",
- "time_years = time / 365.2425 / 86400"
+ "time_years = time / 365.2425 / 86400\n"
]
},
{
@@ -179,7 +180,7 @@
" pd.read_csv(f\"references/bourgeat_pGR.csv\"),\n",
" pd.read_csv(f\"references/bourgeat_pLR.csv\")]\n",
"\n",
- "header = list(refs[0].keys())"
+ "header = list(refs[0].keys())\n"
]
},
{
@@ -190,7 +191,7 @@
"outputs": [],
"source": [
"indices = {\"Gas saturation\" : 0,\"Gas pressure\" : 1,\"Liquid pressure\" : 2}\n",
- "labels = [\"$s_{G}$\", '$p_{GR}$', '$p_{LR}$']"
+ "labels = [\"$s_{G}$\", '$p_{GR}$', '$p_{LR}$']\n"
]
},
{
@@ -267,7 +268,7 @@
" ax1.legend()\n",
"\n",
"\n",
- "fig1.savefig('results_sG_pGR_pLR.pdf')"
+ "fig1.savefig('results_sG_pGR_pLR.pdf')\n"
]
},
{
diff --git a/Tests/Data/TH2M/H2/mcWhorter/mcWhorter.ipynb b/Tests/Data/TH2M/H2/mcWhorter/mcWhorter.ipynb
index 8a76622f4eb..f6082c759a6 100644
--- a/Tests/Data/TH2M/H2/mcWhorter/mcWhorter.ipynb
+++ b/Tests/Data/TH2M/H2/mcWhorter/mcWhorter.ipynb
@@ -5,6 +5,7 @@
"id": "4001a58a",
"metadata": {},
"source": [
+ "+++\n",
"title = \"McWhorter & Sunada Problem\"\n",
"date = \"2022-10-19\"\n",
"author = \"Norbert Grunwald\"\n",
@@ -12,7 +13,7 @@
"web_subsection = \"th2m\"\n",
"coupling = \"h2\"\n",
"weight = 4\n",
- ""
+ "+++\n"
]
},
{
@@ -84,7 +85,7 @@
"import numpy as np\n",
"# Import analytical solution from a CSV file\n",
"exact = np.loadtxt('data/ref_solution_saturation.csv', delimiter=\",\")\n",
- "# Zeroth column is location, first column is saturation"
+ "# Zeroth column is location, first column is saturation\n"
]
},
{
@@ -106,7 +107,7 @@
"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -129,7 +130,7 @@
"\n",
"# run OGS\n",
"model=OGS(PROJECT_FILE=\"mcWhorter_h2.prj\")\n",
- "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")"
+ "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")\n"
]
},
{
@@ -141,7 +142,7 @@
"source": [
"import vtuIO\n",
"# read OGS results from PVD file\n",
- "pvdfile = vtuIO.PVDIO(f\"{out_dir}/result_McWhorter_H2.pvd\", dim=2, interpolation_backend=\"vtk\")"
+ "pvdfile = vtuIO.PVDIO(f\"{out_dir}/result_McWhorter_H2.pvd\", dim=2, interpolation_backend=\"vtk\")\n"
]
},
{
@@ -165,7 +166,7 @@
"\n",
"# Absolute and relative errors\n",
"err_abs = exact[:,1] - sL_num\n",
- "err_rel = err_abs / exact[:,1]"
+ "err_rel = err_abs / exact[:,1]\n"
]
},
{
@@ -219,7 +220,7 @@
"ax2.legend(lns, labs, loc=0)\n",
"\n",
"\n",
- "fig1.savefig(f\"{out_dir}/mcWhorter.pdf\")"
+ "fig1.savefig(f\"{out_dir}/mcWhorter.pdf\")\n"
]
},
{
diff --git a/Tests/Data/TH2M/H2M/Liakopoulos/ogs-jupyter-lab-h2m-2d-liakopoulos.ipynb b/Tests/Data/TH2M/H2M/Liakopoulos/ogs-jupyter-lab-h2m-2d-liakopoulos.ipynb
index c727e9e61c8..7805e383240 100644
--- a/Tests/Data/TH2M/H2M/Liakopoulos/ogs-jupyter-lab-h2m-2d-liakopoulos.ipynb
+++ b/Tests/Data/TH2M/H2M/Liakopoulos/ogs-jupyter-lab-h2m-2d-liakopoulos.ipynb
@@ -5,6 +5,7 @@
"id": "ac287b2f",
"metadata": {},
"source": [
+ "+++\n",
"title = \"H2M Liakopoulos benchmark\"\n",
"date = \"2022-08-16\"\n",
"author = \"Norbert Grunwald, Olaf Kolditz\"\n",
@@ -12,7 +13,15 @@
"web_subsection = \"th2m\"\n",
"coupling = \"h2m\"\n",
"weight = 7\n",
- ""
+ "+++\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "eaca06f7",
+ "metadata": {},
+ "source": [
+ "## Notebook setup"
]
},
{
@@ -33,7 +42,7 @@
"import matplotlib.pyplot as plt\n",
"#import vtk\n",
"import matplotlib.tri as tri\n",
- "import vtuIO"
+ "import vtuIO\n"
]
},
{
@@ -52,7 +61,7 @@
"\n",
"prj_file_test = \"liakopoulos_TH2M.prj\"\n",
"pvd_file_test = f\"{out_dir}/result_liakopoulos.pvd\"\n",
- "vtu_mesh_file = \"domain.vtu\""
+ "vtu_mesh_file = \"domain.vtu\"\n"
]
},
{
@@ -81,7 +90,7 @@
}
],
"source": [
- "Image(filename = fig_dir + \"ogs-jupyter-lab.png\", width=150, height=100)"
+ "Image(filename = fig_dir + \"ogs-jupyter-lab.png\", width=150, height=100)\n"
]
},
{
@@ -108,17 +117,7 @@
}
],
"source": [
- "Image(filename = fig_dir + \"h2m-tet.png\", width=150, height=100)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "e520ca69",
- "metadata": {},
- "outputs": [],
- "source": [
- "#3-description (markdown)"
+ "Image(filename = fig_dir + \"h2m-tet.png\", width=150, height=100)\n"
]
},
{
@@ -222,7 +221,7 @@
"source": [
"mesh = pv.read(vtu_mesh_file)\n",
"print(\"inspecting vtu_mesh_file\")\n",
- "mesh"
+ "mesh\n"
]
},
{
@@ -260,7 +259,7 @@
"plotter.view_xy()\n",
"plotter.add_axes()\n",
"plotter.show_bounds(mesh, xlabel=\"x\", ylabel=\"y\")\n",
- "plotter.show()"
+ "plotter.show()\n"
]
},
{
@@ -293,7 +292,7 @@
"print(f\"ogs -o {out_dir} {prj_file_test} > {out_dir}/log.txt\")\n",
"! ogs -o {out_dir} {prj_file_test} > {out_dir}/log.txt\n",
"tf = time.time()\n",
- "print(\"computation time: \", round(tf - t0, 2), \" s.\")"
+ "print(\"computation time: \", round(tf - t0, 2), \" s.\")\n"
]
},
{
@@ -320,7 +319,7 @@
"#print(yaxis)\n",
"line_mesh = mesh.slice_along_line(yaxis)\n",
"y_num = line_mesh.points[:,1]\n",
- "reader = pv.get_reader(pvd_file_test)"
+ "reader = pv.get_reader(pvd_file_test)\n"
]
},
{
@@ -434,7 +433,7 @@
"ax2[1].plot(y_num, u_y4800, label=r\"$u_y$ t=4800\")\n",
"ax2[1].plot(y_num, u_y7200, label=r\"$u_y$ t=7200\")\n",
"ax2[1].legend()\n",
- "ax2[1].grid()"
+ "ax2[1].grid()\n"
]
},
{
@@ -490,7 +489,7 @@
"fig.colorbar(contour_left,ax=ax[0],label='$p$ / [MPa]')\n",
"fig.colorbar(contour_mid,ax=ax[1],label='$S$ / [-]')\n",
"fig.colorbar(contour_right,ax=ax[2],label='$u$ / [m]')\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
diff --git a/Tests/Data/TH2M/TH/Ogata-Banks/Ogata-Banks.ipynb b/Tests/Data/TH2M/TH/Ogata-Banks/Ogata-Banks.ipynb
index dd0e45d8c0b..36c2fe0415b 100644
--- a/Tests/Data/TH2M/TH/Ogata-Banks/Ogata-Banks.ipynb
+++ b/Tests/Data/TH2M/TH/Ogata-Banks/Ogata-Banks.ipynb
@@ -5,6 +5,7 @@
"id": "10a2c579",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Ogata-Banks Problem\"\n",
"date = \"2022-10-19\"\n",
"author = \"Norbert Grunwald\"\n",
@@ -12,7 +13,7 @@
"web_subsection = \"th2m\"\n",
"coupling = \"th\"\n",
"weight = 5\n",
- ""
+ "+++\n"
]
},
{
@@ -138,7 +139,7 @@
"domain_size = 50 # metre\n",
"\n",
"# Groundwater velocity\n",
- "v_x = 1.5e-6"
+ "v_x = 1.5e-6\n"
]
},
{
@@ -172,7 +173,7 @@
" a2 = np.divide((x+v_x*t),d,where=t!=0)\n",
" \n",
" result = (T_0-T_i) / 2. * (erfc(a1)+np.exp(v_x*x/alpha)*erfc(a2)) + T_i\n",
- " return result"
+ " return result\n"
]
},
{
@@ -194,7 +195,7 @@
"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -223,7 +224,7 @@
"model.replace_text(delta_time, xpath=\"./time_loop/processes/process/time_stepping/timesteps/pair/delta_t\")\n",
"# Output every timestep \n",
"model.replace_text(1, xpath=\"./time_loop/output/timesteps/pair/each_steps\")\n",
- "model.write_input()"
+ "model.write_input()\n"
]
},
{
@@ -243,7 +244,7 @@
],
"source": [
"# Run OGS\n",
- "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m . -s .\")"
+ "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m . -s .\")\n"
]
},
{
@@ -282,7 +283,7 @@
"x_axis=[(i,0,0) for i in length]\n",
"\n",
"# Discrete locations for T vs. t plots\n",
- "location = [1.,5.,10.,20.,50.]"
+ "location = [1.,5.,10.,20.,50.]\n"
]
},
{
@@ -295,7 +296,7 @@
"# The sample locations have to be converted into a 'dict' for vtuIO\n",
"observation_points = dict(('x='+str(x),(x,0.0,0.0)) for x in location)\n",
"# Samples temperature field at the observation points for all timesteps\n",
- "T_over_t_at_x = pvdfile.read_time_series('temperature_interpolated', observation_points)"
+ "T_over_t_at_x = pvdfile.read_time_series('temperature_interpolated', observation_points)\n"
]
},
{
@@ -360,7 +361,7 @@
"\n",
"ax1.legend()\n",
"ax2.legend()\n",
- "fig1.savefig(f\"{out_dir}/ogata_banks.pdf\")"
+ "fig1.savefig(f\"{out_dir}/ogata_banks.pdf\")\n"
]
},
{
@@ -395,7 +396,7 @@
"\n",
"# von-Neumann-Stability-Criterion\n",
"Ne = alpha * delta_time / (dx*dx)\n",
- "print (Ne)"
+ "print (Ne)\n"
]
},
{
@@ -422,7 +423,7 @@
],
"source": [
"dt = 0.5*(dx*dx)/alpha\n",
- "print(\"Smallest timestep should not exceed\",dt, \"seconds.\")"
+ "print(\"Smallest timestep should not exceed\",dt, \"seconds.\")\n"
]
},
{
@@ -452,7 +453,7 @@
],
"source": [
"dx = np.sqrt(2*alpha*delta_time)\n",
- "print(\"Minimum element size should be\",dx,\" metre.\")"
+ "print(\"Minimum element size should be\",dx,\" metre.\")\n"
]
},
{
diff --git a/Tests/Data/TH2M/TH/idealGasLaw/confined_gas_compression.ipynb b/Tests/Data/TH2M/TH/idealGasLaw/confined_gas_compression.ipynb
index 62469b77aa3..31199770888 100644
--- a/Tests/Data/TH2M/TH/idealGasLaw/confined_gas_compression.ipynb
+++ b/Tests/Data/TH2M/TH/idealGasLaw/confined_gas_compression.ipynb
@@ -5,6 +5,7 @@
"id": "75afeb19",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Confined Gas Compression\"\n",
"date = \"2022-10-19\"\n",
"author = \"Norbert Grunwald\"\n",
@@ -12,7 +13,7 @@
"web_subsection = \"th2m\"\n",
"coupling = \"h2\"\n",
"weight = 2\n",
- ""
+ "+++\n"
]
},
{
@@ -74,7 +75,7 @@
"outputs": [],
"source": [
"import numpy as np\n",
- "import matplotlib.pyplot as plt"
+ "import matplotlib.pyplot as plt\n"
]
},
{
@@ -102,7 +103,7 @@
"kappa=c_p/c_v\n",
"\n",
"# density\n",
- "rho_GR = rho_0*np.exp(-e)"
+ "rho_GR = rho_0*np.exp(-e)\n"
]
},
{
@@ -160,7 +161,7 @@
"outputs": [],
"source": [
"# gas pressure\n",
- "p_GR=p_0*np.exp(-kappa*e)"
+ "p_GR=p_0*np.exp(-kappa*e)\n"
]
},
{
@@ -184,7 +185,7 @@
"outputs": [],
"source": [
"# temperature\n",
- "T = p_GR*M/R/rho_GR"
+ "T = p_GR*M/R/rho_GR\n"
]
},
{
@@ -203,7 +204,7 @@
"outputs": [],
"source": [
"from ogs6py.ogs import OGS\n",
- "import vtuIO"
+ "import vtuIO\n"
]
},
{
@@ -217,7 +218,7 @@
"\n",
"out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)"
+ " os.makedirs(out_dir)\n"
]
},
{
@@ -238,7 +239,7 @@
"source": [
"# run OGS\n",
"cube_compression=OGS(PROJECT_FILE=\"compression_gas.prj\")\n",
- "cube_compression.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")"
+ "cube_compression.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")\n"
]
},
{
@@ -251,7 +252,7 @@
"# read PVD file\n",
"pvdfile = vtuIO.PVDIO(f\"{out_dir}/result_compression_gas.pvd\", dim=2)\n",
"# get all timesteps\n",
- "time = pvdfile.timesteps"
+ "time = pvdfile.timesteps\n"
]
},
{
@@ -455,7 +456,7 @@
"ax3.set_ylim(-0.0035,0.0002)\n",
"\n",
"fig1.tight_layout()\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
@@ -515,7 +516,7 @@
"ax3.set_ylim(-0.002,0.000125)\n",
"\n",
"fig1.tight_layout()\n",
- "plt.show()"
+ "plt.show()\n"
]
}
],
diff --git a/Tests/Data/TH2M/TH2/heatpipe/heatpipe.ipynb b/Tests/Data/TH2M/TH2/heatpipe/heatpipe.ipynb
index 06c306e7041..d0b163f3547 100644
--- a/Tests/Data/TH2M/TH2/heatpipe/heatpipe.ipynb
+++ b/Tests/Data/TH2M/TH2/heatpipe/heatpipe.ipynb
@@ -5,6 +5,7 @@
"id": "7613d48f",
"metadata": {},
"source": [
+ "+++\n",
"title = \"Heat pipe verification problem\"\n",
"date = \"2022-09-14\"\n",
"author = \"Kata Kurgyis\"\n",
@@ -12,7 +13,7 @@
"image = \"figures/placeholder_heatpipe.png\"\n",
"coupling = \"h2t\"\n",
"weight = 6\n",
- ""
+ "+++\n"
]
},
{
@@ -120,7 +121,7 @@
"k_rG_min = 1e-5 # used for normalization of BC model\n",
"k_rL_min = 1e-5 # used for normalization of BC model\n",
"p_thr_BC = 5.0e3 # entry pressure for Brooks-Corey model [Pa]\n",
- "exp_BC = 3.0 # Corey exponent for Brooks-Corey model [-]"
+ "exp_BC = 3.0 # Corey exponent for Brooks-Corey model [-]\n"
]
},
{
@@ -157,7 +158,7 @@
" return max(k_rG_min, ((1.-sL_eff) ** 2) * (1-(sL_eff ** ((2.+exp_BC)/exp_BC))) )\n",
"\n",
"def relative_permeability_liquid(sL_eff):\n",
- " return max(k_rL_min, sL_eff ** ((2.+3*exp_BC)/exp_BC))"
+ " return max(k_rL_min, sL_eff ** ((2.+3*exp_BC)/exp_BC))\n"
]
},
{
@@ -185,7 +186,7 @@
"\n",
"def partial_pressure_vapour(p_G, p_c, xA_G, T):\n",
" p_sat = saturation_vapour_pressure(T)\n",
- " return vapour_pressure(p_sat, p_G, p_c, xA_G, T)"
+ " return vapour_pressure(p_sat, p_G, p_c, xA_G, T)\n"
]
},
{
@@ -218,7 +219,7 @@
"def kinematic_viscosity_gas_phase(p_G, xA_G, T):\n",
" mu_G = viscosity_gas_phase(xA_G)\n",
" rho_G = density_gas_phase(p_G, xA_G, T)\n",
- " return mu_G / rho_G"
+ " return mu_G / rho_G\n"
]
},
{
@@ -237,7 +238,7 @@
"outputs": [],
"source": [
"def diffusivity(sL_eff):\n",
- " return phi * (1. - sL_eff) * D_pm"
+ " return phi * (1. - sL_eff) * D_pm\n"
]
},
{
@@ -260,7 +261,7 @@
" phi_G = (1. - sL) * phi\n",
" phi_L = sL * phi\n",
" phi_S = 1. - phi\n",
- " return lambda_G * phi_G + lambda_L * phi_L + lambda_S * phi_S"
+ " return lambda_G * phi_G + lambda_L * phi_L + lambda_S * phi_S\n"
]
},
{
@@ -451,7 +452,7 @@
" gamma = gamma_(sL_eff, p_G, xA_G, T)\n",
" nu_G = kinematic_viscosity_gas_phase(p_G, xA_G, T)\n",
" th_cond = thermal_conductivity(sL_eff)\n",
- " return dpC_dsL_eff * (1. - eta) / eta * dh_evap / (nu_G * th_cond) * K / gamma"
+ " return dpC_dsL_eff * (1. - eta) / eta * dh_evap / (nu_G * th_cond) * K / gamma\n"
]
},
{
@@ -526,7 +527,7 @@
"dsL_eff = (sL_eff_high - sL_eff_low) / n_dsL_eff\n",
"\n",
"# execute analytical solution\n",
- "M, sL_eff_list = full_Euler(dsL_eff, y0, sL_eff_low, sL_eff_high)"
+ "M, sL_eff_list = full_Euler(dsL_eff, y0, sL_eff_low, sL_eff_high)\n"
]
},
{
@@ -570,7 +571,7 @@
"\n",
"prj_file = \"heat_pipe_rough.prj\"\n",
"model=ogs.OGS(INPUT_FILE=prj_file, PROJECT_FILE=prj_file)\n",
- "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")"
+ "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")\n"
]
},
{
@@ -616,7 +617,7 @@
"S_num_interp = np.interp(M[0,:], x_num, S_num)\n",
"xA_G_num_interp = np.interp(M[0,:], x_num, xA_G_num)\n",
"p_G_num_interp = np.interp(M[0,:], x_num, p_G_num)\n",
- "T_num_interp = np.interp(M[0,:], x_num, T_num)"
+ "T_num_interp = np.interp(M[0,:], x_num, T_num)\n"
]
},
{
@@ -777,7 +778,7 @@
"ax3.legend()\n",
"ax3.grid(True)\n",
"fig3.tight_layout()\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
diff --git a/Tests/Data/ThermoHydroMechanics/Linear/Point_injection/SaturatedPointheatsource.ipynb b/Tests/Data/ThermoHydroMechanics/Linear/Point_injection/SaturatedPointheatsource.ipynb
index 4448cf6a282..80751ba8b26 100644
--- a/Tests/Data/ThermoHydroMechanics/Linear/Point_injection/SaturatedPointheatsource.ipynb
+++ b/Tests/Data/ThermoHydroMechanics/Linear/Point_injection/SaturatedPointheatsource.ipynb
@@ -4,6 +4,7 @@
"cell_type": "raw",
"metadata": {},
"source": [
+ "+++\n",
"author = \"Jörg Buchwald and Kata Kurgyis\"\n",
"date = \"2022-11-02\"\n",
"title = \"Point-Heatsource Problem\"\n",
@@ -11,7 +12,7 @@
"image = \"figures/placeholder_pointheatsource.png\"\n",
"web_subsection = \"th2m\"\n",
"coupling = \"thm\"\n",
- ""
+ "+++\n"
]
},
{
@@ -304,7 +305,7 @@
" self.Y = 1/(self.lambd+2*self.G) * (self.X/((1-self.c/self.kappa)*self.a_u)+self.bprime/self.a_u)\n",
" self.Z = 1/(self.lambd+2*self.G) * (self.X/((1-self.c/self.kappa)*self.a_u))\n",
"\n",
- "ana_model = ANASOL()"
+ "ana_model = ANASOL()\n"
]
},
{
@@ -353,7 +354,7 @@
"prj_file_trm = \"point_heat_source_2D.prj\"\n",
"path_trm = f\"{data_dir}/ThermoRichardsMechanics/PointHeatSource\"\n",
"prj_filepath_trm = f\"{path_trm}/{prj_file_trm}\"\n",
- "ogs_model_trm = ogs.OGS(INPUT_FILE=prj_filepath_trm, PROJECT_FILE=f\"{out_dir}/pointheatsource_trm.prj\")"
+ "ogs_model_trm = ogs.OGS(INPUT_FILE=prj_filepath_trm, PROJECT_FILE=f\"{out_dir}/pointheatsource_trm.prj\")\n"
]
},
{
@@ -367,7 +368,7 @@
"ogs_model_lin.set(t_end=t_end)\n",
"ogs_model_quad.set(t_end=t_end)\n",
"ogs_model_th2m.set(t_end=t_end)\n",
- "ogs_model_trm.set(t_end=t_end)"
+ "ogs_model_trm.set(t_end=t_end)\n"
]
},
{
@@ -380,7 +381,7 @@
"ogs_model_quad.set(output_prefix=\"pointheatsource_quad\")\n",
"ogs_model_th2m.set(output_prefix=\"pointheatsource_th2m\")\n",
"ogs_model_th2m.replace_text(\"150\", xpath=\"./parameters/parameter[name='temperature_source_term']/value\")\n",
- "ogs_model_trm.set(output_prefix=\"pointheatsource_trm\")"
+ "ogs_model_trm.set(output_prefix=\"pointheatsource_trm\")\n"
]
},
{
@@ -392,7 +393,7 @@
"ogs_model_lin.write_input()\n",
"ogs_model_quad.write_input()\n",
"ogs_model_th2m.write_input()\n",
- "ogs_model_trm.write_input()"
+ "ogs_model_trm.write_input()\n"
]
},
{
@@ -433,7 +434,7 @@
" for result in results:\n",
" print(result[0])\n",
" runtimes.append(result[1])\n",
- "print(f\"Elapsed time for all simulations: {timer() - start} s\")"
+ "print(f\"Elapsed time for all simulations: {timer() - start} s\")\n"
]
},
{
@@ -463,7 +464,7 @@
"\n",
"pvds = []\n",
"for i, prj in enumerate(projects):\n",
- " pvds.append(vtuIO.PVDIO(f\"{out_dir}/{prj}.pvd\", dim=2))"
+ " pvds.append(vtuIO.PVDIO(f\"{out_dir}/{prj}.pvd\", dim=2))\n"
]
},
{
@@ -525,7 +526,7 @@
" \n",
"ax2.legend(loc='upper right') \n",
"\n",
- "fig1.tight_layout()"
+ "fig1.tight_layout()\n"
]
},
{
@@ -561,7 +562,7 @@
"\n",
"ax2.legend(loc='upper right')\n",
"\n",
- "fig1.tight_layout()"
+ "fig1.tight_layout()\n"
]
},
{
@@ -597,7 +598,7 @@
"\n",
"ax2.legend(loc='lower right') \n",
"\n",
- "fig1.tight_layout()"
+ "fig1.tight_layout()\n"
]
},
{
@@ -620,7 +621,7 @@
"\n",
"# Radial coordinates for plotting\n",
"x = np.linspace(start=0.0001, stop=10.0, num=100)\n",
- "r = [(i,0,0) for i in x]"
+ "r = [(i,0,0) for i in x]\n"
]
},
{
@@ -656,7 +657,7 @@
" \n",
"ax2.legend()\n",
"\n",
- "fig1.tight_layout()"
+ "fig1.tight_layout()\n"
]
},
{
@@ -691,7 +692,7 @@
"\n",
"ax2.legend()\n",
"\n",
- "fig1.tight_layout()"
+ "fig1.tight_layout()\n"
]
},
{
@@ -726,7 +727,7 @@
"\n",
"ax2.legend()\n",
"\n",
- "fig1.tight_layout()"
+ "fig1.tight_layout()\n"
]
},
{
@@ -749,7 +750,7 @@
"mesh = ['thm linear', 'thm quadratic', 'th2m', 'trm']\n",
"ax.bar(mesh,runtimes)\n",
"plt.ylabel(\"exec. time / s\")\n",
- "plt.show()"
+ "plt.show()\n"
]
},
{
From 28ce66f1bbe9e868b3ab11165399063cd5f2d503 Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 11:31:56 +0200
Subject: [PATCH 4/8] [nb] Format notebooks with black.
---
.../ssd-cube.ipynb | 6 +-
.../SeabedResponse/Stationary_waves.ipynb | 560 +++++++----
..._Disc_with_hole_convergence_analysis.ipynb | 73 +-
.../Mechanics/Linear/SimpleMechanics.ipynb | 18 +-
Tests/Data/Mechanics/PLLC/PLLC.ipynb | 227 ++++-
Tests/Data/Notebooks/SimplePETSc.ipynb | 16 +-
.../Notebooks/thermo-osmosis.run-skip.ipynb | 598 +++++------
.../DiffusionSorptionDecay.ipynb | 309 +++---
.../MultiLayerDiffusion.ipynb | 257 +++--
.../DecayChain/DecayChain.ipynb | 718 +++++++++-----
.../RadionuclidesMigration.ipynb | 89 +-
.../LiquidFlow/AxiSymTheis/axisym_theis.ipynb | 167 ++--
.../BlockingConductingFracture.ipynb | 81 +-
.../HeatPipe/heatpipe.ipynb | 933 ++++++++++--------
.../TwoPhaseFlowPrho/MoMaS/MoMaS.ipynb | 274 ++---
.../Kregime_Propagating_jupyter.ipynb | 124 ++-
16 files changed, 2708 insertions(+), 1742 deletions(-)
diff --git a/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb b/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb
index fe9adb84908..624ed8ad900 100644
--- a/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb
+++ b/Tests/Data/Elliptic/cube_1x1x1_SteadyStateDiffusion/ssd-cube.ipynb
@@ -45,7 +45,7 @@
"if \"CI\" in os.environ:\n",
" pv.set_jupyter_backend(\"static\")\n",
"else:\n",
- " pv.set_jupyter_backend(\"client\")\n"
+ " pv.set_jupyter_backend(\"client\")"
]
},
{
@@ -58,7 +58,7 @@
"outputs": [],
"source": [
"resolution = \"2e4\"\n",
- "! ogs cube_{resolution}.prj -o {out_dir} > {out_dir}/log.txt\n"
+ "! ogs cube_{resolution}.prj -o {out_dir} > {out_dir}/log.txt"
]
},
{
@@ -89,7 +89,7 @@
"\n",
"plotter = pv.Plotter(notebook=True)\n",
"plotter.add_mesh(mesh, scalars=\"v\") # pressure\n",
- "plotter.show()\n"
+ "plotter.show()"
]
}
],
diff --git a/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb b/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb
index 1dc7b1fd727..ded6fcfdbc6 100644
--- a/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb
+++ b/Tests/Data/HydroMechanics/SeabedResponse/Stationary_waves.ipynb
@@ -140,7 +140,7 @@
"\\end{align}\n",
"$$\n",
"\n",
- "where $p$ is the pore pressure, $\\tilde{p}$ is the amplitude of the applied load, $\\sigma'_{yy}$ is the effective vertical stress and $\\sigma'_{xy}$ is the effective shear stress. The boundary condition of the pore pressure describes the space- and time-dependent water wave. Compared to Arnold Verruijt's solution, in this example there is a phase shift of $-\\frac{\\pi}{2}$ in the time-dependent part. The phase shift is necessary to obtain a water wave that starts oszillating from the equilibrium state (sine instead of cosine) and thus to be able to set an initial condition of $p=0$ Pa on the whole domain in the numerical solution. \n",
+ "where $p$ is the pore pressure, $\\tilde{p}$ is the amplitude of the applied load, $\\sigma'_{yy}$ is the effective vertical stress and $\\sigma'_{xy}$ is the effective shear stress. The boundary condition of the pore pressure describes the space- and time-dependent water wave. Compared to Arnold Verruijt's solution, in this example there is a phase shift of $-\\frac{\\pi}{2}$ in the time-dependent part. The phase shift is necessary to obtain a water wave that starts oszillating from the equilibrium state (sine instead of cosine) and thus to be able to set an initial condition of $p=0$ Pa on the whole domain in the numerical solution.\n",
"\n",
"With these boundary conditions, the following four constants are determined:\n",
"\n",
@@ -181,15 +181,17 @@
"import numpy as np\n",
"\n",
"import matplotlib.pyplot as plt\n",
- "plt.rc ('font', size = 8)\n",
- "plt.rc ('axes', titlesize = 10)\n",
- "plt.rc ('axes', labelsize = 10)\n",
+ "\n",
+ "plt.rc(\"font\", size=8)\n",
+ "plt.rc(\"axes\", titlesize=10)\n",
+ "plt.rc(\"axes\", labelsize=10)\n",
"\n",
"import gmsh\n",
"\n",
"import pyvista as pv\n",
+ "\n",
"pv.set_plot_theme(\"document\")\n",
- "pv.set_jupyter_backend(\"static\")\n"
+ "pv.set_jupyter_backend(\"static\")"
]
},
{
@@ -201,38 +203,91 @@
},
"outputs": [],
"source": [
- "def compute_pressure_and_stresses(t,x,z):\n",
- " \n",
- " n=0.4\n",
- " G=100e3 # [Pa]\n",
- " K=2/3*G # [Pa] (with ny=0)\n",
- " ny=0 # E = 3K(1-2ny) = 2G(1+ny)\n",
- " Cf=0 # in the book: Cf = 0.001/K\n",
- " Cs=0\n",
- " Cm=1/K\n",
- " my=1.3e-3 # [Pa*s]\n",
- " kappa=1e-11 # [m²] (medium sand, kf=10e-4 m/s) \n",
- " gamma_w = 9.81e3 # [Pa/m]\n",
- " lam=2*np.pi*0.1*10/100\n",
- " omega=2*np.pi*0.1\n",
- " \n",
- " k = kappa*gamma_w/my # Gl. (1.33)\n",
- " alpha = 1-Cs/Cm # Gl. (4.15)\n",
- " S = n*Cf + (alpha-n)*Cs # Gl. (1.28)\n",
- " theta = S*G/alpha**2 # Gl. (4.13)\n",
- " m = 1/(1-2*ny) # = K+1/3*G/G # Gl. (4.5)\n",
- " cv = k*G*(1+m) / (alpha**2*(1+theta+m*theta)*gamma_w) # Gl. (4.12)\n",
- " xi_2 = complex(lam**2, (omega/cv)) # Gl. (4.19)\n",
- " \n",
- " B1 = (1+m)*(xi_2-lam**2)-2*lam*(np.sqrt(xi_2)-lam)\n",
- " B2 = 2*m*theta*lam*np.sqrt(xi_2)+theta*((1+m)*(xi_2-lam**2)-2*lam*(np.sqrt(xi_2)-lam))\n",
- " B3 = 2*m*theta*lam\n",
- " D = 2*lam*(2*lam*(np.sqrt(xi_2)-lam)-(1+m)*(1+m*theta)*(xi_2-lam**2))\n",
- " p_rel = np.real((-2*lam*B1*np.exp(-lam*z) - (1+m)*(xi_2-lam**2)*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.cos(lam*x))\n",
- " sig_xx_rel = np.real(((-2*(m-1)*lam*theta + 2*lam*(1+m*theta)*lam*z)*B1*np.exp(-lam*z) - 2*lam*B2*np.exp(-lam*z) + ((m-1)*(xi_2-lam**2) - 2*lam**2)*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.cos(lam*x))\n",
- " sig_zz_rel = np.real(((-2*(m+1)*lam*theta - 2*lam*(1+m*theta)*lam*z)*B1*np.exp(-lam*z) + 2*lam*B2*np.exp(-lam*z) + ((m-1)*(xi_2-lam**2) + 2*xi_2)*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.cos(lam*x))\n",
- " sig_xz_rel = np.real(((-2*lam*(1+m*theta)*lam*z-2*lam*theta)*B1*np.exp(-lam*z) + 2*lam*B2*np.exp(-lam*z) + 2*np.sqrt(xi_2)*lam*B3*np.exp(-np.sqrt(xi_2)*z))/D * np.exp((omega*t-np.pi*0.5)*1j)*np.sin(lam*x))\n",
- " return p_rel, sig_xx_rel, sig_zz_rel, sig_xz_rel\n"
+ "def compute_pressure_and_stresses(t, x, z):\n",
+ " n = 0.4\n",
+ " G = 100e3 # [Pa]\n",
+ " K = 2 / 3 * G # [Pa] (with ny=0)\n",
+ " ny = 0 # E = 3K(1-2ny) = 2G(1+ny)\n",
+ " Cf = 0 # in the book: Cf = 0.001/K\n",
+ " Cs = 0\n",
+ " Cm = 1 / K\n",
+ " my = 1.3e-3 # [Pa*s]\n",
+ " kappa = 1e-11 # [m²] (medium sand, kf=10e-4 m/s)\n",
+ " gamma_w = 9.81e3 # [Pa/m]\n",
+ " lam = 2 * np.pi * 0.1 * 10 / 100\n",
+ " omega = 2 * np.pi * 0.1\n",
+ "\n",
+ " k = kappa * gamma_w / my # Gl. (1.33)\n",
+ " alpha = 1 - Cs / Cm # Gl. (4.15)\n",
+ " S = n * Cf + (alpha - n) * Cs # Gl. (1.28)\n",
+ " theta = S * G / alpha**2 # Gl. (4.13)\n",
+ " m = 1 / (1 - 2 * ny) # = K+1/3*G/G # Gl. (4.5)\n",
+ " cv = (\n",
+ " k * G * (1 + m) / (alpha**2 * (1 + theta + m * theta) * gamma_w)\n",
+ " ) # Gl. (4.12)\n",
+ " xi_2 = complex(lam**2, (omega / cv)) # Gl. (4.19)\n",
+ "\n",
+ " B1 = (1 + m) * (xi_2 - lam**2) - 2 * lam * (np.sqrt(xi_2) - lam)\n",
+ " B2 = 2 * m * theta * lam * np.sqrt(xi_2) + theta * (\n",
+ " (1 + m) * (xi_2 - lam**2) - 2 * lam * (np.sqrt(xi_2) - lam)\n",
+ " )\n",
+ " B3 = 2 * m * theta * lam\n",
+ " D = (\n",
+ " 2\n",
+ " * lam\n",
+ " * (\n",
+ " 2 * lam * (np.sqrt(xi_2) - lam)\n",
+ " - (1 + m) * (1 + m * theta) * (xi_2 - lam**2)\n",
+ " )\n",
+ " )\n",
+ " p_rel = np.real(\n",
+ " (\n",
+ " -2 * lam * B1 * np.exp(-lam * z)\n",
+ " - (1 + m) * (xi_2 - lam**2) * B3 * np.exp(-np.sqrt(xi_2) * z)\n",
+ " )\n",
+ " / D\n",
+ " * np.exp((omega * t - np.pi * 0.5) * 1j)\n",
+ " * np.cos(lam * x)\n",
+ " )\n",
+ " sig_xx_rel = np.real(\n",
+ " (\n",
+ " (-2 * (m - 1) * lam * theta + 2 * lam * (1 + m * theta) * lam * z)\n",
+ " * B1\n",
+ " * np.exp(-lam * z)\n",
+ " - 2 * lam * B2 * np.exp(-lam * z)\n",
+ " + ((m - 1) * (xi_2 - lam**2) - 2 * lam**2)\n",
+ " * B3\n",
+ " * np.exp(-np.sqrt(xi_2) * z)\n",
+ " )\n",
+ " / D\n",
+ " * np.exp((omega * t - np.pi * 0.5) * 1j)\n",
+ " * np.cos(lam * x)\n",
+ " )\n",
+ " sig_zz_rel = np.real(\n",
+ " (\n",
+ " (-2 * (m + 1) * lam * theta - 2 * lam * (1 + m * theta) * lam * z)\n",
+ " * B1\n",
+ " * np.exp(-lam * z)\n",
+ " + 2 * lam * B2 * np.exp(-lam * z)\n",
+ " + ((m - 1) * (xi_2 - lam**2) + 2 * xi_2) * B3 * np.exp(-np.sqrt(xi_2) * z)\n",
+ " )\n",
+ " / D\n",
+ " * np.exp((omega * t - np.pi * 0.5) * 1j)\n",
+ " * np.cos(lam * x)\n",
+ " )\n",
+ " sig_xz_rel = np.real(\n",
+ " (\n",
+ " (-2 * lam * (1 + m * theta) * lam * z - 2 * lam * theta)\n",
+ " * B1\n",
+ " * np.exp(-lam * z)\n",
+ " + 2 * lam * B2 * np.exp(-lam * z)\n",
+ " + 2 * np.sqrt(xi_2) * lam * B3 * np.exp(-np.sqrt(xi_2) * z)\n",
+ " )\n",
+ " / D\n",
+ " * np.exp((omega * t - np.pi * 0.5) * 1j)\n",
+ " * np.sin(lam * x)\n",
+ " )\n",
+ " return p_rel, sig_xx_rel, sig_zz_rel, sig_xz_rel"
]
},
{
@@ -242,7 +297,7 @@
"source": [
"By evaluating these equations at different times $t$ and depths $y$, we gain a better understanding of the pressure and stress distribution in the seabed. The below plot illustrates the pore pressure and the amplitude of the effective stresses as a function of depth directly underneath an anti-node of the standing water wave (the place where the amplitude is at maximum, i.e. for $x = k \\cdot \\frac{L}{2}$, where $k=0, 1, 2,$ ...).\n",
"\n",
- "Along the top edge of the seabed, the pore pressure is always as large as the applied load and the effective stresses are zero. This means, that all the change in pressure is absorbed by the fluid while the soil particles remain in their initial stress state (in this case zero, since body forces are being disregarded). The increased pore pressure at the top edge cannot propagate freely downwards into the seabed because seepage is limited by the hydraulic conductivity of the soil. Consequently, the pore pressure decreases with depth as the soil matrix gradually takes up the remaining share of the total stress in the seabed. "
+ "Along the top edge of the seabed, the pore pressure is always as large as the applied load and the effective stresses are zero. This means, that all the change in pressure is absorbed by the fluid while the soil particles remain in their initial stress state (in this case zero, since body forces are being disregarded). The increased pore pressure at the top edge cannot propagate freely downwards into the seabed because seepage is limited by the hydraulic conductivity of the soil. Consequently, the pore pressure decreases with depth as the soil matrix gradually takes up the remaining share of the total stress in the seabed."
]
},
{
@@ -250,6 +305,7 @@
"execution_count": 3,
"id": "4f48e224-330e-4f3f-89aa-734981c8fdd4",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -265,29 +321,56 @@
}
],
"source": [
- "y = np.linspace(0,100,1000)\n",
- "y_rel = y/100\n",
- "colors = {0:\"orangered\", 2:\"gold\", 4:\"blueviolet\", 6:\"forestgreen\", 8:\"darkorange\", 10:\"royalblue\"}\n",
- "\n",
- "fig, ax = plt.subplots(ncols=2, figsize=(15,7))\n",
- "for idx in (0,1):\n",
+ "y = np.linspace(0, 100, 1000)\n",
+ "y_rel = y / 100\n",
+ "colors = {\n",
+ " 0: \"orangered\",\n",
+ " 2: \"gold\",\n",
+ " 4: \"blueviolet\",\n",
+ " 6: \"forestgreen\",\n",
+ " 8: \"darkorange\",\n",
+ " 10: \"royalblue\",\n",
+ "}\n",
+ "\n",
+ "fig, ax = plt.subplots(ncols=2, figsize=(15, 7))\n",
+ "for idx in (0, 1):\n",
" ax[idx].grid(True)\n",
" ax[idx].set_ylabel(\"$y$ / $L$\")\n",
- " ax[idx].set_xlim(-1.1,1.1)\n",
+ " ax[idx].set_xlim(-1.1, 1.1)\n",
"\n",
- "for t in [0,2,4,6,8,10]:\n",
- " ax[0].plot(compute_pressure_and_stresses(t,0,y)[0], -y_rel, color=colors[t], label= \"t = %.1f s\" %t)\n",
+ "for t in [0, 2, 4, 6, 8, 10]:\n",
+ " ax[0].plot(\n",
+ " compute_pressure_and_stresses(t, 0, y)[0],\n",
+ " -y_rel,\n",
+ " color=colors[t],\n",
+ " label=\"t = %.1f s\" % t,\n",
+ " )\n",
"\n",
- "t=2.5\n",
+ "t = 2.5\n",
"ax[0].set_xlabel(\"$p$ / $\\\\tilde{p}$\")\n",
"ax[0].legend()\n",
- "ax[1].plot(compute_pressure_and_stresses(t,0,y)[1], -y_rel, color = colors[6], label = r\"$\\sigma'_{xx}/(\\alpha\\tilde{p})$\")\n",
- "#ax[1].plot(compute_pressure_and_stresses(t,0,y)[1]+compute_pressure_and_stresses(t,0,y)[0], -y_rel, linestyle = \"--\", color = colors[3], label = \"$\\\\sigma_{xx}$/$\\\\alpha\\\\tilde{p}$\") # Total horizontal stress\n",
- "ax[1].plot(compute_pressure_and_stresses(t,0,y)[2], -y_rel, color = colors[2], label = r\"$\\sigma'_{yy}/(\\alpha\\tilde{p})$\")\n",
- "#ax[1].plot(compute_pressure_and_stresses(t,0,y)[2]+compute_pressure_and_stresses(t,0,y)[0], -y_rel, linestyle = \"--\", color = colors[1], label = \"$\\\\sigma_{yy}$/$\\\\alpha\\\\tilde{p}$\") # Total vertical stress\n",
- "ax[1].plot(compute_pressure_and_stresses(t,0,y)[3], -y_rel, color = colors[4], label = r\"$\\sigma'_{xy}/(\\alpha\\tilde{p})$\")\n",
+ "ax[1].plot(\n",
+ " compute_pressure_and_stresses(t, 0, y)[1],\n",
+ " -y_rel,\n",
+ " color=colors[6],\n",
+ " label=r\"$\\sigma'_{xx}/(\\alpha\\tilde{p})$\",\n",
+ ")\n",
+ "# ax[1].plot(compute_pressure_and_stresses(t,0,y)[1]+compute_pressure_and_stresses(t,0,y)[0], -y_rel, linestyle = \"--\", color = colors[3], label = \"$\\\\sigma_{xx}$/$\\\\alpha\\\\tilde{p}$\") # Total horizontal stress\n",
+ "ax[1].plot(\n",
+ " compute_pressure_and_stresses(t, 0, y)[2],\n",
+ " -y_rel,\n",
+ " color=colors[2],\n",
+ " label=r\"$\\sigma'_{yy}/(\\alpha\\tilde{p})$\",\n",
+ ")\n",
+ "# ax[1].plot(compute_pressure_and_stresses(t,0,y)[2]+compute_pressure_and_stresses(t,0,y)[0], -y_rel, linestyle = \"--\", color = colors[1], label = \"$\\\\sigma_{yy}$/$\\\\alpha\\\\tilde{p}$\") # Total vertical stress\n",
+ "ax[1].plot(\n",
+ " compute_pressure_and_stresses(t, 0, y)[3],\n",
+ " -y_rel,\n",
+ " color=colors[4],\n",
+ " label=r\"$\\sigma'_{xy}/(\\alpha\\tilde{p})$\",\n",
+ ")\n",
"ax[1].set_xlabel(r\"$\\sigma'/(\\alpha\\tilde{p})$\")\n",
- "ax[1].legend();\n"
+ "ax[1].legend()"
]
},
{
@@ -303,6 +386,7 @@
"execution_count": 4,
"id": "9cc304d2-bd0a-443f-98dc-9c8488989d61",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -318,28 +402,43 @@
}
],
"source": [
- "t=np.linspace(0,20,200)\n",
- "colors = {1:\"gold\", 2:\"blueviolet\", 3:\"forestgreen\", 4:\"royalblue\"}\n",
+ "t = np.linspace(0, 20, 200)\n",
+ "colors = {1: \"gold\", 2: \"blueviolet\", 3: \"forestgreen\", 4: \"royalblue\"}\n",
"\n",
- "fig, ax = plt.subplots(ncols=2, figsize=(15,7))\n",
- "for idx in (0,1):\n",
+ "fig, ax = plt.subplots(ncols=2, figsize=(15, 7))\n",
+ "for idx in (0, 1):\n",
" ax[idx].grid(True)\n",
" ax[idx].set_xlabel(\"$t$ / s\")\n",
"\n",
- "for y in (np.linspace(0,100,6)):\n",
- " ax[0].plot( t, compute_pressure_and_stresses(t,0,y)[0], color = colors[4])\n",
+ "for y in np.linspace(0, 100, 6):\n",
+ " ax[0].plot(t, compute_pressure_and_stresses(t, 0, y)[0], color=colors[4])\n",
" ax[0].set_ylabel(\"$p/\\\\tilde{p}$\")\n",
- " ax[1].plot(t, compute_pressure_and_stresses(t,0,y)[1], color = colors[3], label = r\"$\\sigma'_{xx}/(\\alpha\\tilde{p})$\")\n",
- " ax[1].plot(t, compute_pressure_and_stresses(t,0,y)[2], color = colors[1], label = r\"$\\sigma'_{yy}/(\\alpha\\tilde{p})$\")\n",
- " ax[1].plot(t, compute_pressure_and_stresses(t,0,y)[3], color = colors[2], label = r\"$\\sigma'_{xy}/(\\alpha\\tilde{p})$\")\n",
+ " ax[1].plot(\n",
+ " t,\n",
+ " compute_pressure_and_stresses(t, 0, y)[1],\n",
+ " color=colors[3],\n",
+ " label=r\"$\\sigma'_{xx}/(\\alpha\\tilde{p})$\",\n",
+ " )\n",
+ " ax[1].plot(\n",
+ " t,\n",
+ " compute_pressure_and_stresses(t, 0, y)[2],\n",
+ " color=colors[1],\n",
+ " label=r\"$\\sigma'_{yy}/(\\alpha\\tilde{p})$\",\n",
+ " )\n",
+ " ax[1].plot(\n",
+ " t,\n",
+ " compute_pressure_and_stresses(t, 0, y)[3],\n",
+ " color=colors[2],\n",
+ " label=r\"$\\sigma'_{xy}/(\\alpha\\tilde{p})$\",\n",
+ " )\n",
" if y == 0:\n",
" ax[1].legend(loc=\"upper right\")\n",
"\n",
"ax[1].set_ylabel(\"$\\sigma$'/$\\\\alpha\\\\tilde{p}$\")\n",
"\n",
- " \n",
+ "\n",
"ax[0].set_title(\"Pore pressure over time\")\n",
- "ax[1].set_title(\"Effective stresses over time\");\n"
+ "ax[1].set_title(\"Effective stresses over time\")"
]
},
{
@@ -355,6 +454,7 @@
"execution_count": 5,
"id": "739678d6-b1a4-4d0d-94e8-1774a2eb5b17",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -370,28 +470,28 @@
}
],
"source": [
- "x, y = np.meshgrid(np.linspace(0,200,1000),np.linspace(0,100,1000))\n",
+ "x, y = np.meshgrid(np.linspace(0, 200, 1000), np.linspace(0, 100, 1000))\n",
"t = 2.5\n",
"\n",
- "fig, ax = plt.subplots(ncols=2, nrows=2, figsize=(15,7))\n",
- "l1=ax[0][0].contourf(x,-y, compute_pressure_and_stresses(t,x,y)[0], 15)\n",
- "l2=ax[0][1].contourf(x,-y, compute_pressure_and_stresses(t,x,y)[1], 15)\n",
- "l3=ax[1][1].contourf(x,-y, compute_pressure_and_stresses(t,x,y)[2], 15)\n",
- "l4=ax[1][0].contourf(x,-y, compute_pressure_and_stresses(t,x,y)[3], 15)\n",
- "fig.colorbar(l1,ax=ax[0][0])\n",
- "fig.colorbar(l2,ax=ax[0][1])\n",
- "fig.colorbar(l3,ax=ax[1][1])\n",
- "fig.colorbar(l4,ax=ax[1][0])\n",
- "for i in (0,1):\n",
- " for j in (0,1):\n",
- " ax[i][j].set_aspect('equal')\n",
- " ax[i][j].set_xlabel('$x$ / m')\n",
- " ax[i][j].set_ylabel('$y$ / m')\n",
+ "fig, ax = plt.subplots(ncols=2, nrows=2, figsize=(15, 7))\n",
+ "l1 = ax[0][0].contourf(x, -y, compute_pressure_and_stresses(t, x, y)[0], 15)\n",
+ "l2 = ax[0][1].contourf(x, -y, compute_pressure_and_stresses(t, x, y)[1], 15)\n",
+ "l3 = ax[1][1].contourf(x, -y, compute_pressure_and_stresses(t, x, y)[2], 15)\n",
+ "l4 = ax[1][0].contourf(x, -y, compute_pressure_and_stresses(t, x, y)[3], 15)\n",
+ "fig.colorbar(l1, ax=ax[0][0])\n",
+ "fig.colorbar(l2, ax=ax[0][1])\n",
+ "fig.colorbar(l3, ax=ax[1][1])\n",
+ "fig.colorbar(l4, ax=ax[1][0])\n",
+ "for i in (0, 1):\n",
+ " for j in (0, 1):\n",
+ " ax[i][j].set_aspect(\"equal\")\n",
+ " ax[i][j].set_xlabel(\"$x$ / m\")\n",
+ " ax[i][j].set_ylabel(\"$y$ / m\")\n",
"ax[0][0].set_title(\"$p/\\\\tilde{p}$\")\n",
"ax[0][1].set_title(\"$\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\")\n",
"ax[1][1].set_title(\"$\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\")\n",
"ax[1][0].set_title(\"$\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\")\n",
- "fig.tight_layout();\n"
+ "fig.tight_layout()"
]
},
{
@@ -437,8 +537,8 @@
"import os\n",
"\n",
"# out_dir will contain all data we produce\n",
- "out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
- "os.makedirs(out_dir, exist_ok=True)\n"
+ "out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"_out\")\n",
+ "os.makedirs(out_dir, exist_ok=True)"
]
},
{
@@ -450,10 +550,10 @@
},
"outputs": [],
"source": [
- "def generate_mesh_axb(a,b,Nx,Ny,P):\n",
+ "def generate_mesh_axb(a, b, Nx, Ny, P):\n",
" output_file = f\"{out_dir}/square_{a}x{b}.msh\"\n",
- " \n",
- " lc=0.5\n",
+ "\n",
+ " lc = 0.5\n",
"\n",
" # Before using any functions in the Python API, Gmsh must be initialized:\n",
" gmsh.initialize()\n",
@@ -465,13 +565,12 @@
" dim2 = 2\n",
"\n",
" # Outer points (ccw)\n",
- " gmsh.model.geo.addPoint(0, -b, 0, lc, 1)\n",
- " gmsh.model.geo.addPoint(a, -b, 0, lc, 2)\n",
- " gmsh.model.geo.addPoint(a, -b/2, 0, lc, 3)\n",
- " gmsh.model.geo.addPoint(a, 0, 0, lc, 4)\n",
- " gmsh.model.geo.addPoint(0, 0, 0, lc, 5)\n",
- " gmsh.model.geo.addPoint(0, -b/2, 0, lc, 6)\n",
- "\n",
+ " gmsh.model.geo.addPoint(0, -b, 0, lc, 1)\n",
+ " gmsh.model.geo.addPoint(a, -b, 0, lc, 2)\n",
+ " gmsh.model.geo.addPoint(a, -b / 2, 0, lc, 3)\n",
+ " gmsh.model.geo.addPoint(a, 0, 0, lc, 4)\n",
+ " gmsh.model.geo.addPoint(0, 0, 0, lc, 5)\n",
+ " gmsh.model.geo.addPoint(0, -b / 2, 0, lc, 6)\n",
"\n",
" # Outer lines (ccw)\n",
" gmsh.model.geo.addLine(1, 2, 1)\n",
@@ -482,11 +581,10 @@
" gmsh.model.geo.addLine(6, 1, 6)\n",
" gmsh.model.geo.addLine(6, 3, 7)\n",
"\n",
- "\n",
- " # The third elementary entity is the surface. In order to define a surface \n",
+ " # The third elementary entity is the surface. In order to define a surface\n",
" # from the curves defined above, a curve loop has first to be defined (ccw).\n",
- " gmsh.model.geo.addCurveLoop([ 1, 2, -7, 6], 1)\n",
- " gmsh.model.geo.addCurveLoop([ 7, 3, 4, 5], 2)\n",
+ " gmsh.model.geo.addCurveLoop([1, 2, -7, 6], 1)\n",
+ " gmsh.model.geo.addCurveLoop([7, 3, 4, 5], 2)\n",
"\n",
" # Add plane surfaces defined by one or more curve loops.\n",
" gmsh.model.geo.addPlaneSurface([1], 1)\n",
@@ -495,13 +593,13 @@
" gmsh.model.geo.synchronize()\n",
"\n",
" # Prepare structured grid\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 1, Nx)\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 2, int(Ny*0.3))\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 3, Ny, \"Progression\", -P)\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 4, Nx)\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 5, Ny, \"Progression\", P)\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 6, int(Ny*0.3))\n",
- " gmsh.model.geo.mesh.setTransfiniteCurve( 7, Nx)\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(1, Nx)\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(2, int(Ny * 0.3))\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(3, Ny, \"Progression\", -P)\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(4, Nx)\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(5, Ny, \"Progression\", P)\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(6, int(Ny * 0.3))\n",
+ " gmsh.model.geo.mesh.setTransfiniteCurve(7, Nx)\n",
"\n",
" gmsh.model.geo.mesh.setTransfiniteSurface(1, \"Alternate\")\n",
" gmsh.model.geo.mesh.setTransfiniteSurface(2, \"Alternate\")\n",
@@ -531,10 +629,10 @@
"\n",
" gmsh.model.mesh.generate(dim2)\n",
" # gmsh.option.setNumber('Mesh.SecondOrderIncomplete', 1) # serendipity elements\n",
- " gmsh.model.mesh.setOrder(2) # higher order elements (quadratic)\n",
+ " gmsh.model.mesh.setOrder(2) # higher order elements (quadratic)\n",
" gmsh.write(output_file)\n",
"\n",
- " gmsh.finalize()\n"
+ " gmsh.finalize()"
]
},
{
@@ -542,6 +640,7 @@
"execution_count": 8,
"id": "137f610d-adbc-4e3f-9ea0-8ee958bbb817",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -580,7 +679,7 @@
}
],
"source": [
- "generate_mesh_axb(200,100,25,45,1.07)\n"
+ "generate_mesh_axb(200, 100, 25, 45, 1.07)"
]
},
{
@@ -588,11 +687,12 @@
"execution_count": 9,
"id": "f0aaf7e1-9c00-4c16-a0ef-605cbf877377",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
"source": [
- "input_file = f\"{out_dir}/square_200x100.msh\"\n"
+ "input_file = f\"{out_dir}/square_200x100.msh\""
]
},
{
@@ -600,6 +700,7 @@
"execution_count": 10,
"id": "a362da7c-dcc4-47f9-9e43-c5871f1006ed",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -643,7 +744,7 @@
],
"source": [
"!msh2vtu --ogs {input_file}\n",
- "assert _exit_code == 0\n"
+ "assert _exit_code == 0"
]
},
{
@@ -663,6 +764,7 @@
"execution_count": 11,
"id": "9c745eea-75c9-49db-8b40-833aca73b436",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -682,12 +784,12 @@
"pv.set_jupyter_backend(\"static\")\n",
"\n",
"mesh = pv.read(f\"{out_dir}/square_200x100_domain.vtu\")\n",
- "plotter = pv.Plotter(window_size = [1000, 800])\n",
+ "plotter = pv.Plotter(window_size=[1000, 800])\n",
"plotter.add_mesh(mesh, show_edges=True, show_scalar_bar=False, color=None, scalars=None)\n",
"\n",
"plotter.show_bounds(ticks=\"outside\", xlabel=\"x / m\", ylabel=\"y / m\")\n",
"plotter.view_xy()\n",
- "plotter.show()\n"
+ "plotter.show()"
]
},
{
@@ -703,7 +805,7 @@
"\n",
"In this example, the boundary conditions are defined as follows:\n",
"\n",
- "**Top:** \n",
+ "**Top:**\n",
"$$\n",
"\\begin{align}\n",
"p(y=0)&=\\tilde{p}\\cdot \\sin(\\omega \\cdot t) \\cdot \\cos(\\frac{2 \\pi}{L} \\cdot x) \\\\\n",
@@ -756,7 +858,7 @@
},
"outputs": [],
"source": [
- "from ogs6py import ogs\n"
+ "from ogs6py import ogs"
]
},
{
@@ -769,75 +871,88 @@
"outputs": [],
"source": [
"## Helper Functions\n",
- "def read_timestep_mesh(a,time):\n",
+ "def read_timestep_mesh(a, time):\n",
" reader = pv.PVDReader(f\"{out_dir}/square_{a}x100.pvd\")\n",
- " reader.set_active_time_point(int(time*4)) # time [s], delta t = 0.25 s\n",
+ " reader.set_active_time_point(int(time * 4)) # time [s], delta t = 0.25 s\n",
" mesh = reader.read()[0]\n",
" return mesh\n",
"\n",
+ "\n",
"def slice_along_line(mesh, start_point, end_point):\n",
- " line = pv.Line(start_point, end_point, resolution = 2)\n",
+ " line = pv.Line(start_point, end_point, resolution=2)\n",
" return mesh.slice_along_line(line)\n",
"\n",
+ "\n",
"def get_pressure_sorted(mesh):\n",
" pressure = mesh.point_data[\"pressure_interpolated\"]\n",
- " depth = mesh.points[:,1]\n",
+ " depth = mesh.points[:, 1]\n",
" indices_sorted = np.argsort(depth)\n",
" pressure_sorted = pressure[indices_sorted]\n",
" return pressure_sorted\n",
"\n",
+ "\n",
"def get_stresses_sorted(mesh):\n",
" sigma = mesh.point_data[\"sigma\"]\n",
- " depth = mesh.points[:,1]\n",
+ " depth = mesh.points[:, 1]\n",
" indices_sorted = np.argsort(depth)\n",
- " sigma_xx = - sigma[indices_sorted, 0] # switching sign convention\n",
- " sigma_yy = - sigma[indices_sorted, 1]\n",
- " #sigma_zz = - sigma[indices_sorted, 2]\n",
- " sigma_xy = + sigma[indices_sorted, 3]\n",
- " return sigma_xx, sigma_yy, sigma_xy #,sigma_zz\n",
+ " sigma_xx = -sigma[indices_sorted, 0] # switching sign convention\n",
+ " sigma_yy = -sigma[indices_sorted, 1]\n",
+ " # sigma_zz = - sigma[indices_sorted, 2]\n",
+ " sigma_xy = +sigma[indices_sorted, 3]\n",
+ " return sigma_xx, sigma_yy, sigma_xy # ,sigma_zz\n",
+ "\n",
"\n",
"def get_depth_sorted(mesh):\n",
- " depth = mesh.points[:,1]\n",
+ " depth = mesh.points[:, 1]\n",
" indices_sorted = np.argsort(depth)\n",
" return depth[indices_sorted]\n",
"\n",
+ "\n",
"def compute_abs_and_rel_pressure_error(pressures, depth, t, x):\n",
" num_points = pressures.shape[0]\n",
" f_abs = np.zeros(num_points)\n",
" f_rel = np.zeros(num_points)\n",
- " \n",
- " for pt_idx in range(num_points): \n",
- " y = -depth[pt_idx]\n",
- " pressure_ana = compute_pressure_and_stresses(t,x,y)[0] # returns pressure normalised to the pressure amplitude\n",
- " pressure_num = pressures[pt_idx]/0.1e5 # absolute pressure divided by pressure amplitude\n",
+ "\n",
+ " for pt_idx in range(num_points):\n",
+ " y = -depth[pt_idx]\n",
+ " pressure_ana = compute_pressure_and_stresses(t, x, y)[\n",
+ " 0\n",
+ " ] # returns pressure normalised to the pressure amplitude\n",
+ " pressure_num = (\n",
+ " pressures[pt_idx] / 0.1e5\n",
+ " ) # absolute pressure divided by pressure amplitude\n",
" f_abs[pt_idx] = pressure_num - pressure_ana\n",
- " \n",
+ "\n",
" if pressure_ana == 0:\n",
" f_rel[pt_idx] = f_abs[pt_idx] / 1e-2\n",
" else:\n",
" f_rel[pt_idx] = f_abs[pt_idx] / pressure_ana\n",
- " \n",
+ "\n",
" return f_abs, f_rel\n",
"\n",
+ "\n",
"def compute_abs_and_rel_stress_error(sigmas, depth, t, x):\n",
" num_points = depth.shape[0]\n",
" f_abs = np.zeros((3, num_points))\n",
" f_rel = np.zeros((3, num_points))\n",
- " \n",
- " for stress_idx in (0,1,2):\n",
- " \n",
+ "\n",
+ " for stress_idx in (0, 1, 2):\n",
" for pt_idx in range(num_points):\n",
" y = -depth[pt_idx]\n",
- " sigma_ana = compute_pressure_and_stresses(t,x,y)[stress_idx+1] # returns stresses normalised to the pressure amplitude\n",
- " sigma_num = sigma[stress_idx][pt_idx]/0.1e5 # absolute stresses divided by pressure amplitude\n",
+ " sigma_ana = compute_pressure_and_stresses(t, x, y)[\n",
+ " stress_idx + 1\n",
+ " ] # returns stresses normalised to the pressure amplitude\n",
+ " sigma_num = (\n",
+ " sigma[stress_idx][pt_idx] / 0.1e5\n",
+ " ) # absolute stresses divided by pressure amplitude\n",
" f_abs[stress_idx][pt_idx] = sigma_num - sigma_ana\n",
"\n",
" if sigma_ana == 0:\n",
- " f_rel[stress_idx][pt_idx] = f_abs[stress_idx][pt_idx]/ 1e-2\n",
+ " f_rel[stress_idx][pt_idx] = f_abs[stress_idx][pt_idx] / 1e-2\n",
" else:\n",
" f_rel[stress_idx][pt_idx] = f_abs[stress_idx][pt_idx] / sigma_ana\n",
- " \n",
- " return f_abs, f_rel\n"
+ "\n",
+ " return f_abs, f_rel"
]
},
{
@@ -845,6 +960,7 @@
"execution_count": 14,
"id": "848ce73f-688f-4b19-94ef-a4718ad61570",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -858,9 +974,10 @@
}
],
"source": [
- "model = ogs.OGS(INPUT_FILE=\"seabed_response_200x100.prj\", PROJECT_FILE=\"seabed_response_200x100.prj\")\n",
- "model.run_model(logfile=f\"{out_dir}/out.txt\",\n",
- " args=f\"-o {out_dir} -m {out_dir}\")\n"
+ "model = ogs.OGS(\n",
+ " INPUT_FILE=\"seabed_response_200x100.prj\", PROJECT_FILE=\"seabed_response_200x100.prj\"\n",
+ ")\n",
+ "model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir} -m {out_dir}\")"
]
},
{
@@ -876,6 +993,7 @@
"execution_count": 15,
"id": "ed7c61b9-18e9-48d5-87d7-2fb3f932adf9",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -893,17 +1011,24 @@
"source": [
"time = 2.5 # [s]\n",
"reader = pv.get_reader(f\"{out_dir}/square_200x100.pvd\")\n",
- "reader.set_active_time_point(int(time*4))\n",
+ "reader.set_active_time_point(int(time * 4))\n",
"mesh = reader.read()[0]\n",
"\n",
"plotter = pv.Plotter()\n",
"\n",
- "sargs = dict(title=\"p / Pa\" , height=0.25, position_x=0.2, position_y=0.02)\n",
- "plotter.add_mesh(mesh, scalars = \"pressure_interpolated\", show_edges=False, show_scalar_bar=True, label=\"p\", scalar_bar_args=sargs)\n",
- "plotter.show_bounds(ticks=\"outside\", xlabel = \"x / m\", ylabel = \"y / m\")\n",
+ "sargs = dict(title=\"p / Pa\", height=0.25, position_x=0.2, position_y=0.02)\n",
+ "plotter.add_mesh(\n",
+ " mesh,\n",
+ " scalars=\"pressure_interpolated\",\n",
+ " show_edges=False,\n",
+ " show_scalar_bar=True,\n",
+ " label=\"p\",\n",
+ " scalar_bar_args=sargs,\n",
+ ")\n",
+ "plotter.show_bounds(ticks=\"outside\", xlabel=\"x / m\", ylabel=\"y / m\")\n",
"plotter.add_axes()\n",
"plotter.view_xy()\n",
- "plotter.show()\n"
+ "plotter.show()"
]
},
{
@@ -911,9 +1036,9 @@
"id": "d4631296-5f3a-42fa-96d1-5ce0556bf206",
"metadata": {},
"source": [
- "For a more detailed comparison between the analytical and the numerical solution, both solutions are evaluated along the vertical line directly underneath an anti-node of the standing wave. As before, the pore pressure and the amplitude of the effective stresses are illustrated as a function of depth. The results of the numerical solution are marked as dots in the same color as the analytical solution. Additionally, the absolute errors $\\Delta p = p_{numerical}-p_{analtical}$ and $\\Delta \\sigma_{i}' = \\sigma_{i, numerical}'-\\sigma_{i, analytical}'$ are illustrated on the right. \n",
+ "For a more detailed comparison between the analytical and the numerical solution, both solutions are evaluated along the vertical line directly underneath an anti-node of the standing wave. As before, the pore pressure and the amplitude of the effective stresses are illustrated as a function of depth. The results of the numerical solution are marked as dots in the same color as the analytical solution. Additionally, the absolute errors $\\Delta p = p_{numerical}-p_{analtical}$ and $\\Delta \\sigma_{i}' = \\sigma_{i, numerical}'-\\sigma_{i, analytical}'$ are illustrated on the right.\n",
"\n",
- "The plot shows that the absolute errors are very small at about $2 \\%$ of the wave's amplitude. They can mostly be ascribed to the space- and time-discretization. Close to the top boundary of the domain, larger errors occur. These errors could originate in the definition of both a pressure and displacement (Neumann-) boundary condition along the top edge. "
+ "The plot shows that the absolute errors are very small at about $2 \\%$ of the wave's amplitude. They can mostly be ascribed to the space- and time-discretization. Close to the top boundary of the domain, larger errors occur. These errors could originate in the definition of both a pressure and displacement (Neumann-) boundary condition along the top edge."
]
},
{
@@ -921,6 +1046,7 @@
"execution_count": 16,
"id": "2e06842d-1f73-4182-9ffa-02498a9f9341",
"metadata": {
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -937,28 +1063,55 @@
],
"source": [
"x = 0\n",
- "y = np.linspace(0,100,1000)\n",
- "y_rel = y/100\n",
- "colors = {0:\"orangered\", 2:\"gold\", 4:\"blueviolet\", 6:\"forestgreen\", 8:\"darkorange\", 10:\"royalblue\"}\n",
- "\n",
- "fig, ax = plt.subplots(ncols=2, nrows=2, figsize=(15,15))\n",
+ "y = np.linspace(0, 100, 1000)\n",
+ "y_rel = y / 100\n",
+ "colors = {\n",
+ " 0: \"orangered\",\n",
+ " 2: \"gold\",\n",
+ " 4: \"blueviolet\",\n",
+ " 6: \"forestgreen\",\n",
+ " 8: \"darkorange\",\n",
+ " 10: \"royalblue\",\n",
+ "}\n",
+ "\n",
+ "fig, ax = plt.subplots(ncols=2, nrows=2, figsize=(15, 15))\n",
"\n",
"## Plotting analytical solution\n",
- "for t in [2,4,6,8,10]:\n",
- " ax[0][0].plot(compute_pressure_and_stresses(t,x,y)[0], -y_rel, color=colors[t], label= \"analytical, t = %.1f s\" %t)\n",
- "\n",
- "ax[1][0].plot(compute_pressure_and_stresses(2.5,x,y)[1], -y_rel, color = colors[6], label = \"analytical, $\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\")\n",
- "ax[1][0].plot(compute_pressure_and_stresses(2.5,x,y)[2], -y_rel, color = colors[2], label = \"analytical, $\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\")\n",
- "ax[1][0].plot(compute_pressure_and_stresses(2.5,x,y)[3], -y_rel, color = colors[4], label = \"analytical, $\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\")\n",
+ "for t in [2, 4, 6, 8, 10]:\n",
+ " ax[0][0].plot(\n",
+ " compute_pressure_and_stresses(t, x, y)[0],\n",
+ " -y_rel,\n",
+ " color=colors[t],\n",
+ " label=\"analytical, t = %.1f s\" % t,\n",
+ " )\n",
+ "\n",
+ "ax[1][0].plot(\n",
+ " compute_pressure_and_stresses(2.5, x, y)[1],\n",
+ " -y_rel,\n",
+ " color=colors[6],\n",
+ " label=\"analytical, $\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\",\n",
+ ")\n",
+ "ax[1][0].plot(\n",
+ " compute_pressure_and_stresses(2.5, x, y)[2],\n",
+ " -y_rel,\n",
+ " color=colors[2],\n",
+ " label=\"analytical, $\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\",\n",
+ ")\n",
+ "ax[1][0].plot(\n",
+ " compute_pressure_and_stresses(2.5, x, y)[3],\n",
+ " -y_rel,\n",
+ " color=colors[4],\n",
+ " label=\"analytical, $\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\",\n",
+ ")\n",
"\n",
"## Plotting numerical solution\n",
- "p1 = (x+1e-6, 0, 0)\n",
- "p2 = (x+1e-6, -100, 0)\n",
+ "p1 = (x + 1e-6, 0, 0)\n",
+ "p2 = (x + 1e-6, -100, 0)\n",
"\n",
"for t_num in (2, 2.5, 4, 6, 8, 10):\n",
" mesh = read_timestep_mesh(200, t_num)\n",
- " \n",
- " line_mesh = slice_along_line(mesh, p1, p2) \n",
+ "\n",
+ " line_mesh = slice_along_line(mesh, p1, p2)\n",
" pressure = get_pressure_sorted(line_mesh)\n",
" sigma = get_stresses_sorted(line_mesh)\n",
" depth = get_depth_sorted(line_mesh)\n",
@@ -966,35 +1119,80 @@
" f_abs_sigma = compute_abs_and_rel_stress_error(sigma, depth, t_num, x)[0]\n",
"\n",
" if t_num != 2.5:\n",
- " ax[0][0].plot(pressure/0.1e5, depth/100, \"o\", markevery=10, color=colors[t_num], label= \"numerical, t = %.1f s\" %t_num) \n",
+ " ax[0][0].plot(\n",
+ " pressure / 0.1e5,\n",
+ " depth / 100,\n",
+ " \"o\",\n",
+ " markevery=10,\n",
+ " color=colors[t_num],\n",
+ " label=\"numerical, t = %.1f s\" % t_num,\n",
+ " )\n",
" ax[0][0].set_xlabel(\"$p$ / $\\\\tilde{p}$\")\n",
"\n",
- " ax[0][1].plot(f_abs_pressure, depth/100, color=colors[t_num], label = \"t = %.1f s\" %t_num)\n",
+ " ax[0][1].plot(\n",
+ " f_abs_pressure, depth / 100, color=colors[t_num], label=\"t = %.1f s\" % t_num\n",
+ " )\n",
" ax[0][1].set_xlabel(\"$\\\\Delta p /\\\\tilde{p}$\")\n",
- " \n",
+ "\n",
" if t_num == 2.5:\n",
- " ax[1][0].plot(sigma[0]/0.1e5, depth/100, \"o\", markevery=10, color = colors[6], label = \"numerical, $\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\")\n",
- " ax[1][0].plot(sigma[1]/0.1e5, depth/100, \"o\", markevery=10, color = colors[2], label = \"numerical, $\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\")\n",
- " ax[1][0].plot(sigma[2]/0.1e5, depth/100, \"o\", markevery=10, color = colors[4], label = \"numerical, $\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\")\n",
+ " ax[1][0].plot(\n",
+ " sigma[0] / 0.1e5,\n",
+ " depth / 100,\n",
+ " \"o\",\n",
+ " markevery=10,\n",
+ " color=colors[6],\n",
+ " label=\"numerical, $\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\",\n",
+ " )\n",
+ " ax[1][0].plot(\n",
+ " sigma[1] / 0.1e5,\n",
+ " depth / 100,\n",
+ " \"o\",\n",
+ " markevery=10,\n",
+ " color=colors[2],\n",
+ " label=\"numerical, $\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\",\n",
+ " )\n",
+ " ax[1][0].plot(\n",
+ " sigma[2] / 0.1e5,\n",
+ " depth / 100,\n",
+ " \"o\",\n",
+ " markevery=10,\n",
+ " color=colors[4],\n",
+ " label=\"numerical, $\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\",\n",
+ " )\n",
" ax[1][0].set_xlabel(\"$\\\\sigma$'/$\\\\alpha\\\\tilde{p}$\")\n",
- " \n",
- " ax[1][1].plot(f_abs_sigma[0], depth/100, color = colors[6], label = \"$\\\\Delta\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\")\n",
- " ax[1][1].plot(f_abs_sigma[1], depth/100, color = colors[2], label = \"$\\\\Delta\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\")\n",
- " ax[1][1].plot(f_abs_sigma[2], depth/100, color = colors[4], label = \"$\\\\Delta\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\")\n",
+ "\n",
+ " ax[1][1].plot(\n",
+ " f_abs_sigma[0],\n",
+ " depth / 100,\n",
+ " color=colors[6],\n",
+ " label=\"$\\\\Delta\\\\sigma'_{xx}/\\\\alpha\\\\tilde{p}$\",\n",
+ " )\n",
+ " ax[1][1].plot(\n",
+ " f_abs_sigma[1],\n",
+ " depth / 100,\n",
+ " color=colors[2],\n",
+ " label=\"$\\\\Delta\\\\sigma'_{yy}/\\\\alpha\\\\tilde{p}$\",\n",
+ " )\n",
+ " ax[1][1].plot(\n",
+ " f_abs_sigma[2],\n",
+ " depth / 100,\n",
+ " color=colors[4],\n",
+ " label=\"$\\\\Delta\\\\sigma'_{xy}/\\\\alpha\\\\tilde{p}$\",\n",
+ " )\n",
" ax[1][1].set_xlabel(\"$\\\\Delta\\\\sigma$'/$\\\\alpha\\\\tilde{p}$\")\n",
- " \n",
- " #ax[1][0].plot(sigma[3]/0.1e5, depth/100, \"o\", markevery=10, color = colors[4], label = \"numerical, $\\\\sigma'_{zz}/\\\\alpha\\\\tilde{p}$\")\n",
+ "\n",
+ " # ax[1][0].plot(sigma[3]/0.1e5, depth/100, \"o\", markevery=10, color = colors[4], label = \"numerical, $\\\\sigma'_{zz}/\\\\alpha\\\\tilde{p}$\")\n",
"\n",
"## layout settings\n",
- "ax[0][0].set_title('Comparison numerical and analytical solution')\n",
- "ax[0][1].set_title('Absolute error')\n",
+ "ax[0][0].set_title(\"Comparison numerical and analytical solution\")\n",
+ "ax[0][1].set_title(\"Absolute error\")\n",
"\n",
- "for idx_1 in (0,1):\n",
- " for idx_2 in (0,1):\n",
+ "for idx_1 in (0, 1):\n",
+ " for idx_2 in (0, 1):\n",
" ax[idx_1][idx_2].grid(True)\n",
" ax[idx_1][idx_2].set_ylabel(\"$y$ / $L$\")\n",
" ax[idx_1][0].set_xlim(-1.1, 1.1)\n",
- " ax[idx_1][idx_2].legend()\n"
+ " ax[idx_1][idx_2].legend()"
]
},
{
diff --git a/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb b/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb
index 8ead903b5f0..1a801d39c0e 100644
--- a/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb
+++ b/Tests/Data/Mechanics/Linear/DiscWithHole/Linear_Disc_with_hole_convergence_analysis.ipynb
@@ -77,6 +77,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
@@ -98,7 +99,7 @@
"plt.rcParams[\"axes.spines.left\"] = True\n",
"plt.rcParams[\"axes.spines.bottom\"] = True\n",
"plt.rcParams[\"axes.axisbelow\"] = True\n",
- "plt.rcParams[\"figure.figsize\"] = (8, 6)\n"
+ "plt.rcParams[\"figure.figsize\"] = (8, 6)"
]
},
{
@@ -108,7 +109,8 @@
"metadata": {
"jupyter": {
"source_hidden": true
- }
+ },
+ "lines_to_next_cell": 2
},
"outputs": [],
"source": [
@@ -118,7 +120,7 @@
"# ATTENTION: We assume that this notebook is executed in the directory where\n",
"# it is stored. Otherwise this notebook might not work!\n",
"out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"out\")\n",
- "os.makedirs(out_dir, exist_ok=True)\n"
+ "os.makedirs(out_dir, exist_ok=True)"
]
},
{
@@ -138,7 +140,7 @@
"STUDY_indices = [8, 16, 24, 40, 60, 80, 240]\n",
"\n",
"# With this parameter the length of one axis of the square plate is defined\n",
- "STUDY_mesh_size = 20\n"
+ "STUDY_mesh_size = 20"
]
},
{
@@ -274,7 +276,7 @@
"def resample_mesh_to_240_resolution(idx):\n",
" mesh_fine = read_last_timestep_mesh(240)\n",
" mesh_coarse = read_last_timestep_mesh(idx)\n",
- " return mesh_fine.sample(mesh_coarse)\n"
+ " return mesh_fine.sample(mesh_coarse)"
]
},
{
@@ -308,11 +310,12 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
"source": [
- "import mesh_quarter_of_rectangle_with_hole\n"
+ "import mesh_quarter_of_rectangle_with_hole"
]
},
{
@@ -323,6 +326,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -542,7 +546,7 @@
" NR=idx,\n",
" Nr=idx,\n",
" P=1,\n",
- " )\n"
+ " )"
]
},
{
@@ -563,13 +567,14 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
"source": [
"for idx in STUDY_indices:\n",
" input_file = f\"{out_dir}/disc_with_hole_idx_is_{idx}.msh\"\n",
- " ! msh2vtu -r --ogs -o {out_dir}/disc_with_hole_idx_is_{idx} {input_file}\n"
+ " ! msh2vtu -r --ogs -o {out_dir}/disc_with_hole_idx_is_{idx} {input_file}"
]
},
{
@@ -598,6 +603,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
@@ -605,7 +611,7 @@
"import pyvista as pv\n",
"\n",
"pv.set_plot_theme(\"document\")\n",
- "pv.set_jupyter_backend(\"static\")\n"
+ "pv.set_jupyter_backend(\"static\")"
]
},
{
@@ -616,6 +622,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -648,7 +655,7 @@
"p.camera.zoom(1.3)\n",
"p.window_size = [1000, 500]\n",
"\n",
- "p.show()\n"
+ "p.show()"
]
},
{
@@ -667,12 +674,13 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
"source": [
"from ogs6py import ogs\n",
- "import shutil\n"
+ "import shutil"
]
},
{
@@ -717,7 +725,7 @@
" prj_path = os.path.join(out_dir, prj_file)\n",
"\n",
" model = ogs.OGS(INPUT_FILE=prj_path, PROJECT_FILE=prj_path)\n",
- " model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")\n"
+ " model.run_model(logfile=f\"{out_dir}/out.txt\", args=f\"-o {out_dir}\")"
]
},
{
@@ -807,7 +815,7 @@
" * np.sin(2 * np.pi * theta / 180)\n",
" )\n",
" * np.heaviside(r + 1e-7 - a, 1)\n",
- " )\n"
+ " )"
]
},
{
@@ -910,7 +918,7 @@
" # only a single 4-vector will be converted\n",
" return vec4_to_mat3x3polar_single(vec4, xs, ys)\n",
" else:\n",
- " return vec4_to_mat3x3polar_multi(vec4, xs, ys)\n"
+ " return vec4_to_mat3x3polar_multi(vec4, xs, ys)"
]
},
{
@@ -921,6 +929,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
@@ -937,7 +946,7 @@
" STUDY_num_result_meshes_by_index[idx] = mesh\n",
"\n",
"\n",
- "read_simulation_result_meshes()\n"
+ "read_simulation_result_meshes()"
]
},
{
@@ -948,6 +957,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
@@ -965,7 +975,7 @@
" STUDY_num_result_xaxis_meshes_by_index[idx] = line_mesh\n",
"\n",
"\n",
- "compute_xaxis_meshes()\n"
+ "compute_xaxis_meshes()"
]
},
{
@@ -976,6 +986,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
@@ -993,7 +1004,7 @@
" STUDY_num_result_yaxis_meshes_by_index[idx] = line_mesh\n",
"\n",
"\n",
- "compute_yaxis_meshes()\n"
+ "compute_yaxis_meshes()"
]
},
{
@@ -1022,7 +1033,7 @@
" STUDY_num_result_diagonal_meshes_by_index[idx] = line_mesh\n",
"\n",
"\n",
- "compute_diagonal_meshes()\n"
+ "compute_diagonal_meshes()"
]
},
{
@@ -1043,6 +1054,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -1240,7 +1252,7 @@
" fig.tight_layout()\n",
"\n",
"\n",
- "plot_stress_distribution_along_xaxis()\n"
+ "plot_stress_distribution_along_xaxis()"
]
},
{
@@ -1329,7 +1341,7 @@
},
"outputs": [],
"source": [
- "from vtkmodules.vtkFiltersParallel import vtkIntegrateAttributes\n"
+ "from vtkmodules.vtkFiltersParallel import vtkIntegrateAttributes"
]
},
{
@@ -1350,7 +1362,7 @@
" integrator.Update()\n",
" return pv.wrap(\n",
" integrator.GetOutputDataObject(0)\n",
- " ) # that is an entire mesh with one point and one cell\n"
+ " ) # that is an entire mesh with one point and one cell"
]
},
{
@@ -1377,7 +1389,7 @@
" l2_tt = np.sqrt(sum(list_tt))\n",
" l2_rt = np.sqrt(sum(list_rt))\n",
"\n",
- " return l2_rr, l2_tt, l2_rt\n"
+ " return l2_rr, l2_tt, l2_rt"
]
},
{
@@ -1407,7 +1419,7 @@
" l2_x = np.sqrt(sum(list_x))\n",
" l2_y = np.sqrt(sum(list_y))\n",
"\n",
- " return l2_x, l2_y\n"
+ " return l2_x, l2_y"
]
},
{
@@ -1431,7 +1443,7 @@
" l2_rt = np.linalg.norm(sig_rt_240 - sig_rt)\n",
"\n",
" points = sig_rr.shape[0]\n",
- " return l2_rr / np.sqrt(points), l2_tt / np.sqrt(points), l2_rt / np.sqrt(points)\n"
+ " return l2_rr / np.sqrt(points), l2_tt / np.sqrt(points), l2_rt / np.sqrt(points)"
]
},
{
@@ -1462,7 +1474,7 @@
" l2_x = np.linalg.norm(dis_x_240 - dis_x)\n",
" l2_y = np.linalg.norm(dis_y_240 - dis_y)\n",
"\n",
- " return l2_x / np.sqrt(points), l2_y / np.sqrt(points)\n"
+ " return l2_x / np.sqrt(points), l2_y / np.sqrt(points)"
]
},
{
@@ -1502,7 +1514,7 @@
" L2_tt = np.sqrt(integration_result_mesh.point_data[\"diff_tt_squared\"][0])\n",
" L2_rt = np.sqrt(integration_result_mesh.point_data[\"diff_rt_squared\"][0])\n",
"\n",
- " return L2_rr, L2_tt, L2_rt\n"
+ " return L2_rr, L2_tt, L2_rt"
]
},
{
@@ -1542,7 +1554,7 @@
" L2_x = np.sqrt(integration_result_mesh.point_data[\"diff_x_squared\"][0])\n",
" L2_y = np.sqrt(integration_result_mesh.point_data[\"diff_y_squared\"][0])\n",
"\n",
- " return L2_x, L2_y\n"
+ " return L2_x, L2_y"
]
},
{
@@ -1608,7 +1620,7 @@
" size[idx] = compute_cell_size(idx, mesh_coarse)\n",
"\n",
"\n",
- "compute_error_norms()\n"
+ "compute_error_norms()"
]
},
{
@@ -1632,7 +1644,7 @@
" y_ = xs[0] ** slope\n",
" ys = y0 / y_ * xs**slope\n",
" ax.plot(xs, ys, color=\"black\")\n",
- " ax.text(xs[-1] * 1.05, ys[-1], slope)\n"
+ " ax.text(xs[-1] * 1.05, ys[-1], slope)"
]
},
{
@@ -1643,6 +1655,7 @@
"jupyter": {
"source_hidden": true
},
+ "lines_to_next_cell": 2,
"tags": []
},
"outputs": [
@@ -1740,7 +1753,7 @@
"for i in range(3):\n",
" ax[i].legend()\n",
" ax[i].set_xlabel(\"h / cm\")\n",
- " ax[i].loglog(base=10)\n"
+ " ax[i].loglog(base=10)"
]
},
{
diff --git a/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb b/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb
index 82e57b38535..c69a1a6da29 100644
--- a/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb
+++ b/Tests/Data/Mechanics/Linear/SimpleMechanics.ipynb
@@ -25,21 +25,25 @@
"cell_type": "code",
"execution_count": 19,
"id": "420713a5-74d6-47ad-815c-4ca9e7e914bf",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"import os\n",
"\n",
"out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"_out\")\n",
"if not os.path.exists(out_dir):\n",
- " os.makedirs(out_dir)\n"
+ " os.makedirs(out_dir)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "8da3a8e8-be97-4092-88a9-1fb7792fa644",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [
{
"name": "stdout",
@@ -173,14 +177,16 @@
"\n",
"from datetime import datetime\n",
"\n",
- "print(datetime.now())\n"
+ "print(datetime.now())"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "1d730e79",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [
{
"data": {
@@ -256,7 +262,7 @@
")\n",
"plt.legend()\n",
"plt.xlabel(\"t\")\n",
- "plt.ylabel(\"u\")\n"
+ "plt.ylabel(\"u\")"
]
},
{
diff --git a/Tests/Data/Mechanics/PLLC/PLLC.ipynb b/Tests/Data/Mechanics/PLLC/PLLC.ipynb
index a503be3c990..5c5de5df16c 100644
--- a/Tests/Data/Mechanics/PLLC/PLLC.ipynb
+++ b/Tests/Data/Mechanics/PLLC/PLLC.ipynb
@@ -28,7 +28,9 @@
"cell_type": "code",
"execution_count": null,
"id": "7962f42f-fd53-4fc1-b966-a8ba924aca6c",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"import contextlib\n",
@@ -40,16 +42,18 @@
"from ogs6py import ogs\n",
"\n",
"prj_name = \"uniax_compression\"\n",
- "data_dir = os.environ.get('OGS_DATA_DIR', str(os.getcwd()).split(\"/Data/\")[0] + \"/Data/\")\n",
+ "data_dir = os.environ.get(\n",
+ " \"OGS_DATA_DIR\", str(os.getcwd()).split(\"/Data/\")[0] + \"/Data/\"\n",
+ ")\n",
"input_file = f\"{data_dir}/Mechanics/PLLC/{prj_name}.prj\"\n",
- "out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', f'{data_dir}/Mechanics/PLLC/_out')\n",
+ "out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", f\"{data_dir}/Mechanics/PLLC/_out\")\n",
"\n",
"if not os.path.exists(out_dir):\n",
" os.makedirs(out_dir)\n",
"os.chdir(out_dir)\n",
"\n",
"prj_file = f\"{out_dir}/{prj_name}_out.prj\"\n",
- "ogs_model = ogs.OGS(INPUT_FILE=input_file, PROJECT_FILE=prj_file)\n"
+ "ogs_model = ogs.OGS(INPUT_FILE=input_file, PROJECT_FILE=prj_file)"
]
},
{
@@ -67,18 +71,123 @@
"cell_type": "code",
"execution_count": null,
"id": "5a20a14e",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"# Unfortunately the source for the WIPP data has gone missing - will be added if it's found again\n",
"ExData = {\n",
- " \"WIPP CS 25\": (25, \"^\", [[9.87970002, 2.013560846E-05], [11.84642707, 3.178356756E-05], [7.87388785, 1.66059726E-06]]),\n",
- " \"WIPP CS 60\": (60, \"^\", [[3.98589289, 5.7824853E-06], [5.94266985, 2.075776623E-05], [7.87388785, 1.953209818E-05], [9.96978837, 5.841438703E-05], [11.84642707, 0.00011762092257], [13.94911482, 0.00026749321794], [17.9857158, 0.00111804208073], [1.9814251, 8.7645834E-07], [3.91418422, 4.01350889E-06], [5.88897108, 3.34371363E-06], [7.87388785, 1.129440706E-05], [9.87970002, 2.99068674E-05], [11.84642707, 7.681792203E-05], [13.82306874, 0.00011067584933], [15.83934389, 0.00052247037957]]),\n",
- " \"DeVries 1988 25\": (25, \"s\", [[4.99, 2.10816E-06], [4.99, 2.4192E-06], [5, 1.8144E-06], [9.99, 2.2032E-05], [14.96, 9.2448E-05], [14.98, 0.000216]]),\n",
- " \"DeVries 1988 100\": (100, \"s\", [[4.95, 9.6768E-05], [6.77, 0.000292896], [7.46, 0.000324], [8.55, 0.000664416], [8.92, 0.00091584], [8.98, 0.0009936], [9.91, 0.00124416], [10.1, 0.00139968], [10.22, 0.00093312], [10.27, 0.00132192], [12.1, 0.00216], [12.3, 0.00409536], [12.35, 0.00320544], [12.37, 0.00292032], [12.39, 0.00253152], [12.4, 0.0026784], [12.46, 0.0025056], [12.49, 0.00347328], [13.57, 0.00273024], [13.78, 0.00242784], [14.7, 0.00482112], [16.87, 0.0095904], [17.2, 0.0123552], [19.96, 0.030672]]),\n",
- " \"DeVries 1988 200\": (200, \"s\", [[3.47, 0.00117504], [4.71, 0.0032832], [6.67, 0.0104544], [6.78, 0.0132192], [9.86, 0.214272]]),\n",
- " \"Berest 2015 14.3\": (14.3, \"P\", [[0.09909639, 8.944207E-08], [0.19575886, 1.4118213E-07], [0.29452325, 1.4118213E-07], [0.49411031, 9.799173E-08]]),\n",
- " \"Berest 2017 7.8\": (7.8, \"P\", [[0.19575886,2.2285256E-07], [0.19575886,9.505469E-08], [0.19754389,2.5947583E-07], [0.19754389,2.647936E-08], [0.39379426,4.9162047E-07], [0.39738509,6.801413E-08], [0.59247161,4.0957628E-07], [0.59247161,5.7241269E-07], [0.59787408,1.0735864E-07], [1.0591736,1.11804208E-06]])}\n"
+ " \"WIPP CS 25\": (\n",
+ " 25,\n",
+ " \"^\",\n",
+ " [\n",
+ " [9.87970002, 2.013560846e-05],\n",
+ " [11.84642707, 3.178356756e-05],\n",
+ " [7.87388785, 1.66059726e-06],\n",
+ " ],\n",
+ " ),\n",
+ " \"WIPP CS 60\": (\n",
+ " 60,\n",
+ " \"^\",\n",
+ " [\n",
+ " [3.98589289, 5.7824853e-06],\n",
+ " [5.94266985, 2.075776623e-05],\n",
+ " [7.87388785, 1.953209818e-05],\n",
+ " [9.96978837, 5.841438703e-05],\n",
+ " [11.84642707, 0.00011762092257],\n",
+ " [13.94911482, 0.00026749321794],\n",
+ " [17.9857158, 0.00111804208073],\n",
+ " [1.9814251, 8.7645834e-07],\n",
+ " [3.91418422, 4.01350889e-06],\n",
+ " [5.88897108, 3.34371363e-06],\n",
+ " [7.87388785, 1.129440706e-05],\n",
+ " [9.87970002, 2.99068674e-05],\n",
+ " [11.84642707, 7.681792203e-05],\n",
+ " [13.82306874, 0.00011067584933],\n",
+ " [15.83934389, 0.00052247037957],\n",
+ " ],\n",
+ " ),\n",
+ " \"DeVries 1988 25\": (\n",
+ " 25,\n",
+ " \"s\",\n",
+ " [\n",
+ " [4.99, 2.10816e-06],\n",
+ " [4.99, 2.4192e-06],\n",
+ " [5, 1.8144e-06],\n",
+ " [9.99, 2.2032e-05],\n",
+ " [14.96, 9.2448e-05],\n",
+ " [14.98, 0.000216],\n",
+ " ],\n",
+ " ),\n",
+ " \"DeVries 1988 100\": (\n",
+ " 100,\n",
+ " \"s\",\n",
+ " [\n",
+ " [4.95, 9.6768e-05],\n",
+ " [6.77, 0.000292896],\n",
+ " [7.46, 0.000324],\n",
+ " [8.55, 0.000664416],\n",
+ " [8.92, 0.00091584],\n",
+ " [8.98, 0.0009936],\n",
+ " [9.91, 0.00124416],\n",
+ " [10.1, 0.00139968],\n",
+ " [10.22, 0.00093312],\n",
+ " [10.27, 0.00132192],\n",
+ " [12.1, 0.00216],\n",
+ " [12.3, 0.00409536],\n",
+ " [12.35, 0.00320544],\n",
+ " [12.37, 0.00292032],\n",
+ " [12.39, 0.00253152],\n",
+ " [12.4, 0.0026784],\n",
+ " [12.46, 0.0025056],\n",
+ " [12.49, 0.00347328],\n",
+ " [13.57, 0.00273024],\n",
+ " [13.78, 0.00242784],\n",
+ " [14.7, 0.00482112],\n",
+ " [16.87, 0.0095904],\n",
+ " [17.2, 0.0123552],\n",
+ " [19.96, 0.030672],\n",
+ " ],\n",
+ " ),\n",
+ " \"DeVries 1988 200\": (\n",
+ " 200,\n",
+ " \"s\",\n",
+ " [\n",
+ " [3.47, 0.00117504],\n",
+ " [4.71, 0.0032832],\n",
+ " [6.67, 0.0104544],\n",
+ " [6.78, 0.0132192],\n",
+ " [9.86, 0.214272],\n",
+ " ],\n",
+ " ),\n",
+ " \"Berest 2015 14.3\": (\n",
+ " 14.3,\n",
+ " \"P\",\n",
+ " [\n",
+ " [0.09909639, 8.944207e-08],\n",
+ " [0.19575886, 1.4118213e-07],\n",
+ " [0.29452325, 1.4118213e-07],\n",
+ " [0.49411031, 9.799173e-08],\n",
+ " ],\n",
+ " ),\n",
+ " \"Berest 2017 7.8\": (\n",
+ " 7.8,\n",
+ " \"P\",\n",
+ " [\n",
+ " [0.19575886, 2.2285256e-07],\n",
+ " [0.19575886, 9.505469e-08],\n",
+ " [0.19754389, 2.5947583e-07],\n",
+ " [0.19754389, 2.647936e-08],\n",
+ " [0.39379426, 4.9162047e-07],\n",
+ " [0.39738509, 6.801413e-08],\n",
+ " [0.59247161, 4.0957628e-07],\n",
+ " [0.59247161, 5.7241269e-07],\n",
+ " [0.59787408, 1.0735864e-07],\n",
+ " [1.0591736, 1.11804208e-06],\n",
+ " ],\n",
+ " ),\n",
+ "}"
]
},
{
@@ -96,18 +205,27 @@
"cell_type": "code",
"execution_count": null,
"id": "8066a6d3",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
- "A1 = 0.18 # d^-1\n",
- "Q1 = 54e3 # kJ / mol\n",
- "A2 = 6.5e-5 # m^3 K d^−1\n",
- "Q2 = 24.5e3 # kJ / mol\n",
- "dGrain = 5e-2 # m\n",
- "sref = 1. # MPa\n",
- "BGRa = lambda sig, T: A1 * np.exp(-Q1/(8.3145*(273.15+T))) * np.power(sig/sref,5.)\n",
- "PLLC = lambda sig, T: A1 * np.exp(-Q1/(8.3145*(273.15+T))) * np.power(sig/sref,5.) + \\\n",
- " A2 * np.exp(-Q2/(8.3145*(273.15+T))) * sig/sref / np.power(dGrain, 3) / (273.15+T)\n"
+ "A1 = 0.18 # d^-1\n",
+ "Q1 = 54e3 # kJ / mol\n",
+ "A2 = 6.5e-5 # m^3 K d^−1\n",
+ "Q2 = 24.5e3 # kJ / mol\n",
+ "dGrain = 5e-2 # m\n",
+ "sref = 1.0 # MPa\n",
+ "BGRa = (\n",
+ " lambda sig, T: A1\n",
+ " * np.exp(-Q1 / (8.3145 * (273.15 + T)))\n",
+ " * np.power(sig / sref, 5.0)\n",
+ ")\n",
+ "PLLC = lambda sig, T: A1 * np.exp(-Q1 / (8.3145 * (273.15 + T))) * np.power(\n",
+ " sig / sref, 5.0\n",
+ ") + A2 * np.exp(-Q2 / (8.3145 * (273.15 + T))) * sig / sref / np.power(dGrain, 3) / (\n",
+ " 273.15 + T\n",
+ ")"
]
},
{
@@ -125,29 +243,36 @@
"cell_type": "code",
"execution_count": null,
"id": "7e2e294c-e803-4f02-b5ab-9bdfef94b00f",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"lo_stresses = np.array([0.2e6, 0.6e6])\n",
"hi_stresses = np.array([2e6, 10e6])\n",
- "Exps = {7.8: ('blue', lo_stresses), 14.3: ('orange', lo_stresses),\n",
- " 25: ('lime', hi_stresses), 60: ('red', hi_stresses),\n",
- " 100: ('gray', hi_stresses), 200: ('mediumpurple', hi_stresses)}\n",
+ "Exps = {\n",
+ " 7.8: (\"blue\", lo_stresses),\n",
+ " 14.3: (\"orange\", lo_stresses),\n",
+ " 25: (\"lime\", hi_stresses),\n",
+ " 60: (\"red\", hi_stresses),\n",
+ " 100: (\"gray\", hi_stresses),\n",
+ " 200: (\"mediumpurple\", hi_stresses),\n",
+ "}\n",
"\n",
"fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n",
- "ax.set_xlabel('$\\\\sigma_\\\\mathrm{ax}$ / MPa')\n",
- "ax.set_ylabel('$\\\\dot{\\\\epsilon}_{zz}$ / d$^{-1}$')\n",
+ "ax.set_xlabel(\"$\\\\sigma_\\\\mathrm{ax}$ / MPa\")\n",
+ "ax.set_ylabel(\"$\\\\dot{\\\\epsilon}_{zz}$ / d$^{-1}$\")\n",
"ax.set_xlim(0.15, 30)\n",
"ax.set_ylim(1e-15, 1e1)\n",
- "ax.grid(visible=True, which='both')\n",
- "points = {'pt0': (1., 1., 1.)}\n",
+ "ax.grid(visible=True, which=\"both\")\n",
+ "points = {\"pt0\": (1.0, 1.0, 1.0)}\n",
"\n",
"sigs = np.logspace(-1, 2, 100)\n",
- "for temp, (col, stresses) in Exps.items(): \n",
+ "for temp, (col, stresses) in Exps.items():\n",
" # plot analytical curves\n",
" if temp >= 25:\n",
- " ax.plot(sigs, BGRa(sigs, temp), color=col, ls='--')\n",
- " ax.plot(sigs, PLLC(sigs, temp), color=col, ls='-')\n",
+ " ax.plot(sigs, BGRa(sigs, temp), color=col, ls=\"--\")\n",
+ " ax.plot(sigs, PLLC(sigs, temp), color=col, ls=\"-\")\n",
"\n",
" # simulation in ogs and plot results\n",
" eps_dot = []\n",
@@ -157,14 +282,15 @@
" ogs_model.write_input()\n",
" # hide output\n",
" with contextlib.redirect_stdout(None):\n",
- " ogs_model.run_model(logfile=f\"{out_dir}/out.txt\", \n",
- " args=\"-m \" + f\"{data_dir}/Mechanics/PLLC/\")\n",
+ " ogs_model.run_model(\n",
+ " logfile=f\"{out_dir}/out.txt\", args=\"-m \" + f\"{data_dir}/Mechanics/PLLC/\"\n",
+ " )\n",
" pvdfile = vtuIO.PVDIO(f\"{prj_name}.pvd\", dim=3)\n",
" eps_zz = pvdfile.read_time_series(\"epsilon\", points)[\"pt0\"][:, 2]\n",
" eps_zz_dot = np.abs(np.diff(eps_zz)) / np.diff(pvdfile.timesteps)\n",
" # omit the first timestep\n",
" eps_dot += [np.mean(eps_zz_dot[1:])]\n",
- " ax.loglog(1e-6*stresses, eps_dot, 'o', c=col, markeredgecolor=\"k\")\n",
+ " ax.loglog(1e-6 * stresses, eps_dot, \"o\", c=col, markeredgecolor=\"k\")\n",
"\n",
"# plot experimental data points\n",
"for Ex, (temp, m, Data) in ExData.items():\n",
@@ -172,20 +298,23 @@
" ax.loglog(stresses, eps_dot, m, c=Exps[temp][0])\n",
"\n",
"# create legend\n",
- "patches = [mpl.patches.Patch(color=col, label=str(temp) + '°C')\n",
- " for temp, (col, _) in Exps.items() if temp >= 25][::-1]\n",
- "addLeg = lambda **args : patches.append(mpl.lines.Line2D([], [], **args))\n",
- "addLeg(c='k', label='PLLC')\n",
- "addLeg(c='k', ls='--', label='BGRa')\n",
- "addLeg(c='w', ls='None', marker='o', mec=\"k\", label='OGS')\n",
- "addLeg(c='k', ls='None', marker='s', label='DeVries (1988)')\n",
- "addLeg(c='k', ls='None', marker='^', label='WIPP CS')\n",
- "addLeg(c='b', ls='None', marker='P', label='Bérest (2017) 7.8°C')\n",
- "addLeg(c='orange', ls='None', marker='P', label='Bérest (2015) 14.3°C')\n",
- "ax.legend(handles=patches, loc='best')\n",
+ "patches = [\n",
+ " mpl.patches.Patch(color=col, label=str(temp) + \"°C\")\n",
+ " for temp, (col, _) in Exps.items()\n",
+ " if temp >= 25\n",
+ "][::-1]\n",
+ "addLeg = lambda **args: patches.append(mpl.lines.Line2D([], [], **args))\n",
+ "addLeg(c=\"k\", label=\"PLLC\")\n",
+ "addLeg(c=\"k\", ls=\"--\", label=\"BGRa\")\n",
+ "addLeg(c=\"w\", ls=\"None\", marker=\"o\", mec=\"k\", label=\"OGS\")\n",
+ "addLeg(c=\"k\", ls=\"None\", marker=\"s\", label=\"DeVries (1988)\")\n",
+ "addLeg(c=\"k\", ls=\"None\", marker=\"^\", label=\"WIPP CS\")\n",
+ "addLeg(c=\"b\", ls=\"None\", marker=\"P\", label=\"Bérest (2017) 7.8°C\")\n",
+ "addLeg(c=\"orange\", ls=\"None\", marker=\"P\", label=\"Bérest (2015) 14.3°C\")\n",
+ "ax.legend(handles=patches, loc=\"best\")\n",
"\n",
"fig.tight_layout()\n",
- "plt.show()\n"
+ "plt.show()"
]
},
{
@@ -198,7 +327,7 @@
"\n",
"Zill, Florian, Wenqing Wang, and Thomas Nagel. Influence of THM Process Coupling and Constitutive Models on the Simulated Evolution of Deep Salt Formations during Glaciation. The Mechanical Behavior of Salt X. CRC Press, 2022. https://doi.org/10.1201/9781003295808-33.\n",
"\n",
- "Li, Shiyuan, and Janos Urai. Numerical Studies of the Deformation of Salt Bodies with Embedded Carbonate Stringers. Online, print. Publikationsserver der RWTH Aachen University, 2012. http://publications.rwth-aachen.de/record/211523/files/4415.pdf "
+ "Li, Shiyuan, and Janos Urai. Numerical Studies of the Deformation of Salt Bodies with Embedded Carbonate Stringers. Online, print. Publikationsserver der RWTH Aachen University, 2012. http://publications.rwth-aachen.de/record/211523/files/4415.pdf"
]
}
],
diff --git a/Tests/Data/Notebooks/SimplePETSc.ipynb b/Tests/Data/Notebooks/SimplePETSc.ipynb
index 59993379282..34c1fc3519a 100644
--- a/Tests/Data/Notebooks/SimplePETSc.ipynb
+++ b/Tests/Data/Notebooks/SimplePETSc.ipynb
@@ -25,15 +25,17 @@
"cell_type": "code",
"execution_count": 8,
"id": "7962f42f-fd53-4fc1-b966-a8ba924aca6c",
- "metadata": {},
+ "metadata": {
+ "lines_to_next_cell": 2
+ },
"outputs": [],
"source": [
"import os\n",
"\n",
"prj_name = \"square_1e1_neumann\"\n",
- "data_dir = os.environ.get('OGS_DATA_DIR', '../../../Data')\n",
+ "data_dir = os.environ.get(\"OGS_DATA_DIR\", \"../../../Data\")\n",
"prj_file = f\"{data_dir}/EllipticPETSc/{prj_name}.prj\"\n",
- "out_dir = os.environ.get('OGS_TESTRUNNER_OUT_DIR', '_out')\n",
+ "out_dir = os.environ.get(\"OGS_TESTRUNNER_OUT_DIR\", \"_out\")\n",
"\n",
"if not os.path.exists(out_dir):\n",
" os.makedirs(out_dir)\n",
@@ -43,7 +45,8 @@
"! mpirun -np 2 ogs {prj_file} > out.txt\n",
"\n",
"from datetime import datetime\n",
- "print(datetime.now())\n"
+ "\n",
+ "print(datetime.now())"
]
},
{
@@ -80,15 +83,16 @@
"\n",
"pvdfile = vtuIO.PVDIO(f\"{prj_name}.pvd\", dim=2)\n",
"time = pvdfile.timesteps\n",
- "points={'pt0': (0.3,0.5,0.0), 'pt1': (0.24,0.21,0.0)}\n",
+ "points = {\"pt0\": (0.3, 0.5, 0.0), \"pt1\": (0.24, 0.21, 0.0)}\n",
"pressure_linear = pvdfile.read_time_series(\"pressure\", points)\n",
"\n",
"import matplotlib.pyplot as plt\n",
+ "\n",
"plt.plot(time, pressure_linear[\"pt0\"], \"b-\", label=\"pt0 linear interpolated\")\n",
"plt.plot(time, pressure_linear[\"pt1\"], \"r-\", label=\"pt1 linear interpolated\")\n",
"plt.legend()\n",
"plt.xlabel(\"t\")\n",
- "plt.ylabel(\"p\")\n"
+ "plt.ylabel(\"p\")"
]
}
],
diff --git a/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb b/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb
index ea37258df64..2f57bd7e3ae 100644
--- a/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb
+++ b/Tests/Data/Notebooks/thermo-osmosis.run-skip.ipynb
@@ -1,285 +1,317 @@
{
- "cells": [
- {
- "cell_type": "raw",
- "metadata": {},
- "source": [
- "+++\n",
- "author = \"Jörg Buchwald\"\n",
- "date = \"2022-05-27T12:39:58+01:00\"\n",
- "title = \"Thermo-Osmosis in a one-dimensional column\"\n",
- "weight = 70\n",
- "web_subsection = \"thermo-hydro-mechanics\"\n",
- "+++\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## Problem description\n",
- "\n",
- "The problem describes a one-dimensional column at $T$=300 K in sudden contact with a temperature reservoir at one side at $T_1$ = 350 K.\n",
- "\n",
- "Thermo-osmotic and filtration effects are described by contributions to the hydraulic flux $J^w$\n",
- "\\begin{equation}\n",
- "J^w=-\\rho_w \\frac{\\mathbf{k}}{\\mu}\\left(\\nabla p-\\rho_w \\mathbf{g} \\right)-\\rho_w \\mathbf{k}_{pT} \\nabla T,\n",
- "\\end{equation}\n",
- "and the conductive heat flux $I$\n",
- "\\begin{equation}\n",
- "I=- \\mathbf{\\lambda}_s (1-\\phi)+\\mathbf{\\lambda}_w \\phi)- \\mathbf{k}_{Tp} \\nabla p,\n",
- "\\end{equation}\n",
- "\n",
- "where $\\mathbf{k}_{pT}$ is the phenomenological coefficient of thermo-osmosis and $\\mathbf{k}_{Tp}$ the phenomenological coefficient of thermo-filtration. \n",
- "It can be shown that $\\mathbf{k}_{Tp}=T*\\mathbf{k}_{pT}$ (Zhou et al. 1998)."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "## Get benchmark results\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/buchwalj/.local/lib/python3.10/site-packages/vtuIO.py:147: PerformanceWarning: DataFrame is highly fragmented. This is usually the result of calling `frame.insert` many times, which has poor performance. Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`\n",
- " df[\"r_\"+str(i)] = (df[x]-val[x]) * (df[x]-val[x]) + (df[y]-val[y]) * (df[y]-val[y])\n"
- ]
- }
- ],
- "source": [
- "import os\n",
- "import vtuIO\n",
- "import numpy as np\n",
- "\n",
- "filename = \"expected_Column_ts_68_t_7200000.000000.vtu\"\n",
- "data_dir = os.environ.get('OGS_DATA_DIR', '../../Data')\n",
- "file = {}\n",
- "file[\"THM\"] = f\"{data_dir}/ThermoHydroMechanics/Linear/ThermoOsmosis/{filename}\"\n",
- "file[\"TR\"] = f\"{data_dir}/ThermoRichardsFlow/ThermoOsmosis/{filename}\"\n",
- "file[\"TRM\"] = f\"{data_dir}/ThermoRichardsMechanics/ThermoOsmosis/{filename}\"\n",
- "x=np.array([i*0.1 for i in range(200)])\n",
- "r = np.array([[i,0.5,0.0] for i in x])\n",
- "resp = {}\n",
- "respvars = [\"temperature\", \"pressure\"]\n",
- "for model in file:\n",
- " resp[model] = {}\n",
- " f = vtuIO.VTUIO(file[model], dim=2)\n",
- " for var in respvars:\n",
- " if \"M\" in model:\n",
- " resp[model][var] = f.get_set_data(f\"{var}_interpolated\",pointsetarray=r)\n",
- " else:\n",
- " resp[model][var] = f.get_set_data(f\"{var}\",pointsetarray=r)\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Read-in the analytical solution\n",
- "\n",
- "An analytical solution was provided by Zhou et al. 1998 and can be obtained via [github](https://github.com/joergbuchwald/thermo-osmosis_analytical_solution).\n",
- "For this example we used $\\mathbf{k}_{pT}=2.7e-10\\, m^2/(s K)$ and a fully saturated material. More details on model parameters can be found in the corresponding project files.\n",
- "The Thermo-Richards (TR) model uses a correction to account for mechanical effects in the mass-balance equation. See Buchwald et al. 2021 for further details."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "import zhou_solution_thermo_osmosis\n",
- "aTO = zhou_solution_thermo_osmosis.ANASOL(0,50,100)\n",
- "aNoTO = zhou_solution_thermo_osmosis.ANASOL(0,50,100)\n",
- "aNoTO.Sw = 0\n",
- "t=7.2e6\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Plot temperature and pressure along the column"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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FytXrmTcuHHe85177rnccsst3u2PPPIIW7ZsYf78+bRq5frYcOWVV/L4449z8803k56eXqdrPR6eWgjf+3Trrbfy1FNPceutt/LWW29VKD9u3Dj69u0LwNSpU5k1axafffYZgwYNatS4RZoDJQ9+JCoxgbibb2T1mjdp1+0w2Z+9x8g5s4lK1GzTIiIeERER3HbbbXz66aeUlJQQEBDA+vXradu2bZXlBw4c6H3evn17AHbt2kWvXr0ACA0N5ZprrmHVqlWUl5djjGHfvn1s2LChxjiMMVxyySXcf//97N+/n3bt2vHpp58SHx9Phw4d6nRtH3zwAUOGDCE8PLzC+s8++8z7vHXr1jz11FO8+uqrHDhwgFatWrFjxw72799fp3Oefvrp3HXXXWzevJlLL72UUaNGce+993q3f/jhh3Tt2tV7vzxOPPFEnnnmGXbu3EmXLl3qdO66+vDDDxkyZAhhYWHedUFBQQwdOpQPP/wQa603qYCqfwd27tzZeAGLNCNKHvxISmYqb2T9h8kH2tGuG5T2CmRm1kIuDDiXafETnQ5PRJqRunzj7w/Ky8uZNGkSBw4c4P3336dnz54AjBkzhqKioir38f0g7vn23tM/4PDhw4wdO5aePXvy8ccf065dOwD69OlT7fF8XXrppcybN4/XXnuNq6++mhdffJHLLruszte3Z88ehg0bVmOZ2267jb/97W989NFHnHzyyYDrm/i77rqrTud84403eOihh3j++ed5+umn6d27N7fffjszZszwxuS5L748H8L37NnT6MlDdfepffv2FBQUkJ+fX2F0ppp+B0Tk2KjDtB+ZFj+RZ+Oupdf3BwDo0L6IhQNnKXEQEXFbv349K1as4He/+503cTgeX375JTk5OVx33XVVfkA+mpiYGEaNGsXLL79Mfn4+n376Keeee26d4+nYseNRaxBeeuklzjzzTG/icLzCw8O544472LRpEx999BHR0dFcddVVfPjhh96Y9u3bd8R+nnUdO3as8fgBAQFYayusO3z48HHFXFNMYWFhR9TciEj9UfLgR3LTM8iev4Ckq6/m4OFQgoLKSHv1n+SmZzgdmoiIX/DUBvg2SQHYsWNHvR2vvLyc3bt31/oYl112GcuXL+fBBx/k3HPPJTg4uML2oKAg74fnw4cPH9Ee39eZZ57J2rVrKSgoqLB+2rRpfPrpp96Y6+v6AS666CLAdQ/GjRvHsmXLALx9Gc444wx27tzJzz//XGG/VatWkZCQcNRah86dO1dIiPbu3cvevXuPKHcs9+mMM85g7dq15Of/MidSaWkpaWlpnHHGGUfcHxGpP0oe/Eje+hxi3X0cdhe42u4GnRhD3nrNOC0iAjBo0CD69evHokWLvB9IX3/9dbKzs+t0vJNPPpmoqCgWLlxIYWEhAA8//HCFD6VHM336dIKDg7nnnnuqbLLUt29f9uzZQ1FREcuXL+eGG26o9lhz584lICCAuXPnej9I/+Mf/2DNmjWMHOma++fcc8/lgw8+ICPD9cXSDz/8wGuvvVbreCt79dVXWbJkiff1F198QWBgIKeffjoAN954Iz179mTOnDmUlpYCrtqP7777joceeuioxx89ejQffPCBd6jZRx55hMjIyCPKHct9uvPOOzHGcPvtt3vv01//+lcOHTpUob+GiDQAJ4d6ak6P+hiq1VfWmq/t6vdvtp8tm1evxxWRlqe5DdWamZlpx44da7t06WJHjx5tb7jhBjts2DAbERFhk5KSbFFRkb344ottly5dLGCTkpJsenq6ve+++2yvXr0sYOPi4uzrr79urXUNuTpixAjbvXt3O2bMGHvXXXfZHj162Hbt2tnx48fbrVu32qSkJBsREeE9x86dOyvENGXKFDtw4MAq4925c6cdM2aMHTBggB0yZIj997//bd977z2blJRkAdulSxc7adIkb/m1a9fac8891/bu3dsmJSXZ8847z+bk5Hi379u3z1522WW2S5cudtSoUXbatGn2sssu817rl19+aX/3u99VuNbnnnuu2vv5wAMP2BEjRtjExESbmJhoTzzxRLts2bIKZTZt2mSnT59ue/XqZfv162dPOukk+8EHH3i3P/XUUzYuLs4CtlevXnbWrFnebT///LMdP3687dGjhx0zZox99913bXR0tG3Xrp31fe881vuUkZFhzznnHNu7d28bHR1tzzjjDLt69Wrv9ldffbVCTPfcc49du3ZtheNdeuml1d4XESf581CtxlZqhyh1M3z4cLt69ep6O15xYSFpn9xJYGA5/YbOoV2nzvV2bBFpWbKysoiLi3M6jGZt3rx5BAYGcuuttzodiog0A7X4v+1Y2zw1W/JTwaGhFBS7Eoafvv/2KKVFRMRJS5cu5ZJLLnE6DBGRBqfkwY+FtxkAwKF9PzgciYiIVDZ69GiKior4/PPP6datG9HR0U6HJCLS4JQ8+LGwHa6h7EJabeeOpYsA14hMW5YsczAqEREB1+hEgwYN4qabbuKRRx5xOhwRkUahSeL8WM8h8WSsX0t4ZBEle7O9Q7nGzpntdGgiIi2eZ+hUEZGWRDUPfiwqMYEy2w2AofnB3sQhKjHB4chEREREpCVS8uDHUjJT+fTwNgA6t7d82buUmVkLSclMdTgyEREREWmJ1GzJj02Ln8iuom5s3JVC66hChu+O5Ldx1xIVr5oHEREREWl8qnnwY7npGfz06BPk57cDIGTSGLLnLyA3PcPhyERERESkJVLy4Mfy1ucQO2c24e0GAVBkdxM7ZzZ563McjkxEREREWiI1W/JjPadOAaD35jZszfqS4MCttB4yWB2mRURERMQRqnloAjr36EVhYRhBQaX8/GOW0+GIiIiISAvVbJMHY8wSY4w1xnzqdCzHKyAggPKA3gBs35TucDQiIi3Ltm3bSE5OJjIykjFjxjgdTq3MmDGD3r17Y4xh48aNDX6+p59+msGDB2OMYfHixQ1+vuburbfeIjk5GWMMc+fOdTockQr8LnkwxvQxxlxnjHnPGLPdGFNijDlkjEkzxtxtjGlXi2NMAc4/hnNOMsZ8YozJdZ9rpTHm8uO5jvrWodtgAEoLNzobiIhIC9O9e3fS0tIYPnx4nfZftmwZjz766BHr16xZQ/v27fn666+PM8IjPf/888ybN6/ej1udq6++mnfeeee4juHEffIHixcvPiLhmjx5MmlpaY7EI3WXmppKp06d2Lx5s9OhNCi/Sx6AlcCjwFpgMhADTAAygNuAb4wxHavb2RjTBngC+Lk2JzPG3A68BewDxgAnAmnAYmPMc3W8hnrXLy6Z8nJDeOh+Du7f53Q4IiJSS9V9KI6IiCA6OpqIiIjGD8oPtdT7VFXyIE1TmzZtiI6OJiQkxOlQGpQ/Jg8AC621N1lrV1lrN1lrV1hrLwX+B/QFrq5h3/uBMuDBo53EGDMamAesAaZZa9OstVnW2quBt4EZxpjLjvtq6sGe9/7L4cPtMAb+9c4rgGso1y1LljkbmIiI1MnAgQNZs2YNQ4YMcToUv6b7JE3F6aefzurVq+ncubPToTQof0weZgEPVLPtG/eyyp+KMeZkXInFtcDhWpzrTvfyMWttWaVtC9zLO2pxnAYXGdOfog35ALQ3e8lNzyB7/gIiY/o7HJmISOP65JNPmDRpEieccAJJSUmMHDnyiCYz55xzDl27dsUYw6pVqzjrrLPo06cPo0aNYu3atRXKvvnmm4wfP57hw4eTmJjImDFjWLlyZY0x/POf/6RHjx4YY4iPj2fp0qUAPPnkk/Tr14/27dszb948zjrrLN566y1vv4nk5GTuv/9+3n///WrbtK9bt45JkyYRHR1NUlISJ554Ivfffz95eXkAbNiwgd/+9rckJyczdOhQkpOTefjhhykrq/w2Vjtbt25l+vTpJCYmMnToUEaNGsUDD1R8G968eTMXXXQR0dHR9O/fn5NPPpmPPvqoxuN+/vnnR1xjbm4uycnJBAcHc8UVV3jL1uU+ZWZmMnHiRPr06UPfvn2ZMGEC3377rXe7bz+MJ598kpkzZ5KUlESfPn144oknjnpfkpOTad++PX369OHdd99l3Lhx9OzZkzPPPJMtW7ZUKFteXs4DDzzAwIEDiY2NJSYmhrlz51JaWlrt8cvKykhOTmb16tWsXr3ae90vvfTSEeX+9Kc/MWzYMHr27Mmtt956xLF+/vlnpk2bRnR0NDExMYwdO7ZCMy/fe7Fw4UJmzZrFsGHDCAwM5IYbbqjQR+bDDz9k0qRJ9O3blxNPPJGMjAy2b9/OtGnT6N+/PyNHjmTdunVHxPD3v/+d+Ph4YmNj6dOnDzfccAOHD9fmo5irj8eIESMYMGAA0dHRXHnllezatatCmcWLFzN06FCGDh1KYmIil156qbdpV+Xru+qqq4iPj6dfv368/vrrlJaWMnv2bBITE+nfvz9Lliw5IoYvvviC0aNH069fP6Kjo7ngggvIyak4NP5//vMfRo4cyQknnEBiYiJTp07l008/BWDRokVV9vupzd9Xk2OtbRIPwACfAxaYUsX2YFxNnVLcr69wl/20muN1xlVDYYFeVWwPAgrd24cdLb5hw4bZhpb9yUd29fs32y/f+rNdcckVdv936Q1+ThFp+tatW+d0CPVq1qxZ9pZbbrHl5eXWWmu//PJLGxYWZletWlWh3J133mkBe91119mysjJbUlJiTz/9dHvSSSdVKHfWWWfZZ555xvv6jTfesBEREfbnn3+uUG706NF29OjR3teff/65BezSpUsrlLvlllvsE0884X19+eWX2+jo6CqvBbB33nmn9/X69ettVFSUnT17tvf6lixZYo0xds2aNdZaa//1r3/ZsWPH2oKCAmuttdu3b7cDBgywDz/8cIVjL1q0yAL2p59+qvLcHuPHj7dXXXWV93ypqanW9fHAZc+ePbZXr152+vTptqSkxFpr7QsvvGADAwPt+++/7y33008/WcAuWrSoxmu01tro6Gh7+eWXV1h3LPfpxx9/tG3atLE33XSTN+4777zTRkRE2PT0X94bPTElJCTYDRs2WGutfeaZZ6wxxmZlZdV4XzwxtWnTxt5+++3WWmsPHTpkBw4caC+66KIK5a655hrbtWtXm52d7T1v79697aWXXnrUc1T+vap83dHR0Xb16tXWWmvff/99C1S4756fz3nnnWeLi4uttdbOnz/fhoeHV7hGz72IjY21GRkZ1lprH374YXv99ddba3/5fZk+fbotLCy0JSUl9rTTTrMJCQn2jjvu8K475ZRT7CmnnFIhzgceeMBGRETY5cuXW2ut3bt3rx06dKgdM2aMLSsrq/H6X331VRsYGGiXLVtmrbW2oKDAnnXWWTYuLs7m5eVZa6397LPPbEhIiM3JybHWWpuXl2dHjx5d4XfCc32JiYl206ZN1lpr//KXv9igoCB7++23e9f98Y9/tBEREXb//v3efT///HMbHBxsH3vsMWuttWVlZfbKK6+0Xbp0sdu2bbPWuv42g4OD7RdffGGttba4uNhedNFFFX6Pq/obONrfV3Vq8X/bsc/kfj/PgzEmBBgEzAFOAu611i6rouifgR7A+FoeehiumpfD1tojerZYa0uMMRuAOGAEv9R6OCIlM5U3dvyH68LaExZWzKpBbViQtZALA85lWvxEJ0MTkSbom//OcToEAIZNmH/M+9xyyy106tQJYwwAJ598MomJifz973+vslPzlVdeSUBAAAEBAUyaNIk5c+ZQVFTkbZf8+OOP069fP2/5Cy64gN///ve88sor/OlPf6o2jlNOOYV+/frx8ssvM2XKFMD1hVxKSspRay6qM3fuXMrKyrj77ru913f++edz6qmnEhDgaixw1llnMW7cOEJDQwHo2rUrU6dO5bnnnmP27NnHfM6VK1cybtw47/nOPfdcbrnlFu/2Rx55hC1btjB//nxatXJ9bLjyyit5/PHHufnmm0lPb/xRAD21EL736dZbb+Wpp57i1ltv5a233qpQfty4cfTt2xeAqVOnMmvWLD777DMGDRp01HMdOnSIG264AYDIyEjOPPPMCt9c//jjjzz99NPcfffdDBw4EIA+ffpw0003cf3113PDDTdwwgkn1Plak5OTGTZsGAATJkwgMjKSTz/9lAkTJgCun8/mzZv5+OOPCQoKAuDGG2/k0Ucf5f777z+iP8X48eOJj48HYNasWRw6dKjC9osvvtj7t3Heeedx8803c88993jXTZkyhT/+8Y8UFxcTHBzMgQMHuOuuu7j44os56aSTAGjfvj1z587lvPPOY9myZUydOrXKa7PWMmfOHMaOHct5550HQGhoKA8++CBJSUk888wzzJ49m6+++oqQkBC6d+8OuPrB3H333VXWbIwfP57evV0jVF5wwQXcd9995OXledf96le/4sEHH2TVqlWceeaZAPz5z3+md+/e/OEPfwBco1w++OCD/POf/+S+++7jscceY82aNRQXF3t/j4KCgrj11lv57rvvavz5He3vqynyx2ZLXsaYFbi+/U/DlUCcYq29rYpyg4BbgD9Za3fU8vCe9j47ayiz3b3sV0OZRjEtfiLPDr6W/B2ufwx9wtvybNy1ShxEpMWJiIjgtttuY9iwYSQmJpKcnExmZiYbNmyosrznAx24PtQAFZpEhIaGcs011zB06FCSkpJITk5m37591R7PwxjDJZdcQmpqKvv37wfg008/JT4+ng4dOtTp2j744AOGDBlCeHh4hfWfffYZiYmJALRu3ZrXXnuNU045hfj4eJKTk1m8ePFR463O6aefzl133cU111zD8uXLKS8v59577/Vu//DDD+natSu9evWqsJ+nScvOnTW9jTaMDz/8kCFDhhAWFuZdFxQUxNChQ/nwww89LQi8qvodqG3cHTt29O7j2d93348++ghrLSNGjKiw34knngi4fqbHwzd2gHbt2lU4/4cffkjnzp2JiYnxrgsMDGTQoEHeJjW+4uLivM8jIiLo2rVrhe2+x/Fct++6Dh06YK31xrBixQry8/PrdP3Z2dls3rz5iH0TExMJDQ317nvqqaeSl5fHiSeeyLPPPsvu3bs57bTTOPvss484Zm3iB9ixw/VxMT8/nxUrVhwRQ8eOHenbt683hhEjRhAWFsYpp5zCggUL2Lx5M0OGDOHiiy+u9vrg6H9fTZG/1zxMA1oDscD1wHJjzF+BO6215QDGlco9i6tm4NljOHYb9zK/hjIF7mXbYwm6IXj6OHT49URgJWHRwWTPX0DsnNmacVpEjlldvvH3B+Xl5UyaNIkDBw7w/vvv07NnTwDGjBlDUVFRlfv4fhD3fHvv6R9w+PBhxo4dS8+ePfn4449p1841GnifPn2qPZ6vSy+9lHnz5vHaa69x9dVX8+KLL3LZZXUfZ2PPnj3eb5mrc9ttt/G3v/2Njz76iJNPPhlwfRN/11131emcb7zxBg899BDPP/88Tz/9NL179+b2229nxowZ3pg898WX54PZnj176NKlS53OXVfV3af27dtTUFBAfn5+hdGZavodOJrKiVxAQADl5eUVYgGOuEe+9+d4VHV+39j37NnDwYMHSU5OrlAuNzf3iCQKXLUntT2f59vyqtZ5Yqjt9c+YMYPVq1d7tz///PMUFhZWua9nnWffUaNG8b///Y8HHniA3//+91x77bWcd955PPbYY/To0eO44t+3bx/l5eXV/o7/+OOPAERHR/PVV19x3333ceutt3LTTTcxbtw4Hn/8cQYPHnzEvh5H+/tqivy65sFau9lau85auxQYB6zANVyr70hKM4FRwExb1V/J8TGeUKrcaMxMY8xqY8zq3bt31/OpK8pbn0PsnNnEjZ5AebkhIuIAvf7f1eStzzn6ziIizcT69etZsWIFv/vd77yJw/H48ssvycnJ4brrrqvyw8PRxMTEMGrUKF5++WXy8/P59NNPOffcc+scT8eOHb21GNV56aWXOPPMM72Jw/EKDw/njjvuYNOmTXz00UdER0dz1VVX8eGHH3pj2rfvyCHCPes6dqx29HTA9WG38ttzbTvSVqemmMLCwo74wN2QPNdfOZ7a3p/6OH+3bt1IS0ur8Ni4cSObNm1q0HN7zg9Hv/7nn3++QnzDhw+vdl+A/fv3V7h3p556Km+//TZbtmxh3rx5vPvuu0yfPv2442/fvj0BAQHV/j75xpCQkMArr7zCjh07ePLJJ0lLS+Pss8+ukExWdrS/r6bIr5MHX+6aBs/XKn8wxkQZY7rhGpnpAWvt2ur3rtJB97Km/zChlcpWjulZa+1wa+3wTp06HePpj03PqVOISkwgPLI1+YUdMAb22Hx6Tp3SoOcVEfEnntoAz7eHHp4mCPVxvPLyco7lC6HLLruM5cuX8+CDD3LuuecSHBxcYXtQUJD3w/Phw4ePaI/v68wzz2Tt2rUUFBRUWD9t2jRvE5SioqJ6u36Aiy66CHDdg3HjxrFs2TIAb1+GM844g507d/LzzxWnT1q1ahUJCQlHrXXo3LlzhYRo79697N2794hyx3KfzjjjDNauXUt+/i+NB0pLS0lLS+OMM8444v40pPHjx3tH9fLlee1pV18d3+vevXv3MX+o9Iz+VPnD7/vvv8/tt99+TMeqi5NOOonw8PA6XX9sbCy9evU6Yt+MjAwKCwu9+77yyiu8/fbbAHTp0oVbbrmFGTNm1Et/m/DwcE466aQjYti7dy8//fSTN4aPPvqI559/HoC2bdty7bXXcuutt7J582Zyc3OrPf7R/r6aoiaTPLhluJfBwFBck8e1BW4yxuT5PoCn3WVP81nvm2B4vrKv6b9eN/eybg1JG0hIpKu7Ru7u7x2ORESkcQ0aNIh+/fqxaNEi7wfS119/nezs7Dod7+STTyYqKoqFCxd6m1A8/PDDFT6UHs306dMJDg7mnnvuqbLJUt++fdmzZw9FRUUsX77c2/m2KnPnziUgIIC5c+d6P1D+4x//YM2aNYwcORJwdbj84IMPyMhwvSX+8MMPvPbaa7WOt7JXX321QgfgL774gsDAQE4//XTA1fm2Z8+ezJkzxzv06EsvvcR3333HQw89dNTjjx49mg8++MA71OwjjzxSZdOZY7lPd955J8YYbr/9du99+utf/8qhQ4cavT35gAEDuPrqq3nyySf54YcfANfQqQsWLODSSy89amfpvn37snXrVqy1LFu2jL/+9a/HdP4bb7yR7t27c8MNN1BcXAy4hta9/vrrSUpKqttFHYO2bdty55138uqrr7JixQrAVWswd+5cxowZ4x1MoCrGGObPn88nn3zi/VBdWFjIn/70JwYNGsSsWbMA1+/4Aw88wMGDru9yCwoK+Pbbbxk3bly9XMP999/Pzz//zGOPPQa4vkD485//TLt27fjLX/4CuO7pAw884O3rUVpayldffUViYmKFPjGVHe3vq0lycqinyg9cfRsuq2F7G1xNiCxwFq7+EDHVPP7oLveVz7pon2PVZqjWAvf24UeLvTGGavX4OecH15Ctb99y1CHQRESa21CtmZmZduzYsbZLly529OjR9oYbbrDDhg2zERERNikpyRYVFdmLL77YdunSxQI2KSnJpqen2/vuu8/26tXLAjYuLs6+/vrr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",
- "text/plain": [
- "
\n\n"""
+ second_cell.source = text + second_cell.source
- for cell in nb["cells"]:
- # Check frontmatter has its own cell
- if (
- cell.cell_type == "markdown"
- and cell.source.startswith("+++")
- and not cell.source.endswith("+++")
- ):
- print(
- f"Error: {notebook_filename} notebook metadata is not a separate cell (in markdown: separate by two newlines)!"
- )
- success = False
- # Get first regular markdown cell
- if cell.cell_type == "markdown" and not cell.source.startswith("+++"):
- first_markdown_cell = cell
- break
-
- first_markdown_cell.source = text + first_markdown_cell.source
nbformat.write(nb, f)
status_string = ""
From cba134db414aecc674bb799b0ecce5c6a1bad755 Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 12:50:03 +0200
Subject: [PATCH 6/8] [nb] Removed nb2hugo dependency.
---
Tests/Data/requirements-dev.txt | 1 -
scripts/docker/Dockerfile.web | 2 +-
web/.gitignore | 2 +-
.../documentation/jupyter-docs/index.md | 4 ++--
.../userguide/basics/jupyter-notebooks/index.md | 1 -
web/data/versions.json | 1 -
web/package.json | 1 -
web/scripts/convert_notebooks.py | 17 +++++++++++++----
8 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/Tests/Data/requirements-dev.txt b/Tests/Data/requirements-dev.txt
index e04f5bd31f8..3d158732b79 100644
--- a/Tests/Data/requirements-dev.txt
+++ b/Tests/Data/requirements-dev.txt
@@ -1,4 +1,3 @@
-git+https://github.com/bilke/nb2hugo@f9744903ed17d46afb3877ffe244420a50aaecc6#egg=nb2hugo
nbconvert==7.2.9
nbformat==5.7.3
toml==0.10.2
diff --git a/scripts/docker/Dockerfile.web b/scripts/docker/Dockerfile.web
index 67c8511717b..df4ced3d635 100644
--- a/scripts/docker/Dockerfile.web
+++ b/scripts/docker/Dockerfile.web
@@ -18,4 +18,4 @@ ENV HUGO_VERSION=0.117.0
RUN curl -fSL -O "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb" \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y /hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& rm /hugo_extended_${HUGO_VERSION}_linux-amd64.deb
-RUN pip install git+https://github.com/bilke/nb2hugo@f9744903ed17d46afb3877ffe244420a50aaecc6#egg=nb2hugo
+RUN pip install nbconvert
diff --git a/web/.gitignore b/web/.gitignore
index d0b7de38029..96a23300b6c 100644
--- a/web/.gitignore
+++ b/web/.gitignore
@@ -17,6 +17,6 @@ data/bibliography.json
# generated css
static/css/all.css
-# Generated by nb2hugo
+# Generated by nbconvert
content/docs/benchmarks/notebooks
static/docs/benchmarks/notebooks
diff --git a/web/content/docs/devguide/documentation/jupyter-docs/index.md b/web/content/docs/devguide/documentation/jupyter-docs/index.md
index a645379353a..d88b4e67717 100644
--- a/web/content/docs/devguide/documentation/jupyter-docs/index.md
+++ b/web/content/docs/devguide/documentation/jupyter-docs/index.md
@@ -55,10 +55,10 @@ Make sure that you execute the cells in the notebook and save the notebook (with
To get a preview of the web page run the `convert_notebooks`-script:
```bash
-# You need the converter-tool nb2hugo installed. Recommended way is to
+# You need the converter-tool nbconvert installed. Recommended way is to
# create and activate a virtual environment and install it there:
python -m venv .venv # or `python3 -m ...` on some systems
-pip install git+https://github.com/bilke/nb2hugo@ogs
+pip install nbconvert
python web/scripts/convert_notebooks.py
diff --git a/web/content/docs/userguide/basics/jupyter-notebooks/index.md b/web/content/docs/userguide/basics/jupyter-notebooks/index.md
index 283fdffeddb..cf93d3847d7 100644
--- a/web/content/docs/userguide/basics/jupyter-notebooks/index.md
+++ b/web/content/docs/userguide/basics/jupyter-notebooks/index.md
@@ -38,7 +38,6 @@ Image `registry.opengeosys.org/ogs/ogs/ogs-serial-jupyter` contains:
- Jupyter-related tools:
- [nbconvert](https://nbconvert.readthedocs.io) — Format conversion
- [nbdime](https://nbdime.readthedocs.io) — Diffs for notebooks
- - [nb2hugo](https://github.com/bilke/nb2hugo/tree/ogs) — Notebook to website markdown conversion
- [Gmsh](https://gmsh.info) — Mesh generator (incl. Python bindings)
Image `registry.opengeosys.org/ogs/ogs/ogs-petsc-jupyter` additionally contains:
diff --git a/web/data/versions.json b/web/data/versions.json
index 6eda2385be2..43efacea260 100644
--- a/web/data/versions.json
+++ b/web/data/versions.json
@@ -59,7 +59,6 @@
"git+https://github.com/joergbuchwald/ogs6py@71f49a896381152e648801740833450022115981#egg=ogs6py",
"git+https://github.com/joergbuchwald/VTUinterface@05793c7be84fbcb7d9f8f740c3dc667089a61505#egg=VTUinterface",
"git+https://github.com/joergbuchwald/heatsource_thm@main#egg=heatsource-py",
- "git+https://github.com/bilke/nb2hugo@53d62ae5aef1be271eb91491d3b37da487bd1498#egg=nb2hugo",
"ogstools==0.0.3",
"ipykernel==6.9.1",
"jinja2==3.0.3",
diff --git a/web/package.json b/web/package.json
index 38588e883e9..b15691e5de5 100644
--- a/web/package.json
+++ b/web/package.json
@@ -3,7 +3,6 @@
"scripts": {
"build": "npx tailwindcss -o static/css/all.css -i assets/css/main.css -m && hugo",
"watch": "npx tailwindcss -o static/css/all.css -i assets/css/main.css -m --watch",
- "build-with-nb": "find ../Tests/Notebooks -type f -iname '*.ipynb' -not -path \"*.ipynb_checkpoints*\" | xargs -n1 nb2hugo --site-dir . --section docs/benchmarks/notebooks --template ../Tests/Notebooks/nbconvert_templates/collapsed.md.j2 && npx tailwindcss -o static/css/all.css -i assets/css/main.css -m && hugo",
"server": "hugo server",
"index": "hugo-algolia -toml",
"upload-index": "hugo-algolia --toml -s"
diff --git a/web/scripts/convert_notebooks.py b/web/scripts/convert_notebooks.py
index 19237c167b7..c1cc55c6ba1 100644
--- a/web/scripts/convert_notebooks.py
+++ b/web/scripts/convert_notebooks.py
@@ -16,11 +16,20 @@
)
exit_code = 1
continue
- print(f"Converting {notebook} ...")
+ template = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "../../Tests/Data/Notebooks/nbconvert_templates/collapsed.md.j2",
+ )
subprocess.run(
- f"nb2hugo --site-dir .. --section {nb.parent.parent} {notebook}",
- shell=True,
- check=True,
+ [
+ "jupyter",
+ "nbconvert",
+ "--to",
+ "markdown",
+ f"--template-file={template}",
+ "--output=index",
+ notebook,
+ ]
)
sys.exit(exit_code)
From 6d473c994232a762b41186ae5f980c43043b0940 Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 13:27:15 +0200
Subject: [PATCH 7/8] [ci] On web only pipelines run notebook benchmarks only.
---
scripts/ci/extends/template-build-linux.yml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scripts/ci/extends/template-build-linux.yml b/scripts/ci/extends/template-build-linux.yml
index 1066bb556fe..ee5ab676da3 100644
--- a/scripts/ci/extends/template-build-linux.yml
+++ b/scripts/ci/extends/template-build-linux.yml
@@ -76,6 +76,10 @@
ctest_arguments="${ctest_arguments} -LE large"
fi
+ if [[ "$CI_MERGE_REQUEST_LABELS" =~ [.*web\ only.*] ]]; then
+ ctest_arguments="${ctest_arguments} -R nb-"
+ fi
+
if [[ ! -z "$CTEST_TIMEOUT" ]]; then
ctest_timeout="$CTEST_TIMEOUT"
fi
From 461d28016da2b46e8dac1526d0c93bd4e6681d11 Mon Sep 17 00:00:00 2001
From: Lars Bilke
Date: Thu, 12 Oct 2023 14:11:05 +0200
Subject: [PATCH 8/8] [ci] Add check=True to subprocess.run.
---
Tests/Data/Notebooks/testrunner.py | 3 ++-
web/scripts/convert_notebooks.py | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/Tests/Data/Notebooks/testrunner.py b/Tests/Data/Notebooks/testrunner.py
index f35386c2b54..3cc73eb667f 100644
--- a/Tests/Data/Notebooks/testrunner.py
+++ b/Tests/Data/Notebooks/testrunner.py
@@ -47,7 +47,8 @@ def save_to_website(exec_notebook_file, web_path):
"--output=index",
output_path_arg,
exec_notebook_file,
- ]
+ ],
+ check=True,
)
if not "Tests/Data" in exec_notebook_file:
diff --git a/web/scripts/convert_notebooks.py b/web/scripts/convert_notebooks.py
index c1cc55c6ba1..2663be46ec3 100644
--- a/web/scripts/convert_notebooks.py
+++ b/web/scripts/convert_notebooks.py
@@ -29,7 +29,8 @@
f"--template-file={template}",
"--output=index",
notebook,
- ]
+ ],
+ check=True,
)
sys.exit(exit_code)