-
-
Notifications
You must be signed in to change notification settings - Fork 166
Add fenicsx and simplified Landlab solvers #889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
joargu
wants to merge
21
commits into
precice:develop
Choose a base branch
from
joargu:develop
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 12 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
59f942f
Add files via upload
joargu 523bb41
Change order of positions
joargu e1f50aa
Use one mesh for read and write
joargu 7b317e8
Change order of positions
joargu e7d3a33
Add fenicsx and simplified Landlab solvers
joargu 3da0c2d
Merge branch 'precice:develop' into develop
joargu aa045df
Delete wolf-sheep-soil-creep/solver-fenicsx directory
joargu 942a8ad
Delete wolf-sheep-soil-creep/soil-creep-fenicsx directory
joargu 92ed024
Combine solver-fenicsx and soil-creep-fenicsx
joargu 5b6f010
Clarify boundary comment
joargu 00c74f0
Add alpha variable for description
joargu 7d3f1e3
Clarify internal stability substeps with comments
joargu 39969a5
Merge branch 'precice:develop' into develop
joargu 06a2b44
Add FEniCSx to README
joargu b593136
Update keywords in README
joargu 67fe19e
Add simplified Landlab to README
joargu 0c8c9d7
Fix ALPHA variable reference in simplified Landlab
joargu 33af58a
Fix diffusion equation comment
joargu 24e1dcb
Make clean and run scripts executable
joargu f7f7634
Add Python bindings to requirements
joargu 0f9c76b
Clarify boundary comment
joargu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file modified
BIN
-10.5 KB
(89%)
wolf-sheep-soil-creep/images/tutorials-wolf-sheep-soil-creep-precice-config.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,69 +1,61 @@ | ||
| <?xml version="1.0" encoding="UTF-8" ?> | ||
| <precice-configuration> | ||
|
|
||
| <log> | ||
| <sink | ||
| filter="%Severity% > debug" | ||
| format="---[precice] %ColorizedSeverity% %Message%" | ||
| enabled="true" /> | ||
| </log> | ||
|
|
||
|
|
||
| <data:scalar name="Grass" /> | ||
| <data:scalar name="Soil" /> | ||
|
|
||
| <mesh name="Wolf-Sheep-Grass-Mesh" dimensions="2"> | ||
| <use-data name="Grass" /> | ||
| <use-data name="Soil" /> | ||
| </mesh> | ||
|
|
||
| <mesh name="Soil-Creep-Mesh" dimensions="2"> | ||
| <use-data name="Grass" /> | ||
| </mesh> | ||
|
|
||
| <mesh name="Soil-Grass-Mesh" dimensions="2"> | ||
| <use-data name="Soil" /> | ||
| </mesh> | ||
|
|
||
| <mesh name="Soil-Depth-Mesh" dimensions="2"> | ||
| <use-data name="Soil" /> | ||
| </mesh> | ||
|
|
||
| <participant name="Wolf-Sheep-Grass"> | ||
| <receive-mesh name="Soil-Depth-Mesh" from="Soil-Creep" /> | ||
| <receive-mesh name="Soil-Creep-Mesh" from="Soil-Creep" /> | ||
| <provide-mesh name="Wolf-Sheep-Grass-Mesh" /> | ||
| <provide-mesh name="Soil-Grass-Mesh" /> | ||
| <write-data name="Grass" mesh="Wolf-Sheep-Grass-Mesh" /> | ||
| <read-data name="Soil" mesh="Soil-Grass-Mesh" /> | ||
| <read-data name="Soil" mesh="Wolf-Sheep-Grass-Mesh" /> | ||
| <mapping:nearest-neighbor | ||
| direction="read" | ||
| from="Soil-Depth-Mesh" | ||
| to="Soil-Grass-Mesh" | ||
| from="Soil-Creep-Mesh" | ||
| to="Wolf-Sheep-Grass-Mesh" | ||
| constraint="consistent" /> | ||
| </participant> | ||
|
|
||
| <participant name="Soil-Creep"> | ||
| <receive-mesh name="Wolf-Sheep-Grass-Mesh" from="Wolf-Sheep-Grass" /> | ||
| <provide-mesh name="Soil-Creep-Mesh" /> | ||
| <provide-mesh name="Soil-Depth-Mesh" /> | ||
| <read-data name="Grass" mesh="Soil-Creep-Mesh" /> | ||
| <write-data name="Soil" mesh="Soil-Depth-Mesh" /> | ||
| <write-data name="Soil" mesh="Soil-Creep-Mesh" /> | ||
| <mapping:nearest-neighbor | ||
| direction="read" | ||
| from="Wolf-Sheep-Grass-Mesh" | ||
| to="Soil-Creep-Mesh" | ||
| constraint="consistent" /> | ||
| </participant> | ||
|
|
||
|
|
||
| <m2n:sockets acceptor="Wolf-Sheep-Grass" connector="Soil-Creep" exchange-directory=".." /> | ||
|
|
||
|
|
||
| <coupling-scheme:serial-explicit> | ||
| <participants first="Soil-Creep" second="Wolf-Sheep-Grass" /> | ||
| <time-window-size value="2" /> | ||
| <max-time value="100" /> | ||
| <exchange | ||
| data="Grass" | ||
| mesh="Wolf-Sheep-Grass-Mesh" | ||
| from="Wolf-Sheep-Grass" | ||
| to="Soil-Creep" | ||
| initialize="true" /> | ||
| <exchange data="Soil" mesh="Soil-Depth-Mesh" from="Soil-Creep" to="Wolf-Sheep-Grass" /> | ||
| <exchange data="Grass" mesh="Wolf-Sheep-Grass-Mesh" from="Wolf-Sheep-Grass" to="Soil-Creep" initialize="true"/> | ||
| <exchange data="Soil" mesh="Soil-Creep-Mesh" from="Soil-Creep" to="Wolf-Sheep-Grass" /> | ||
| </coupling-scheme:serial-explicit> | ||
|
|
||
| </precice-configuration> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #!/usr/bin/env sh | ||
| set -e -u | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| cd "$SCRIPT_DIR" | ||
|
|
||
| rm -rfv ./output/ | ||
|
|
||
| . ../../tools/cleaning-tools.sh | ||
|
|
||
| clean_fenicsx . |
19 changes: 19 additions & 0 deletions
19
wolf-sheep-soil-creep/soil-creep-fenicsx/precice-adapter-config.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "participant_name": "Soil-Creep", | ||
| "precice_config_file_path": "../precice-config.xml", | ||
| "interfaces": [ | ||
| { | ||
| "mesh_name": "Soil-Creep-Mesh", | ||
| "write_data": [ | ||
| { | ||
| "name": "Soil" | ||
| } | ||
| ], | ||
| "read_data": [ | ||
| { | ||
| "name": "Grass" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } |
|
joargu marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| numpy >1, <2 | ||
| fenicsxprecice~=1.0 | ||
| matplotlib>=3,<4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #!/usr/bin/env bash | ||
| set -e -u | ||
|
|
||
| . ../../tools/log.sh | ||
|
|
||
| exec > >(tee --append "$LOGFILE") 2>&1 | ||
|
|
||
| if [ ! -v PRECICE_TUTORIALS_NO_VENV ]; then | ||
|
|
||
| if [ ! -d ".venv" ]; then | ||
| python3 -m venv --system-site-packages .venv | ||
| source .venv/bin/activate | ||
| pip install -r requirements.txt && pip freeze > pip-installed-packages.log | ||
| else | ||
| source .venv/bin/activate | ||
| fi | ||
|
|
||
| fi | ||
|
|
||
| mkdir -p output | ||
| python3 soil_creep.py | ||
|
|
||
| close_log |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. self-note: I could not install FEniCSx on my system at the moment. In any case, we should test it on the system tests once the respective entries are there (see the checklist in the PR description). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,241 @@ | ||
| """ | ||
| Linear diffusion equation of soil with Dirichlet boundary. | ||
| z' = div(D*grad(z)) in the square [0,19] x [0,19] | ||
| z = 0 on the bottom boundary | ||
| """ | ||
|
|
||
| import copy | ||
| import matplotlib as mpl | ||
| import matplotlib.pyplot as plt | ||
| import ufl | ||
| import numpy as np | ||
| from petsc4py import PETSc | ||
| from mpi4py import MPI | ||
| from dolfinx import default_scalar_type, fem, mesh | ||
| from dolfinx.fem.petsc import ( | ||
| assemble_vector, | ||
| assemble_matrix, | ||
| create_vector, | ||
| apply_lifting, | ||
| set_bc, | ||
| ) | ||
| from fenicsxprecice import Adapter, CouplingMesh | ||
|
|
||
| def bottom_boundary(x): | ||
| return np.isclose(x[1], 0) | ||
|
|
||
| # Volume coupling | ||
| def coupling_boundary(x): | ||
| return np.ones(x.shape[1], dtype=bool) | ||
|
|
||
|
|
||
| initial_soil_depth = 0.3 | ||
|
|
||
| # Set the soil-thickness scale for limiting creep where little soil is available | ||
| hstar = 0.2 | ||
|
|
||
| # Set parameters for two soil creep coefficients: slow (full grass cover) and fast (partial or "eaten" grass cover) | ||
| fast_creep = 0.1 | ||
| slow_creep = 0.001 | ||
|
|
||
| # Set grid size (same as W-S-G model's grid) | ||
| # Adjust refinement by changing number of nodes ny/nx (e.g. double refinement by setting ny = nx = 40). | ||
| nx = ny = 20 | ||
| length_x = length_y = 19.0 | ||
| dx = length_x / (nx - 1) | ||
|
|
||
| fenics_dt = 0.2 * dx * dx / fast_creep | ||
|
|
||
| comm = MPI.COMM_WORLD | ||
|
|
||
| # Create domain and function space | ||
| domain = mesh.create_rectangle( | ||
| comm, | ||
| [np.array([0.0, 0.0]), np.array([length_x, length_y])], | ||
| [nx - 1, ny - 1], | ||
| mesh.CellType.triangle, | ||
| ) | ||
| V = fem.functionspace(domain, ("Lagrange", 1)) | ||
| Q = fem.functionspace(domain, ("DG", 0)) | ||
|
|
||
| # u is elev function | ||
| u_n = fem.Function(V) | ||
| u_n.interpolate(lambda x: 0.1 * x[1]) | ||
|
|
||
| initial_elev = fem.Function(V) | ||
| initial_elev.x.array[:] = u_n.x.array | ||
|
|
||
| # D is diffusivity function / creep coefficient | ||
| D = fem.Function(Q) | ||
|
|
||
| # Functions for coupling | ||
| soil = fem.Function(V) | ||
| soil.x.array[:] = initial_soil_depth | ||
|
|
||
| grass = fem.Function(V) | ||
|
|
||
| # Auxiliary functions | ||
| grass_diffusivity = fem.Function(V) | ||
| soil_scaling = fem.Function(V) | ||
|
|
||
| # Dirichlet boundary condition | ||
| bottom_dofs = fem.locate_dofs_geometrical(V, bottom_boundary) | ||
| bc = fem.dirichletbc(default_scalar_type(0), bottom_dofs, V) | ||
|
|
||
| # preCICE setup | ||
| participant = Adapter(adapter_config_filename="precice-adapter-config.json", mpi_comm=comm) | ||
|
|
||
| coupling_mesh = CouplingMesh("Soil-Creep-Mesh", coupling_boundary, {"Grass": V}, {"Soil": soil}) | ||
| participant.initialize([coupling_mesh]) | ||
|
|
||
| # Define the variational formualation | ||
| u, v = ufl.TrialFunction(V), ufl.TestFunction(V) | ||
| dt_constant = fem.Constant(domain, default_scalar_type(fenics_dt)) | ||
|
|
||
| a = u * v * ufl.dx + dt_constant * D * ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx | ||
| L = u_n * v * ufl.dx | ||
|
|
||
| bilinear_form = fem.form(a) | ||
| linear_form = fem.form(L) | ||
|
|
||
| # Create the matrix and vector for the linear problem | ||
| b = create_vector(fem.extract_function_spaces(linear_form)) | ||
| uh = fem.Function(V) | ||
|
|
||
| # Define a linear variational solver | ||
| solver = PETSc.KSP().create(domain.comm) | ||
| solver.setType(PETSc.KSP.Type.PREONLY) | ||
| solver.getPC().setType(PETSc.PC.Type.LU) | ||
|
|
||
|
|
||
| while participant.is_coupling_ongoing(): | ||
| precice_dt = participant.get_max_time_step_size() | ||
| dt = np.min([fenics_dt, precice_dt]) | ||
| dt_constant.value = default_scalar_type(dt) | ||
|
|
||
| participant.read_data("Soil-Creep-Mesh", "Grass", dt, grass) | ||
|
|
||
| grass_diffusivity.x.array[:] = np.where( | ||
| grass.x.array == 1, | ||
| fast_creep, | ||
| slow_creep, | ||
| ) | ||
| grass_diffusivity.x.scatter_forward() | ||
|
|
||
| soil_scaling.x.array[:] = 1.0 - np.exp(-soil.x.array / hstar) | ||
| soil_scaling.x.scatter_forward() | ||
|
|
||
| D_expr = fem.Expression( | ||
| grass_diffusivity * soil_scaling, | ||
| Q.element.interpolation_points, | ||
| ) | ||
| D.interpolate(D_expr) | ||
|
|
||
| # Reassemble problem because D is updated | ||
| A = assemble_matrix(bilinear_form, bcs=[bc]) | ||
| A.assemble() | ||
| solver.setOperators(A) | ||
|
|
||
| # Update the right hand side reusing the initial vector | ||
| with b.localForm() as loc_b: | ||
| loc_b.set(0) | ||
| assemble_vector(b, linear_form) | ||
|
|
||
| apply_lifting(b, [bilinear_form], [[bc]]) | ||
| b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) | ||
|
|
||
| set_bc(b, [bc]) | ||
|
|
||
| # Solve linear problem | ||
| solver.solve(b, uh.x.petsc_vec) | ||
| uh.x.scatter_forward() | ||
|
|
||
| soil.x.array[:] += uh.x.array - u_n.x.array | ||
| soil.x.scatter_forward() | ||
|
|
||
| # Update solution at previous time step (u_n) | ||
| u_n.x.array[:] = uh.x.array | ||
|
|
||
| participant.write_data("Soil-Creep-Mesh", "Soil", soil) | ||
|
|
||
| participant.advance(dt) | ||
|
|
||
|
|
||
| participant.finalize() | ||
|
|
||
|
|
||
|
|
||
| dofs_coupling_coordinates = V.tabulate_dof_coordinates()[:, :2].copy() | ||
|
|
||
| def values_to_grid(values): | ||
| grid = np.full((ny, nx), np.nan) | ||
|
|
||
| for coord, value in zip(dofs_coupling_coordinates, values): | ||
| i = int(round(coord[0] / length_x * (nx - 1))) | ||
| j = int(round(coord[1] / length_y * (ny - 1))) | ||
| grid[j, i] = value | ||
|
|
||
| return grid | ||
|
|
||
|
|
||
| # Mask for closed boundaries (mimic Landlab) | ||
| closed = np.zeros((ny, nx), dtype=bool) | ||
|
|
||
| closed[1:-1, 0] = True | ||
| closed[1:-1, -1] = True | ||
| closed[-1, :] = True | ||
|
|
||
| # Calculate and plot the erosion/deposition patterns | ||
| ero_dep = u_n.x.array - initial_elev.x.array | ||
| ero_dep_grid = values_to_grid(ero_dep) | ||
|
|
||
| maxchange = np.max(np.abs(ero_dep_grid)) | ||
|
|
||
| cmap = mpl.colormaps["coolwarm_r"].copy() | ||
| cmap.set_bad("black") | ||
|
|
||
| plt.figure() | ||
| plt.imshow( | ||
| np.ma.array(ero_dep_grid, mask=closed), | ||
| origin="lower", | ||
| vmin=-maxchange, | ||
| vmax=maxchange, | ||
| cmap=cmap | ||
| ) | ||
| plt.colorbar(label="Depth of soil accumulation (+) or loss (-), m") | ||
| plt.savefig("output/erosion_deposition_patterns.png") | ||
| plt.close() | ||
|
|
||
| # Soil thickness | ||
| soil_grid = values_to_grid(soil.x.array) | ||
|
|
||
| cmap = mpl.colormaps["pink"].copy() | ||
| cmap.set_bad("black") | ||
|
|
||
| plt.figure() | ||
| plt.imshow( | ||
| np.ma.array(soil_grid, mask=closed), | ||
| origin="lower", | ||
| cmap=cmap, | ||
| ) | ||
| plt.colorbar(label="Soil thickness, m") | ||
| plt.savefig("output/soil_thickness.png") | ||
| plt.close() | ||
|
|
||
| # Ground cover | ||
| gm_grid = values_to_grid(grass.x.array) | ||
|
|
||
| cmap = mpl.colormaps["YlGn"].copy() | ||
| cmap.set_bad("black") | ||
|
|
||
| plt.figure() | ||
| plt.imshow( | ||
| np.ma.array(gm_grid, mask=closed), | ||
| origin="lower", | ||
| cmap=cmap, | ||
| vmin=1, | ||
| vmax=2, | ||
| ) | ||
| plt.colorbar(label="Ground cover (1 = bare, 2 = grass)") | ||
| plt.savefig("output/grass_map.png") | ||
| plt.close() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.