diff --git a/.github/workflows/clear-cache.yml b/.github/workflows/clear-cache.yml index 6673e4e003..98b4081ca0 100644 --- a/.github/workflows/clear-cache.yml +++ b/.github/workflows/clear-cache.yml @@ -13,11 +13,19 @@ jobs: with: script: | console.log("Getting action cache") - const caches = await github.rest.actions.getActionsCacheList({ + const parameters = { owner: context.repo.owner, repo: context.repo.repo, - }) - for (const cache of caches.data.actions_caches) { + per_page: 100, + direction: "asc", + sort: "created_at", + } + const caches = await github.paginate( + github.rest.actions.getActionsCacheList, + parameters, + (response) => response.data, + ) + for (const cache of caches) { if (cache.key.startsWith("ccache-")) { console.log("Deleting cache entry", cache) github.rest.actions.deleteActionsCacheById({ diff --git a/doc/main/api/orange.rst b/doc/main/api/orange.rst index 254a69ddfe..058d1c4caf 100644 --- a/doc/main/api/orange.rst +++ b/doc/main/api/orange.rst @@ -21,8 +21,8 @@ Runtime interfaces Geometry creation ----------------- -ORANGE geometry can (TODO: not yet, but eventually) be constructed from -multiple geometry representations, including Geant4 HEP geometry. +ORANGE geometry can be constructed from multiple geometry representations, +including Geant4 HEP geometry. CSG unit ^^^^^^^^ @@ -36,17 +36,18 @@ implementations and relationships, and specifying which of them are volumes. The Object interface is implemented by: Shape - A convex, finite region of space defined by the intersection of multiple - quadric surfaces. The Shape is implemented using a single ConvexRegion, + A finite (and usually convex) region of space defined by the intersection of + multiple quadric surfaces. The Shape is implemented using a single + IntersectRegion, which is an implementation that builds the underlying surfaces and bounding boxes. Shapes should be as simple as possible, aligned along and centered on the Z axis. Solid A shape that's hollowed out and/or has a slice removed. It is equivalent to a CSG operation on two shapes of the same type and an azimuthal wedge. -ExtrudedSolid - NOT YET IMPLEMENTED: a union of transformed solids along the Z axis, which - can also be hollowed and sliced. +PolySolid + A union of transformed solids along the Z axis, which can also be hollowed + and sliced azimuthally. Transformed Applies a transform to another CSG object. AnyObjects, AllObjects, and NegatedObject @@ -60,6 +61,8 @@ be reused in multiple locations. .. doxygenclass:: celeritas::orangeinp::Solid +.. doxygenclass:: celeritas::orangeinp::PolyCone + .. doxygenclass:: celeritas::orangeinp::Transformed .. doxygenclass:: celeritas::orangeinp::NegatedObject @@ -90,22 +93,22 @@ be reused in multiple locations. Transformed *-- Object class ShapeBase { - #ConvexRegion const& interior()* + #IntersectRegion const& interior()* } <> ShapeBase class Shape { -string label; - -ConvexRegion region; + -IntersectRegion region; } - Shape *-- ConvexRegion + Shape *-- IntersectRegion - class ConvexRegion { - +void build(ConvexSurfaceBuilder&)* + class IntersectRegion { + +void build(IntersectSurfaceBuilder&)* } - <> ConvexRegion - ConvexRegion <|-- Box - ConvexRegion <|-- Sphere + <> IntersectRegion + IntersectRegion <|-- Box + IntersectRegion <|-- Sphere class Box { -Real3 halfwidths @@ -144,7 +147,7 @@ Geant4 geometry translation ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Geant4 geometry is a hierarchy of "logical volumes" comprised of solids. -Deeper ("daughter") volumes are "placed" into a parent ("mother") volume after +Child ("daughter") volumes are "placed" into a parent ("mother") volume after applying a transformation (translation, rotation, reflection, or a combination), displacing the material in the parent volume. Besides this displacement, no overlap is allowed. @@ -155,12 +158,16 @@ always convex. See the `Geant4 documentation`_ for descriptions of all the predefined solids. A logical volume can be referenced multiple times, i.e., placed multiple times in -multiple different volumes. The Geant4-ORANGE converter decomposes (TODO: not -yet implemented) the graph of logical volume relationships into subgraphs that -each become a CSG unit. The decomposition should minimize the number of -subgraphs while minimizing (eliminating even?) the number of interior nodes -with multiple incoming edges, i.e., the number of solids that have to be -duplicated *within* a unit. +multiple different volumes. The Geant4-ORANGE converter decomposes the graph of +logical volume relationships into subgraphs that +each become a CSG unit. This decomposition is currently tuned so that: + +- Volumes with no children are directly placed as "material" leaf nodes into a + unit +- Logical volumes placed in a singular location without transforms are also + placed as materials with child volumes explicitly subtracted out +- Union or poly volumes (for now!) must be placed as materials even if they are + used multiple times and have daughter volumes. .. _Geant4 documentation: https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/index.html diff --git a/scripts/user/gdml-to-dot.py b/scripts/user/gdml-to-dot.py deleted file mode 100755 index 0a1531f655..0000000000 --- a/scripts/user/gdml-to-dot.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 UT-Battelle, LLC, and other Celeritas developers. -# See the top-level COPYRIGHT file for details. -# SPDX-License-Identifier: (Apache-2.0 OR MIT) -""" -Generate a GraphViz DAG of GDML logical volume relationships. - -The resulting output file can be converted to a PDF file with, e.g.:: - - dot -Tpdf:quartz demo.gdml.dot -o demo.pdf - -""" - -import json -import re -import xml.etree.ElementTree as ET -import networkx as nx - -from collections import defaultdict -from pathlib import Path - -class PointerReplacer: - sub = re.compile(r'0x[0-9a-f]{4,}').sub - - def __init__(self): - self.addrs = {} - - def repl(self, match): - val = self.addrs.setdefault(match.group(0), len(self.addrs)) - return f"@{val:d}" - - def __call__(self, s): - return self.sub(self.repl, s) - -class Graph: - def __init__(self): - self.nodes = [] - self.edges = defaultdict(int) - self.replace_pointers = PointerReplacer() - - def add_volume(self, el): - edges = self.edges - - pname = self.replace_pointers(el.attrib["name"]) - self.nodes.append(pname) - for vrel in el.iter("volumeref"): - dname = self.replace_pointers(vrel.attrib["ref"]) - edges[(pname, dname)] += 1 - - def add_world(self, vrel): - pname = self.replace_pointers(vrel.attrib["ref"]) - self.nodes.append(pname) - - @property - def weighted_edges(self): - for ((u, v), weight) in self.edges.items(): - yield (u, v, weight) - - @property - def labeled_edges(self): - for ((u, v), weight) in self.edges.items(): - yield (u, v, ("" if weight == 1 else f"×{weight}")) - - @property - def pointer_addresses(self): - return self.replace_pointers.addrs - -def read_graph(filename): - tree = ET.parse(filename) - structure = next(tree.iter("structure")) - - g = Graph() - for el in structure: - if el.tag in ('volume', 'assembly'): - g.add_volume(el) - else: - raise ValueError(f"Unrecognized structure tag: {el!r}") - g.add_world(tree.findall("./setup/world")[0]) - - return g - -def write_graph(g, filename): - graph = nx.DiGraph() - graph.add_nodes_from(reversed(g.nodes)) - graph.add_weighted_edges_from(g.labeled_edges, weight='label') - graph.graph['graph']={'rankdir':'LR'} - nx.nx_pydot.write_dot(graph, filename) - - with open(filename, 'a') as f: - f.write("// Pointer mapping:\n") - addrs = g.pointer_addresses.items() - for (idx, addr) in sorted((v, k) for (k, v) in addrs): - f.write(f"// {idx:04d}: {addr}\n") - -def main(*args): - from argparse import ArgumentParser - parser = ArgumentParser(description=__doc__, prog="gdml-to-dot") - parser.add_argument('-o', '--output') - parser.add_argument('input') - ns = parser.parse_args(*args) - input = Path(ns.input) - g = read_graph(input) - write_graph(g, ns.output or (input.stem + ".dot")) - -if __name__ == "__main__": - main() diff --git a/src/celeritas/io/ImportParameters.hh b/src/celeritas/io/ImportParameters.hh index 6dfdde7e2d..84df22f3e6 100644 --- a/src/celeritas/io/ImportParameters.hh +++ b/src/celeritas/io/ImportParameters.hh @@ -53,7 +53,7 @@ struct ImportEmParameters double msc_safety_factor{0.6}; //! MSC lambda limit [length] double msc_lambda_limit{1 * units::millimeter}; - //! Polar angle limii between single and multiple Coulomb scattering + //! Polar angle limit between single and multiple Coulomb scattering double msc_theta_limit{constants::pi}; //! Kill secondaries below production cut bool apply_cuts{false};