Skip to content
Open
Changes from 25 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4d93988
amrvac amrgridpatch vs stretchedgrid
jordidj Jun 22, 2026
315637e
amrvac stretching parameters
jordidj Jun 22, 2026
08392e2
amrvac missed dxmid
jordidj Jun 23, 2026
3b4fe24
amrvac nlevelshi
jordidj Jun 25, 2026
0c17684
amrvac limit to uniform stretching
jordidj Jun 25, 2026
113e051
amrvac stretched grid attempt 1
jordidj Jun 25, 2026
bb219df
amrvac grid restructure
jordidj Jun 25, 2026
5a6e656
amrvac check meshlist presence
jordidj Jun 25, 2026
9b0e8a0
python syntax error
jordidj Jun 25, 2026
78aacc4
amrvac morton index fix
jordidj Jun 26, 2026
4d6a2da
cleanup
jordidj Jun 26, 2026
7c47b02
indices
jordidj Jun 26, 2026
e0092fe
amrvac cell widths
jordidj Jun 26, 2026
dd66a77
amrvac minor fixes
jordidj Jun 26, 2026
051f479
amrvac if checks
jordidj Jun 26, 2026
6e76bbf
amrvac stretched_dims
jordidj Jun 26, 2026
e7f5131
amrvac remove error
jordidj Jun 26, 2026
4b9d719
amrvac if fix
jordidj Jun 26, 2026
d87aa66
amrvac stretching formula fix
jordidj Jun 26, 2026
e9ac0e7
amrvac 2d fix
jordidj Jul 13, 2026
1cd0c51
amrvac small stylistic changes
jordidj Jul 17, 2026
62fe138
amrvac cell_widths comprehension
jordidj Jul 17, 2026
a75969e
amrvac base stretch case selection
jordidj Jul 17, 2026
3445d47
amrvac cleanup
jordidj Jul 17, 2026
3a1a565
amrvac case
jordidj Jul 17, 2026
e642459
amrvac style
jordidj Jul 20, 2026
78d2604
amrvac removed extra variables
jordidj Jul 20, 2026
c81cd74
amrvac type check stretch_dim elements
jordidj Jul 20, 2026
fbbf0cd
f90nml parser access
jordidj Jul 20, 2026
fb9799e
amrvac read list assignments from parfile
jordidj Jul 20, 2026
2037d71
amrvac ruff check
jordidj Jul 22, 2026
e9ce693
amrvac stretched small optimization
jordidj Aug 26, 2026
70c76f5
amrvac stretched cleaner cell width construction
jordidj Aug 26, 2026
dbb9ea6
amrvac stretched legibility
jordidj Aug 26, 2026
2872e2b
amrvac stretched cell_widths rewrite
jordidj Aug 26, 2026
b0fd280
amrvac stretched grid support doc
jordidj Aug 26, 2026
54dde2a
amrvac doc deleted double statement
jordidj Aug 26, 2026
29bf77e
amrvac removed unnecessary import
jordidj Aug 26, 2026
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
131 changes: 119 additions & 12 deletions yt/frontends/amrvac/data_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
from pathlib import Path

import numpy as np
from itertools import product
from more_itertools import always_iterable

from yt.config import ytcfg
from yt.data_objects.index_subobjects.grid_patch import AMRGridPatch
from yt.data_objects.index_subobjects.stretched_grid import StretchedGrid
from yt.data_objects.static_output import Dataset
from yt.funcs import mylog, setdefaultattr
from yt.geometry.api import Geometry
Expand Down Expand Up @@ -52,17 +53,18 @@ def _parse_geometry(geometry_tag: str) -> Geometry:
return Geometry(geometry_str.lower())


class AMRVACGrid(AMRGridPatch):
class AMRVACGrid(StretchedGrid):
"""A class to populate AMRVACHierarchy.grids, setting parent/children relations."""

_id_offset = 0

