From 323c963081b15025175c83084f6f7c26f8363cf1 Mon Sep 17 00:00:00 2001 From: Gertjan van Zwieten Date: Fri, 11 Aug 2023 09:48:34 +0200 Subject: [PATCH 1/5] reintroduce default val of ConcatPoints duplicates This patch reintroduces the default value of the ConcatPoints duplicates argument, which used to be an empty frozenset prior to 31f0e6597. The main reason for reintroduction is that some examples rely on the old behavour. Moreover, the docstring still lists the duplicates argument as "optional". --- nutils/points.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nutils/points.py b/nutils/points.py index d84ee6117..9391b9429 100644 --- a/nutils/points.py +++ b/nutils/points.py @@ -288,7 +288,7 @@ class ConcatPoints(Points): triggering deduplication and resulting in a smaller total point count. ''' - def __init__(self, allpoints: Tuple[Points,...], duplicates: FrozenSet[Tuple[Tuple[Integral,Integral],...]]): + def __init__(self, allpoints: Tuple[Points,...], duplicates: FrozenSet[Tuple[Tuple[Integral,Integral],...]] = frozenset()): assert isinstance(allpoints, tuple) and all(isinstance(p, Points) for p in allpoints), 'allpoints={allpoints!r}' assert isinstance(duplicates, frozenset) and all(isinstance(d, tuple) and all(isinstance(n, tuple) and len(n) == 2 and all(isinstance(ni, Integral) for ni in n) for n in d) for d in duplicates), f'duplicates={duplicates!r}' self.allpoints = allpoints From 723a990e9e2a2fa1dec205379161bd8e4e523a1e Mon Sep 17 00:00:00 2001 From: Gertjan van Zwieten Date: Thu, 10 Aug 2023 16:35:37 +0200 Subject: [PATCH 2/5] fix platewithhole default value for mode parameter This patch fixes the default value mode=NURBS of the platewithhole example, which lacked the parentheses to become an instance rather than the class. --- examples/platewithhole.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/platewithhole.py b/examples/platewithhole.py index 48d777650..2d0973dfd 100644 --- a/examples/platewithhole.py +++ b/examples/platewithhole.py @@ -80,7 +80,7 @@ def generate(self, radius): return topo.withboundary(hole='left', sym='top,bottom', far='right'), geom, nurbsbasis, 5 -def main(mode: Union[FCM, NURBS] = NURBS, +def main(mode: Union[FCM, NURBS] = NURBS(), radius: float = .5, traction: float = .1, poisson: float = .3): From 194b57da5896bc5ca68246b1559e6e6ff45e9de5 Mon Sep 17 00:00:00 2001 From: Gertjan van Zwieten Date: Fri, 11 Aug 2023 10:19:25 +0200 Subject: [PATCH 3/5] fix missing points in trimmed topology This patch fixes a bug in SubsetTopology.locate with skip_missing=True, caused by incorrect preprocessing of the CoorsPoints argument during elimination of points that are found in basetopo but that lie outside the trimmed topo. The unit test is updated to include the previously uncovered code path. --- nutils/topology.py | 2 +- tests/test_topology.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/nutils/topology.py b/nutils/topology.py index f918a18f0..105e8dfe5 100644 --- a/nutils/topology.py +++ b/nutils/topology.py @@ -2654,7 +2654,7 @@ def locate(self, geom, coords, *, eps=0, skip_missing=False, **kwargs): if not mymissing: # no points are missing -> keep existing points object newpoints.append(points_) elif len(mymissing) < points_.npoints: # some points are missing -> create new CoordsPoints object - newpoints.append(points.CoordsPoints(points_.coords[~numeric.asboolean(mymissing, points_.npoints)])) + newpoints.append(points.CoordsPoints(types.arraydata(points_.coords[~numeric.asboolean(mymissing, points_.npoints)]))) else: # all points are missing -> remove element from return sample selection[isampleelem] = False del missing[:len(mymissing)] diff --git a/tests/test_topology.py b/tests/test_topology.py index 7f8dba317..5d1308edf 100644 --- a/tests/test_topology.py +++ b/tests/test_topology.py @@ -943,8 +943,12 @@ def test_invalidargs(self): self.domain.locate(self.geom, target, eps=1e-15, tol=1e-12, arguments=dict(scale=.123)) def test_invalidpoint(self): - target = numpy.array([(.3, 1), (.2, .3), (.1, .9), (0, 1), (.1, .3)]) - # the first point is outside the domain, but inside basetopo for mode==trimmed + target = numpy.array([(.3, .3), (.21, 1), (.2, 1), (.1, .9), (0, 1), (.1, .3), (.3, .3)]) + # The first two points are outside the domain, but inside basetopo for + # mode==trimmed, triggering a post-processing by SubsetTopology.locate. + # Moreover, the second point is in the same basetopo element as the + # third, which requires the formation of a new CoordsPoints, whereas + # the element of the first point can be dropped altogether. with self.subTest('skip_missing=False'), self.assertRaises(topology.LocateError): self.domain.locate(self.geom, target, eps=1e-15, tol=1e-12, arguments=dict(scale=.123)) with self.subTest('skip_missing=True'): From c92bf1cfdd941be3b23beb2b209afeabdeebaeb2 Mon Sep 17 00:00:00 2001 From: Joost van Zwieten Date: Fri, 11 Aug 2023 11:13:48 +0200 Subject: [PATCH 4/5] update Docker base image to Debian Bookworm This patch updates the Docker base image to Debian Bookworm and accommodates for the following changes. * The APT sources list in the container changed from `/etc/apt/sources.list` to `/etc/apt/sources.list.d/debian.sources`. A `.sources` file is a list of key value pairs including a `Components` key. * The version of the libtbb dependency changed from 2 to 12. * Since Python 3.11 pip complains about installing packages outside of a virtual environment unless the `--break-system-packages` flag is used. --- devtools/container/build.py | 2 +- devtools/container/build_base.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/devtools/container/build.py b/devtools/container/build.py index f575a767a..64160ba75 100644 --- a/devtools/container/build.py +++ b/devtools/container/build.py @@ -66,7 +66,7 @@ container = stack.enter_context(Container.new_from(base, mounts=[Mount(src=wheel, dst=f'/{wheel.name}')])) - container.run('pip', 'install', '--no-cache-dir', f'/{wheel.name}[export_mpl,import_gmsh,matrix_scipy]', env=dict(PYTHONHASHSEED='0')) + container.run('pip', 'install', '--break-system-packages', '--no-cache-dir', f'/{wheel.name}[export_mpl,import_gmsh,matrix_scipy]', env=dict(PYTHONHASHSEED='0')) container.add_label('org.opencontainers.image.url', 'https://github.com/evalf/nutils') container.add_label('org.opencontainers.image.source', 'https://github.com/evalf/nutils') container.add_label('org.opencontainers.image.authors', 'Evalf') diff --git a/devtools/container/build_base.py b/devtools/container/build_base.py index e1a42a81d..176da2d4b 100644 --- a/devtools/container/build_base.py +++ b/devtools/container/build_base.py @@ -14,12 +14,13 @@ log.info(f'building container base image with name `{image_name}`') -with Container.new_from('debian:bullseye', network='host') as container: - container.run('sed', '-i', 's/ main$/ main contrib non-free/', '/etc/apt/sources.list') +with Container.new_from('debian:bookworm', network='host') as container: + container.run('sed', '-i', 's/^Components: .*$/Components: main contrib non-free/', '/etc/apt/sources.list.d/debian.sources') container.run('apt', 'update') - # Package `libtbb2` is required when using Intel MKL with environment + # Package `libtbb12` is required when using Intel MKL with environment # variable `MKL_THREADING_LAYER` set to `TBB`, which is nowadays the default. - container.run('apt', 'install', '-y', '--no-install-recommends', 'python3', 'python3-pip', 'python3-wheel', 'python3-ipython', 'python3-numpy', 'python3-scipy', 'python3-matplotlib', 'python3-pil', 'libmkl-rt', 'libomp-dev', 'libtbb2', 'python3-gmsh', env=dict(DEBIAN_FRONTEND='noninteractive')) + container.run('apt', 'install', '-y', '--no-install-recommends', 'python3', 'python3-pip', 'python3-wheel', 'python3-ipython', 'python3-numpy', 'python3-scipy', 'python3-matplotlib', 'python3-pil', 'libmkl-rt', 'libomp-dev', 'libtbb12', 'python3-gmsh', env=dict(DEBIAN_FRONTEND='noninteractive')) + container.run('apt', 'clean') container.add_label('org.opencontainers.image.url', 'https://github.com/evalf/nutils') container.add_label('org.opencontainers.image.source', 'https://github.com/evalf/nutils') container.add_label('org.opencontainers.image.authors', 'Evalf') From bb55072b92f1e1b563c97a813488942bc230a45e Mon Sep 17 00:00:00 2001 From: Joost van Zwieten Date: Fri, 11 Aug 2023 11:26:57 +0200 Subject: [PATCH 5/5] fix Docker image build script Commit 163ea934 changed the build system for the Nutils package from setuptools to Flit. This patch replaces the call to `setup.py` with `pip wheel` in the build script for the Docker image. --- devtools/container/build.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/devtools/container/build.py b/devtools/container/build.py index 64160ba75..d0af2a7a4 100644 --- a/devtools/container/build.py +++ b/devtools/container/build.py @@ -51,8 +51,10 @@ log.info(f'installing Nutils from {wheel}') else: log.info(f'building wheel for commit {commit}') - run(sys.executable, 'setup.py', 'bdist_wheel', cwd=str(src.path), env=dict(SOURCE_DATE_EPOCH=str(src.get_commit_timestamp('HEAD')))) - wheel, = (src.path / 'dist').glob('nutils-*.whl') + dist_dir = src.path / 'dist' + dist_dir.mkdir() + run(sys.executable, '-m', 'pip', 'wheel', '--no-deps', str(src.path), cwd=str(src.path / 'dist'), env=dict(SOURCE_DATE_EPOCH=str(src.get_commit_timestamp('HEAD')))) + wheel, = dist_dir.glob('nutils-*.whl') if args.examples: examples = Path(args.examples)