t4_geom_convert.Kernel.Volume package

Submodules

t4_geom_convert.Kernel.Volume.ByUniverse module

t4_geom_convert.Kernel.Volume.ByUniverse.by_universe(mcnp_cell_dict)

Classify MCNP cells by the universe which they belong to. Return the classification as a dictionary associating the universe number to the list of cell IDs.

t4_geom_convert.Kernel.Volume.CellConversion module

class t4_geom_convert.Kernel.Volume.CellConversion.CellConversion(int_cell, int_surf, d_dictClassT4, d_dictSurfaceT4, d_dicSurfaceMCNP, d_dicCellMCNP)

Bases: object

Class which contains methods to convert the Cell of MCNP in T4 Volume

apply_trcl(trcls, geometry)

Apply the given coordinate transformation to the given cell AST (geometry).

Returns:

the transformed AST

cell_transform(cell_key, transform, cache=True)

Apply transform to cell, update dictionaries and return the ID of the new cell.

static conv_equa(list_surface)

Method converting a list of if of surface and return a tuple with the informations of the volume EQUA T4

static conv_intersection(*ids)

Convert a T4 INTE and return a tuple with the information of the T4 VOLUME

static conv_union(*ids)

Convert a T4 UNION and return a tuple with the information of the T4 VOLUME

static conv_union_helpers(*ids, union_ids)

Convert a T4 UNION and return a tuple with the information of the T4 VOLUME

convert_cellref(cell, matching, union_ids)
convert_surface(surf, idorigin)
develop_lattice(key)
extract_surfaces(cell)
pot_complement(tree)
pot_convert(cell, matching, union_ids)
pot_expand_surfs(p_tree, matching)

Replace collections of surfaces with ASTs representing the intersection/union of the collection (necessary for one-nappe cones and macrobodies). Also replace MCNP surface IDs with T4 surface IDs.

pot_fill(key, dict_universe, inline_filled=False, inline_filling=False)
pot_flag(p_tree)

Method that takes a tree and return a tuple of tuple with flag to decorate each tree in the tree.

pot_optimise(p_tree)

Method that optimizes the MCNP cells.

pot_to_t4_cell(p_tree, idorigin, matching, union_ids)

Take the tree create by pot_flag() and fill a dictionary (of VolumeT4 instance).

pot_transform(p_tree, p_transf)

t4_geom_convert.Kernel.Volume.CellConversionError module

Module containing the definition of the CellConversionError class.

exception t4_geom_convert.Kernel.Volume.CellConversionError.CellConversionError

Bases: Exception

A class that models errors in the cell conversion process.

t4_geom_convert.Kernel.Volume.CellInlining module

Utilities for cell definition inlining.

t4_geom_convert.Kernel.Volume.CellInlining.compute_inlining_scores(dic, occurrences)

Associate scores for inlining to each of the cells in occurrences. The lower the score, the more likely the cell is to be inlined.

t4_geom_convert.Kernel.Volume.CellInlining.extract_subcells(geometry)

Extract any subcells from the given geometry tree and return them as a list.

>>> from .CellMCNP import CellRef
>>> extract_subcells(['*', 1, 2])
[]
>>> extract_subcells(['*', 1, CellRef(100), 2])
[100]
>>> extract_subcells(['*', 1, CellRef(100), [':', CellRef(5), CellRef(6)]])
[100, 5, 6]
t4_geom_convert.Kernel.Volume.CellInlining.find_occurrences(dic)

Find occurrences of inlined cells. Returns a dictionary associating a cell id key to a list of cell ids where key is inlined.

t4_geom_convert.Kernel.Volume.CellInlining.geometry_size(geometry)

Count the number of nodes in the given geometry.

>>> from .CellMCNP import CellRef
>>> geometry_size(['*', 1, 2])
2
>>> geometry_size(['*', 1, CellRef(100), 2])
3
>>> geometry_size(['*', 1, CellRef(100), [':', CellRef(5), CellRef(6)]])
4
t4_geom_convert.Kernel.Volume.CellInlining.inline_cells(dic, max_inline_score)

Perform inlining on the cells in dic.

t4_geom_convert.Kernel.Volume.CellInlining.inline_cells_worker(geometry, dic, to_inline)

Inline the cells in the to_inline set in geometry. Returns a new geometry.

t4_geom_convert.Kernel.Volume.CellMCNP module

class t4_geom_convert.Kernel.Volume.CellMCNP.CellMCNP(p_materialID, p_density, syntaxTreeMCNP, p_importance, p_universe, fillid, filltr, lattice, trcl, idorigin=None)

