Skip to content
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

Integration with Chmy.jl #141

Merged
merged 39 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
bb0e7a4
store 1D vectors instead of ranges
boriskaus Oct 8, 2024
53275a7
add Chmy interface and multiple dispatch for most functions
boriskaus Oct 8, 2024
884272f
missing dependencies
boriskaus Oct 8, 2024
4abc21f
spellcheck
boriskaus Oct 8, 2024
0cf7795
add functionality for above/belowSurface
boriskaus Oct 9, 2024
5a3b2cd
spell check
boriskaus Oct 9, 2024
94daeea
correct test
boriskaus Oct 9, 2024
7a65cf2
albert's suggestion
boriskaus Oct 9, 2024
7b4c24e
changes to make this work with purely 2D arrays
boriskaus Oct 9, 2024
749ea32
activate 2D for more routines
boriskaus Oct 9, 2024
48b6791
deactivate test that fails locally but runs on CI
boriskaus Oct 9, 2024
95f4335
bugfix for add_sphere!, more tests
boriskaus Oct 9, 2024
a032cac
Merge branch 'main' into bk-chmy
boriskaus Oct 9, 2024
12971e2
fix cylinder bug
boriskaus Oct 9, 2024
1ce3c6a
bugfixes for 2D
boriskaus Oct 9, 2024
fc905eb
Merge remote-tracking branch 'origin/main' into bk-chmy
boriskaus Oct 9, 2024
787dc9f
remove debugging
boriskaus Oct 9, 2024
2b123bd
bugfixes
boriskaus Oct 9, 2024
231db49
add released 1.11 to CI
boriskaus Oct 9, 2024
ab0ad0b
test intel Macs as well
boriskaus Oct 9, 2024
8b5ea61
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
b0416c9
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
12ead9b
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
a4decaf
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
30a658e
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
8fb92e6
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
4a1a436
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
769cb68
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
3d1899e
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
c0f9cdc
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
7016142
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
fb57455
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
8fb17a3
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
a34d1f1
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
41e9b43
Update src/Setup_geometry.jl
boriskaus Oct 9, 2024
779798d
add Chmy tutorial to the docs
boriskaus Oct 9, 2024
7dc6bd8
Merge remote-tracking branch 'origin/bk-chmy' into bk-chmy
boriskaus Oct 9, 2024
3050774
cancel running ongoing CI runs upon new push
boriskaus Oct 9, 2024
115a1cc
some of albert's suggestions broke the tests
boriskaus Oct 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ on:
branches:
- main
tags: '*'

# Cancel redundant CI tests automatically
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
run_tests:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
Expand All @@ -16,11 +22,12 @@ jobs:
version:
- '1.9'
- '1.10'
- '~1.11.0-0'
- '1.11'
- 'nightly'
os:
- ubuntu-latest
- macOS-latest
- macos-14
- windows-latest
arch:
- x64
Expand Down
17 changes: 11 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "GeophysicalModelGenerator"
uuid = "3700c31b-fa53-48a6-808a-ef22d5a84742"
authors = ["Boris Kaus", "Marcel Thielmann"]
version = "0.7.7"
version = "0.7.8"

