Skip to content

Commit 91fc146

Browse files
committed
store reverse_mode in IntervalMesh
1 parent c19e001 commit 91fc146

4 files changed

Lines changed: 40 additions & 12 deletions

File tree

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ ClimaCore.jl Release Notes
44
main
55
-------
66

7+
- Store `reverse_mode` in the `IntervalMesh` struct, so that we can access it when writing
8+
and reading the mesh for restarts
9+
10+
v0.14.39
11+
-------
12+
713
v0.14.38
814
-------
915

src/InputOutput/readers.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,19 +315,26 @@ function read_mesh_new(reader::HDF5Reader, name::AbstractString)
315315
nelements = attrs(group)["nelements"]
316316
faces_type = get(attrs(group), "faces_type", nothing)
317317
stretch_type = get(attrs(group), "stretch_type", nothing)
318+
reverse_mode = get(attrs(group), "reverse_mode", false)
318319
if stretch_type == "Uniform" || faces_type == "Range"
319320
return Meshes.IntervalMesh(
320321
domain,
321322
Meshes.Uniform();
322323
nelems = nelements,
324+
reverse_mode,
323325
)
324326
end
325327
stretch_params = get(attrs(group), "stretch_params", nothing)
326328
if stretch_type "UnknownStretch" && !isnothing(stretch_params)
327329
CT = Domains.coordinate_type(domain)
328330
stretch =
329331
getproperty(Meshes, Symbol(stretch_type))(stretch_params...)
330-
return Meshes.IntervalMesh(domain, stretch; nelems = nelements)
332+
return Meshes.IntervalMesh(
333+
domain,
334+
stretch;
335+
nelems = nelements,
336+
reverse_mode,
337+
)
331338
end
332339
# Fallback: read from array
333340
@assert faces_type == "Array"

src/InputOutput/writers.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ function write_new!(
205205
write_attribute(group, "type", "IntervalMesh")
206206
write_attribute(group, "domain", domainname)
207207
write_attribute(group, "nelements", Meshes.nelements(mesh))
208+
write_attribute(group, "reverse_mode", mesh.reverse_mode)
208209
if occursin("LinRange", string(typeof(mesh.faces)))
209210
write_attribute(group, "faces_type", "Range")
210211
else
@@ -324,11 +325,13 @@ end
324325
defaultname(::DataLayouts.IJHMask) = "IJHMask"
325326
defaultname(::Grids.SpectralElementGrid1D) = "horizontal_grid"
326327
defaultname(::Grids.SpectralElementGrid2D) = "horizontal_grid"
327-
defaultname(::Grids.ExtrudedFiniteDifferenceGrid) =
328-
"extruded_finite_difference_grid"
328+
defaultname(
329+
::Grids.ExtrudedFiniteDifferenceGrid,
330+
) = "extruded_finite_difference_grid"
329331
defaultname(grid::Grids.FiniteDifferenceGrid) = defaultname(grid.topology)
330-
defaultname(grid::Grids.LevelGrid) =
331-
"$(defaultname(grid.full_grid)): level $(grid.level)"
332+
defaultname(
333+
grid::Grids.LevelGrid,
334+
) = "$(defaultname(grid.full_grid)): level $(grid.level)"
332335

333336
"""
334337
write_new!(writer, space, name)

src/Meshes/interval.jl

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ Constuct a 1D mesh on `domain` with `nelems` elements, using `stretching`. Possi
1717
- [`ExponentialStretching(H)`](@ref)
1818
- [`GeneralizedExponentialStretching(dz_bottom, dz_top)`](@ref)
1919
- [`HyperbolicTangentStretching(dz_bottom)`](@ref)
20+
21+
If `reverse_mode` is `true`, the smallest element is at the top, and the largest at the bottom
22+
(this is typical for land model configurations).
2023
"""
2124
struct IntervalMesh{S, I <: IntervalDomain, V <: AbstractVector, M} <:
2225
AbstractMesh1D
2326
stretch::S
2427
domain::I
2528
faces::V
2629
meta::M
30+
reverse_mode::Bool
2731
end
2832

2933
# implies isequal
@@ -141,7 +145,8 @@ function IntervalMesh(domain::IntervalDomain, faces::AbstractArray)
141145
nelems = length(faces)
142146
nelems < 1 && throw(ArgumentError("`nelems` must be ≥ 1"))
143147
monotonic_check(faces)
144-
IntervalMesh(UnknownStretch(), domain, faces, nothing)
148+
reverse_mode = false
149+
IntervalMesh(UnknownStretch(), domain, faces, nothing, reverse_mode)
145150
end
146151

147152
"""
@@ -161,7 +166,8 @@ function IntervalMesh(
161166
end
162167
faces = range(domain.coord_min, domain.coord_max; length = nelems + 1)
163168
monotonic_check(faces)
164-
IntervalMesh(stretch, domain, faces, nothing)
169+
reverse_mode = false
170+
IntervalMesh(stretch, domain, faces, nothing, reverse_mode)
165171
end
166172

167173

@@ -217,7 +223,7 @@ function IntervalMesh(
217223
reverse!(faces)
218224
end
219225
monotonic_check(faces)
220-
IntervalMesh(stretch, domain, faces, nothing)
226+
IntervalMesh(stretch, domain, faces, nothing, reverse_mode)
221227
end
222228

223229
"""
@@ -338,7 +344,7 @@ function IntervalMesh(
338344
faces[end] = faces[end] == -z_bottom ? z_bottom : faces[1]
339345
end
340346
monotonic_check(faces)
341-
IntervalMesh(stretch, domain, CT.(faces), (; h_top))
347+
IntervalMesh(stretch, domain, CT.(faces), (; h_top), reverse_mode)
342348
end
343349

344350
"""
@@ -356,13 +362,13 @@ For an interval ``[z_0,z_1]``, this makes the elements uniformally spaced in
356362
\\eta = 1 - \\frac{tanh[\\gamma(1-\\zeta)]}{tanh(\\gamma)},
357363
```
358364
where ``\\eta = \\frac{z - z_0}{z_1-z_0}``. The stretching parameter ``\\gamma``
359-
is chosen to achieve a given resolution `dz_surface` at the surface.
365+
is chosen to achieve a given resolution `dz_surface` at the surface.
360366
361367
Then, the user can define a stretched mesh via
362368
363369
ClimaCore.Meshes.IntervalMesh(interval_domain, HyperbolicTangentStretching(dz_surface); nelems::Int, reverse_mode)
364370
365-
`reverse_mode` is default to false for atmosphere configurations. For land configurations,
371+
`reverse_mode` is default to false for atmosphere configurations. For land configurations,
366372
use `reverse_mode` = `true`.
367373
368374
`faces` contain reference z without any warping.
@@ -427,7 +433,13 @@ function IntervalMesh(
427433
faces[end] = faces[end] == -z_bottom ? z_bottom : faces[1]
428434
end
429435
monotonic_check(faces)
430-
IntervalMesh(stretch, domain, CT.(faces), (; γ_sol = γ_sol.root))
436+
IntervalMesh(
437+
stretch,
438+
domain,
439+
CT.(faces),
440+
(; γ_sol = γ_sol.root),
441+
reverse_mode,
442+
)
431443
end
432444

433445
"""

0 commit comments

Comments
 (0)