Skip to content

Domain loaders

Build a Domain from a file path or from the valence-domains registry.

From files

load_domain_from_fort14

admesh.load_domain_from_fort14

load_domain_from_fort14(path: str | Path) -> Domain

Load a domain boundary from a fort.14 mesh file.

Extracts the outer boundary polygon from a fort.14 mesh. Uses mesh node coordinates to compute bbox and boundary vertices as fixed points.

Parameters:

Name Type Description Default
path str or Path

Path to fort.14 mesh file.

required

Returns:

Type Description
Domain

Domain with polygon rings extracted from fort.14 boundaries.

Source code in src/admesh/loaders.py
def load_domain_from_fort14(path: str | Path) -> Domain:
    """Load a domain boundary from a fort.14 mesh file.

    Extracts the outer boundary polygon from a fort.14 mesh. Uses mesh
    node coordinates to compute bbox and boundary vertices as fixed points.

    Parameters
    ----------
    path : str or Path
        Path to fort.14 mesh file.

    Returns
    -------
    Domain
        Domain with polygon rings extracted from fort.14 boundaries.
    """
    from admesh.fort14 import read_fort14

    mesh = read_fort14(path)

    # Extract outer boundary from first land boundary segment
    rings = []
    if mesh.boundaries:
        # Use first land boundary as outer ring
        for seg in mesh.boundaries:
            if not seg.is_open:
                ring_indices = seg.node_ids
                ring_coords = mesh.nodes[ring_indices]
                rings.append(ring_coords)
                break

    if not rings:
        raise ValueError(f"No land boundary found in {path}")


    # Mark boundary vertices as fixed points
    fixed_points = None
    if rings and len(rings[0]) > 0:
        fixed_points = np.array(rings[0][[0, len(rings[0]) // 2, -1]], dtype=np.float64)

    return _domain_from_polygon(rings, pfix=fixed_points)

load_domain_from_json

admesh.load_domain_from_json

load_domain_from_json(path: str | Path) -> Domain

Load a domain definition from a JSON file.

Expected JSON structure::

{
  "name": "example",
  "bbox": [-1.0, -1.0, 1.0, 1.0],
  "rings": [
    [[-1, -1], [1, -1], [1, 1], [-1, 1]],
    [[-0.25, -0.25], [0.25, -0.25], [0.25, 0.25], [-0.25, 0.25]]
  ],
  "fixed_points": [[-1, -1], [1, 1]]
}

Parameters:

Name Type Description Default
path str or Path

Path to JSON domain file.

required

Returns:

Type Description
Domain

Ready for admesh.triangulate().

Notes

The declared bbox in the file, if present, overrides the bounding box computed from ring extent. Omit bbox to auto-compute.

Source code in src/admesh/loaders.py
def load_domain_from_json(path: str | Path) -> Domain:
    """Load a domain definition from a JSON file.

    Expected JSON structure::

        {
          "name": "example",
          "bbox": [-1.0, -1.0, 1.0, 1.0],
          "rings": [
            [[-1, -1], [1, -1], [1, 1], [-1, 1]],
            [[-0.25, -0.25], [0.25, -0.25], [0.25, 0.25], [-0.25, 0.25]]
          ],
          "fixed_points": [[-1, -1], [1, 1]]
        }

    Parameters
    ----------
    path : str or Path
        Path to JSON domain file.

    Returns
    -------
    Domain
        Ready for admesh.triangulate().

    Notes
    -----
    The declared ``bbox`` in the file, if present, overrides the bounding box
    computed from ring extent. Omit ``bbox`` to auto-compute.
    """
    path = Path(path)
    with open(path) as f:
        data = json.load(f)

    bbox_raw = data.get("bbox")
    bbox = None
    if bbox_raw:
        if len(bbox_raw) != 4:
            raise ValueError(f"JSON bbox must be a 4-tuple; got {bbox_raw}")
        bbox = tuple(float(x) for x in bbox_raw)  # type: ignore[arg-type]

    rings_raw = data.get("rings", [])
    if not rings_raw:
        raise ValueError("JSON rings must contain at least one ring (outer boundary)")

    rings = [np.array(r, dtype=np.float64) for r in rings_raw]

    fixed_points = None
    fixed_raw = data.get("fixed_points")
    if fixed_raw:
        fixed_points = np.array(fixed_raw, dtype=np.float64)

    return _domain_from_polygon(rings, pfix=fixed_points, bbox=bbox)

load_domain_from_toml

admesh.load_domain_from_toml

load_domain_from_toml(path: str | Path) -> Domain

Load a domain definition from a TOML file.

Expected TOML structure::

[domain]
name = "example"
bbox = [-1.0, -1.0, 1.0, 1.0]

[[domain.rings]]
coords = [[-1, -1], [1, -1], [1, 1], [-1, 1]]

[[domain.rings]]  # Optional: interior islands
coords = [[-0.25, -0.25], [0.25, -0.25], [0.25, 0.25], [-0.25, 0.25]]

[[domain.fixed_points]]  # Optional: pinned vertices
coords = [[-1, -1], [1, 1]]

Parameters:

Name Type Description Default
path str or Path

Path to TOML domain file.

required

Returns:

Type Description
Domain

Ready for admesh.triangulate().

Notes

The declared bbox in the file, if present, overrides the bounding box computed from ring extent. Omit bbox to auto-compute.

Source code in src/admesh/loaders.py
def load_domain_from_toml(path: str | Path) -> Domain:
    """Load a domain definition from a TOML file.

    Expected TOML structure::

        [domain]
        name = "example"
        bbox = [-1.0, -1.0, 1.0, 1.0]

        [[domain.rings]]
        coords = [[-1, -1], [1, -1], [1, 1], [-1, 1]]

        [[domain.rings]]  # Optional: interior islands
        coords = [[-0.25, -0.25], [0.25, -0.25], [0.25, 0.25], [-0.25, 0.25]]

        [[domain.fixed_points]]  # Optional: pinned vertices
        coords = [[-1, -1], [1, 1]]

    Parameters
    ----------
    path : str or Path
        Path to TOML domain file.

    Returns
    -------
    Domain
        Ready for admesh.triangulate().

    Notes
    -----
    The declared ``bbox`` in the file, if present, overrides the bounding box
    computed from ring extent. Omit ``bbox`` to auto-compute.
    """
    path = Path(path)
    with open(path, "rb" if hasattr(tomllib, "load") else "r") as f:  # type: ignore[arg-type]
        if hasattr(tomllib, "load"):
            data = tomllib.load(f)  # type: ignore[attr-defined]
        else:
            data = tomllib.load(f)  # type: ignore[attr-defined]

    domain_spec = data.get("domain", {})
    bbox_raw = domain_spec.get("bbox")
    bbox = None
    if bbox_raw:
        if len(bbox_raw) != 4:
            raise ValueError(f"TOML domain.bbox must be a 4-tuple; got {bbox_raw}")
        bbox = tuple(float(x) for x in bbox_raw)  # type: ignore[arg-type]

    rings_raw = domain_spec.get("rings", [])
    if not rings_raw:
        raise ValueError("TOML domain.rings must contain at least one ring (outer boundary)")

    rings = [np.array(r.get("coords", []), dtype=np.float64) for r in rings_raw]

    fixed_points = None
    fixed_raw = domain_spec.get("fixed_points")
    if fixed_raw:
        coords_list = [fp.get("coords") for fp in fixed_raw]
        if coords_list and coords_list[0]:
            fixed_points = np.array(coords_list[0], dtype=np.float64)

    # bbox intentionally recomputed from the land-boundary ring extent: the full
    # mesh-node extent includes open-ocean nodes outside the ring polygon (#205).
    return _domain_from_polygon(rings, pfix=fixed_points, bbox=bbox)

From the registry

Registry lookups need the valence-domains package. Manifest schemas 0.3 and 0.4 are both supported; see the valence-domains contract.

load_domain_from_registry

admesh.load_domain_from_registry

load_domain_from_registry(name: str, mesh_id: str = 'default@v1') -> Domain

Fetch a domain from the ADMESH-Domains registry by name.

Requires the valence-domains package. Network downloads through Mesh.load() additionally require the optional [registry] extra (pip install admesh2D[registry]).

Parameters:

Name Type Description Default
name str

Domain name in the registry (e.g. 'BaranjaHill').

required
mesh_id str

Mesh id within the domain. Defaults to "default@v1"; falls back to the first available mesh if the id is unknown.

'default@v1'

Returns:

Type Description
Domain

Domain ready for :func:admesh.triangulate.

Raises:

Type Description
ImportError

If valence-domains is not installed, or if huggingface_hub is needed for a network fetch and is not installed.

ValueError

If the domain name is not in the registry. On valence-domains releases that define MeshNotHostedError (a ValueError subclass), that error is raised when the mesh is registered but not hosted; its message names the mesh and says it is not hosted.

Examples:

>>> from admesh import load_domain_from_registry, triangulate
>>> domain = load_domain_from_registry('BaranjaHill')
>>> mesh = triangulate(domain, h0=0.1)
Source code in src/admesh/registry.py
def load_domain_from_registry(name: str, mesh_id: str = "default@v1") -> Domain:
    """Fetch a domain from the ADMESH-Domains registry by ``name``.

    Requires the ``valence-domains`` package. Network downloads through
    ``Mesh.load()`` additionally require the optional ``[registry]`` extra
    (``pip install admesh2D[registry]``).

    Parameters
    ----------
    name : str
        Domain name in the registry (e.g. ``'BaranjaHill'``).
    mesh_id : str, optional
        Mesh id within the domain. Defaults to ``"default@v1"``; falls
        back to the first available mesh if the id is unknown.

    Returns
    -------
    Domain
        Domain ready for :func:`admesh.triangulate`.

    Raises
    ------
    ImportError
        If ``valence-domains`` is not installed, or if ``huggingface_hub``
        is needed for a network fetch and is not installed.
    ValueError
        If the domain name is not in the registry. On ``valence-domains``
        releases that define ``MeshNotHostedError`` (a ``ValueError``
        subclass), that error is raised when the mesh is registered but not
        hosted; its message names the mesh and says it is not hosted.

    Examples
    --------
    >>> from admesh import load_domain_from_registry, triangulate
    >>> domain = load_domain_from_registry('BaranjaHill')
    >>> mesh = triangulate(domain, h0=0.1)
    """
    from admesh.fort14 import read_fort14

    mesh_ref = _resolve_mesh(name, mesh_id)
    src = read_fort14(mesh_ref.path)
    return Domain.from_mesh(src)

load_domain_with_metadata

admesh.load_domain_with_metadata

load_domain_with_metadata(name: str, mesh_id: str = 'default@v1') -> tuple[Domain, dict]

Load a domain plus provenance metadata from the registry.

Returns the same :class:Domain as :func:load_domain_from_registry plus a metadata dict drawn from the upstream Domain/Mesh objects (license, contributor, bounding box, etc.; missing fields are skipped).

Parameters:

Name Type Description Default
name str

Domain name in the registry.

required
mesh_id str

Mesh id within the domain.

'default@v1'

Returns:

Name Type Description
domain Domain

Domain ready for :func:admesh.triangulate.

metadata dict

Provenance fields extracted from the registry objects.

Raises:

Type Description
ImportError

If valence-domains (or huggingface_hub for the download) is not installed.

ValueError

If the domain name is not in the registry.

Source code in src/admesh/registry.py
def load_domain_with_metadata(
    name: str, mesh_id: str = "default@v1"
) -> tuple[Domain, dict]:
    """Load a domain plus provenance metadata from the registry.

    Returns the same :class:`Domain` as :func:`load_domain_from_registry`
    plus a metadata dict drawn from the upstream ``Domain``/``Mesh``
    objects (license, contributor, bounding box, etc.; missing fields
    are skipped).

    Parameters
    ----------
    name : str
        Domain name in the registry.
    mesh_id : str, optional
        Mesh id within the domain.

    Returns
    -------
    domain : Domain
        Domain ready for :func:`admesh.triangulate`.
    metadata : dict
        Provenance fields extracted from the registry objects.

    Raises
    ------
    ImportError
        If ``valence-domains`` (or ``huggingface_hub`` for the download)
        is not installed.
    ValueError
        If the domain name is not in the registry.
    """
    from admesh.fort14 import read_fort14

    _import_valence_domains()

    try:
        ad_domain = _valence_compat.get_domain_or_group(name)
    except (KeyError, AttributeError) as e:
        raise ValueError(
            f"Domain '{name}' not found in Valence-Domains registry"
        ) from e

    mesh_ref = _resolve_mesh(name, mesh_id)
    src = read_fort14(mesh_ref.path)
    domain = Domain.from_mesh(src)

    metadata: dict[str, Any] = {}
    for found in (
        _valence_compat.entry_metadata(ad_domain, _valence_compat.DOMAIN_FIELDS),
        _valence_compat.entry_metadata(mesh_ref, _valence_compat.MESH_FIELDS),
    ):
        for field, value in found.items():
            metadata.setdefault(field, value)

    if "bounding_box" not in metadata:
        metadata["bounding_box"] = getattr(ad_domain, "bounding_box", None)

    return domain, metadata

list_available_domains

admesh.list_available_domains

list_available_domains() -> dict[str, str]

List domains and collections available in the Valence-Domains registry.

Requires the valence-domains package.

Returns:

Type Description
dict[str, str]

Mapping of primary domain or collection name to a short description (full_name if populated, otherwise description, otherwise an empty string), sorted by domain name.

Raises:

Type Description
ImportError

If valence-domains is not installed.

Source code in src/admesh/registry.py
def list_available_domains() -> dict[str, str]:
    """List domains and collections available in the Valence-Domains registry.

    Requires the ``valence-domains`` package.

    Returns
    -------
    dict[str, str]
        Mapping of primary domain or collection name to a short description (``full_name`` if
        populated, otherwise ``description``, otherwise an empty string),
        sorted by domain name.

    Raises
    ------
    ImportError
        If ``valence-domains`` is not installed.
    """
    _import_valence_domains()
    items = _valence_compat.list_entries()
    return {
        d.name: (getattr(d, "full_name", None) or getattr(d, "description", None) or "")
        for d in sorted(items, key=lambda d: d.name)
    }