[deps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Expand Down Expand Up @@ -32,23 +32,26 @@ WhereTheWaterFlows = "ea906314-1493-4d22-a0af-f886a20c9fba"
WriteVTK = "64499a7a-5c06-52f2-abe2-ccb03c286192"

[weakdeps]
Chmy = "33a72cf0-4690-46d7-b987-06506c2248b9"
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
GMT = "5752ebe1-31b9-557e-87aa-f909b540aa54"
GridapGmsh = "3025c34a-b394-11e9-2a55-3fee550c04c8"

[extensions]
Chmy_utils = "Chmy"
GLMakie_Visualisation = "GLMakie"
GMT_utils = "GMT"
Gmsh_utils = "GridapGmsh"

[compat]
Chmy = "0.1.20"
Colors = "0.9 - 0.12"
Downloads = "1"
FFMPEG = "0.4"
FileIO = "1"
GDAL_jll = "300.900.0 - 301.900.0"
GLMakie = "0.10"
GMT = "1"
GDAL_jll = "300.900.0 - 301.901.0"
GLMakie = "0.8, 0.9, 0.10"
GMT = "1.0 - 1.14"
GeoParams = "0.2 - 0.6"
Geodesy = "1"
GeometryBasics = "0.1 - 0.4"
Expand All @@ -63,15 +66,17 @@ NearestNeighbors = "0.2 - 0.4"
Parameters = "0.9 - 0.12"
SpecialFunctions = "1.0, 2"
StaticArrays = "1"
WhereTheWaterFlows = "0.10"
WhereTheWaterFlows = "0.10, 0.11"
WriteVTK = "1"
julia = "1.9"

[extras]
Chmy = "33a72cf0-4690-46d7-b987-06506c2248b9"
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
GMT = "5752ebe1-31b9-557e-87aa-f909b540aa54"
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "GMT", "StableRNGs", "GridapGmsh"]
test = ["Test", "GMT", "StableRNGs", "GridapGmsh", "Chmy","KernelAbstractions"]
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ makedocs(;
"Gravity code" => "man/gravity_code.md",
"Numerical model setups" => "man/geodynamic_setups.md",
"LaMEM" => "man/lamem.md",
"pTatin" => "man/lamem.md",
"pTatin" => "man/ptatin.md",
"Chmy" => "man/Tutorial_Chmy_MPI.md",
"Profile Processing" => "man/profile_processing.md",
"Gmsh" => "man/gmsh.md",
"Movies" => "man/movies.md"
Expand Down
160 changes: 160 additions & 0 deletions docs/src/man/Tutorial_Chmy_MPI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
```@meta
EditURL = "../../../tutorials/Tutorial_Chmy_MPI.jl"
```

# Create an initial model setup for Chmy and run it in parallel

## Aim
In this tutorial, your will learn how to use [Chmy](https://github.com/PTsolvers/Chmy.jl) to perform a 2D diffusion simulation
on one or multiple CPU's or GPU's.
`Chmy` is a package that allows you to specify grids and fields and create finite difference simulations

## 1. Load Chmy and required packages

```julia
using Chmy, Chmy.Architectures, Chmy.Grids, Chmy.Fields, Chmy.BoundaryConditions, Chmy.GridOperators, Chmy.KernelLaunch
using KernelAbstractions
using Printf
using CairoMakie
using GeophysicalModelGenerator
```

In case you want to use GPU's, you need to sort out whether you have AMD or NVIDIA GPU's
and load the package accordingly:
using AMDGPU
AMDGPU.allowscalar(false)
using CUDA
CUDA.allowscalar(false)

To run this in parallel you need to load this:

```julia
using Chmy.Distributed
using MPI
MPI.Init()
```

## 2. Define computational routines
You need to specify compute kernel for the gradients:

```julia
@kernel inbounds = true function compute_q!(q, C, χ, g::StructuredGrid, O)
I = @index(Global, NTuple)
I = I + O
q.x[I...] = -χ * ∂x(C, g, I...)
q.y[I...] = -χ * ∂y(C, g, I...)
end
```

You need to specify compute kernel to update the concentration

```julia
@kernel inbounds = true function update_C!(C, q, Δt, g::StructuredGrid, O)
I = @index(Global, NTuple)
I = I + O
C[I...] -= Δt * divg(q, g, I...)
end
```

And a main function is required:

```julia
@views function main(backend=CPU(); nxy_l=(126, 126))
arch = Arch(backend, MPI.COMM_WORLD, (0, 0))
topo = topology(arch)
me = global_rank(topo)

# geometry
dims_l = nxy_l
dims_g = dims_l .* dims(topo)
grid = UniformGrid(arch; origin=(-2, -2), extent=(4, 4), dims=dims_g)
launch = Launcher(arch, grid, outer_width=(16, 8))

##@info "mpi" me grid

nx, ny = dims_g
# physics
χ = 1.0
# numerics
Δt = minimum(spacing(grid))^2 / χ / ndims(grid) / 2.1
# allocate fields
C = Field(backend, grid, Center())
P = Field(backend, grid, Center(), Int32) # phases

q = VectorField(backend, grid)
C_v = (me==0) ? KernelAbstractions.zeros(CPU(), Float64, size(interior(C)) .* dims(topo)) : nothing

# Use the `GeophysicalModelGenerator` to set the initial conditions. Note that
# you have to call this for a `Phases` and a `Temp` grid, which we call `C` here.
add_box!(P,C,grid, xlim=(-1.0,1.0), zlim=(-1.0,1.0), phase=ConstantPhase(4), T=ConstantTemp(400))

# set BC's and updates the halo:
bc!(arch, grid, C => Neumann(); exchange=C)

# visualisation
fig = Figure(; size=(400, 320))
ax = Axis(fig[1, 1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="it = 0")
plt = heatmap!(ax, centers(grid)..., interior(C) |> Array; colormap=:turbo)
Colorbar(fig[1, 2], plt)
# action
nt = 100
for it in 1:nt
(me==0) && @printf("it = %d/%d \n", it, nt)
launch(arch, grid, compute_q! => (q, C, χ, grid))
launch(arch, grid, update_C! => (C, q, Δt, grid); bc=batch(grid, C => Neumann(); exchange=C))
end
KernelAbstractions.synchronize(backend)
gather!(arch, C_v, C)
if me == 0
fig = Figure(; size=(400, 320))
ax = Axis(fig[1, 1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="it = 0")
plt = heatmap!(ax, C_v; colormap=:turbo) # how to get the global grid for axes?
Colorbar(fig[1, 2], plt)
save("out_gather_$nx.png", fig)
end
return
end
```

In the code above, the part that calls `GMG` is:

```julia
add_box!(P,C,grid, xlim=(-1.0,1.0), zlim=(-1.0,1.0), phase=ConstantPhase(4), T=ConstantTemp(400))
```
which works just like any of the other GMG function.

## 3. Run the simulation on one CPU machine or GPU card:

Running the code on the CPU is done with this:

```julia
n = 128
main(; nxy_l=(n, n) .- 2)
```

If you instead want to run this on AMD or NVIDIA GPU's do this:

```julia
# main(ROCBackend(); nxy_l=(n, n) .- 2)
# main(CUDABackend(); nxy_l=(n, n) .- 2)
```

And we need to finalize the simulation with

```julia
MPI.Finalize()
```

## 4. Run the simulation on an MPI-parallel machine
If you want to run this on multiple cores, you will need to setup the [MPI.jl]() package,
such that `mpiexecjl` is created on the command line.

You can than run it with:
mpiexecjl -n 4 --project=. julia Tutorial_Chmy_MPI.jl

The full file can be downloaded [here](../../../tutorials/Tutorial_Chmy_MPI.jl)

---

*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*

108 changes: 108 additions & 0 deletions ext/Chmy_utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#helper functions to make GMG work with Chmy grids and fields
module Chmy_utils

using Chmy, Chmy.Grids, Chmy.Fields

import GeophysicalModelGenerator: create_CartGrid, CartGrid, CartData
import GeophysicalModelGenerator: add_box!, add_sphere!, add_ellipsoid!, add_cylinder!
import GeophysicalModelGenerator: add_layer!, add_polygon!, add_slab!, add_stripes!, add_volcano!
import GeophysicalModelGenerator: above_surface, below_surface

println("Loading Chmy-GMG tools")

"""
CartGrid = create_CartGrid(grid::StructuredGrid; ylevel=0.0)

Creates a GMG `CartGrid` data structure from a `Chmy` grid object
"""
function create_CartGrid(grid::StructuredGrid; ylevel=0.0)

coord1D = Vector.(coords(grid, Vertex()))
coord1D_cen = Vector.(coords(grid, Center()))
N = length.(coord1D)
L = extent(grid, Vertex())
X₁ = origin(grid, Vertex())
Δ = spacing(grid)
ConstantΔ = false;
if isa(grid, UniformGrid)
ConstantΔ = true
end
if ndims(grid)==2
# we need a special treatment of this, as all GMG routines work with 3D coordinates
X₁ = (X₁[1], ylevel, X₁[2])
L = (L[1], 0.0, L[2])
Δ = (Δ[1], 0.0, Δ[2])
N = (N[1],1,N[2])
coord1D = (coord1D[1], [0.0], coord1D[2])
coord1D_cen = (coord1D_cen[1], [0.0], coord1D_cen[2])
end
Xₙ = X₁ .+ L


return CartGrid(ConstantΔ,N,Δ,L,X₁,Xₙ,coord1D, coord1D_cen)
end

# all functions to be ported
function_names = (:add_box!, :add_sphere!, :add_ellipsoid!, :add_cylinder!, :add_layer!, :add_polygon!, :add_slab!, :add_stripes!, :add_volcano!)

for fn in function_names

@eval begin
"""
$($fn)( Phase::Field,
Temp::Field,
Grid::StructuredGrid; # required input
kwargs...)

Sets `$($fn)` function for `Chmy` fields and grids.
"""
function $fn( Phase::Field,
Temp::Field,
Grid::StructuredGrid; # required input
kwargs...)

CartGrid = create_CartGrid(Grid)

cell = false
if all(location(Phase).==Center())
cell = true
end

return ($fn)(Phase, Temp, CartGrid; cell=cell, kwargs...)
end
end

end


# all functions to be ported
function_names = (:above_surface, :below_surface)

for fn in function_names

@eval begin
"""
$($fn)( Grid::StructuredGrid, field::Field, DataSurface_Cart::CartData; kwargs...)

Sets `$($fn)` function for `Chmy` grids and the field `field` which can be either on vertices or centers
"""
function $fn( Grid::StructuredGrid,
field::Field,
DataSurface_Cart::CartData;
kwargs...)

CartGrid = create_CartGrid(Grid)

cell = false
if all(location(field).==Center())
cell = true
end

return ($fn)(CartGrid, DataSurface_Cart; cell=cell, kwargs...)
end
end

end


end # end of module
Loading
Loading