Bases: object

Class which permit to access precisely to the information of the block CELLS.

copy()
evaluateASTMCNP()

Method evaluating the syntax tree of the geometry of a cell of MCNP.

inverseASTMCNP()

Method applying the De Morgan law on a syntax tree.

class t4_geom_convert.Kernel.Volume.CellMCNP.CellRef(cell)

Bases: object

t4_geom_convert.Kernel.Volume.ConstructVolumeT4 module

t4_geom_convert.Kernel.Volume.ConstructVolumeT4.construct_volume_t4(mcnp_parser, lattice_params, cell_cache_path, dic_surface_t4, dic_surface_mcnp, inline_filled, inline_filling, max_inline_score)

A function that orchestrates the conversion steps for TRIPOLI-4 volumes.

t4_geom_convert.Kernel.Volume.ConstructVolumeT4.extract_tr_surf_ids(mcnp_dict)

Return the list of MCNP surface IDs above 1000.

Surface IDs above 1000 are interpreted by MCNP as (surf_id + 1000*cell_id), where cell_id indicates a cell with a trcl card. The surface is modified by applying the trcl card of the cell.

t4_geom_convert.Kernel.Volume.ConstructVolumeT4.extract_used_surfaces(volumes)

Return the IDs of the surfaces used in the given volumes, as a set.

t4_geom_convert.Kernel.Volume.ConstructVolumeT4.remove_empty_volumes(dic_volume, union_ids)

Remove cells that are patently empty.

t4_geom_convert.Kernel.Volume.ConstructVolumeT4.remove_unused_volumes(dic)

Remove unused virtual (FICTIVE) volumes from the given dictionary. This function modifies the given dictionary in place.

Parameters:

dic (DictVolumeT4) – a dictionary of VolumeT4 objects.

>>> from .VolumeT4 import VolumeT4
>>> dic = DictVolumeT4()
>>> dic[1] = VolumeT4([], [], ops=['UNION', (2, 3)], fictive=False)
>>> dic[2] = VolumeT4([], [], ops=None, fictive=True)
>>> dic[3] = VolumeT4([], [], ops=None, fictive=True)
>>> dic[4] = VolumeT4([], [], ops=None, fictive=True)
>>> dic[5] = VolumeT4([], [], ops=None, fictive=False)
>>> remove_unused_volumes(dic)
>>> sorted(list(dic.keys()))
[1, 2, 3, 5]

t4_geom_convert.Kernel.Volume.DictVolumeT4 module

class t4_geom_convert.Kernel.Volume.DictVolumeT4.DictVolumeT4

Bases: MutableMapping

A simple wrapper around an collections.OrderedDict for storing VolumeT4 objects.

copy()

Return a copy of self.

t4_geom_convert.Kernel.Volume.Lattice module

Utilities for handling lattices.

class t4_geom_convert.Kernel.Volume.Lattice.LatticeBounds(bounds)

Bases: object

A simple class to hold a list of range bounds. It provides some useful services such as the size() method.

copy()

Return a copy of self.

dims()

Return the number of non-trivial dimensions.

indices()

Yield all the valid indices in the bounds, in canonical order (loop over the leftmost index first).

>>> bounds = LatticeBounds([(-1, 1), (-2, 2)])
>>> list(bounds.indices())
[(-1, -2), (0, -2), (1, -2), (-1, -1), (0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1), (1, 1), (-1, 2), (0, 2), (1, 2)]
>>> list(LatticeBounds([(0, 2)]).indices())
[(0,), (1,), (2,)]
size()

Return the total size of the range bounds, i.e. the product of the range lengths.

>>> LatticeBounds([(0, 4)]).size()
5
>>> LatticeBounds([(-1, 1), (-3, 3)]).size()
21
>>> LatticeBounds([]).size()
1
exception t4_geom_convert.Kernel.Volume.Lattice.LatticeError

Bases: Exception

An exception class for errors generated during lattice processing.

class t4_geom_convert.Kernel.Volume.Lattice.LatticeSpec(bounds, spec)

Bases: object

A simple class that holds a list of n*m*l integers and provides n-dimensional indexing into the list.

items()

Iterate over the lattice indices and the lattice specification, as (indices, spec) pairs.

>>> bounds = LatticeBounds([(1, 2), (0, 1)])
>>> spec = LatticeSpec(bounds, ['a', 'b', 'c', 'd'])
>>> list(spec.items())
[((1, 0), 'a'), ((2, 0), 'b'), ((1, 1), 'c'), ((2, 1), 'd')]
t4_geom_convert.Kernel.Volume.Lattice.areHexSidesAdjacent(plane1, plane2, other_surf1, other_surf2)

