Conversation
- Ellipsoid.approximate: correct axis mapping for the c >= a >= b ordering and sort the b >= c >= a ordering explicitly (grains were tessellated with the wrong orientation) - Ellipsoid.limits: exact bounding box for rotated ellipsoids - Ellipsoid: fix the (c, ratio_bc) solver, write rot_seq with quoted axes - Ellipse: axes keyword, orthonormality check of matrix/orientation, 'axes' in area_expectation - Ellipse/Ellipsoid.reflect: broadcasting and unscaling - *_expectation: accept numpy scalars; seed the Monte-Carlo estimates - NBox.within honours the rotation; NBox.__str__ full precision - Rectangle(length=...) alone; Square.area_expectation return value - Sphere.plot on a fresh figure; NSphere.best_fit with integer points - __eq__ for Ellipse, Ellipsoid and NBox Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- from_info: iterate keywords in sorted order (the RNG chain depended on the per-process set order) and do not modify the rng_seeds argument - calc_rtol is the single implementation of the overlap-tolerance fit (position() used a duplicate); handles a single seed - Seed: breakdowns are float arrays also when read from a file (seeds loaded from seeds.txt could not be repositioned); a geometry center or position is respected; update_breakdown(); robust __eq__; clear error for unsupported shapes; parseable __str__/__repr__ - position(): 'random' entries in per-axis position distributions - sample_pos_within raises instead of looping forever - SeedList(seeds=None); numpy arrays as per-item plot keywords; plot_breakdown in 3D on a fresh figure; remove unused sampling helpers Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Cells that intersect a circular/elliptical domain without a vertex inside it are no longer dropped; cells cut twice are clipped correctly; a cell containing the domain becomes a boundary polygon - _loop_area indexes the loop (stored areas of clipped cells were wrong) - _segment_cross uses a fixed number of bisections (hung for large coordinates) - edge_opt works on a copy, displaces seeds rigidly and applies only the accepted moves to the caller's seeds; quiet unless verbose - Full-precision points in text files; write(format='poly') writes the file; plot() in 3D on a fresh figure; numpy arrays as per-item plot keywords; __eq__ is silent and linear Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- 3D: honour mesh_max_volume and per-phase max_volume (TetGen never saw them); 2D: per-phase values are not capped by the global one and an infinite global value is not passed as the mis-parsed switch 'ainf' - RasterMesh: 'ij' grid indexing (elements were clockwise / inverted), facets derived from cell differences, correct Abaqus face ids, vtk output (also with voids), 3D plot - tet/tri writer: valid .ele/.edge/.face files - Abaqus: exterior surface unions only reference defined surfaces; polymesh optional - Full-precision points in text files; no dangling headers; clear errors for unknown meshers and non-simplex elements; gmsh path with default phases and without unused nodes; _sort_facets reports disjoint loops Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- cdf inputs: pass density=False to rv_histogram (distributions were distorted for unevenly spaced x); 'pdf' as an alias of 'histogram' - plot_tri: the 3D visibility walk terminates when voids touch the boundary (it looped forever) - dict_convert passes the input file path into repeated tags (relative filenames failed with more than one material) - from_str: no infinite recursion on 'true'/'false' substrings; inf/nan - run(): no mutable defaults, arguments are not modified; unsupported output types and missing input files reported clearly; mesher names case-insensitive - <include>: repeated materials are concatenated instead of discarded - verification: angle_rad inputs are kept, 'random' orientations and vector-valued parameters work, unknown phase fields are ignored, the caller's phases are not modified; single-material colour maps Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
SeedList.position(periodic=...) accepts True, a list of booleans or axis
names ('x', 'xy', ...). A seed that crosses a periodic face of a
rectangular domain takes part in the overlap test through its images
translated across the domain (all combinations of the crossed faces, so
edges and corners are covered); placed seeds enter the AABB tree with
their images. _misc.periodic_axes parses the specification and
_misc.periodic_domain_limits checks the domain.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PolyMesh.from_seeds(periodic=...) computes the Laguerre tessellation in Voro++'s periodic mode (breakdown centers wrapped into the domain), cuts each wrapped cell at the periodic faces and translates the outside pieces into the domain, so the pieces of a seed tile the unit cell. Cut edges become wall facets; neighbors are resolved to the pieces sharing the edge. Points and facets on opposite faces are paired, snapped to exact translates, and stored in periodic_axes / periodic_points / periodic_facets, which the text format persists. 3D raises NotImplementedError for now. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A periodic PolyMesh gives a periodic TriMesh: the facets on opposite periodic faces are subdivided identically and Triangle runs with -Y (no Steiner points on the boundary), so the nodes on opposite faces are images of each other. Nodes and facets are paired, snapped to exact translates and stored in periodic_axes / periodic_nodes / periodic_facets, persisted in the text format and written to Abaqus as node sets in matching order. Raster meshes of periodic polymeshes are paired too (the mesh size must divide the domain length). gmsh is not supported for periodic meshes. The pairing helpers live in _misc and are shared with PolyMesh. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ation <periodic> is a field of <domain> in the XML input (True, a list of flags, or axis names such as 'xy'); cli.run(periodic=...) passes it to the seed placement and the tessellation, the meshes inherit it. seeds_of_best_fit unwraps the points of grains split by the periodic faces around their seed before fitting. Documented in the domain page and the changelog. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Cells that cross a periodic face of a box are cut by the face planes (convex polyhedron clipping, with the cap face taken as the convex hull of the cut points), the pieces are translated back into the domain and their neighbours are resolved, so the polyhedral mesh tiles space along the periodic axes. Vertices within a small tolerance of a cut plane are snapped onto it before cutting and nearly coincident points are merged globally afterwards, which keeps the cuts of the two cells sharing a face consistent and lets the points and facets on opposite faces be paired exactly, as in 2D. Pieces are dropped only when they are flat. Validated against the non-periodic tessellation of the 3x3x3 tiled seeds (per-seed volumes) and against a single sphere tiling the cube. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The polygons on the periodic faces of the polyhedral mesh are fan-triangulated and their images on the opposite face receive the corresponding triangles, then TetGen runs with -Y (no Steiner points on the boundary), so the nodes and the surface triangles on opposite faces coincide. Raster meshes, the periodic node/facet pairs in the text files and the Abaqus periodic node sets already worked in 3D and are now tested there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Cells of the same amorphous phase that share a facet are merged into one region of the mesh. The Triangle/TetGen mesher labelled the region with the seed number of its first cell while the raster mesher, the gmsh mesher and the Abaqus writer used the smallest seed number of the region. Both conventions agree when the regions of the polymesh are in seed order, but not in a periodic mesh, where the pieces of the cells that cross the periodic faces reorder the regions. A single helper now computes the label of every region: the smallest seed number of the merged region, which in a periodic mesh also joins the pieces of one seed and the amorphous cells that touch across a periodic face, since they form one region of the periodic medium. The new tests check that the cells of a periodic mesh partition the domain (closed convex cells, volumes adding up to the domain, random points in exactly one cell) and that the elements partition the cells (positive volumes, manifold faces, attribute volumes equal to the cell volumes, element centroids inside the cells of their attribute). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
With -Y (no Steiner points on the boundary), TetGen can leave some of the sub-faces of a facet unmarked even though the tetrahedra conform to it. The region attribute of the cell on one side then floods through the unmarked sub-faces into the cell on the other side, and the facet is incomplete in the output. This happened for one facet in 30 random periodic meshes (two tetrahedra with the wrong seed number). For periodic meshes, the element attributes and the facets are now computed from the geometry of the polymesh: each element gets the label of the convex cell that contains its centroid, the facets are the faces between elements with different labels and the faces on the boundary, and each is numbered by the polymesh facet it lies on, found from the cells that contain the center of the face (merged amorphous cells are not separated by facets of the mesh, so an element may span several of them). A mesh that does not conform to the polymesh raises an error instead of being mislabelled silently. The geometry tests now also check that every face between elements with different attributes is a facet of the mesh and that the facets cover the facets of the polymesh exactly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The quality and size settings of the triangular/tetrahedral mesh (min_angle, max_volume, the max_volume of each phase, max_edge_length) now act on periodic meshes as on non-periodic ones. Fixing the boundary with -Y is not an option: the bundled Triangle then degrades every wall-adjacent triangle, and the bundled TetGen refuses any Steiner point that encroaches a sub-face, interior facets included, unless every facet is already at the target size. In 2D, the cells that touch the periodic faces are copied outside the faces while meshing, so that Triangle sees the same geometry on both sides of each face and refines both faces of a pair the same way. The mesh is built without -Y; when some nodes on the faces have no image, the points Triangle added on the faces are put on both faces (as fine as the finest of the two, not their union) and the mesh is built again, which converges in one to three passes. The elements outside the domain are removed, and the rare nodes still without an image are mirrored by splitting the element behind them. The quality equals that of the free mesh: the triangles below the minimum angle are those at cell corners with smaller angles, in both. In 3D, the domain is meshed once as usual (with all the facets given as constrained Delaunay triangulations, since TetGen 1.5 crashes on polygon facets with collinear vertices), then every facet is triangulated with the points TetGen added on it, the facets on opposite periodic faces with the points of both faces (merged by a spacing-aware rule) and with a minimum angle of 20 degrees and the area given by the size settings, and the mesh is built again with the facets fixed. Compared with the free mesh of the same periodic polymesh, the mesh has 20-25 % more tetrahedra and a 5th-percentile dihedral angle of 18-19 instead of 20-21 degrees; the maximum volumes, per phase too, and the maximum edge length on the faces are met, and the nodes on opposite faces match exactly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two CLI examples, periodic_2D.xml (a square periodic in both directions, with circular and elliptical grains, edge optimization and mesh quality settings) and periodic_3D.xml (a cube of two phases of spherical grains, periodic in the three directions), and a package example, periodic_tiling.py, which builds a 2D and a 3D periodic microstructure with the API and plots them tiled, so that the grains continue across the periodic faces and the paired nodes of the triangular mesh are visible. Each has a page in the examples of the documentation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The coefficients of the rtol='fit' rational polynomial dated from the original submission of the paper; these are the published ones. For very wide size distributions they allow less overlap (2D asymptote 0.18 instead of 0.36), so some seeds of high-cv inputs may be rejected during placement (basalt example: 41 of 1300). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
max_edge_length now acts in 3D on the grain boundaries: when it is set, the facets of the polyhedral mesh are triangulated to that edge length (with Triangle, minimum angle 20 degrees) before TetGen meshes the cells, for periodic and non-periodic meshes alike, so that the elements can be smaller at the interfaces than inside the grains. TetGen has no such control of its own. Meshing a periodic polymesh with many small cells showed that the geometric tests of a mesh against its polymesh were too strict: the snapping of the points to the periodic faces makes some facets non-planar by up to a few 1e-7 of the domain size, more than the tolerances of 1e-9 and 1e-8 used to find the cell of an element and the facet of a face, so that a conforming mesh was rejected as non-conforming. The tolerance is now four times the largest non-planarity of the facets, each element is assigned to the cell in which its centroid is deepest, and the extra points of a facet are projected on its plane. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…aces Voro++ computes each cell on its own, so two cells that share a vertex hold copies of it that differ by its precision (a few 1e-9 of the domain here), and in periodic mode the copies can lie in different images of the domain. The pieces of the two cells were matched along their shared edges with a tolerance of 1e-10, which failed for such a vertex during an edge optimization: "Cannot resolve the neighbor of the edge ...". The copies of the vertices that coincide, modulo the length of the domain along the periodic axes, are now replaced by their mean before the cells are cut, and snapped onto the periodic faces once for all cells, so that the cells are cut consistently and their pieces match exactly; the pieces are matched with the merge tolerance of the points. Verified on the failing case, the tiled-reference tests and a stress test of random realizations with edge optimization in 2D and 3D. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e refinement pbx_2D.xml and pbx_3D.xml build a periodic particulate composite, such as a plastic-bonded explosive: crystalline inclusions with lognormal sizes in a binder, which is a matrix phase seeded with small circles or spheres. pbx_interface_2D.xml and pbx_interface_3D.xml mesh the same material with elements refined along the grain boundaries (the binder-inclusion interfaces) and coarse inside the grains, through max_edge_length and a larger max_volume. Each has a page in the examples of the documentation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A seed that barely crosses a periodic face, or ends just inside it, leaves a thin piece of its grain on the opposite face, and the mesh has elements much smaller than its target size there. The new periodic_margin option of SeedList.position (and setting of the CLI) rejects the positions where a seed ends within the margin of a periodic face or crosses it by less than the margin, and tries another position; 'auto' in the CLI sets the margin to half the target edge length of the mesh, from mesh_max_edge_length or mesh_max_volume. Over eight realizations of the periodic 2D example, a margin of half the target edge length halves the number of boundary triangles with edges below a quarter of the target and removes a third of the thin pieces; the edge optimization, which does not act on the thin pieces, reduces the small elements elsewhere, and the two combine. The thin pieces that remain come from corners of cells crossing the faces, which the geometry of the seeds cannot predict. The periodic 2D example uses the margin. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The points of a periodic polymesh are snapped onto the periodic faces within _SNAP_TOL of the domain size, which makes some facets non-planar by up to that distance and the cell volumes of the two sides of such a facet differ at the same level. The partition tests now use twice the snapping tolerance for planarity, convexity and containment, compare the volume sums at 1e-6 and check for gaps and overlaps with widened and shrunk cells respectively, instead of tolerances of 1e-8 and 1e-9 that a snapped vertex can exceed. A cube case with such a vertex is added. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The edge optimization now works on the features of the mesh: its edges and, in periodic meshes, the thickness of every piece of a cell at a periodic face. With a positive periodic_margin (a new argument of PolyMesh.from_seeds, passed on by the CLI from its setting), every piece thinner than the margin is a target besides the shortest feature: the seed of the piece is pushed so that the piece reaches the margin or retracted so that the cell ends a margin inside the face, then it and the seeds of its neighbors are moved randomly normal to the face and to their facets with it. A trial is accepted when the shortest feature that it changes gets longer (the features of the two meshes are matched by their geometry), which is the previous criterion for the shortest edge and lets the optimization move on to the next target when one is stuck. Seeds moved across a periodic face are wrapped back into the domain. The CLI writes and plots the seeds again after the optimization, so that the seed file reproduces the polygonal mesh. The periodic tiling example uses the margin, and the documentation describes the optimization. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The 'auto' periodic_margin is now the smaller of half the target edge length of the mesh and an eighth of the size of the smallest seed (its smallest diameter or side): the smallest particle needs about four elements across it, so the mesh cannot be coarser than a quarter of it, and a seed cannot satisfy a margin larger than itself, which rejected the small seeds near the faces at placement. The periodic examples ship with periodic_margin auto and edge_opt (10 iterations in 3D, 25 in 2D), and the tiling example computes the same margin from its seeds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A corner of a cell at a periodic face that is narrower than the minimum angle of the mesh cannot be meshed to that angle: the mesher refines it in shells of very small elements instead (in the periodic meshes, each pass deepens the shells further). Such corners are now features of the edge optimization, with the size of the elements they force (a quarter of the thickness of the wedge at the end of its shorter side), and are targets like thin pieces when under the margin. The facet turns with the line between the seeds on its two sides, so the first trial moves them along the facet, in opposite directions, by the amount that opens the corner to the minimum angle plus two degrees, and the others move them along the facet randomly. PolyMesh.from_seeds takes the minimum angle of the mesh to be built as min_angle; the CLI passes its mesh_min_angle setting, so no new setting is needed. The tiling example passes it too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
When the nodes on the periodic faces did not match after a pass, the next pass put the points that Triangle had added on the faces back into the facets and meshed the cells again from scratch. In a corner narrower than the minimum angle, where Triangle refines in shells of small elements, each pass then split the segment at the tip once more, one level per pass, down to very small elements. Now all the points of the previous mesh are the input of the next pass, with the points on a periodic face and on its image merged and put on both faces, so that Triangle only refines the mesh around the merged points, in the same surroundings (the copies of the cells outside the faces) that produced them. The faces match after two passes in the examples, nothing is mirrored, and the quality is that of the first pass. The copies of the cells at the corners of the domain, moved along both axes, were open on the side of the periodic wall facet that was skipped as if it lay on the opposite face; Triangle discarded part of them. The copies are closed now, which also makes the first pass match the faces better, and the mesher checks that Triangle kept its input points. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The pages of the interface refinement examples have the Materials and Domain Geometry sections of the other pages and point to the seed and polygonal mesh figures of the binder and inclusions examples, which they share; the tiling example page has the sections of the other package examples (Domain, Phases, Seeds, Meshing, Plotting). Two numbers in the pages that no longer matched the input files (the overlap tolerance of the 3D binder example, the maximum edge length of the 3D interface example) are corrected, the pages mention the narrow corners that the optimization opens, the comments of the periodic 2D input file describe the current margin rule, and the mesh comment of the 3D interface input file sits next to the mesh settings. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The periodic domain and settings pages referred to each other with the labels cli_domain and cli_settings, which did not exist. The labels are added at the top of the two pages; the documentation now builds without warnings. The outputs that the documentation build writes into the package (the example results, the gallery and the copied CSV files) are ignored by git. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The wall ids of a rectangular domain are decoded by one helper, the check that a cell of a periodic tessellation is narrower than the domain is one function for 2D and 3D, the points of a region are collected by one helper, the CLI evaluates the periodic margin once, and the shortest edge finder that the optimizer no longer uses is removed. No arithmetic changes: the meshes of the examples and of the regression cases are identical. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The wedge configuration, the shortest edge of a polygonal mesh, the volumes of the cells of each seed, the tiled reference tessellation and the check of the pairs on the periodic faces were written twice, for 2D and 3D or in two test files. They are one module now, and the 2D and 3D tests use the same checks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The disjoint sets of the point mergers, of the merging of amorphous cells and of the classes of periodic edges are one class, and the clustering of close points (the pairs of a KD-tree, the sets, the mean of each cluster) is one function used by both point mergers. The partitions and the means are computed the same way as before: the meshes of the regression cases are identical. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Matching a piece by the two ends of an edge is matching it by the vertices of a face applied to two points, and the wall on which an edge lies is found the way the wall of a face is: the 3D helpers serve both dimensions. Same distances, same tests: the regression cases are identical. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The polygonal and the triangular meshes paired the points and the facets on their periodic faces with the same two calls, the triangular mesh allowing for a missing facet list; that is one function of the helpers module now. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The loop over the cells whose bounding box contains some points, with the signed distances of those points to the facet planes, was written three times in the attribute assignment and in the collection of the facet points of the 3D meshes; it is one method of the cell geometry helper now, with the same products in the same order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Cutting a cell at the periodic faces (snap the vertices, check the width, clip below and above each face, drop the flat pieces, translate the outside pieces into the domain) was written once with the loop clipper and once with the polyhedron clipper; the loop takes the clipper as an argument now. Same operations in the same order: the regression cases are identical. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Triangle and TetGen list the edges/faces of a mesh in an order, and with an orientation, that vary from one run to the next, so the mesh files of otherwise identical runs differed in their facet lists. The facets are now sorted when the mesh is created, whatever the mesher: nodes in ascending order within a facet and facets in lexicographic order, with their attributes carried along. The orientation of a facet is not used by the package. The facets of the periodic meshes, computed from the polygonal mesh, were already in that order and are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The CI import-order check (isort, force_single_line, microstructpy as the first-party section) rejected five files: the scipy import of the mesh module belonged after the matplotlib imports, and the imports of the shared test helpers belong with the third-party section. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The workflow installed pytest 6.2.5 and a current pytest-cov, then the
requirements pinned tox 3.14, whose pluggy < 1 requirement downgraded
pluggy to 0.13; pytest-cov then failed to load ("unexpected keyword
argument 'wrapper'") and no test ran. The workflow installs the current
pytest, tox is no longer a requirement of the package (nothing imports
it; tox.ini stays for local use), and the jobs of the test matrix no
longer cancel each other when one fails, so that every platform reports
its own result.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pyvoro-mmalahe bundles Voro++ 0.4.6, whose radical (Laguerre) tessellation can return a cell uncut: the cells then overlap, and Triangle and TetGen can crash on the polygonal mesh. This is why the tests fail on Linux and macOS in the continuous integration. The pyvoro-rimoli fork provides the same pyvoro module with the current Voro++, where this is fixed, and has wheels for Linux, macOS and Windows. The README and the installation guide tell users to uninstall pyvoro-mmalahe before upgrading, since both packages install the same files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_periodic_3d_matches_tiled_reference compares the periodic tessellation of 83 seeds (about 3000 breakdown spheres) with a non-periodic tessellation of the seeds copied across the periodic faces. With all 27 copies, that reference needs about 10 GB of memory (peak footprint on macOS, where memory compression hides part of it from the resident size), in the test process and again in the pyvoro probe subprocess. The Linux runners of the continuous integration (16 GB, no memory compression) ran out of memory there and were shut down, which is why the Linux test jobs failed. tiled_reference_volumes takes an optional margin: only the copies whose center is within that distance of the domain are kept, and the tiled domain ends there, plus the extent of the largest breakdown. The 3D test uses a margin of 1, half the side of the domain; the reference volumes are the same as with all the copies to rounding (relative difference 3e-15; a margin of 0.7 is not enough). The peak memory of the test file goes from 10 GB to 3.3 GB and its time from 77 s to 32 s. The 2D tests keep all the copies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the Docs used Python 3.8, for which pyvoro-rimoli has no release (it supports Python 3.9 and later), so the build stopped when installing the package; it already failed on 3.8 for other pull requests, when a pinned dependency dropped 3.8. It now uses Python 3.10 and installs requirements.txt as well, like the documentation check of the continuous integration, so that the same versions (numpy < 2 among them) are used. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branch adds periodic microstructures in 2D and 3D, fixes a round of bugs found while going through the package, and gets the CI running again. The full list of changes is in
CHANGELOG.rstunder "Unreleased".Periodic microstructures
<periodic>in<domain>selects the periodic axes (True, or e.g.xy); the same option is an argument ofcli.run,SeedList.positionandPolyMesh.from_seeds.mesh_min_angle,mesh_max_volume, per-phasemax_volume,mesh_max_edge_length) act as on non-periodic meshes.periodic_margin, keeps seeds from leaving thin slivers on the faces. It is off by default, and the examples useauto.edge_optnow also thickens thin pieces of cells at the faces and opens narrow corners there.periodic_2D.xml,periodic_3D.xml,pbx_2D.xml,pbx_3D.xml,pbx_interface_2D.xml,pbx_interface_3D.xmlandperiodic_tiling.py.Bug fixes and changes
The fixes are listed under "Fixed" in the changelog. They include reproducible seeding,
cdfsize distributions, TetGen volume constraints, the orientation of some ellipsoid breakdowns, cells clipped by circular and elliptical domains, several hangs, and the raster mesh andTriMesh.writeoutputs.Some changes affect existing inputs, listed under "Changed":
rtol='fit'now uses the coefficients published in CMAME 370 (2020) 113242, Eqs. (14) and (15).mesh_max_edge_lengthnow also refines the grain boundaries of 3D meshes.Tests and docs
CI
CI runs again and passes on Linux, macOS and Windows. The fixes on this branch:
tox==3.14.0pin inrequirements.txtforced an old pluggy that the current pytest-cov cannot load. This would also have hit master on its next push.requirements.txt, like the documentation check.One check is still red. Read the Docs now installs everything, but the build runs every example, and with the new periodic examples it goes past the 15-minute limit of the free plan. The documentation checks on GitHub build the same pages and pass.
Trying it
pyvoro-rimoli installs the same
pyvoromodule as pyvoro-mmalahe, so uninstall the old one first:🤖 Generated with Claude Code