Source code for ldrb.cli

import argparse
import json
import logging
from dataclasses import dataclass
from pathlib import Path
from typing import Sequence

from mpi4py import MPI

import dolfinx

from . import io, ldrb


[docs] @dataclass class Geometry: mesh: dolfinx.mesh.Mesh ffun: dolfinx.mesh.meshtags markers: dict[str, list[int]]
def get_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( description=( "ldrb - Generate a microstructure for a given mesh and markers using the LDRB method." ) ) parser.add_argument("mesh_file", type=Path, help="Path to mesh file") parser.add_argument("-fo", "--full-output", action="store_true", help="Output all fields") parser.add_argument("-o", "--output", type=Path, default="output", help="Output file") parser.add_argument("-mn", "--mesh-name", type=str, default="Mesh", help="Name of the mesh") parser.add_argument( "-mf", "--markers-file", type=Path, default=None, help="Path to markers file" ) parser.add_argument( "-ffn", "--facet-tags-name", type=str, default="Facet tags", help="Name of the facet tags" ) parser.add_argument("-fs", "--fiber-space", type=str, default="P_1", help="Fiber space to use") parser.add_argument("-aenlv", "--alpha-endo-lv", type=float, default=60.0, help="Alpha endo LV") parser.add_argument("-aeplv", "--alpha-epi-lv", type=float, default=-60.0, help="Alpha epi LV") parser.add_argument("-aenrv", "--alpha-endo-rv", type=float, default=60.0, help="Alpha endo RV") parser.add_argument("-aepirv", "--alpha-epi-rv", type=float, default=-60.0, help="Alpha epi RV") parser.add_argument( "-aensept", "--alpha-endo-sept", type=float, default=60.0, help="Alpha endo sept" ) parser.add_argument( "-aepisept", "--alpha-epi-sept", type=float, default=-60.0, help="Alpha epi sept" ) parser.add_argument("-benlv", "--beta-endo-lv", type=float, default=0.0, help="Beta endo LV") parser.add_argument("-beplv", "--beta-epi-lv", type=float, default=0.0, help="Beta epi LV") parser.add_argument("-benrv", "--beta-endo-rv", type=float, default=0.0, help="Beta endo RV") parser.add_argument("-bepirv", "--beta-epi-rv", type=float, default=0.0, help="Beta epi RV") parser.add_argument( "-bensept", "--beta-endo-sept", type=float, default=0.0, help="Beta endo sept" ) parser.add_argument( "-bepisept", "--beta-epi-sept", type=float, default=0.0, help="Beta epi sept" ) parser.add_argument("-lv", "--lv-marker", type=int, default=10, help="Left ventricle marker") parser.add_argument("-rv", "--rv-marker", type=int, default=20, help="RV ventricle marker") parser.add_argument("-epi", "--epi-marker", type=int, default=30, help="Epicardium marker") parser.add_argument("-base", "--base-marker", type=int, default=40, help="Base marker") parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output") parser.add_argument("-ow", "--overwrite", action="store_true", help="Overwrite output file") # parser.add_argument("args", nargs=argparse.REMAINDER, help="Arguments to pass to the command") return parser def parse_geometry( mesh_file: Path, mesh_name: str = "Mesh", facet_tags_name="Facet tags", markers_file: Path | None = None, lv_marker: int = 10, rv_marker: int = 20, epi_marker: int = 30, base_marker: int = 40, **kwargs, ) -> Geometry: if mesh_file.suffix == ".xdmf": with dolfinx.io.XDMFFile(MPI.COMM_WORLD, str(mesh_file), "r") as xdmf: mesh = xdmf.read_mesh(name=mesh_name) # Read facet tags mesh.topology.create_connectivity(2, 3) facet_tags = xdmf.read_meshtags(mesh, name=facet_tags_name) if markers_file is not None: markers = json.loads(markers_file.read_text()) else: markers = dict(lv=[lv_marker], rv=[rv_marker], epi=[epi_marker], base=[base_marker]) return Geometry(mesh=mesh, ffun=facet_tags, markers=markers) def main(argv: Sequence[str] | None = None) -> int: parser = get_parser() args = vars(parser.parse_args(argv)) loglevel = logging.DEBUG if args["verbose"] else logging.INFO logging.basicConfig(level=loglevel) geo = parse_geometry(**args) results = ldrb.dolfinx_ldrb( mesh=geo.mesh, ffun=geo.ffun, markers=geo.markers, fiber_space=args["fiber_space"], alpha_endo_lv=args["alpha_endo_lv"], alpha_epi_lv=args["alpha_epi_lv"], alpha_endo_rv=args["alpha_endo_rv"], alpha_epi_rv=args["alpha_epi_rv"], alpha_endo_sept=args["alpha_endo_sept"], alpha_epi_sept=args["alpha_epi_sept"], beta_endo_lv=args["beta_endo_lv"], beta_epi_lv=args["beta_epi_lv"], beta_endo_rv=args["beta_endo_rv"], beta_epi_rv=args["beta_epi_rv"], beta_endo_sept=args["beta_endo_sept"], beta_epi_sept=args["beta_epi_sept"], ) outdir = args["output"] outdir.mkdir(exist_ok=True, parents=True) io.save( comm=geo.mesh.comm, filename=outdir / "microstructure.bp", functions=[results.f0, results.s0, results.n0], overwrite=args["overwrite"], ) if args["full_output"]: for k, v in results._asdict().items(): if v is None: continue if args["fiber_space"].startswith("Q"): # Cannot visualize Quadrature spaces yet continue print(k, v) with dolfinx.io.VTXWriter( geo.mesh.comm, outdir / f"{k}-viz.bp", [v], engine="BP4" ) as vtx: vtx.write(0.0) return 0