If plane1 and plane2 are adjacent in the hexagonal prism closed off by other_plane1 and other_plane2, this function returns the line given by the intersection of the two planes, in the form of a (point, vector) pair; otherwise, it returns None.

t4_geom_convert.Kernel.Volume.Lattice.hexLatticeBaseVectors(surfaces)

Compute the base vectors for a hexagonal lattice.

t4_geom_convert.Kernel.Volume.Lattice.hexSortSides(surfs)

Return an adjacency dictionary for the sides of the hexagon. The dictionary keys are pairs of indices of sides of the hexagon; the possible values are None if the given sides are not adjacent, or a straight line (in (point, direction) form) representing the intersection between the two planes if they are adjacent. The keys are always sorted in such a way that the smallest index comes first: so, for instance, (0, 1) is a possible key, but (1, 0) is not.

The surfs argument is the list of surfaces representing the hexagon. Each surface must be a (plane, side) pair, where plane is a plane (represented as a (point, normal) pair) and side indicates on which side of the plane the hexagonal cell lies (±1). The surfaces in surfs must appear in the canonical order: first, the surface that separates the base cell of the hexagonal lattice from the (1, 0, 0) cell; then the opposite plane; then the surface that separates the base cell from the (0, 1, 0) cell; then the opposite plane; and, finally, the two remaining planes, in no particular order.

As an example, consider the regular hexagon:

>>> from math import cos, sin, pi, isclose, fabs
>>> vertices = [(cos(i*pi/3.), sin(i*pi/3.), 0.) for i in range(6)]
>>> sides = [vdiff(v2, v1)
...          for v1, v2 in zip(vertices, vertices[1:] + [vertices[0]])]

We compute the normals to the planes:

>>> from t4_geom_convert.Kernel.VectUtils import renorm, vect
>>> normals = [renorm(vect(side, (0, 0, 1))) for side in sides]
... # these are outgoing normals

The hexagon looks like this:

2
———
/
4 / 0
/
/
1 / 5
/
———
3

The numbers indicate the way we have chosen to order the planes. We construct the list of surfaces to respect this constraint:

>>> planes = [((vertices[i], normals[i]), -1)  # -1 is the side
...           for i in (0, 3, 1, 4, 2, 5)]

Here is the adjacency dictionary:

>>> adj = hexSortSides(planes)
>>> adj[(0, 2)] is not None
True
>>> adj[(0, 5)] is not None
True
>>> adj[(0, 1)] is None
True

We can also modify the plane numbering. For instance:

5
———
/
2 / 0
/
/
1 / 3
/
———
4
>>> planes = [((vertices[i], normals[i]), -1)  # -1 is the side
...           for i in (0, 3, 2, 5, 4, 1)]
>>> adj = hexSortSides(planes)
>>> adj[(0, 2)] is None
True
>>> adj[(0, 3)] is not None
True
>>> point, direction = adj[(0, 3)]
>>> (isclose(point[0], 1)
...  and isclose(point[1], 0, abs_tol=1e-10)
...  and isclose(point[2], 0, abs_tol=1e-10))
True
>>> (isclose(direction[0], 0, abs_tol=1e-10)
...  and isclose(direction[1], 0, abs_tol=1e-10)
...  and isclose(fabs(direction[2]), 1))
True

We can also test a weird hexagon:

>>> vertices = [(0, 1, 0), (3, 1, 0), (5, 2, 0),
...             (5, 3, 0), (2, 3, 0), (0, 2, 0)]
>>> sides = [vdiff(v2, v1)
...          for v1, v2 in zip(vertices, vertices[1:] + [vertices[0]])]
>>> normals = [renorm(vect(side, (0, 0, 1))) for side in sides]

It looks approximately like this:

0
/———+
3 / |
/ | 4
| /
5 | / 2
x———/
1

The x represents the first vertex and the sides unfold counterclockwise. We impose the numbering given in the figure:

>>> planes = [((vertices[i], normals[i]), -1)  # -1 is the side
...           for i in (3, 0, 1, 4, 2, 5)]
>>> adj = hexSortSides(planes)
>>> adj[(0, 1)] is None
True
>>> adj[(0, 2)] is None
True
>>> adj[(0, 3)] is not None
True
>>> point, _ = adj[(0, 3)]
>>> point
(2.0, 3.0, 0.0)
>>> point, _ = adj[(1, 2)]
>>> point
(3.0, 1.0, 0.0)
t4_geom_convert.Kernel.Volume.Lattice.hexVertices(surfs, first_side)

