From c9c01089e5c84f246a24ff332e210d842404e29d Mon Sep 17 00:00:00 2001 From: Cyrille Bonamy Date: Fri, 12 May 2023 10:19:45 +0200 Subject: [PATCH 1/5] support region/sets read --- fluidfoam/readof.py | 68 ++++++++++++++++++++++++++++++++++++++---- fluidfoam/test_read.py | 1 + 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/fluidfoam/readof.py b/fluidfoam/readof.py index 14382f4..f7f8081 100644 --- a/fluidfoam/readof.py +++ b/fluidfoam/readof.py @@ -70,6 +70,7 @@ def __init__( name=None, structured=False, boundary=None, + region=None, order="F", precision=15, datatype=None, @@ -79,7 +80,10 @@ def __init__( self.pathcase = path if time_name == "latestTime": time_name = _find_latesttime(path) - self.path = _make_path(path, time_name, name) + if region is None: + self.path = _make_path(path, time_name, name) + else: + self.path = _make_path(path, time_name, os.path.join(region, name)) self.verbose = verbose if self.verbose: print("Reading file " + self.path) @@ -129,6 +133,8 @@ def __init__( self._parse_points(precision=precision) elif name.endswith("owner") or name.endswith("neighbour"): self._parse_owner() + elif name.startswith("sets/"): + self._parse_sets() else: self._parse_data(boundary=boundary, precision=precision, @@ -539,6 +545,35 @@ def _parse_owner(self): self.nb_faces = self.values.size self.nb_cell = np.max(self.values) + 1 + def _parse_sets(self): + + for line in self.lines_stripped: + try: + int(line) + break + except ValueError: + continue + break + self.nb_cell = int(line) + data = self.content.split(line, 2)[-1] + + self.type_data = self.header[b"class"] + + if not self.is_ascii: + nb_numbers = self.nb_cell + data = b"\n(".join(data.split(b"\n(")[1:]) + self.values = np.array( + struct.unpack( + "{}i".format(nb_numbers), + data[: nb_numbers * struct.calcsize("i")], + ) + ) + else: + lines = data.split(b"\n(")[1:] + lines = [line.split(b")")[0] for line in lines] + data = b" ".join(lines).strip() + self.values = np.array([int(s) for s in data.split()]) + def _determine_order(self, boundary, order, precision): xs, ys, zs = readmesh( @@ -591,6 +626,7 @@ def readfield( name=None, structured=False, boundary=None, + region=None, order="F", precision=15, datatype=None, @@ -606,6 +642,7 @@ def readfield( name: str\n structured: False or True\n boundary: None or str\n + region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n datatype: None (default) or str ("scalar", "vector"...) necessary in @@ -627,6 +664,7 @@ def readfield( name, structured=structured, boundary=boundary, + region=region, order=order, precision=precision, datatype=datatype, @@ -668,6 +706,7 @@ def readscalar( name=None, structured=False, boundary=None, + region=None, order="F", precision=15, mode=None, @@ -683,6 +722,7 @@ def readscalar( name: str\n structured: False or True\n boundary: None or str\n + region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n verbose : True or False (default: True). @@ -704,6 +744,7 @@ def readscalar( name, structured=structured, boundary=boundary, + region=region, order=order, precision=precision, datatype="scalar", @@ -726,6 +767,7 @@ def readvector( name=None, structured=False, boundary=None, + region=None, order="F", precision=15, verbose=True, @@ -740,6 +782,7 @@ def readvector( name: str\n structured: False or True\n boundary: None or str\n + region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n verbose : True or False (default: True). @@ -759,6 +802,7 @@ def readvector( name, structured=structured, boundary=boundary, + region=region, order=order, precision=precision, datatype="vector", @@ -788,6 +832,7 @@ def readsymmtensor( name=None, structured=False, boundary=None, + region=None, order="F", precision=15, verbose=True, @@ -802,6 +847,7 @@ def readsymmtensor( name: str\n structured: False or True\n boundary: None or str\n + region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n verbose : True or False (default: True). @@ -821,6 +867,7 @@ def readsymmtensor( name, structured=structured, boundary=boundary, + region=region, order=order, precision=precision, datatype="symmtensor", @@ -850,6 +897,7 @@ def readtensor( name=None, structured=False, boundary=None, + region=None, order="F", precision=15, verbose=True, @@ -864,6 +912,7 @@ def readtensor( name: str\n structured: False or True\n boundary: None or str\n + region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n verbose : True or False (default: True). @@ -883,6 +932,7 @@ def readtensor( name, structured=structured, boundary=boundary, + region=region, order=order, precision=precision, datatype="tensor", @@ -912,6 +962,7 @@ def readmesh( time_name=None, structured=False, boundary=None, + region=None, order="F", precision=15, verbose=True @@ -924,6 +975,7 @@ def readmesh( time_name: str ('latestTime' is supported)\n structured: False or True\n boundary: None or str\n + region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n verbose : True or False (default: True). @@ -960,10 +1012,6 @@ def readmesh( facefile = OpenFoamFile( path + "/constant/polyMesh/", name="faces", verbose=verbose ) - pointfile = OpenFoamFile( - path + "/constant/polyMesh/", - name="faces", - verbose=verbose) if time_name is not None: pointfile = OpenFoamFile( path=path, @@ -1075,6 +1123,16 @@ def readmesh( xs = xs[ind].reshape(shape, order=order) ys = ys[ind].reshape(shape, order=order) zs = zs[ind].reshape(shape, order=order) + if region is not None: + regionfile = OpenFoamFile( + path=path + "/constant/polyMesh/", + name="sets/"+region, + precision=precision, + verbose=verbose + ) + xs = xs[regionfile.values] + ys = ys[regionfile.values] + zs = zs[regionfile.values] return xs, ys, zs diff --git a/fluidfoam/test_read.py b/fluidfoam/test_read.py index 1f7a141..7fbf6de 100644 --- a/fluidfoam/test_read.py +++ b/fluidfoam/test_read.py @@ -66,6 +66,7 @@ def _test_functions( readvector("output_samples/ascii", "0", "Uuniform") alphauniform = readscalar("output_samples/bin", "0", "alphauniform") x, y, z = readmesh("output_samples/ascii", boundary="bottom") + x, y, z = readmesh("output_samples/ascii", region="testSet") x, y, z = readmesh("output_samples/bin", boundary="bottom") x, y, z = readmesh("output_samples/bin/3d") x, y, z = readmesh("output_samples/bin/3d", boundary="bottom") From 12fd7dac71ecd5a9fef9c27857abe8ca5ce30c95 Mon Sep 17 00:00:00 2001 From: Cyrille Bonamy Date: Fri, 12 May 2023 10:50:48 +0200 Subject: [PATCH 2/5] add missing file to test region/set read --- .../ascii/constant/polyMesh/sets/testSet | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 output_samples/ascii/constant/polyMesh/sets/testSet diff --git a/output_samples/ascii/constant/polyMesh/sets/testSet b/output_samples/ascii/constant/polyMesh/sets/testSet new file mode 100644 index 0000000..9534275 --- /dev/null +++ b/output_samples/ascii/constant/polyMesh/sets/testSet @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2206 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + arch "LSB;label=32;scalar=64"; + class cellSet; + location "constant/polyMesh/sets"; + object testSet; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +14 +( +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +) + + +// ************************************************************************* // From 15bfa90df186d433e3d0ded68f2d0c1de4fc3f12 Mon Sep 17 00:00:00 2001 From: Cyrille Bonamy Date: Fri, 12 May 2023 14:56:31 +0200 Subject: [PATCH 3/5] support region again and split region and sets options --- fluidfoam/readof.py | 88 +++++++++++++++++++++++++++--------------- fluidfoam/test_read.py | 2 +- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/fluidfoam/readof.py b/fluidfoam/readof.py index f7f8081..8b9729c 100644 --- a/fluidfoam/readof.py +++ b/fluidfoam/readof.py @@ -70,7 +70,7 @@ def __init__( name=None, structured=False, boundary=None, - region=None, + sets=None, order="F", precision=15, datatype=None, @@ -80,10 +80,10 @@ def __init__( self.pathcase = path if time_name == "latestTime": time_name = _find_latesttime(path) - if region is None: + if sets is None: self.path = _make_path(path, time_name, name) else: - self.path = _make_path(path, time_name, os.path.join(region, name)) + self.path = _make_path(path, time_name, os.path.join(sets, name)) self.verbose = verbose if self.verbose: print("Reading file " + self.path) @@ -626,6 +626,7 @@ def readfield( name=None, structured=False, boundary=None, + sets=None, region=None, order="F", precision=15, @@ -642,6 +643,7 @@ def readfield( name: str\n structured: False or True\n boundary: None or str\n + sets: None or str\n region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n @@ -658,13 +660,15 @@ def readfield( field = fluidfoam.readfield('path_of_OpenFoam_case', '0', 'alpha') """ + if region is not None: + sets = region field = OpenFoamFile( path, time_name, name, structured=structured, boundary=boundary, - region=region, + sets=sets, order=order, precision=precision, datatype=datatype, @@ -706,6 +710,7 @@ def readscalar( name=None, structured=False, boundary=None, + sets=None, region=None, order="F", precision=15, @@ -722,6 +727,7 @@ def readscalar( name: str\n structured: False or True\n boundary: None or str\n + sets: None or str\n region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n @@ -735,6 +741,9 @@ def readscalar( A way you might use me is:\n scalar_a = fluidfoam.readscalar('path_of_OpenFoam_case', '0', 'alpha') """ + + if region is not None: + sets = region if mode == "parallel": raise ValueError("Not Implemented") else: @@ -744,7 +753,7 @@ def readscalar( name, structured=structured, boundary=boundary, - region=region, + sets=sets, order=order, precision=precision, datatype="scalar", @@ -767,6 +776,7 @@ def readvector( name=None, structured=False, boundary=None, + sets=None, region=None, order="F", precision=15, @@ -782,6 +792,7 @@ def readvector( name: str\n structured: False or True\n boundary: None or str\n + sets: None or str\n region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n @@ -796,13 +807,15 @@ def readvector( U = fluidfoam.readvector('path_of_OpenFoam_case', '0', 'U') """ + if region is not None: + sets = region vector = OpenFoamFile( path, time_name, name, structured=structured, boundary=boundary, - region=region, + sets=sets, order=order, precision=precision, datatype="vector", @@ -832,6 +845,7 @@ def readsymmtensor( name=None, structured=False, boundary=None, + sets=None, region=None, order="F", precision=15, @@ -847,6 +861,7 @@ def readsymmtensor( name: str\n structured: False or True\n boundary: None or str\n + sets: None or str\n region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n @@ -861,13 +876,15 @@ def readsymmtensor( sigma = fluidfoam.readsymmtensor('path_of_OpenFoam_case', '0', 'sigma') """ + if region is not None: + sets = region scalar = OpenFoamFile( path, time_name, name, structured=structured, boundary=boundary, - region=region, + sets=sets, order=order, precision=precision, datatype="symmtensor", @@ -897,6 +914,7 @@ def readtensor( name=None, structured=False, boundary=None, + sets=None, region=None, order="F", precision=15, @@ -912,6 +930,7 @@ def readtensor( name: str\n structured: False or True\n boundary: None or str\n + sets: None or str\n region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n @@ -926,13 +945,15 @@ def readtensor( tens = fluidfoam.readtensor('path_of_OpenFoam_case', '0', 'tens') """ + if region is not None: + sets = region scalar = OpenFoamFile( path, time_name, name, structured=structured, boundary=boundary, - region=region, + sets=sets, order=order, precision=precision, datatype="tensor", @@ -962,6 +983,7 @@ def readmesh( time_name=None, structured=False, boundary=None, + sets=None, region=None, order="F", precision=15, @@ -975,6 +997,7 @@ def readmesh( time_name: str ('latestTime' is supported)\n structured: False or True\n boundary: None or str\n + sets: None or str\n region: None or str\n order: "F" (default) or "C" \n precision : Number of decimal places to round to (default: 15)\n @@ -1001,16 +1024,20 @@ def readmesh( # because in dynamic Mesh cases, no polyMesh directory for initial time if time_name == "0": time_name = None - if not os.path.exists(os.path.join(path, "constant/polyMesh")): + if region is None: + meshpath = "/constant/polyMesh/" + else: + meshpath = "/constant/"+region+"/polyMesh/" + if not os.path.exists(path+meshpath): raise ValueError( - "No constant/polyMesh directory in ", + "No ", meshpath, " directory in ", path, " Please verify the directory of your case.", ) if boundary is not None: facefile = OpenFoamFile( - path + "/constant/polyMesh/", name="faces", verbose=verbose + path + meshpath, name="faces", verbose=verbose ) if time_name is not None: pointfile = OpenFoamFile( @@ -1022,13 +1049,13 @@ def readmesh( ) else: pointfile = OpenFoamFile( - path + "/constant/polyMesh/", + path + meshpath, name="points", precision=precision, verbose=verbose ) bounfile = OpenFoamFile( - path + "/constant/polyMesh/", + path + meshpath, name="boundary", verbose=verbose ) @@ -1048,25 +1075,24 @@ def readmesh( zs[i] = np.mean(pointfile.values_z[id_pts[0:npts]]) else: owner = OpenFoamFile( - path + "/constant/polyMesh/", name="owner", verbose=verbose + path + meshpath, name="owner", verbose=verbose ) nmesh = owner.nb_cell - if time_name is None and os.path.exists(os.path.join(path, - "constant/C")): + if (time_name is None and region is None + and os.path.exists(os.path.join(path, "constant/C"))): xs, ys, zs = readvector( path, "constant", "C", precision=precision, verbose=verbose ) - elif time_name is not None and os.path.exists(_make_path(path, - time_name, - "C")): + elif (time_name is not None and region is None + and os.path.exists(_make_path(path, time_name, "C"))): xs, ys, zs = readvector( path, time_name, "C", precision=precision, verbose=verbose ) else: facefile = OpenFoamFile( - path + "/constant/polyMesh/", name="faces", verbose=verbose + path + meshpath, name="faces", verbose=verbose ) - if time_name is not None: + if time_name is not None and region is None: pointfile = OpenFoamFile( path=path, time_name=time_name, @@ -1076,13 +1102,13 @@ def readmesh( ) else: pointfile = OpenFoamFile( - path + "/constant/polyMesh/", + path + meshpath, name="points", precision=precision, verbose=verbose ) neigh = OpenFoamFile( - path + "/constant/polyMesh/", name="neighbour", verbose=verbose + path + meshpath, name="neighbour", verbose=verbose ) xs = np.empty(owner.nb_cell, dtype=float) ys = np.empty(owner.nb_cell, dtype=float) @@ -1123,16 +1149,16 @@ def readmesh( xs = xs[ind].reshape(shape, order=order) ys = ys[ind].reshape(shape, order=order) zs = zs[ind].reshape(shape, order=order) - if region is not None: - regionfile = OpenFoamFile( - path=path + "/constant/polyMesh/", - name="sets/"+region, + if sets is not None: + setsfile = OpenFoamFile( + path=path+meshpath, + name="sets/"+sets, precision=precision, verbose=verbose - ) - xs = xs[regionfile.values] - ys = ys[regionfile.values] - zs = zs[regionfile.values] + ) + xs = xs[setsfile.values] + ys = ys[setsfile.values] + zs = zs[setsfile.values] return xs, ys, zs diff --git a/fluidfoam/test_read.py b/fluidfoam/test_read.py index 7fbf6de..f2db271 100644 --- a/fluidfoam/test_read.py +++ b/fluidfoam/test_read.py @@ -66,7 +66,7 @@ def _test_functions( readvector("output_samples/ascii", "0", "Uuniform") alphauniform = readscalar("output_samples/bin", "0", "alphauniform") x, y, z = readmesh("output_samples/ascii", boundary="bottom") - x, y, z = readmesh("output_samples/ascii", region="testSet") + x, y, z = readmesh("output_samples/ascii", sets="testSet") x, y, z = readmesh("output_samples/bin", boundary="bottom") x, y, z = readmesh("output_samples/bin/3d") x, y, z = readmesh("output_samples/bin/3d", boundary="bottom") From 6d86a80e6e09ebc76fc981052c899e82ca03c6ce Mon Sep 17 00:00:00 2001 From: Cyrille Bonamy Date: Sun, 14 May 2023 19:07:36 +0200 Subject: [PATCH 4/5] update favicon conf (doc) --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index fab077c..bedf6a9 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -59,7 +59,7 @@ 'sphinx.ext.viewcode', 'sphinx.ext.autosummary', 'numpydoc', 'sphinx_gallery.gen_gallery', - 'sphinx-favicon', + 'sphinx_favicon', # 'mathmacro', # 'breathe' ] From 51ab063c5050c46001e6aa1b10fbaabcf274e63f Mon Sep 17 00:00:00 2001 From: Cyrille Bonamy Date: Sun, 14 May 2023 19:12:21 +0200 Subject: [PATCH 5/5] increase version number --- README.rst | 2 +- doc/index.rst | 2 +- fluidfoam/_version.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 783220c..4c109da 100644 --- a/README.rst +++ b/README.rst @@ -26,7 +26,7 @@ What is this repository for? ---------------------------- * Openfoam Tools -* Version : 0.2.4 +* Version : 0.2.5 * Supported OpenFoam Versions : 2.4.0, 4.1 to 9, v1712plus to v2212plus * Supported Python Versions : >= 3.8 diff --git a/doc/index.rst b/doc/index.rst index 1d1c899..0e1e950 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -13,7 +13,7 @@ What is this repository for? ---------------------------- * Openfoam Tools -* Version : 0.2.4 +* Version : 0.2.5 * Supported OpenFoam Versions : 2.4.0, 4.1 to 9, v1712plus to v2212plus * Supported Python Versions : >= 3.8 diff --git a/fluidfoam/_version.py b/fluidfoam/_version.py index f61d6bf..e5b9f25 100644 --- a/fluidfoam/_version.py +++ b/fluidfoam/_version.py @@ -11,4 +11,4 @@ 'a' or 'alpha' means alpha version (internal testing), 'b' or 'beta' means beta version (external testing). """ -__version__ = "0.2.4" +__version__ = "0.2.5"