def __init__(self, id, index, level):
def __init__(self, id, cell_widths, filename, index, level, dims):
# <level> should use yt's convention (start from 0)
super().__init__(id, filename=index.index_filename, index=index)
super().__init__(id=id, filename=filename, index=index, cell_widths=cell_widths)
self.Parent = None
self.Children = []
self.Level = level
self.ActiveDimensions = dims

def get_global_startindex(self):
"""Refresh and retrieve the starting index for each dimension at current level.
Expand Down Expand Up @@ -100,6 +102,14 @@ def __init__(self, ds, dataset_type="amrvac"):
self.directory = os.path.dirname(self.index_filename)
self.float_type = np.float64

self.stretch_dim = ["none"] * self.dataset.dimensionality
if self.dataset.namelist is not None:
meshlist = self.dataset.namelist["meshlist"]
if (stretch_dim := meshlist.get("stretch_dim")) is not None:
assert isinstance(stretch_dim, list)
Comment thread
jordidj marked this conversation as resolved.
assert len(stretch_dim) >= self.dataset.dimensionality
self.stretch_dim = stretch_dim

super().__init__(ds, dataset_type)

def _detect_output_fields(self):
Expand Down Expand Up @@ -139,20 +149,117 @@ def _parse_index(self):
dx0 = (
domain_width / self.dataset.parameters["domain_nx"]
) # dx at coarsest grid level (YT level 0)
dim = self.dataset.dimensionality
ndim = self.dataset.dimensionality

self.grids = np.empty(self.num_grids, dtype="object")
stretched_dims = [not (x == "none" or x == "") for x in self.stretch_dim]
base_stretch = np.ones(3, dtype="float64")
if np.any(stretched_dims):
meshlist = self.dataset.namelist["meshlist"]
stretch_baselevel = meshlist.get("qstretch_baselevel")
match stretch_baselevel:
case None:
Comment thread
jordidj marked this conversation as resolved.
# compute default values dynamically, just as done in AMRVAC
assert sum(stretched_dims) == 1 # exactly one stretched direction
stretched_dim = stretched_dims.index(True) + 1 # AMRVAC index (1 offset, Fortran convention)
base_stretch[stretched_dim-1] = (
meshlist[f"xprobmax{stretched_dim}"]
/ meshlist[f"xprobmin{stretched_dim}"]
) ** (1.0 / meshlist[f"domain_nx{stretched_dim}"])
case list() | tuple():
Comment thread
jordidj marked this conversation as resolved.
Outdated
assert len(stretch_baselevel) >= ndim
base_stretch[:ndim] = (
float(b) for b in stretch_baselevel[:ndim]
)
case float() | int():
assert sum(stretched_dims) == 1 # exactly one stretched direction
stretched_dim = stretched_dims.index(True)
base_stretch[stretched_dim] = stretch_baselevel
Comment thread
jordidj marked this conversation as resolved.
Outdated
case _:
raise ValueError(
f"Unknown type for qstretch_baselevel: {type(stretch_baselevel)}"
)

qstretch = np.zeros((self.max_level + 2, ndim), dtype="float64")
dxfirst = np.zeros((self.max_level + 2, ndim), dtype="float64")
for dim in range(ndim):
match self.stretch_dim[dim]:
case "none" | "":
continue
case "uni" | "uniform":
qstretch[1, dim] = base_stretch[dim]
dxfirst[1, dim] = (
domain_width[dim] * (1.0 - qstretch[1, dim])
/ (1.0 - qstretch[1, dim] ** meshlist[f"domain_nx{dim + 1}"])
)
qstretch[0, dim] = qstretch[1, dim] ** 2
dxfirst[0, dim] = dxfirst[1, dim] * (1.0 + qstretch[1, dim])
if self.max_level > 0:
for ilev in range(2, self.max_level + 2):
qstretch[ilev, dim] = np.sqrt(qstretch[ilev - 1, dim])
dxfirst[ilev, dim] = dxfirst[ilev - 1, dim] / (
1.0 + np.sqrt(qstretch[ilev - 1, dim])
)
case "symm" | "symmetric":
raise ValueError(
f"Symmetric stretching is not currently supported for AMRVAC data."
)
case _:
raise ValueError(
f"Unknown stretch_dim '{self.stretch_dim[dim]}' for dimension {dim}."
Comment thread
jordidj marked this conversation as resolved.
Outdated
)

for igrid, (ytlevel, morton_index) in enumerate(
zip(ytlevels, morton_indices, strict=True)
):
dx = dx0 / self.dataset.refine_by**ytlevel
left_edge = xmin + (morton_index - 1) * block_nx * dx

left_edge = np.zeros(ndim, dtype="float64")
right_edge = np.zeros(ndim, dtype="float64")
cw_aux = []

dim_count = 0
for dim in range(ndim):
match self.stretch_dim[dim]:
case "none" | "":
dx = dx0 / self.dataset.refine_by**ytlevel
left_edge[dim] = xmin[dim] + (morton_index[dim] - 1) * block_nx[dim] * dx[dim]
right_edge[dim] = left_edge[dim] + block_nx[dim] * dx[dim]
cw_aux.append([dx[dim]] * block_nx[dim])
case "uni" | "uniform":
# left edge
center1 = (xmin[dim] + 0.5 * dxfirst[ytlevel+1, dim]) * qstretch[ytlevel+1, dim] ** ((morton_index[dim] - 1) * block_nx[dim])
Comment thread
jordidj marked this conversation as resolved.
Outdated
dcenter1 = 2.0 * center1 * (qstretch[ytlevel+1, dim] - 1.0) / (qstretch[ytlevel+1, dim] + 1.0)
left_edge[dim] = center1 - 0.5 * dcenter1
# right edge
center2 = (xmin[dim] + 0.5 * dxfirst[ytlevel+1, dim]) * qstretch[ytlevel+1, dim] ** (morton_index[dim] * block_nx[dim] - 1)
dcenter2 = 2.0 * center2 * (qstretch[ytlevel+1, dim] - 1.0) / (qstretch[ytlevel+1, dim] + 1.0)
right_edge[dim] = center2 + 0.5 * dcenter2
# cell widths
dcenter = [
(
(xmin[dim] + 0.5 * dxfirst[ytlevel+1, dim]) * qstretch[ytlevel+1, dim] ** ((morton_index[dim] - 1) * block_nx[dim] + i)
* 2.0 * (qstretch[ytlevel+1, dim] - 1.0) / (qstretch[ytlevel+1, dim] + 1.0)
) for i in range(block_nx[dim])
]
cw_aux.append(dcenter)
Comment thread
jordidj marked this conversation as resolved.
Outdated
dim_count += 1
while dim_count < 3:
cw_aux.append([1.0])
dim_count += 1
prod = np.array(list(product(*cw_aux[::-1])))
cell_widths = (prod.T)[::-1]
Comment thread
jordidj marked this conversation as resolved.
Outdated

# edges and dimensions are filled in a dimensionality-agnostic way
self.grid_left_edge[igrid, :dim] = left_edge
self.grid_right_edge[igrid, :dim] = left_edge + block_nx * dx
self.grid_dimensions[igrid, :dim] = block_nx
self.grids[igrid] = self.grid(igrid, self, ytlevels[igrid])
self.grid_left_edge[igrid, :ndim] = left_edge
self.grid_right_edge[igrid, :ndim] = right_edge
self.grid_dimensions[igrid, :ndim] = block_nx
self.grids[igrid] = self.grid(
id=igrid,
index=self,
level=ytlevels[igrid],
filename=self.index_filename,
cell_widths=cell_widths,
dims=self.grid_dimensions[igrid],
)

def _populate_grid_objects(self):
# required method
Expand Down
Loading