Return the vertices of a base of the hexagonal prism described by the given surfaces and the direction of the prism axis.

The vertices are returned as a list of points. This function guarantees that the returned vertices are consecutive (i.e. v[i] and v[i+i] share a side, and so do v[-1] and v[0]).

The first_side argument is an integer from 0 to 5 that specifies which side should be shared by v[0] and v[-1].

The prism axis is returned as a vector.

Example:

>>> vertices = [(0, 1, 0), (3, 1, 0), (5, 2, 0),
...             (5, 3, 0), (2, 3, 0), (0, 2, 0)]
>>> sides = [vdiff(v2, v1)
...          for v1, v2 in zip(vertices, vertices[1:] + [vertices[0]])]
>>> from t4_geom_convert.Kernel.VectUtils import renorm, vect
>>> normals = [renorm(vect(side, (0, 0, 1))) for side in sides]
>>> planes = [((vertices[i], normals[i]), -1)  # -1 is the side
...           for i in (3, 0, 1, 4, 2, 5)]

This is the same weird hexagonal prism that is used in the docstring for hexSortSides().

Calling hexVertices() with first_side=0 yields the vertices of the hexagon sorted in such a way that the first one and the last one lie on side 0:

>>> verts, axis = hexVertices(planes, 0)
>>> from t4_geom_convert.Kernel.VectUtils import isPointOnPlane
>>> isPointOnPlane(verts[0], planes[0][0])
True
>>> isPointOnPlane(verts[-1], planes[0][0])
True

Other values of first_side lead to different orderings of the vertices:

>>> verts, axis = hexVertices(planes, 4)
>>> isPointOnPlane(verts[0], planes[4][0])
True
>>> isPointOnPlane(verts[-1], planes[4][0])
True

We can check that each plane contains exactly two vertices:

>>> [sum(1 for vert in verts if isPointOnPlane(vert, plane[0]))
...  for plane in planes]
[2, 2, 2, 2, 2, 2]

The axis vector, by construction is parallel to all the side planes:

>>> from t4_geom_convert.Kernel.VectUtils import isVectorParallelToPlane
>>> all(isVectorParallelToPlane(axis, plane[0]) for plane in planes)
True

It is also possible to pass a list of eight planes. In this case, the hexagon is guaranteed to lie on the “top” plane (i.e. surfs[-2]).

>>> planes += [(((10.0, 0.0, 0.0), (1.0, 1.0, 1.0)), -1),
...            (((-10.0, 0.0, 0.0), (1.0, 1.0, 1.0)), 1)]
>>> verts, axis = hexVertices(planes, 2)
>>> all(isPointOnPlane(vert, planes[-2][0]) for vert in verts)
True
>>> [sum(1 for vert in verts if isPointOnPlane(vert, plane[0]))
...  for plane in planes[:-2]]
[2, 2, 2, 2, 2, 2]
>>> all(isVectorParallelToPlane(axis, plane[0]) for plane in planes[:-2])
True
t4_geom_convert.Kernel.Volume.Lattice.latticeReciprocal(base_vecs)

Yield the unit vectors of the reciprocal lattice.

Parameters:

base_vecs – a list of one, two or three vectors describing the base cell of the direct lattice. Vectors are triples of the form (x, y, z).

Returns:

a list of one, two or three base vectors of the reciprocal lattice.

>>> from math import isclose
>>> from ..VectUtils import scal

In the case of a one-dimensional lattice, the reciprocal vector has the same direction as the base vector, but its length is equal to the inverse of the length of the direct vector: >>> vec1 = (3, 0, 4) >>> rec1 = latticeReciprocal([vec1])[0] >>> isclose(scal(rec1, vec1), 1.0) True >>> isclose(scal(rec1, rec1) * scal(vec1, vec1), 1.0) True

A few cases with two-dimensional lattices. The square lattice is self-dual: >>> vec1 = (1, 0, 0) >>> vec2 = (0, 1, 0) >>> latticeReciprocal([vec1, vec2]) [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0)]

A skew lattice: >>> vec1 = (1, 0, 0) >>> vec2 = (1, 1, 0) >>> latticeReciprocal([vec1, vec2]) [(1.0, -1.0, 0.0), (0.0, 1.0, 0.0)]

In three dimensions, the cubic lattice is self-dual: >>> vec1 = (1, 0, 0) >>> vec2 = (0, 1, 0) >>> vec3 = (0, 0, 1) >>> latticeReciprocal([vec1, vec2, vec3]) [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)]

