nixpkgs/pkgs/development/python-modules/fipy/gmsh.patch
Daniel Wheeler 5f80a7ad98 python3Packages.fipy: fix broken build
See #167742

python3Packages.fipy is currently broken on Hydra,
https://hydra.nixos.org/build/172501646. FiPy is unable to read the
version string for Gmsh. This is currently fixed on FiPy's master and
so appropriate patch is now applied.. Patch should be removed at next
release.

Also, Gmsh was not in the path when running the tests so now added to
checkInputs.
2022-04-08 18:17:46 -04:00

183 lines
7.2 KiB
Diff

diff --git a/fipy/meshes/gmshMesh.py b/fipy/meshes/gmshMesh.py
index fc3ff6c8..d529d532 100755
--- a/fipy/meshes/gmshMesh.py
+++ b/fipy/meshes/gmshMesh.py
@@ -13,11 +13,11 @@ import sys
import tempfile
from textwrap import dedent
import warnings
-from distutils.version import StrictVersion
from fipy.tools import numerix as nx
from fipy.tools import parallelComm
from fipy.tools import serialComm
+from fipy.tools.version import Version, parse_version
from fipy.tests.doctestPlus import register_skipper
from fipy.meshes.mesh import Mesh
@@ -38,7 +38,7 @@ def _checkForGmsh():
hasGmsh = True
try:
version = _gmshVersion(communicator=parallelComm)
- hasGmsh = version >= StrictVersion("2.0")
+ hasGmsh = version >= Version("2.0")
except Exception:
hasGmsh = False
return hasGmsh
@@ -68,6 +68,7 @@ def gmshVersion(communicator=parallelComm):
while True:
try:
# gmsh returns version in stderr (Why?!?)
+ # (newer versions of gmsh return the version in stdout)
# spyder on Windows throws
# OSError: [WinError 6] The handle is invalid
# if we don't PIPE stdout, too
@@ -77,8 +78,11 @@ def gmshVersion(communicator=parallelComm):
break
try:
- out, verStr = p.communicate()
- verStr = verStr.decode('ascii').strip()
+ out, err = p.communicate()
+ verStr = err.decode('ascii').strip()
+ if not verStr:
+ # newer versions of gmsh return the version in stdout
+ verStr = out.decode('ascii').strip()
break
except IOError:
# some weird conflict with things like PyQT can cause
@@ -93,12 +97,12 @@ def gmshVersion(communicator=parallelComm):
def _gmshVersion(communicator=parallelComm):
version = gmshVersion(communicator) or "0.0"
try:
- version = StrictVersion(version)
+ version = parse_version(version)
except ValueError:
# gmsh returns the version string in stderr,
# which means it's often unparsable due to irrelevant warnings
# assume it's OK and move on
- version = StrictVersion("3.0")
+ version = Version("3.0")
return version
@@ -133,7 +137,7 @@ def openMSHFile(name, dimensions=None, coordDimensions=None, communicator=parall
# Enforce gmsh version to be either >= 2 or 2.5, based on Nproc.
version = _gmshVersion(communicator=communicator)
- if version < StrictVersion("2.0"):
+ if version < Version("2.0"):
raise EnvironmentError("Gmsh version must be >= 2.0.")
# If we're being passed a .msh file, leave it be. Otherwise,
@@ -176,9 +180,11 @@ def openMSHFile(name, dimensions=None, coordDimensions=None, communicator=parall
gmshFlags = ["-%d" % dimensions, "-nopopup"]
if communicator.Nproc > 1:
- if not (StrictVersion("2.5") < version <= StrictVersion("4.0")):
- warnstr = "Cannot partition with Gmsh version < 2.5 or >= 4.0. " \
- + "Reverting to serial."
+ if ((version < Version("2.5"))
+ or (Version("4.0") <= version < Version("4.5.2"))):
+ warnstr = ("Cannot partition with Gmsh version < 2.5 "
+ "or 4.0 <= version < 4.5.2. "
+ "Reverting to serial.")
warnings.warn(warnstr, RuntimeWarning, stacklevel=2)
communicator = serialComm
@@ -188,13 +194,13 @@ def openMSHFile(name, dimensions=None, coordDimensions=None, communicator=parall
raise ValueError("'dimensions' must be specified to generate a mesh from a geometry script")
else: # gmsh version is adequate for partitioning
gmshFlags += ["-part", "%d" % communicator.Nproc]
- if version >= StrictVersion("4.0"):
+ if version >= Version("4.0"):
# Gmsh 4.x needs to be told to generate ghost cells
- # Unfortunately, the ghosts are broken
+ # Unfortunately, the ghosts are broken in Gmsh 4.0--4.5.1
# https://gitlab.onelab.info/gmsh/gmsh/issues/733
gmshFlags += ["-part_ghosts"]
- gmshFlags += ["-format", "msh2"]
+ gmshFlags += ["-format", "msh2", "-smooth", "8"]
if background is not None:
if communicator.procID == 0:
@@ -1387,6 +1393,11 @@ class _GmshTopology(_MeshTopology):
class Gmsh2D(Mesh2D):
"""Construct a 2D Mesh using Gmsh
+ If called in parallel, the mesh will be partitioned based on the value
+ of `parallelComm.Nproc`. If an `MSH` file is supplied, it must have
+ been previously partitioned with the number of partitions matching
+ `parallelComm.Nproc`.
+
>>> radius = 5.
>>> side = 4.
>>> squaredCircle = Gmsh2D('''
@@ -1875,6 +1886,11 @@ class Gmsh2D(Mesh2D):
class Gmsh2DIn3DSpace(Gmsh2D):
"""Create a topologically 2D Mesh in 3D coordinates using Gmsh
+ If called in parallel, the mesh will be partitioned based on the value
+ of `parallelComm.Nproc`. If an `MSH` file is supplied, it must have
+ been previously partitioned with the number of partitions matching
+ `parallelComm.Nproc`.
+
Parameters
----------
arg : str
@@ -1959,6 +1975,11 @@ class Gmsh2DIn3DSpace(Gmsh2D):
class Gmsh3D(Mesh):
"""Create a 3D Mesh using Gmsh
+ If called in parallel, the mesh will be partitioned based on the value
+ of `parallelComm.Nproc`. If an `MSH` file is supplied, it must have
+ been previously partitioned with the number of partitions matching
+ `parallelComm.Nproc`.
+
Parameters
----------
arg : str
@@ -2225,7 +2246,7 @@ class GmshGrid2D(Gmsh2D):
width = nx * dx
numLayers = int(ny / float(dy))
- if _gmshVersion() < StrictVersion("2.7"):
+ if _gmshVersion() < Version("2.7"):
# kludge: must offset cellSize by `eps` to work properly
eps = float(dx)/(nx * 10)
else:
@@ -2299,7 +2320,7 @@ class GmshGrid3D(Gmsh3D):
width = nx * dx
depth = nz * dz
- if _gmshVersion() < StrictVersion("2.7"):
+ if _gmshVersion() < Version("2.7"):
# kludge: must offset cellSize by `eps` to work properly
eps = float(dx)/(nx * 10)
else:
diff --git a/fipy/tools/version.py b/fipy/tools/version.py
new file mode 100644
index 00000000..93d89c18
--- /dev/null
+++ b/fipy/tools/version.py
@@ -0,0 +1,18 @@
+"""Shim for version checking
+
+`distutils.version` is deprecated, but `packaging.version` is unavailable
+in Python 2.7
+"""
+from __future__ import unicode_literals
+
+__docformat__ = 'restructuredtext'
+
+
+__all__ = ["Version", "parse_version"]
+from future.utils import text_to_native_str
+__all__ = [text_to_native_str(n) for n in __all__]
+
+try:
+ from packaging.version import Version, parse as parse_version
+except ImportError:
+ from distutils.version import StrictVersion as Version, StrictVersion as parse_version