The length of the reciprocal vectors are inversely proportional to the length of the base vectors of the direct lattice: >>> vec1 = (2, 0, 0) >>> vec2 = (0, 4, 0) >>> vec3 = (0, 0, 0.5) >>> latticeReciprocal([vec1, vec2, vec3]) [(0.5, 0.0, 0.0), (0.0, 0.25, 0.0), (0.0, 0.0, 2.0)]

t4_geom_convert.Kernel.Volume.Lattice.latticeVector(base_vecs, index)

Compute a lattice displacement vector from a set of basis vectors and a tuple of indices.

>>> base_vecs = [(1, 0, 0),
...              (0, 0, 2)]
>>> latticeVector(base_vecs, (0, 0))
(0.0, 0.0, 0.0)
>>> latticeVector(base_vecs, (3, 2))
(3.0, 0.0, 4.0)
>>> latticeVector(base_vecs, (-1, -1))
(-1.0, 0.0, -2.0)
t4_geom_convert.Kernel.Volume.Lattice.parse_ranges(intervals)

Parse a list of intervals (in the MCNP syntax: start:end) into a list of pairs of integers.

Parameters:

intervals (list(str)) – A list of strings of the form 'i:j', where i and j are integers.

Returns:

a list of pairs of integers representing the parsed bounds

Return type:

list((int,int))

>>> parse_ranges(['0:4', '0:4', '0:4'])
[(0, 4), (0, 4), (0, 4)]
>>> parse_ranges(['1:2', '3:4', '5:6', '7:8'])
[(1, 2), (3, 4), (5, 6), (7, 8)]
>>> parse_ranges([])
[]
>>> parse_ranges(['0::5'])
Traceback (most recent call last):
    ...
ValueError: needs exactly 2 colon-separated range bounds in argument '0::5'
t4_geom_convert.Kernel.Volume.Lattice.squareLatticeBaseVectors(surfaces)

Compute the base vectors of a square lattice.

t4_geom_convert.Kernel.Volume.Lattice.squareLatticeReciprocalVecs(surfaces)

Compute the reciprocal vectors of a square lattice.

t4_geom_convert.Kernel.Volume.TreeFunctions module

t4_geom_convert.Kernel.Volume.TreeFunctions.isCellRef(tree)

Returns True if tree is a CellRef.

Return type:

bool

t4_geom_convert.Kernel.Volume.TreeFunctions.isIntersection(tree)

Function that tells if a node is an intersection.

Return type:

bool

t4_geom_convert.Kernel.Volume.TreeFunctions.isLeaf(tree)

Function which tells if a tree is an instance of a Surface or a Geometry.

Return type:

bool

t4_geom_convert.Kernel.Volume.TreeFunctions.isSurface(tree)

Returns True if tree is a surface.

Return type:

bool

t4_geom_convert.Kernel.Volume.TreeFunctions.isUnion(tree)

Function that tells if a node is a union.

Return type:

bool

t4_geom_convert.Kernel.Volume.TreeFunctions.largestPureIntersectionNode(nodes)

Returns the index of the largest node of the nodes list that is an intersection of surfaces, or None if no such node is present.

>>> from .CellMCNP import CellRef
>>> largestPureIntersectionNode([[2, '*', 1, 2], [3, '*', 4, 5, 6]])
1
>>> largestPureIntersectionNode([4, 5, 6])
0
>>> largestPureIntersectionNode([[2, '*', 1, 2],
...                              [3, '*', 4, 5, 6],
...                              [4, ':', 7, 8, 9, 10]])
1
>>> largestPureIntersectionNode([[3, '*', 4, 5, 6],
...                              [2, '*', 1, 2],
...                              [4, ':', 7, 8, 9, 10]])
0
>>> largestPureIntersectionNode([[2, ':', 1, 2], [3, ':', 4, 5, 6]])
>>> largestPureIntersectionNode([[3, '*', CellRef(4), 5, 6],
...                              [2, '*', 1, 2]])
1

t4_geom_convert.Kernel.Volume.VolumeT4 module

class t4_geom_convert.Kernel.Volume.VolumeT4.VolumeT4(pluses, minuses, ops=None, idorigin=None, fictive=True)

Bases: object

Class which permits to access precisely of the value of a volume T4.

comment()
copy()

Return a copy of self.

empty()

Return True if the cell is patently empty, i.e. if the same surface ID appears with opposite signs.

surface_ids()

Return the surface IDs used in this volume, as a set.

Module contents