diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f428b1d1380907399fa5e6bc10b9fb16c1c7416..21f032c945367d84095b51b3f7a5fd4f757905ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,5 +22,25 @@ jobs: - name: "Main Script" run: | curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/prepare-and-run-flake8.sh - . ./prepare-and-run-flake8.sh "$(basename $GITHUB_REPOSITORY)" examples + . ./prepare-and-run-flake8.sh "$(basename $GITHUB_REPOSITORY)" test examples + pytest: + name: Pytest on Py${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8] + steps: + - uses: actions/checkout@v2 + - + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: "Main Script" + run: | + sudo apt update + sudo apt install libsilo-dev + EXTRA_INSTALL="numpy pybind11" + ./configure.py --use-silo + curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project.sh + . ./build-and-test-py-project.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 804bc2eb18090c4c6256dbcbfc8f851c11321094..e2d7e97246cd71a862af4bb907fc52763593077c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,29 @@ Flake8: script: - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/prepare-and-run-flake8.sh - - . ./prepare-and-run-flake8.sh "$CI_PROJECT_NAME" examples + - . ./prepare-and-run-flake8.sh "$CI_PROJECT_NAME" test examples tags: - python3 except: - tags +Python 3: + script: | + sudo apt update + sudo apt install libsilo-dev + py_version=3 + ./configure.py --use-silo + EXTRA_INSTALL="numpy pybind11" + curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project.sh + . ./build-and-test-py-project.sh + tags: + - docker-runner + except: + - tags + artifacts: + reports: + junit: test/pytest.xml + Documentation: script: | EXTRA_INSTALL="numpy" diff --git a/examples/silo-unstructured.py b/examples/silo-unstructured.py deleted file mode 100644 index 331541bbf290b76bc4c6b5bddd5df76e8bf5aa48..0000000000000000000000000000000000000000 --- a/examples/silo-unstructured.py +++ /dev/null @@ -1,368 +0,0 @@ -import numpy as np - -# flake8: noqa: E201 - -class Mesh: - dimensions = 2 - - def __init__(self): - self.vertex_coordinates = np.array([ - [ 1.00000000e+00, 1.00000000e+00], - [-1.00000000e+00, 1.00000000e+00], - [-1.00000000e+00, -1.00000000e+00], - [ 1.00000000e+00, -1.00000000e+00], - [ 1.00000000e+00, 0.00000000e+00], - [ 5.00000000e-01, 0.00000000e+00], - [ 4.04508497e-01, 2.93892626e-01], - [ 1.54508497e-01, 4.75528258e-01], - [-1.54508497e-01, 4.75528258e-01], - [-4.04508497e-01, 2.93892626e-01], - [-5.00000000e-01, 6.12323400e-17], - [-4.04508497e-01, -2.93892626e-01], - [-1.54508497e-01, -4.75528258e-01], - [ 1.54508497e-01, -4.75528258e-01], - [ 4.04508497e-01, -2.93892626e-01], - [ 5.00000000e-01, -1.22464680e-16], - [-1.00000000e+00, 0.00000000e+00], - [ 0.00000000e+00, -1.00000000e+00], - [ 0.00000000e+00, 1.00000000e+00], - [ 7.50000000e-01, -6.12323400e-17], - [ 3.76380160e-01, -6.92475869e-01], - [ 2.53742158e-01, 7.19073297e-01], - [ 6.28756830e-01, 4.63210153e-01], - [-5.74443055e-01, -3.53084198e-01], - [-6.18581756e-01, 2.31042725e-01], - [-2.26660566e-01, -6.52489609e-01], - [-1.38777878e-16, -7.15005157e-01], - [-8.32667268e-17, -4.75528258e-01], - [ 1.31420055e-01, -6.30214034e-01], - [ 3.52012743e-01, -5.60408551e-01], - [ 6.68920108e-01, -6.90243593e-01], - [-7.72542486e-02, -5.95266707e-01], - [ 3.23649069e-02, -5.81200949e-01], - [ 7.72542486e-02, -5.09659838e-01], - [-7.72542486e-02, -5.10475584e-01], - [-3.86612967e-01, -6.49034477e-01], - [-5.00000000e-01, -1.00000000e+00], - [-2.65876650e-01, -4.97380593e-01], - [-2.79508497e-01, -3.84710442e-01], - [ 5.00000000e-01, -1.00000000e+00], - [ 2.79508497e-01, -3.84710442e-01], - [ 2.49036745e-01, -4.74202452e-01], - [ 4.17444286e-01, -4.43129989e-01], - [ 3.66059344e-01, -3.72404685e-01], - [ 1.00000000e+00, -5.00000000e-01], - [-2.17008497e-01, -4.30119350e-01], - [-4.29734374e-01, -4.60045845e-01], - [-3.74119094e-01, -3.83497979e-01], - [-1.00000000e+00, -5.00000000e-01], - [ 5.57224765e-01, -3.55834603e-01], - [ 7.21409218e-01, -3.41603211e-01], - [-4.52254249e-01, -1.46946313e-01], - [ 1.85001438e-01, -8.57502578e-01], - [ 6.23193603e-01, -1.62706897e-01], - [ 4.52254249e-01, -1.46946313e-01], - [ 5.12185038e-01, -2.47648931e-01], - [ 4.28381373e-01, -2.20419470e-01], - [ 5.43214916e-01, -9.52713015e-02], - [-6.92549940e-01, -1.43793192e-01], - [-5.15515268e-01, -2.48730988e-01], - [-4.28381373e-01, -2.20419470e-01], - [-5.71866870e-01, -1.04580885e-01], - [-4.76127124e-01, -7.34731565e-02], - [-6.89960366e-01, 5.35552226e-02], - [-2.77500572e-01, -8.09255088e-01], - [-7.30529084e-01, 3.04896602e-01], - [-4.52254249e-01, 1.46946313e-01], - [-5.72946346e-01, 1.04931629e-01], - [-4.76127124e-01, 7.34731565e-02], - [-4.84687225e-01, 2.38714350e-01], - [-4.19217263e-01, 5.95504869e-01], - [-6.41386449e-01, 5.21452559e-01], - [-1.00000000e+00, 5.00000000e-01], - [-5.29677214e-01, 7.27277579e-01], - [-2.79508497e-01, 3.84710442e-01], - [-3.98323250e-01, 4.16812142e-01], - [-3.42008497e-01, 3.39301534e-01], - [-2.72282842e-01, 5.06197960e-01], - [-2.17008497e-01, 4.30119350e-01], - [-5.00000000e-01, 1.00000000e+00], - [ 7.72542486e-02, 7.19631585e-01], - [ 2.77555756e-17, 4.75528258e-01], - [-7.72542486e-02, 5.73039943e-01], - [-7.72542486e-02, 4.75528258e-01], - [ 7.72542486e-02, 5.85355142e-01], - [ 7.72542486e-02, 4.75528258e-01], - [ 4.28743328e-01, 7.41939961e-01], - [-1.00000000e+00, -2.50000000e-01], - [ 2.79508497e-01, 3.84710442e-01], - [ 2.50009912e-01, 5.42623972e-01], - [ 5.00000000e-01, 1.00000000e+00], - [ 2.37711541e-01, 4.58614646e-01], - [ 3.65111148e-01, 4.81894882e-01], - [ 3.75966372e-01, 3.86040540e-01], - [ 1.00000000e+00, 5.00000000e-01], - [-5.43296861e-01, -7.92213176e-01], - [-7.96662390e-01, -3.40516303e-01], - [-6.52705475e-01, -6.10334816e-01], - [ 8.75000000e-01, -1.82460056e-01], - [-2.09778923e-01, 6.41770688e-01], - [-1.04175415e-01, 8.20467199e-01], - [-5.56672529e-01, 3.83610683e-01], - [-8.27449562e-01, 7.55663220e-01], - [-2.50000000e-01, 1.00000000e+00], - [ 7.50000000e-01, 0.00000000e+00], - [ 5.04937767e-01, 5.85487598e-01], - [ 7.87954754e-01, 7.48243953e-01], - [-8.66944614e-01, 1.53933167e-01], - [ 5.52449169e-01, 3.31115121e-01], - [ 4.52254249e-01, 1.46946313e-01], - [ 4.96110705e-01, 2.42426064e-01], - [ 5.77759442e-01, 1.47110460e-01], - [ 4.76127124e-01, 7.34731565e-02], - [ 6.25000000e-01, 0.00000000e+00], - [ 8.06678337e-01, 2.72341866e-01], - [ 7.26562966e-01, 1.46946320e-01], - [ 7.50000000e-01, -1.00000000e+00], - [ 7.97833359e-01, -5.31380557e-01], - [-3.36478386e-01, 8.08917810e-01], - [-8.88250684e-01, -7.50000000e-01], - [ 2.50000000e-01, 1.00000000e+00]]) - self.elements = np.array([[ 50, 44, 98], - [ 25, 37, 35], - [ 99, 8, 82], - [ 25, 31, 12], - [ 98, 19, 53], - [ 21, 120, 80], - [ 98, 53, 50], - [ 60, 51, 59], - [ 73, 71, 70], - [ 44, 50, 117], - [ 9, 75, 101], - [ 69, 9, 101], - [106, 90, 86], - [105, 86, 92], - [ 44, 117, 3], - [ 49, 14, 42], - [ 56, 14, 55], - [ 13, 27, 33], - [ 26, 52, 28], - [118, 73, 70], - [108, 93, 6], - [ 30, 29, 20], - [ 92, 93, 108], - [ 23, 96, 97], - [ 35, 97, 95], - [ 89, 91, 92], - [ 24, 67, 69], - [ 14, 43, 42], - [ 73, 79, 102], - [119, 97, 48], - [ 64, 17, 26], - [ 26, 31, 25], - [ 32, 26, 28], - [ 52, 26, 17], - [ 32, 34, 31], - [ 28, 13, 33], - [ 58, 16, 87], - [ 17, 39, 52], - [ 39, 20, 52], - [ 49, 50, 53], - [ 28, 52, 20], - [ 25, 12, 37], - [ 46, 35, 37], - [ 34, 32, 27], - [ 26, 32, 31], - [ 27, 32, 33], - [ 28, 33, 32], - [ 27, 12, 34], - [ 12, 31, 34], - [ 47, 38, 11], - [ 26, 25, 64], - [ 38, 47, 37], - [ 17, 64, 36], - [ 46, 47, 23], - [ 45, 38, 37], - [ 58, 61, 63], - [ 97, 35, 46], - [ 28, 29, 41], - [ 40, 41, 42], - [ 3, 30, 116], - [ 41, 13, 28], - [ 40, 13, 41], - [ 19, 98, 4], - [ 29, 42, 41], - [ 14, 40, 43], - [ 40, 42, 43], - [ 42, 29, 30], - [ 49, 30, 117], - [ 37, 12, 45], - [ 64, 35, 95], - [ 23, 47, 11], - [ 37, 47, 46], - [ 48, 97, 96], - [ 35, 64, 25], - [ 42, 30, 49], - [ 28, 20, 29], - [ 39, 30, 20], - [ 49, 55, 14], - [ 10, 61, 62], - [ 23, 11, 59], - [ 57, 54, 55], - [ 15, 57, 19], - [ 49, 53, 55], - [ 19, 57, 53], - [ 57, 55, 53], - [ 55, 54, 56], - [ 15, 54, 57], - [ 36, 95, 119], - [ 61, 59, 51], - [ 58, 23, 59], - [101, 24, 69], - [ 59, 11, 60], - [ 59, 61, 58], - [ 9, 69, 66], - [ 61, 51, 62], - [ 63, 67, 24], - [ 87, 96, 58], - [ 46, 23, 97], - [ 63, 10, 67], - [ 68, 66, 67], - [ 10, 63, 61], - [ 69, 67, 66], - [ 63, 24, 65], - [102, 79, 1], - [ 67, 10, 68], - [ 70, 71, 101], - [118, 70, 99], - [ 70, 101, 75], - [118, 79, 73], - [ 72, 65, 71], - [100, 82, 80], - [ 99, 77, 8], - [ 8, 77, 78], - [ 70, 75, 77], - [ 63, 107, 16], - [ 76, 74, 75], - [ 75, 74, 77], - [ 89, 21, 84], - [ 75, 9, 76], - [103, 118, 100], - [ 85, 7, 84], - [ 77, 74, 78], - [ 99, 70, 77], - [ 80, 84, 21], - [ 83, 81, 82], - [ 84, 82, 81], - [ 80, 18, 100], - [103, 100, 18], - [ 84, 7, 89], - [ 82, 8, 83], - [ 82, 84, 80], - [ 89, 7, 91], - [ 84, 81, 85], - [ 86, 90, 120], - [ 87, 48, 96], - [109, 112, 111], - [ 89, 86, 21], - [ 92, 86, 89], - [106, 105, 22], - [105, 106, 86], - [ 7, 88, 91], - [ 92, 91, 88], - [ 93, 92, 88], - [ 18, 80, 120], - [ 88, 6, 93], - [111, 115, 108], - [111, 108, 110], - [ 95, 97, 119], - [101, 71, 65], - [ 1, 72, 102], - [ 16, 58, 63], - [ 58, 96, 23], - [ 64, 95, 36], - [ 44, 4, 98], - [102, 71, 73], - [ 63, 65, 107], - [100, 118, 99], - [ 24, 101, 65], - [ 72, 71, 102], - [ 82, 100, 99], - [115, 111, 113], - [108, 114, 22], - [108, 105, 92], - [ 22, 94, 106], - [ 94, 0, 106], - [ 90, 106, 0], - [ 65, 72, 107], - [ 72, 16, 107], - [ 22, 105, 108], - [110, 108, 6], - [ 6, 109, 110], - [109, 111, 110], - [104, 115, 113], - [ 4, 94, 114], - [114, 115, 4], - [112, 113, 111], - [113, 112, 5], - [ 94, 22, 114], - [ 4, 115, 104], - [108, 115, 114], - [ 49, 117, 50], - [ 30, 39, 116], - [ 3, 117, 30], - [ 79, 118, 103], - [ 48, 2, 119], - [119, 2, 36], - [ 86, 120, 21]]) - - def __len__(self): - return len(self.elements) - - -def add_to_silo_file(silo, mesh, cell_data=[], point_data=[], - line_integral_rules=[], - mesh_name="mesh", - real_only=False): - zonelist_name = mesh_name + "_zonelist" - - from pyvisfile.silo import IntVector - - nodelist = IntVector() - nodelist.extend(int(i) for i in mesh.elements.flat) - - shapetypes = IntVector() - from pyvisfile.silo import DB_ZONETYPE_TRIANGLE - shapetypes.append(DB_ZONETYPE_TRIANGLE) - - shapesizes = IntVector() - shapesizes.append(3) - - shapecounts = IntVector() - shapecounts.append(len(mesh)) - - silo.put_zonelist_2(zonelist_name, len(mesh), mesh.dimensions, nodelist, - 0, 0, shapetypes, shapesizes, shapecounts) - - silo.put_ucdmesh(mesh_name, [], - np.asarray(mesh.vertex_coordinates.T, order="C"), len(mesh), - zonelist_name, None) - - from pyvisfile.silo import DB_NODECENT, DB_ZONECENT - silo.put_ucdvar1("myvar", mesh_name, - np.arange(mesh.vertex_coordinates.shape[0], dtype=np.double), - DB_NODECENT) - silo.put_ucdvar1("myvar2", mesh_name, - np.arange(len(mesh), dtype=np.double), - DB_ZONECENT) - - -def main(): - from pyvisfile.silo import SiloFile - silo = SiloFile("out.silo") - add_to_silo_file(silo, Mesh()) - silo.close() - - -if __name__ == "__main__": - main() diff --git a/examples/vtk-structured.py b/examples/vtk-structured.py deleted file mode 100644 index 3ef71d84fff7e7cf66866a3d1cfa076b9d09f5bd..0000000000000000000000000000000000000000 --- a/examples/vtk-structured.py +++ /dev/null @@ -1,24 +0,0 @@ -from pyvisfile.vtk import write_structured_grid - -import numpy as np - -angle_mesh = np.mgrid[1:2:10j, 0:2*np.pi:20j, 0:np.pi:30j] - -r = angle_mesh[0, np.newaxis] -phi = angle_mesh[1, np.newaxis] -theta = angle_mesh[2, np.newaxis] -mesh = np.vstack(( - r*np.sin(theta)*np.cos(phi), - r*np.sin(theta)*np.sin(phi), - r*np.cos(theta), - )) - -from pytools.obj_array import make_obj_array -vec = make_obj_array([ - np.sin(theta)*np.cos(phi), - np.sin(theta)*np.sin(phi), - np.cos(theta), - ]) - -write_structured_grid("yo.vts", mesh, - point_data=[("phi", phi), ("vec", vec)]) diff --git a/examples/vtk-unstructured-points.py b/examples/vtk-unstructured-points.py deleted file mode 100644 index bba2aa36c2fdfd94570c057aa86ab014c2ec49df..0000000000000000000000000000000000000000 --- a/examples/vtk-unstructured-points.py +++ /dev/null @@ -1,33 +0,0 @@ -import numpy as np -from pyvisfile.vtk import ( - UnstructuredGrid, DataArray, - AppendedDataXMLGenerator, - VTK_VERTEX, VF_LIST_OF_VECTORS, VF_LIST_OF_COMPONENTS) - -n = 5000 -points = np.random.randn(n, 3) - -data = [ - ("p", np.random.randn(n)), - ("vel", np.random.randn(3, n)), -] -file_name = "points.vtu" -compressor = None - -grid = UnstructuredGrid( - (n, DataArray("points", points, vector_format=VF_LIST_OF_VECTORS)), - cells=np.arange(n, dtype=np.uint32), - cell_types=np.asarray([VTK_VERTEX] * n, dtype=np.uint8)) - -for name, field in data: - grid.add_pointdata(DataArray(name, field, - vector_format=VF_LIST_OF_COMPONENTS)) - -from os.path import exists -if exists(file_name): - raise RuntimeError("output file '%s' already exists" - % file_name) - -outf = open(file_name, "w") -AppendedDataXMLGenerator(compressor)(grid).write(outf) -outf.close() diff --git a/pyvisfile/silo/__init__.py b/pyvisfile/silo/__init__.py index da90505d037e0391817bb339776f346dcb382e53..33ed991ba77d426aebb25d95e34b3374be4fd167 100644 --- a/pyvisfile/silo/__init__.py +++ b/pyvisfile/silo/__init__.py @@ -32,20 +32,8 @@ ParallelSiloFile to automatically create a master file along with your SiloFile. """ - -def _ignore_extra_int_vector_warning(): - from warnings import filterwarnings - filterwarnings("ignore", module="pyvisfile.silo", - category=RuntimeWarning, lineno=43) - - -_ignore_extra_int_vector_warning() - - -import sys -import pyublas # noqa try: - import pyvisfile.silo._internal # noqa + import pyvisfile.silo._internal as _silo except ImportError: from warnings import warn warn("Importing the native-code parts of PyVisfile's silo component failed. " @@ -54,50 +42,115 @@ except ImportError: "This requires the libsilo library.") raise -# hackety hack -- not sure why this is needed -_intnl = sys.modules["pyvisfile.silo._internal"] - - -# {{{ handle symbols - -_intnl_symbols = _intnl.symbols() - - -def _export_symbols(): - for name, value in _intnl_symbols.items(): - globals()[name] = value - - -_export_symbols() - -# These are technically redundant, but they help avoid Flake8 warnings below. - -DB_COLLINEAR = _intnl_symbols["DB_COLLINEAR"] -DB_LOCAL = _intnl_symbols["DB_LOCAL"] -DB_NOCLOBBER = _intnl_symbols["DB_NOCLOBBER"] -DB_UNKNOWN = _intnl_symbols["DB_UNKNOWN"] -DB_PDB = _intnl_symbols["DB_PDB"] -DB_APPEND = _intnl_symbols["DB_APPEND"] - -# }}} - - -DBObjectType = _intnl.DBObjectType -DBdatatype = _intnl.DBdatatype - -DBToc = _intnl.DBToc -DBCurve = _intnl.DBCurve -DBQuadMesh = _intnl.DBQuadMesh -DBQuadVar = _intnl.DBQuadVar -IntVector = _intnl.IntVector -get_silo_version = _intnl.get_silo_version -set_deprecate_warnings = _intnl.set_deprecate_warnings +from pyvisfile.silo._internal import ( # noqa: F401 + get_silo_version, set_deprecate_warnings, + # enums + DBObjectType, DBdatatype, + # classes + DBToc, DBCurve, DBQuadMesh, DBQuadVar, IntVector, + ) + +from pyvisfile.silo._internal import ( # noqa: F401 + DB_NETCDF, DB_PDB, DB_TAURUS, DB_UNKNOWN, DB_DEBUG, DB_HDF5X, + DB_PDBP, DB_HDF5, + ) +from pyvisfile.silo._internal import DB_CLOBBER, DB_NOCLOBBER # noqa: F401 +from pyvisfile.silo._internal import DB_READ, DB_APPEND # noqa: F401 +from pyvisfile.silo._internal import ( # noqa: F401 + DB_LOCAL, DB_SUN3, DB_SUN4, DB_SGI, DB_RS6000, DB_CRAY, DB_INTEL, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DBOPT_ALIGN, DBOPT_COORDSYS, DBOPT_CYCLE, DBOPT_FACETYPE, DBOPT_HI_OFFSET, + DBOPT_LO_OFFSET, DBOPT_LABEL, DBOPT_XLABEL, DBOPT_YLABEL, DBOPT_ZLABEL, + DBOPT_MAJORORDER, DBOPT_NSPACE, DBOPT_ORIGIN, DBOPT_PLANAR, DBOPT_TIME, + DBOPT_UNITS, DBOPT_XUNITS, DBOPT_YUNITS, DBOPT_ZUNITS, DBOPT_DTIME, + DBOPT_USESPECMF, DBOPT_XVARNAME, DBOPT_YVARNAME, DBOPT_ZVARNAME, + DBOPT_ASCII_LABEL, DBOPT_MATNOS, DBOPT_NMATNOS, DBOPT_MATNAME, DBOPT_NMAT, + DBOPT_NMATSPEC, DBOPT_BASEINDEX, DBOPT_ZONENUM, DBOPT_NODENUM, + DBOPT_BLOCKORIGIN, DBOPT_GROUPNUM, DBOPT_GROUPORIGIN, DBOPT_NGROUPS, + DBOPT_MATNAMES, DBOPT_EXTENTS_SIZE, DBOPT_EXTENTS, DBOPT_MATCOUNTS, + DBOPT_MATLISTS, DBOPT_MIXLENS, DBOPT_ZONECOUNTS, DBOPT_HAS_EXTERNAL_ZONES, + DBOPT_PHZONELIST, DBOPT_MATCOLORS, DBOPT_BNDNAMES, DBOPT_REGNAMES, + DBOPT_ZONENAMES, DBOPT_HIDE_FROM_GUI, DBOPT_TOPO_DIM, DBOPT_REFERENCE, + DBOPT_GROUPINGS_SIZE, DBOPT_GROUPINGS, DBOPT_GROUPINGNAMES, DBOPT_ALLOWMAT0, + DBOPT_MRGTREE_NAME, DBOPT_REGION_PNAMES, DBOPT_TENSOR_RANK, DBOPT_MMESH_NAME, + DBOPT_TV_CONNECTIVITY, DBOPT_DISJOINT_MODE, DBOPT_MRGV_ONAMES, + DBOPT_MRGV_RNAMES, DBOPT_SPECNAMES, DBOPT_SPECCOLORS, DBOPT_LLONGNZNUM, + DBOPT_CONSERVED, DBOPT_EXTENSIVE, DBOPT_MB_FILE_NS, DBOPT_MB_BLOCK_NS, + DBOPT_MB_BLOCK_TYPE, DBOPT_MB_EMPTY_LIST, DBOPT_MB_EMPTY_COUNT, + DBOPT_MB_REPR_BLOCK_IDX, DBOPT_MISSING_VALUE, DBOPT_ALT_ZONENUM_VARS, + DBOPT_ALT_NODENUM_VARS, DBOPT_GHOST_NODE_LABELS, DBOPT_GHOST_ZONE_LABELS, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DB_TOP, DB_NONE, DB_ALL, DB_ABORT, DB_SUSPEND, DB_RESUME, DB_ALL_AND_DRVR, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + E_NOERROR, E_BADFTYPE, E_NOTIMP, E_NOFILE, E_INTERNAL, E_NOMEM, E_BADARGS, + E_CALLFAIL, E_NOTFOUND, E_TAURSTATE, E_MSERVER, E_PROTO, E_NOTDIR, + E_MAXOPEN, E_NOTFILTER, E_MAXFILTERS, E_FEXIST, E_FILEISDIR, E_FILENOREAD, + E_SYSTEMERR, E_FILENOWRITE, E_INVALIDNAME, E_NOOVERWRITE, E_CHECKSUM, + E_COMPRESSION, E_GRABBED, E_NOTREG, E_CONCURRENT, E_DRVRCANTOPEN, + E_BADOPTCLASS, E_NOTENABLEDINBUILD, E_MAXFILEOPTSETS, E_NOHDF5, + E_EMPTYOBJECT, E_OBJBUFFULL, + ) +from pyvisfile.silo._internal import DB_ROWMAJOR, DB_COLMAJOR # noqa: F401 +from pyvisfile.silo._internal import ( # noqa: F401 + DB_COLLINEAR, DB_NONCOLLINEAR, DB_QUAD_RECT, DB_QUAD_CURV, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DB_NOTCENT, DB_NODECENT, DB_ZONECENT, DB_FACECENT, DB_BNDCENT, + DB_EDGECENT, DB_BLOCKCENT, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DB_CARTESIAN, DB_CYLINDRICAL, DB_SPHERICAL, DB_NUMERICAL, DB_OTHER, + ) +from pyvisfile.silo._internal import DB_RECTILINEAR, DB_CURVILINEAR # noqa: F401 +from pyvisfile.silo._internal import DB_AREA, DB_VOLUME # noqa: F401 +from pyvisfile.silo._internal import DB_ON, DB_OFF # noqa: F401 +from pyvisfile.silo._internal import DB_ABUTTING, DB_FLOATING # noqa: F401 +from pyvisfile.silo._internal import ( # noqa: F401 + DB_VARTYPE_SCALAR, DB_VARTYPE_VECTOR, DB_VARTYPE_TENSOR, + DB_VARTYPE_SYMTENSOR, DB_VARTYPE_ARRAY, DB_VARTYPE_MATERIAL, + DB_VARTYPE_SPECIES, DB_VARTYPE_LABEL, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DB_GHOSTTYPE_NOGHOST, DB_GHOSTTYPE_INTDUP, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DBCSG_QUADRIC_G, DBCSG_SPHERE_PR, DBCSG_ELLIPSOID_PRRR, DBCSG_PLANE_G, + DBCSG_PLANE_X, DBCSG_PLANE_Y, DBCSG_PLANE_Z, DBCSG_PLANE_PN, + DBCSG_PLANE_PPP, DBCSG_CYLINDER_PNLR, DBCSG_CYLINDER_PPR, + DBCSG_BOX_XYZXYZ, DBCSG_CONE_PNLA, DBCSG_CONE_PPA, DBCSG_POLYHEDRON_KF, + DBCSG_HEX_6F, DBCSG_TET_4F, DBCSG_PYRAMID_5F, DBCSG_PRISM_5F, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DBCSG_QUADRATIC_G, DBCSG_CIRCLE_PR, DBCSG_ELLIPSE_PRR, DBCSG_LINE_G, + DBCSG_LINE_X, DBCSG_LINE_Y, DBCSG_LINE_PN, DBCSG_LINE_PP, DBCSG_BOX_XYXY, + DBCSG_ANGLE_PNLA, DBCSG_ANGLE_PPA, DBCSG_POLYGON_KP, DBCSG_TRI_3P, + DBCSG_QUAD_4P, + ) +from pyvisfile.silo._internal import ( # noqa: F401 + DBCSG_INNER, DBCSG_OUTER, DBCSG_ON, DBCSG_UNION, DBCSG_INTERSECT, + DBCSG_DIFF, DBCSG_COMPLIMENT, DBCSG_XFORM, DBCSG_SWEEP, + ) + +if get_silo_version() >= (4, 6, 1): + from pyvisfile.silo._internal import ( # noqa: F401 + DB_HDF5_SEC2, DB_HDF5_STDIO, DB_HDF5_CORE, DB_HDF5_LOG, + DB_HDF5_SPLIT, DB_HDF5_DIRECT, DB_HDF5_FAMILY, DB_HDF5_MPIO, + DB_HDF5_MPIOP, DB_HDF5_MPIP, DB_HDF5_SILO, + ) + from pyvisfile.silo._internal import ( # noqa: F401 + DB_ZONETYPE_BEAM, DB_ZONETYPE_TRIANGLE, DB_ZONETYPE_QUAD, + DB_ZONETYPE_POLYHEDRON, DB_ZONETYPE_TET, DB_ZONETYPE_PYRAMID, + DB_ZONETYPE_PRISM, DB_ZONETYPE_HEX, + ) def _convert_optlist(ol_dict): optcount = len(ol_dict) + 1 - ol = _intnl.DBOptlist(optcount, optcount * 150) + ol = _silo.DBOptlist(optcount, optcount * 150) for key, value in ol_dict.items(): if isinstance(value, int): @@ -114,7 +167,7 @@ def _convert_optlist(ol_dict): return ol -class SiloFile(_intnl.DBFile): +class SiloFile(_silo.DBFile): """This class can be used in a Python 2.5 *with* statement.""" def __enter__(self): return self @@ -130,34 +183,34 @@ class SiloFile(_intnl.DBFile): mode = DB_NOCLOBBER if filetype is None: filetype = DB_PDB - _intnl.DBFile.__init__(self, pathname, mode, target, + _silo.DBFile.__init__(self, pathname, mode, target, fileinfo, filetype) else: if mode is None: mode = DB_APPEND if filetype is None: filetype = DB_UNKNOWN - _intnl.DBFile.__init__(self, pathname, filetype, mode) + _silo.DBFile.__init__(self, pathname, filetype, mode) def put_zonelist_2(self, names, nzones, ndims, nodelist, lo_offset, hi_offset, shapetype, shapesize, shapecounts, optlist={}): - _intnl.DBFile.put_zonelist_2(self, names, nzones, ndims, + _silo.DBFile.put_zonelist_2(self, names, nzones, ndims, nodelist, lo_offset, hi_offset, shapetype, shapesize, shapecounts, _convert_optlist(optlist)) def put_ucdmesh(self, mname, coordnames, coords, nzones, zonel_name, facel_name, optlist={}): - _intnl.DBFile.put_ucdmesh(self, mname, coordnames, coords, + _silo.DBFile.put_ucdmesh(self, mname, coordnames, coords, nzones, zonel_name, facel_name, _convert_optlist(optlist)) def put_ucdvar1(self, vname, mname, vec, centering, optlist={}): - _intnl.DBFile.put_ucdvar1(self, vname, mname, vec, centering, + _silo.DBFile.put_ucdvar1(self, vname, mname, vec, centering, _convert_optlist(optlist)) def put_ucdvar(self, vname, mname, varnames, vars, centering, optlist={}): - _intnl.DBFile.put_ucdvar(self, vname, mname, varnames, vars, centering, + _silo.DBFile.put_ucdvar(self, vname, mname, varnames, vars, centering, _convert_optlist(optlist)) def put_defvars(self, vname, vars): @@ -172,43 +225,43 @@ class SiloFile(_intnl.DBFile): If the type is not specified, scalar is assumed. """ - _intnl.DBFile.put_defvars(self, vname, vars) + _silo.DBFile.put_defvars(self, vname, vars) def put_pointmesh(self, mname, coords, optlist={}): - _intnl.DBFile.put_pointmesh(self, mname, coords, + _silo.DBFile.put_pointmesh(self, mname, coords, _convert_optlist(optlist)) def put_pointvar1(self, vname, mname, var, optlist={}): - _intnl.DBFile.put_pointvar1(self, vname, mname, var, + _silo.DBFile.put_pointvar1(self, vname, mname, var, _convert_optlist(optlist)) def put_pointvar(self, vname, mname, vars, optlist={}): - _intnl.DBFile.put_pointvar(self, vname, mname, vars, + _silo.DBFile.put_pointvar(self, vname, mname, vars, _convert_optlist(optlist)) def put_quadmesh(self, mname, coords, coordtype=DB_COLLINEAR, optlist={}): - _intnl.DBFile.put_quadmesh(self, mname, coords, coordtype, + _silo.DBFile.put_quadmesh(self, mname, coords, coordtype, _convert_optlist(optlist)) def put_quadvar1(self, vname, mname, var, dims, centering, optlist={}): - _intnl.DBFile.put_quadvar1(self, vname, mname, var, dims, centering, + _silo.DBFile.put_quadvar1(self, vname, mname, var, dims, centering, _convert_optlist(optlist)) def put_quadvar(self, vname, mname, varnames, vars, dims, centering, optlist={}): - _intnl.DBFile.put_quadvar(self, vname, mname, + _silo.DBFile.put_quadvar(self, vname, mname, varnames, vars, dims, centering, _convert_optlist(optlist)) def put_multimesh(self, mname, mnames_and_types, optlist={}): - _intnl.DBFile.put_multimesh(self, mname, + _silo.DBFile.put_multimesh(self, mname, mnames_and_types, _convert_optlist(optlist)) def put_multivar(self, vname, vnames_and_types, optlist={}): - _intnl.DBFile.put_multivar(self, vname, + _silo.DBFile.put_multivar(self, vname, vnames_and_types, _convert_optlist(optlist)) def put_curve(self, curvename, xvals, yvals, optlist={}): - _intnl.DBFile.put_curve(self, curvename, xvals, yvals, + _silo.DBFile.put_curve(self, curvename, xvals, yvals, _convert_optlist(optlist)) diff --git a/setup.py b/setup.py index e2cbaa2569d28c208f3d6c9b0fe5c741777fc301..4da42ae69454ee56a229b883161e2fc2396bd4bd 100644 --- a/setup.py +++ b/setup.py @@ -15,14 +15,12 @@ class PyUblasExtension(NumpyExtension): def get_config_schema(): from aksetup_helper import ConfigSchema, \ - IncludeDir, LibraryDir, Libraries, BoostLibraries, \ + IncludeDir, LibraryDir, Libraries, \ Switch, StringListOption, make_boost_base_options return ConfigSchema(make_boost_base_options() + [ Switch("USE_SILO", False, "Compile libsilo interface"), - BoostLibraries("python"), - IncludeDir("SILO", []), LibraryDir("SILO", []), Libraries("SILO", ["siloh5"]), @@ -34,21 +32,18 @@ def get_config_schema(): def main(): from setuptools import find_packages - from aksetup_helper import hack_distutils, get_config, setup + from aksetup_helper import (hack_distutils, get_config, setup, + ExtensionUsingNumpy, check_pybind11, PybindBuildExtCommand, + get_pybind_include) hack_distutils() conf = get_config(get_config_schema(), warn_about_no_config=False) - INCLUDE_DIRS = conf["BOOST_INC_DIR"] # noqa - - LIBRARY_DIRS = conf["BOOST_LIB_DIR"] # noqa - LIBRARIES = conf["BOOST_PYTHON_LIBNAME"] # noqa - - EXTRA_DEFINES = {} # noqa - EXTRA_INCLUDE_DIRS = [] # noqa - EXTRA_LIBRARY_DIRS = [] # noqa - EXTRA_LIBRARIES = [] # noqa + extra_defines = {} + extra_include_dirs = [] + extra_library_dirs = [] + extra_libraries = [] ver_dic = {} ver_file_name = "pyvisfile/__init__.py" @@ -59,19 +54,23 @@ def main(): ext_modules = [] if conf["USE_SILO"]: - EXTRA_DEFINES["USE_SILO"] = 1 - EXTRA_INCLUDE_DIRS.extend(conf["SILO_INC_DIR"]) - EXTRA_LIBRARY_DIRS.extend(conf["SILO_LIB_DIR"]) - EXTRA_LIBRARIES.extend(conf["SILO_LIBNAME"]) + check_pybind11() + + extra_defines["USE_SILO"] = 1 + extra_include_dirs.extend(conf["SILO_INC_DIR"]) + extra_library_dirs.extend(conf["SILO_LIB_DIR"]) + extra_libraries.extend(conf["SILO_LIBNAME"]) - ext_modules.append(PyUblasExtension("_internal", + ext_modules.append(ExtensionUsingNumpy("_internal", ["src/wrapper/wrap_silo.cpp"], - include_dirs=INCLUDE_DIRS + EXTRA_INCLUDE_DIRS, - library_dirs=LIBRARY_DIRS + EXTRA_LIBRARY_DIRS, - libraries=LIBRARIES + EXTRA_LIBRARIES, + include_dirs=[get_pybind_include()] + extra_include_dirs, + library_dirs=extra_library_dirs, + libraries=extra_libraries, extra_compile_args=conf["CXXFLAGS"], - define_macros=list(EXTRA_DEFINES.items()), + define_macros=list(extra_defines.items()), + language="c++", )) + requirements.append("pybind11>=2.5.0") setup(name="pyvisfile", version=ver_dic["VERSION_TEXT"], @@ -111,6 +110,7 @@ def main(): ext_package="pyvisfile.silo", ext_modules=ext_modules, + cmdclass={"build_ext": PybindBuildExtCommand}, zip_safe=False) diff --git a/src/wrapper/wrap_silo.cpp b/src/wrapper/wrap_silo.cpp index df4a6a6102592dd123edb9c753a126bf0dfe4bd3..9a0be8c0d29c61b11fcfbfff99b46c7bb97aebd1 100644 --- a/src/wrapper/wrap_silo.cpp +++ b/src/wrapper/wrap_silo.cpp @@ -1,86 +1,127 @@ // PyVisfile - A Python wrapper around Silo // Copyright (C) 2007 Andreas Kloeckner +// docs for the various types in v.4.10.2 can be found here (2020-10-01) +// https://wci.llnl.gov/content/assets/docs/simulation/computer-codes/silo/LLNL-SM-654357.pdf +#include +#include +#include - -#include -#include -#include -#include -#include -#include -#include #include #include #include #include - - #ifdef SILO_VERS_MAJ -#define PYVISFILE_SILO_VERSION_GE(Maj,Min,Rel) \ - (((SILO_VERS_MAJ==Maj) && (SILO_VERS_MIN==Min) && (SILO_VERS_PAT>=Rel)) || \ - ((SILO_VERS_MAJ==Maj) && (SILO_VERS_MIN>Min)) || \ - (SILO_VERS_MAJ>Maj)) +#define PYVISFILE_SILO_VERSION_GE(Maj, Min, Rel) \ + (((SILO_VERS_MAJ == Maj) && (SILO_VERS_MIN == Min) && (SILO_VERS_PAT >= Rel)) || \ + ((SILO_VERS_MAJ == Maj) && (SILO_VERS_MIN > Min)) || \ + (SILO_VERS_MAJ > Maj)) #else -#define PYVISFILE_SILO_VERSION_GE(Maj,Min,Rel) 0 +#define PYVISFILE_SILO_VERSION_GE(Maj, Min, Rel) 0 #endif +// {{{ macros + #define PYTHON_ERROR(TYPE, REASON) \ { \ PyErr_SetString(PyExc_##TYPE, REASON); \ - throw boost::python::error_already_set(); \ + throw py::error_already_set(); \ } - - - #define ENUM_VALUE(NAME) \ value(#NAME, NAME) + #define DEF_SIMPLE_FUNCTION(NAME) \ - def(#NAME, &NAME) + m.def(#NAME, &NAME) + #define DEF_SIMPLE_METHOD(NAME) \ def(#NAME, &cl::NAME) + #define DEF_SIMPLE_METHOD_WITH_ARGS(NAME, ARGS) \ def(#NAME, &cl::NAME, args ARGS) -#define DEF_SIMPLE_RO_PROPERTY(NAME) \ - add_property(#NAME, &cl::NAME) +#define DEF_SIMPLE_RO_MEMBER(NAME) \ + def_readonly(#NAME, &cl::NAME) +#define DEF_SIMPLE_RO_PROPERTY(NAME) \ + def_property_readonly(#NAME, &cl::get##NAME) +#define CALL_GUARDED(NAME, ARGLIST) \ + if (NAME ARGLIST) \ + throw std::runtime_error(#NAME " failed"); -using namespace boost::python; -using namespace pyublas; +#define COPY_PY_LIST(TYPE, NAME) \ + std::vector NAME; \ + for (auto it: py_##NAME) \ + NAME.push_back(it.cast()); \ +#define MAKE_STRING_POINTER_VECTOR(NAME) \ + std::vector NAME##_ptrs; \ + for(const std::string &s: NAME) \ + NAME##_ptrs.push_back(s.data()); \ +// }}} + +namespace py = pybind11; +// NOTE: for IntVector +PYBIND11_MAKE_OPAQUE(std::vector); namespace { - // basics ------------------------------------------------------------------- - template - std::auto_ptr > construct_vector(object iterable) + // {{{ helpers + + // https://stackoverflow.com/a/26221725 + template + char *string_format(const std::string& format, Args ... args) { - std::auto_ptr > result(new std::vector()); - copy( - stl_input_iterator(iterable), - stl_input_iterator(), - back_inserter(*result)); - return result; + size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; + if (size <= 0) + throw std::runtime_error("Error during formatting."); + + std::unique_ptr buf(new char[size]); + snprintf(buf.get(), size, format.c_str(), args ...); + return buf.get(); } + // https://stackoverflow.com/a/44175911 + class noncopyable { + public: + noncopyable() = default; + ~noncopyable() = default; + private: + noncopyable(const noncopyable&) = delete; + noncopyable& operator=(const noncopyable&) = delete; + }; + py::tuple get_silo_version() + { +#if PYVISFILE_SILO_VERSION_GE(4, 6, 1) + return py::make_tuple(SILO_VERS_MAJ, SILO_VERS_MIN, SILO_VERS_PAT); +#else + return py::make_tuple(4, 5, 1); +#endif + } + +#if !PYVISFILE_SILO_VERSION_GE(4, 6, 1) + int set_dep_warning_dummy(int) + { + return 0; + } +#endif + // }}} - // {{{ constants ------------------------------------------------------------ - dict symbols() + // {{{ constants + + void silo_expose_symbols(py::module &m) { - dict result; #define EXPORT_CONSTANT(NAME) \ - result[#NAME] = NAME + m.attr(#NAME) = NAME /* Drivers */ EXPORT_CONSTANT(DB_NETCDF); @@ -88,14 +129,23 @@ namespace EXPORT_CONSTANT(DB_TAURUS); EXPORT_CONSTANT(DB_UNKNOWN); EXPORT_CONSTANT(DB_DEBUG); + EXPORT_CONSTANT(DB_HDF5X); + EXPORT_CONSTANT(DB_PDBP); + EXPORT_CONSTANT(DB_HDF5); -#if PYVISFILE_SILO_VERSION_GE(4,6,1) +#if PYVISFILE_SILO_VERSION_GE(4, 6, 1) EXPORT_CONSTANT(DB_HDF5_SEC2); EXPORT_CONSTANT(DB_HDF5_STDIO); EXPORT_CONSTANT(DB_HDF5_CORE); + EXPORT_CONSTANT(DB_HDF5_LOG); + EXPORT_CONSTANT(DB_HDF5_SPLIT); + EXPORT_CONSTANT(DB_HDF5_DIRECT); + EXPORT_CONSTANT(DB_HDF5_FAMILY); EXPORT_CONSTANT(DB_HDF5_MPIO); EXPORT_CONSTANT(DB_HDF5_MPIOP); + EXPORT_CONSTANT(DB_HDF5_MPIP); + EXPORT_CONSTANT(DB_HDF5_SILO); #endif /* Flags for DBCreate */ @@ -167,6 +217,36 @@ namespace EXPORT_CONSTANT(DBOPT_REGNAMES); EXPORT_CONSTANT(DBOPT_ZONENAMES); EXPORT_CONSTANT(DBOPT_HIDE_FROM_GUI); + EXPORT_CONSTANT(DBOPT_TOPO_DIM); + EXPORT_CONSTANT(DBOPT_REFERENCE); + EXPORT_CONSTANT(DBOPT_GROUPINGS_SIZE); + EXPORT_CONSTANT(DBOPT_GROUPINGS); + EXPORT_CONSTANT(DBOPT_GROUPINGNAMES); + EXPORT_CONSTANT(DBOPT_ALLOWMAT0); + EXPORT_CONSTANT(DBOPT_MRGTREE_NAME); + EXPORT_CONSTANT(DBOPT_REGION_PNAMES); + EXPORT_CONSTANT(DBOPT_TENSOR_RANK); + EXPORT_CONSTANT(DBOPT_MMESH_NAME); + EXPORT_CONSTANT(DBOPT_TV_CONNECTIVITY); + EXPORT_CONSTANT(DBOPT_DISJOINT_MODE); + EXPORT_CONSTANT(DBOPT_MRGV_ONAMES); + EXPORT_CONSTANT(DBOPT_MRGV_RNAMES); + EXPORT_CONSTANT(DBOPT_SPECNAMES); + EXPORT_CONSTANT(DBOPT_SPECCOLORS); + EXPORT_CONSTANT(DBOPT_LLONGNZNUM); + EXPORT_CONSTANT(DBOPT_CONSERVED); + EXPORT_CONSTANT(DBOPT_EXTENSIVE); + EXPORT_CONSTANT(DBOPT_MB_FILE_NS); + EXPORT_CONSTANT(DBOPT_MB_BLOCK_NS); + EXPORT_CONSTANT(DBOPT_MB_BLOCK_TYPE); + EXPORT_CONSTANT(DBOPT_MB_EMPTY_LIST); + EXPORT_CONSTANT(DBOPT_MB_EMPTY_COUNT); + EXPORT_CONSTANT(DBOPT_MB_REPR_BLOCK_IDX); + EXPORT_CONSTANT(DBOPT_MISSING_VALUE); + EXPORT_CONSTANT(DBOPT_ALT_ZONENUM_VARS); + EXPORT_CONSTANT(DBOPT_ALT_NODENUM_VARS); + EXPORT_CONSTANT(DBOPT_GHOST_NODE_LABELS); + EXPORT_CONSTANT(DBOPT_GHOST_ZONE_LABELS); /* Error trapping method */ EXPORT_CONSTANT(DB_TOP); @@ -175,6 +255,7 @@ namespace EXPORT_CONSTANT(DB_ABORT); EXPORT_CONSTANT(DB_SUSPEND); EXPORT_CONSTANT(DB_RESUME); + EXPORT_CONSTANT(DB_ALL_AND_DRVR); /* Errors */ EXPORT_CONSTANT(E_NOERROR); @@ -188,7 +269,7 @@ namespace EXPORT_CONSTANT(E_NOTFOUND); EXPORT_CONSTANT(E_TAURSTATE); EXPORT_CONSTANT(E_MSERVER); - EXPORT_CONSTANT(E_PROTO ); + EXPORT_CONSTANT(E_PROTO); EXPORT_CONSTANT(E_NOTDIR); EXPORT_CONSTANT(E_MAXOPEN); EXPORT_CONSTANT(E_NOTFILTER); @@ -201,7 +282,17 @@ namespace EXPORT_CONSTANT(E_INVALIDNAME); EXPORT_CONSTANT(E_NOOVERWRITE); EXPORT_CONSTANT(E_CHECKSUM); - EXPORT_CONSTANT(E_NERRORS); + EXPORT_CONSTANT(E_COMPRESSION); + EXPORT_CONSTANT(E_GRABBED); + EXPORT_CONSTANT(E_NOTREG); + EXPORT_CONSTANT(E_CONCURRENT); + EXPORT_CONSTANT(E_DRVRCANTOPEN); + EXPORT_CONSTANT(E_BADOPTCLASS); + EXPORT_CONSTANT(E_NOTENABLEDINBUILD); + EXPORT_CONSTANT(E_MAXFILEOPTSETS); + EXPORT_CONSTANT(E_NOHDF5); + EXPORT_CONSTANT(E_EMPTYOBJECT); + EXPORT_CONSTANT(E_OBJBUFFULL); /* Definitions for MAJOR_ORDER */ EXPORT_CONSTANT(DB_ROWMAJOR); @@ -219,6 +310,8 @@ namespace EXPORT_CONSTANT(DB_ZONECENT); EXPORT_CONSTANT(DB_FACECENT); EXPORT_CONSTANT(DB_BNDCENT); + EXPORT_CONSTANT(DB_EDGECENT); + EXPORT_CONSTANT(DB_BLOCKCENT); /* Definitions for COORD_SYSTEM */ EXPORT_CONSTANT(DB_CARTESIAN); @@ -234,10 +327,15 @@ namespace /* Definitions for PLANAR */ EXPORT_CONSTANT(DB_AREA); EXPORT_CONSTANT(DB_VOLUME); + /* Definitions for flag values */ EXPORT_CONSTANT(DB_ON); EXPORT_CONSTANT(DB_OFF); + /* Definitions for disjoint flags */ + EXPORT_CONSTANT(DB_ABUTTING); + EXPORT_CONSTANT(DB_FLOATING); + /* Definitions for derived variable types */ EXPORT_CONSTANT(DB_VARTYPE_SCALAR); EXPORT_CONSTANT(DB_VARTYPE_VECTOR); @@ -248,6 +346,10 @@ namespace EXPORT_CONSTANT(DB_VARTYPE_SPECIES); EXPORT_CONSTANT(DB_VARTYPE_LABEL); + /* Definitions for ghost labels */ + EXPORT_CONSTANT(DB_GHOSTTYPE_NOGHOST); + EXPORT_CONSTANT(DB_GHOSTTYPE_INTDUP); + /* Definitions for CSG boundary types */ EXPORT_CONSTANT(DBCSG_QUADRIC_G); EXPORT_CONSTANT(DBCSG_SPHERE_PR); @@ -296,6 +398,11 @@ namespace EXPORT_CONSTANT(DBCSG_XFORM); EXPORT_CONSTANT(DBCSG_SWEEP); + /* Definitions for MRG tree traversal flags */ + EXPORT_CONSTANT(DB_PREORDER); + EXPORT_CONSTANT(DB_POSTORDER); + EXPORT_CONSTANT(DB_FROMCWR); + #if PYVISFILE_SILO_VERSION_GE(4,6,1) /* Shape types */ EXPORT_CONSTANT(DB_ZONETYPE_BEAM); @@ -309,45 +416,16 @@ namespace #endif #undef EXPORT_CONSTANT - return result; } // }}} - - - -#define CALL_GUARDED(NAME, ARGLIST) \ - if (NAME ARGLIST) \ - throw std::runtime_error(#NAME " failed"); - -#define COPY_PY_LIST(TYPE, NAME) \ - std::vector NAME; \ - std::copy( \ - stl_input_iterator(NAME##_py), \ - stl_input_iterator(), \ - back_inserter(NAME)); \ - -#define MAKE_STRING_POINTER_VECTOR(NAME) \ - std::vector NAME##_ptrs; \ - BOOST_FOREACH(const std::string &s, NAME) \ - NAME##_ptrs.push_back(s.data()); - -#define PYTHON_FOREACH(NAME, ITERABLE) \ - BOOST_FOREACH(object NAME, \ - std::make_pair( \ - stl_input_iterator(ITERABLE), \ - stl_input_iterator())) - - - - - NPY_TYPES get_varlist_dtype(object varlist) + NPY_TYPES get_varlist_dtype(py::sequence varlist) { bool first = true; NPY_TYPES result = NPY_NOTYPE; - PYTHON_FOREACH(var, varlist) + for(py::object var: varlist) { if (!PyArray_Check(var.ptr())) PYTHON_ERROR(TypeError, "component of variable list is not numpy array"); @@ -364,15 +442,13 @@ namespace return result; } + // {{{ DBoptlist wrapper - - - // {{{ DBoptlist wrapper ---------------------------------------------------- - class DBoptlistWrapper : boost::noncopyable + class DBoptlistWrapper: noncopyable { private: DBoptlist *m_optlist; - boost::scoped_array m_option_storage; + char *m_option_storage; unsigned m_option_storage_size; unsigned m_option_storage_occupied; @@ -388,7 +464,7 @@ namespace } ~DBoptlistWrapper() { - CALL_GUARDED(DBFreeOptlist, (m_optlist)); + DBFreeOptlist(m_optlist); } void add_option(int option, int value) @@ -427,15 +503,15 @@ namespace )); } - void add_option(int option, tuple values_py) + void add_option(int option, py::tuple py_values) { std::vector values; - PYTHON_FOREACH(value_py, values_py) + for(size_t i = 0; i < py::len(py_values); ++i) { - int value = extract (value_py); - values.push_back(value); + values.push_back(py_values[i].cast()); } + CALL_GUARDED(DBAddOption,(m_optlist, option, add_storage_data((void *) &values.front(), values.size()*sizeof(int)) )); @@ -453,7 +529,7 @@ namespace throw std::runtime_error("silo option list storage exhausted" "--specify bigger storage size"); - void *dest = m_option_storage.get() + m_option_storage_occupied; + void *dest = m_option_storage + m_option_storage_occupied; memcpy(dest, data, size); m_option_storage_occupied += size; return dest; @@ -463,9 +539,6 @@ namespace // }}} - - - int get_datatype(int) { return DB_INT; } int get_datatype(short) { return DB_SHORT; } int get_datatype(long) { return DB_LONG; } @@ -488,8 +561,8 @@ namespace case DB_DOUBLE: return NPY_DOUBLE; case DB_CHAR: - return NPY_CHAR; -#if SILO_VERSION_GE(4,7,2) + return NPY_STRING; +#if SILO_VERSION_GE(4, 7, 2) case DB_LONG_LONG: return NPY_LONGLONG; #endif @@ -498,38 +571,35 @@ namespace } } - - - // {{{ data wrappers // {{{ data wrapper helpers #define PYVISFILE_TYPED_ACCESSOR(TYPE,NAME) \ - TYPE NAME() const { return m_data->NAME; } + TYPE get##NAME() const { return m_data->NAME; } #define PYVISFILE_STRING_ACCESSOR(NAME) \ - object NAME() const \ + py::object get##NAME() const \ { \ if (m_data) \ - return object(std::string(m_data->NAME)); \ + return py::cast(std::string(m_data->NAME)); \ else \ - return object(); \ + return py::none(); \ } #define PYVISFILE_TYPED_ARRAY_ACCESSOR(CAST_TO, NAME, SIZE) \ - object NAME() const \ + py::object get##NAME() const \ { \ - list py_list_result; \ + py::list py_list_result; \ for (unsigned i = 0; i < SIZE; ++i) \ py_list_result.append(CAST_TO(m_data->NAME[i])); \ - return tuple(py_list_result); \ + return py::make_tuple(py_list_result); \ } // }}} // {{{ curve wrapper - class DBcurveWrapper : boost::noncopyable + class DBcurveWrapper: noncopyable { public: DBcurve *m_data; @@ -555,15 +625,15 @@ namespace }; #define PYVISFILE_CURVE_DATA_GETTER(COORD) \ - handle<> curve_##COORD(object py_curve) \ + py::handle curve_##COORD(py::object py_curve) \ { \ - DBcurveWrapper &curve((extract(py_curve))); \ + DBcurveWrapper &curve(py_curve.cast()); \ npy_intp dims[] = { curve.m_data->npts }; \ - handle<> result(PyArray_SimpleNewFromData(1, dims, \ + py::handle result(PyArray_SimpleNewFromData(1, dims, \ silo_typenum_to_numpy_typenum(curve.m_data->datatype), \ curve.m_data->COORD)); \ - PyArray_BASE(result.get()) = py_curve.ptr(); \ - Py_INCREF(PyArray_BASE(result.get())); \ + PyArray_BASE(result.ptr()) = py_curve.ptr(); \ + Py_INCREF(PyArray_BASE(result.ptr())); \ return result; \ } @@ -574,7 +644,7 @@ namespace // {{{ quad mesh wrapper - class DBquadmeshWrapper : boost::noncopyable + class DBquadmeshWrapper: noncopyable { public: DBquadmesh *m_data; @@ -620,30 +690,30 @@ namespace PYVISFILE_STRING_ACCESSOR(mrgtree_name); }; - object quadmesh_coords(object py_quadmesh) + py::object quadmesh_coords(py::object py_quadmesh) { - DBquadmeshWrapper &quadmesh((extract(py_quadmesh))); + DBquadmeshWrapper &quadmesh(py_quadmesh.cast()); - list result; - for (unsigned i = 0; i < quadmesh.m_data->ndims; ++i) + py::list result; + for (int i = 0; i < quadmesh.m_data->ndims; ++i) { npy_intp dims[] = { quadmesh.m_data->dims[i] }; - handle<> coord_array(PyArray_SimpleNewFromData(1, dims, + py::handle coord_array(PyArray_SimpleNewFromData(1, dims, silo_typenum_to_numpy_typenum(quadmesh.m_data->datatype), quadmesh.m_data->coords[i])); - PyArray_BASE(coord_array.get()) = py_quadmesh.ptr(); - Py_INCREF(PyArray_BASE(coord_array.get())); + PyArray_BASE(coord_array.ptr()) = py_quadmesh.ptr(); + Py_INCREF(PyArray_BASE(coord_array.ptr())); result.append(coord_array); } - return tuple(result); + return py::make_tuple(result); } // }}} // {{{ quad var wrapper - class DBquadvarWrapper : boost::noncopyable + class DBquadvarWrapper: noncopyable { public: DBquadvar *m_data; @@ -687,13 +757,13 @@ namespace // TODO: region_pnames }; - object quadvar_vals(object py_quadvar) + py::object quadvar_vals(py::object py_quadvar) { - DBquadvarWrapper &quadvar((extract(py_quadvar))); + DBquadvarWrapper &quadvar(py_quadvar.cast()); npy_intp dims[3]; - for (unsigned i = 0; i < quadvar.m_data->ndims; ++i) + for (int i = 0; i < quadvar.m_data->ndims; ++i) dims[i] = quadvar.m_data->dims[i]; int ary_flags = 0; @@ -702,67 +772,65 @@ namespace else ary_flags |= NPY_FARRAY; - list result; - for (unsigned i = 0; i < quadvar.m_data->nvals; ++i) + py::list result; + for (int i = 0; i < quadvar.m_data->nvals; ++i) { PyArray_Descr *tp_descr; tp_descr = PyArray_DescrNewFromType( silo_typenum_to_numpy_typenum(quadvar.m_data->datatype)); if (tp_descr == 0) - throw error_already_set(); + throw py::error_already_set(); - handle<> val_array(PyArray_NewFromDescr( + py::handle val_array(PyArray_NewFromDescr( &PyArray_Type, tp_descr, quadvar.m_data->ndims, dims, /*strides*/ NULL, quadvar.m_data->vals[i], ary_flags, /*obj*/NULL)); - PyArray_BASE(val_array.get()) = py_quadvar.ptr(); - Py_INCREF(PyArray_BASE(val_array.get())); + PyArray_BASE(val_array.ptr()) = py_quadvar.ptr(); + Py_INCREF(PyArray_BASE(val_array.ptr())); result.append(val_array); } - return tuple(result); + return py::make_tuple(result); } // }}} // }}} + // {{{ DBtoc copy - - - // {{{ DBtoc copy ----------------------------------------------------------- - struct DBtocCopy : boost::noncopyable + struct DBtocCopy : noncopyable { - list curve_names; - list multimesh_names; - list multimeshadj_names; - list multivar_names; - list multimat_names; - list multimatspecies_names; - list csgmesh_names; - list csgvar_names; - list defvars_names; - list qmesh_names; - list qvar_names; - list ucdmesh_names; - list ucdvar_names; - list ptmesh_names; - list ptvar_names; - list mat_names; - list matspecies_names; - list var_names; - list obj_names; - list dir_names; - list array_names; - list mrgtree_names; - list groupelmap_names; - list mrgvar_names; + py::list curve_names; + py::list multimesh_names; + py::list multimeshadj_names; + py::list multivar_names; + py::list multimat_names; + py::list multimatspecies_names; + py::list csgmesh_names; + py::list csgvar_names; + py::list defvars_names; + py::list qmesh_names; + py::list qvar_names; + py::list ucdmesh_names; + py::list ucdvar_names; + py::list ptmesh_names; + py::list ptvar_names; + py::list mat_names; + py::list matspecies_names; + py::list var_names; + py::list obj_names; + py::list dir_names; + py::list array_names; + py::list mrgtree_names; + py::list groupelmap_names; + py::list mrgvar_names; }; // }}} - // {{{ DBfile wrapper ------------------------------------------------------- + // {{{ DBfile wrapper #define PYVISFILE_DBFILE_GET_WRAPPER(LOWER_TYPE, CAMEL_TYPE) \ DB##LOWER_TYPE##Wrapper *get_##LOWER_TYPE(const char *name) \ @@ -771,12 +839,9 @@ namespace if (!obj) \ throw std::runtime_error("DBGet" #CAMEL_TYPE " failed"); \ return new DB##LOWER_TYPE##Wrapper(obj); \ - } - - - + } - class DBfileWrapper : boost::noncopyable + class DBfileWrapper: noncopyable { public: // {{{ construction and administrativa @@ -842,10 +907,7 @@ namespace )); } - - - -#if PYVISFILE_SILO_VERSION_GE(4,6,1) +#if PYVISFILE_SILO_VERSION_GE(4, 6, 1) void put_zonelist_2(const char *name, int nzones, int ndims, const std::vector &nodelist, int lo_offset, int hi_offset, const std::vector &shapetype, @@ -873,7 +935,7 @@ namespace // {{{ ucd mesh/var template void put_ucdmesh(const char *name, - object coordnames_py, numpy_vector coords, + py::sequence py_coordnames, py::array_t coords, int nzones, const char *zonel_name, const char *facel_name, DBoptlistWrapper &optlist) { @@ -882,12 +944,13 @@ namespace if (coords.ndim() != 2) throw std::invalid_argument("need 2d array"); - int ndims = coords.dims()[0]; - int nnodes = coords.dims()[1]; + int ndims = coords.shape(0); + int nnodes = coords.shape(1); + auto coords_unchecked = coords.unchecked(); std::vector coord_starts; for (int d = 0; d < ndims; d++) - coord_starts.push_back(&coords.sub(d, 0)); + coord_starts.push_back(&coords_unchecked(d, 0)); CALL_GUARDED(DBPutUcdmesh, (m_dbfile, name, ndims, /* coordnames*/ NULL, @@ -896,37 +959,31 @@ namespace get_datatype(T()), optlist.get_optlist())); } - - - template void put_ucdvar1(const char *vname, const char *mname, - const numpy_vector &v, + const py::array_t &v, /*float *mixvar, int mixlen, */int centering, DBoptlistWrapper &optlist) { ensure_db_open(); CALL_GUARDED(DBPutUcdvar1, (m_dbfile, vname, mname, - (float *) &v.sub(0), + (float *) v.data(), v.size(), /* mixvar */ NULL, /* mixlen */ 0, get_datatype(T()), centering, optlist.get_optlist())); } - - - template void put_ucdvar_backend(const char *vname, const char *mname, - object varnames_py, object vars_py, + py::sequence py_varnames, py::sequence py_vars, /*float *mixvars[], int mixlen,*/ int centering, DBoptlistWrapper &optlist) { ensure_db_open(); - if (len(varnames_py) != len(vars_py)) + if (py::len(py_varnames) != py::len(py_vars)) PYTHON_ERROR(ValueError, "varnames and vars must have the same length"); COPY_PY_LIST(std::string, varnames); @@ -936,24 +993,23 @@ namespace bool first = true; int vlength = 0; - PYTHON_FOREACH(var_py, vars_py) + for(py::object py_var: py_vars) { - numpy_vector v = extract >(var_py); + py::array_t v = py_var.cast>(); if (first) { vlength = v.size(); first = false; } else if (vlength != int(v.size())) - PYTHON_ERROR(ValueError, - boost::str(boost::format( - "field components of '%s' need to have matching lengths") - % vname).c_str()); - vars.push_back((float *) v.data().data()); + PYTHON_ERROR(ValueError, string_format( + "field components of '%s' need to have matching lengths", + vname)); + vars.push_back((float *) v.data()); } CALL_GUARDED(DBPutUcdvar, (m_dbfile, vname, mname, - len(vars_py), + py::len(py_vars), const_cast(&varnames_ptrs.front()), &vars.front(), vlength, @@ -961,26 +1017,23 @@ namespace get_datatype(T()), centering, optlist.get_optlist())); } - - - void put_ucdvar(const char *vname, const char *mname, - object varnames_py, object vars_py, + py::object py_varnames, py::object py_vars, /*float *mixvars[], int mixlen,*/ int centering, DBoptlistWrapper &optlist) { - switch (get_varlist_dtype(vars_py)) + switch (get_varlist_dtype(py_vars)) { case NPY_FLOAT: - put_ucdvar_backend(vname, mname, varnames_py, vars_py, + put_ucdvar_backend(vname, mname, py_varnames, py_vars, centering, optlist); break; case NPY_DOUBLE: - put_ucdvar_backend(vname, mname, varnames_py, vars_py, + put_ucdvar_backend(vname, mname, py_varnames, py_vars, centering, optlist); break; default: - PYUBLAS_PYERROR(TypeError, "unsupported variable type"); + PYTHON_ERROR(TypeError, "unsupported variable type"); } } @@ -988,7 +1041,7 @@ namespace // {{{ defvars - void put_defvars(std::string id, object vars_py) + void put_defvars(std::string id, py::sequence py_vars) { ensure_db_open(); @@ -999,38 +1052,39 @@ namespace std::vector vartypes; std::vector varopts; - PYTHON_FOREACH(entry, vars_py) + for(py::object py_entry: py_vars) { - varnames_container.push_back(extract(entry[0])); - vardefs_container.push_back(extract(entry[1])); - if (len(entry) == 2) + py::tuple entry = py_entry.cast(); + varnames_container.push_back(entry[0].cast()); + vardefs_container.push_back(entry[1].cast()); + if (py::len(entry) == 2) { vartypes.push_back(DB_VARTYPE_SCALAR); varopts.push_back(NULL); } else { - vartypes.push_back(extract(entry[2])); - if (len(entry) == 4) - varopts.push_back(extract(entry[3])()->get_optlist()); + vartypes.push_back(entry[2].cast()); + if (py::len(entry) == 4) + varopts.push_back(entry[3].cast()->get_optlist()); else varopts.push_back(NULL); } } - for (int i = 0; i < len(vars_py); i++) + for (size_t i = 0; i < py::len(py_vars); i++) { varnames.push_back(varnames_container[i].data()); vardefs.push_back(vardefs_container[i].data()); } -#if PYVISFILE_SILO_VERSION_GE(4,6,1) - CALL_GUARDED(DBPutDefvars, (m_dbfile, id.data(), len(vars_py), +#if PYVISFILE_SILO_VERSION_GE(4, 6, 1) + CALL_GUARDED(DBPutDefvars, (m_dbfile, id.data(), py::len(py_vars), const_cast(&varnames.front()), &vartypes.front(), const_cast(&vardefs.front()), &varopts.front())); #else - CALL_GUARDED(DBPutDefvars, (m_dbfile, id.data(), len(vars_py), + CALL_GUARDED(DBPutDefvars, (m_dbfile, id.data(), py::len(py_vars), &varnames.front(), &vartypes.front(), &vardefs.front(), &varopts.front())); #endif @@ -1041,7 +1095,7 @@ namespace // {{{ point mesh/var template - void put_pointmesh(const char *id, const numpy_vector &coords, + void put_pointmesh(const char *id, const py::array_t &coords, DBoptlistWrapper &optlist) { ensure_db_open(); @@ -1049,38 +1103,33 @@ namespace if (coords.ndim() != 2) throw std::invalid_argument("need 2d array"); - int ndims = coords.dims()[0]; - int npoints = coords.dims()[1]; + int ndims = coords.shape(0); + int npoints = coords.shape(1); + auto coords_unchecked = coords.unchecked(); std::vector coord_starts; for (int d = 0; d < ndims; d++) - coord_starts.push_back((float *) &coords.sub(d,0)); + coord_starts.push_back((float *) &coords_unchecked(d, 0)); CALL_GUARDED(DBPutPointmesh, (m_dbfile, id, ndims, &coord_starts.front(), npoints, get_datatype(T()), optlist.get_optlist())); } - - - template void put_pointvar1(const char *vname, const char *mname, - const numpy_vector &v, DBoptlistWrapper &optlist) + const py::array_t &v, DBoptlistWrapper &optlist) { ensure_db_open(); CALL_GUARDED(DBPutPointvar1, (m_dbfile, vname, mname, - (float *) v.data().data(), v.size(), + (float *) v.data(), v.size(), get_datatype(T()), optlist.get_optlist())); } - - - template void put_pointvar_backend(const char *vname, const char *mname, - object vars_py, + py::sequence py_vars, DBoptlistWrapper &optlist) { ensure_db_open(); @@ -1089,45 +1138,41 @@ namespace bool first = true; int vlength = 0; - PYTHON_FOREACH(var_py, vars_py) + for(py::object py_var: py_vars) { - numpy_vector v = extract >(var_py); + py::array_t v = py_var.cast>(); if (first) { vlength = v.size(); first = false; } else if (vlength != int(v.size())) - PYTHON_ERROR(ValueError, - boost::str(boost::format( - "field components of '%s' need to have matching lengths") - % vname).c_str()); + PYTHON_ERROR(ValueError, string_format( + "field components of '%s' need to have matching lengths", + vname)); - vars.push_back((float *) v.data().data()); + vars.push_back((float *) v.data()); } CALL_GUARDED(DBPutPointvar, (m_dbfile, vname, mname, - len(vars_py), &vars.front(), vlength, + py::len(py_vars), &vars.front(), vlength, get_datatype(T()), optlist.get_optlist())); } - - - void put_pointvar(const char *vname, const char *mname, - object vars_py, DBoptlistWrapper &optlist) + py::object py_vars, DBoptlistWrapper &optlist) { - switch (get_varlist_dtype(vars_py)) + switch (get_varlist_dtype(py_vars)) { case NPY_FLOAT: - put_pointvar_backend(vname, mname, vars_py, optlist); + put_pointvar_backend(vname, mname, py_vars, optlist); break; case NPY_DOUBLE: - put_pointvar_backend(vname, mname, vars_py, optlist); + put_pointvar_backend(vname, mname, py_vars, optlist); break; default: - PYUBLAS_PYERROR(TypeError, "unsupported variable type"); + PYTHON_ERROR(TypeError, "unsupported variable type"); } } @@ -1136,17 +1181,17 @@ namespace // {{{ quad mesh/var template - void put_quadmesh_backend(const char *name, object coords_py, + void put_quadmesh_backend(const char *name, py::sequence py_coords, int coordtype, DBoptlistWrapper &optlist) { std::vector dims; std::vector coords; - PYTHON_FOREACH(coord_dim_py, coords_py) + for(py::object py_coord_dim: py_coords) { - numpy_vector coord_dim = extract >(coord_dim_py); + py::array_t coord_dim = py_coord_dim.cast>(); dims.push_back(coord_dim.size()); - coords.push_back((float *) coord_dim.data().data()); + coords.push_back((float *) coord_dim.data()); } CALL_GUARDED(DBPutQuadmesh, (m_dbfile, name, @@ -1159,38 +1204,31 @@ namespace optlist.get_optlist())); } - - - - void put_quadmesh(const char *name, object coords_py, + void put_quadmesh(const char *name, py::object py_coords, int coordtype, DBoptlistWrapper &optlist) { - switch (get_varlist_dtype(coords_py)) + switch (get_varlist_dtype(py_coords)) { case NPY_FLOAT: - put_quadmesh_backend(name, coords_py, coordtype, optlist); + put_quadmesh_backend(name, py_coords, coordtype, optlist); break; case NPY_DOUBLE: - put_quadmesh_backend(name, coords_py, coordtype, optlist); + put_quadmesh_backend(name, py_coords, coordtype, optlist); break; default: - PYUBLAS_PYERROR(TypeError, "unsupported variable type"); + PYTHON_ERROR(TypeError, "unsupported variable type"); } } - - - - template void put_quadvar_backend(const char *vname, const char *mname, - object varnames_py, object vars_py, object dims_py, - /*float *mixvar, int mixlen, */int centering, + py::sequence py_varnames, py::sequence py_vars, py::sequence py_dims, + /* float *mixvar, int mixlen, */ int centering, DBoptlistWrapper &optlist) { COPY_PY_LIST(int, dims); - if (len(varnames_py) != len(vars_py)) + if (py::len(py_varnames) != py::len(py_vars)) PYTHON_ERROR(ValueError, "varnames and vars must have the same length"); COPY_PY_LIST(std::string, varnames); @@ -1200,20 +1238,19 @@ namespace bool first = true; int vlength = 0; - PYTHON_FOREACH(var_py, vars_py) + for(py::object py_var: py_vars) { - numpy_vector v = extract >(var_py); + py::array_t v = py_var.cast>(); if (first) { vlength = v.size(); first = false; } else if (vlength != int(v.size())) - PYTHON_ERROR(ValueError, - boost::str(boost::format( - "field components of '%s' need to have matching lengths") - % vname).c_str()); - vars.push_back((float *) v.data().data()); + PYTHON_ERROR(ValueError, string_format( + "field components of '%s' need to have matching lengths", + vname)); + vars.push_back((float *) v.data()); } CALL_GUARDED(DBPutQuadvar, (m_dbfile, vname, mname, @@ -1228,42 +1265,36 @@ namespace optlist.get_optlist())); } - - - void put_quadvar(const char *vname, const char *mname, - object varnames_py, object vars_py, object dims_py, + py::object py_varnames, py::object py_vars, py::object py_dims, /*float *mixvar, int mixlen, */int centering, DBoptlistWrapper &optlist) { - switch (get_varlist_dtype(vars_py)) + switch (get_varlist_dtype(py_vars)) { case NPY_FLOAT: - put_quadvar_backend(vname, mname, varnames_py, vars_py, - dims_py, centering, optlist); + put_quadvar_backend(vname, mname, py_varnames, py_vars, + py_dims, centering, optlist); break; case NPY_DOUBLE: - put_quadvar_backend(vname, mname, varnames_py, vars_py, - dims_py, centering, optlist); + put_quadvar_backend(vname, mname, py_varnames, py_vars, + py_dims, centering, optlist); break; default: - PYUBLAS_PYERROR(TypeError, "unsupported variable type"); + PYTHON_ERROR(TypeError, "unsupported variable type"); } } - - - template void put_quadvar1(const char *vname, const char *mname, - numpy_vector var, object dims_py, + py::array_t var, py::sequence py_dims, /*float *mixvar, int mixlen, */int centering, DBoptlistWrapper &optlist) { COPY_PY_LIST(int, dims); CALL_GUARDED(DBPutQuadvar1, (m_dbfile, vname, mname, - (float *) var.data().data(), + (float *) var.data(), &dims.front(), dims.size(), /* mix stuff */ NULL, 0, @@ -1279,7 +1310,7 @@ namespace // {{{ multi mesh/var - void put_multimesh(const char *name, object names_and_types, + void put_multimesh(const char *name, py::sequence py_names_and_types, DBoptlistWrapper &optlist) { ensure_db_open(); @@ -1287,10 +1318,11 @@ namespace std::vector meshnames; std::vector meshtypes; - PYTHON_FOREACH(name_and_type, names_and_types) + for(py::object py_name_and_type: py_names_and_types) { - meshnames.push_back(extract(name_and_type[0])); - meshtypes.push_back(extract(name_and_type[1])); + py::tuple name_and_type = py_name_and_type.cast(); + meshnames.push_back(name_and_type[0].cast()); + meshtypes.push_back(name_and_type[1].cast()); } MAKE_STRING_POINTER_VECTOR(meshnames) @@ -1301,10 +1333,7 @@ namespace optlist.get_optlist())); } - - - - void put_multivar(const char *name, object names_and_types, + void put_multivar(const char *name, py::sequence py_names_and_types, DBoptlistWrapper &optlist) { ensure_db_open(); @@ -1312,10 +1341,11 @@ namespace std::vector varnames; std::vector vartypes; - PYTHON_FOREACH(name_and_type, names_and_types) + for(py::object py_name_and_type: py_names_and_types) { - varnames.push_back(extract(name_and_type[0])); - vartypes.push_back(extract(name_and_type[1])); + py::tuple name_and_type = py_name_and_type.cast(); + varnames.push_back(name_and_type[0].cast()); + vartypes.push_back(name_and_type[1].cast()); } MAKE_STRING_POINTER_VECTOR(varnames) @@ -1333,23 +1363,21 @@ namespace template void put_curve(const char *curvename, - const numpy_vector &xvals, - const numpy_vector &yvals, + const py::array_t &xvals, + const py::array_t &yvals, DBoptlistWrapper &optlist) { if (xvals.size() != yvals.size()) PYTHON_ERROR(ValueError, "xvals and yvals must have the same length"); int npoints = xvals.size(); CALL_GUARDED(DBPutCurve, (m_dbfile, curvename, - const_cast(reinterpret_cast(xvals.data().data())), - const_cast(reinterpret_cast(yvals.data().data())), + const_cast(reinterpret_cast(xvals.data())), + const_cast(reinterpret_cast(yvals.data())), get_datatype(T()), npoints, optlist.get_optlist())); } - - PYVISFILE_DBFILE_GET_WRAPPER(curve, Curve); // }}} @@ -1359,7 +1387,7 @@ namespace DBtocCopy *get_toc() { DBtoc *toc = DBGetToc(m_dbfile); - std::auto_ptr result(new DBtocCopy()); + std::unique_ptr result(new DBtocCopy()); #define PYVISFILE_COPY_TOC_LIST(NAME, CNT) \ for (int i = 0; i < toc->CNT; ++i) \ @@ -1407,36 +1435,24 @@ namespace }; // }}} - - - - tuple get_silo_version() - { -#if PYVISFILE_SILO_VERSION_GE(4,6,1) - return make_tuple(SILO_VERS_MAJ, SILO_VERS_MIN, SILO_VERS_PAT); -#else - return make_tuple(4,5,1); -#endif - } - - - - int set_dep_warning_dummy(int) - { - return 0; - } } +// {{{ main wrapper function +static bool import_numpy_helper() +{ + import_array1(false); + return true; +} - -// {{{ main wrapper function -------------------------------------------------- - -BOOST_PYTHON_MODULE(_internal) +PYBIND11_MODULE(_internal, m) { - DEF_SIMPLE_FUNCTION(symbols); + if (!import_numpy_helper()) + throw py::error_already_set(); + + silo_expose_symbols(m); - enum_("DBdatatype") + py::enum_(m, "DBdatatype") .ENUM_VALUE(DB_INT) .ENUM_VALUE(DB_SHORT) .ENUM_VALUE(DB_LONG) @@ -1444,13 +1460,15 @@ BOOST_PYTHON_MODULE(_internal) .ENUM_VALUE(DB_DOUBLE) .ENUM_VALUE(DB_CHAR) .ENUM_VALUE(DB_NOTYPE) -#if SILO_VERSION_GE(4,7,2) +#if SILO_VERSION_GE(4, 7, 2) .ENUM_VALUE(DB_LONG_LONG) #endif ; - enum_("DBObjectType") + py::enum_(m, "DBObjectType") .ENUM_VALUE(DB_INVALID_OBJECT) + .ENUM_VALUE(DB_QUADRECT) + .ENUM_VALUE(DB_QUADCURV) .ENUM_VALUE(DB_QUADMESH) .ENUM_VALUE(DB_QUADVAR) .ENUM_VALUE(DB_UCDMESH) @@ -1478,13 +1496,17 @@ BOOST_PYTHON_MODULE(_internal) .ENUM_VALUE(DB_ARRAY) .ENUM_VALUE(DB_DIR) .ENUM_VALUE(DB_VARIABLE) + .ENUM_VALUE(DB_MRGTREE) + .ENUM_VALUE(DB_GROUPELMAP) + .ENUM_VALUE(DB_MRGVAR) .ENUM_VALUE(DB_USERDEF) ; { typedef DBfileWrapper cl; - class_("DBFile", init()) - .def(init()) + py::class_(m, "DBFile") + .def(py::init()) + .def(py::init()) .DEF_SIMPLE_METHOD(close) .DEF_SIMPLE_METHOD(put_zonelist) @@ -1517,30 +1539,31 @@ BOOST_PYTHON_MODULE(_internal) .def("put_curve", &cl::put_curve) .def("put_curve", &cl::put_curve) .def("get_curve", &cl::get_curve, - return_value_policy()) + py::return_value_policy::take_ownership) .def("get_quadmesh", &cl::get_quadmesh, - return_value_policy()) + py::return_value_policy::take_ownership) .def("get_quadvar", &cl::get_quadvar, - return_value_policy()) + py::return_value_policy::take_ownership) .def("get_toc", &cl::get_toc, - return_value_policy()) + py::return_value_policy::take_ownership) ; } { typedef DBoptlistWrapper cl; - class_("DBOptlist", init()) + py::class_(m, "DBOptlist") + .def(py::init()) .def("add_int_option", (void (cl::*)(int, int)) &cl::add_option) .def("add_option", (void (cl::*)(int, double)) &cl::add_option) .def("add_option", (void (cl::*)(int, const std::string &)) &cl::add_option) - .def("add_option", (void (cl::*)(int, tuple)) &cl::add_option) + .def("add_option", (void (cl::*)(int, py::tuple)) &cl::add_option) ; } { typedef DBcurveWrapper cl; - class_("DBCurve", no_init) + py::class_(m, "DBCurve") .DEF_SIMPLE_RO_PROPERTY(id) .DEF_SIMPLE_RO_PROPERTY(origin) .DEF_SIMPLE_RO_PROPERTY(title) @@ -1551,14 +1574,14 @@ BOOST_PYTHON_MODULE(_internal) .DEF_SIMPLE_RO_PROPERTY(xunits) .DEF_SIMPLE_RO_PROPERTY(yunits) .DEF_SIMPLE_RO_PROPERTY(reference) - .add_property("x", make_function(curve_x)) - .add_property("y", make_function(curve_y)) + .def_property_readonly("x", &curve_x) + .def_property_readonly("y", &curve_y) ; } { typedef DBquadmeshWrapper cl; - class_("DBQuadMesh", no_init) + py::class_(m, "DBQuadMesh") .DEF_SIMPLE_RO_PROPERTY(id) .DEF_SIMPLE_RO_PROPERTY(block_no) .DEF_SIMPLE_RO_PROPERTY(group_no) @@ -1587,13 +1610,13 @@ BOOST_PYTHON_MODULE(_internal) .DEF_SIMPLE_RO_PROPERTY(size_index) .DEF_SIMPLE_RO_PROPERTY(guihide) .DEF_SIMPLE_RO_PROPERTY(mrgtree_name) - .add_property("coords", make_function(quadmesh_coords)) + .def_property_readonly("coords", &quadmesh_coords) ; } { typedef DBquadvarWrapper cl; - class_("DBQuadVar", no_init) + py::class_(m, "DBQuadVar") .DEF_SIMPLE_RO_PROPERTY(id) .DEF_SIMPLE_RO_PROPERTY(name) .DEF_SIMPLE_RO_PROPERTY(units) @@ -1619,56 +1642,66 @@ BOOST_PYTHON_MODULE(_internal) .DEF_SIMPLE_RO_PROPERTY(ascii_labels) .DEF_SIMPLE_RO_PROPERTY(meshname) .DEF_SIMPLE_RO_PROPERTY(guihide) - .add_property("vals", make_function(quadvar_vals)) + .def_property_readonly("vals", &quadvar_vals) ; } { typedef DBtocCopy cl; - class_("DBToc", no_init) - .DEF_SIMPLE_RO_PROPERTY(curve_names) - .DEF_SIMPLE_RO_PROPERTY(multimesh_names) - .DEF_SIMPLE_RO_PROPERTY(multimeshadj_names) - .DEF_SIMPLE_RO_PROPERTY(multivar_names) - .DEF_SIMPLE_RO_PROPERTY(multimat_names) - .DEF_SIMPLE_RO_PROPERTY(multimatspecies_names) - .DEF_SIMPLE_RO_PROPERTY(csgmesh_names) - .DEF_SIMPLE_RO_PROPERTY(csgvar_names) - .DEF_SIMPLE_RO_PROPERTY(defvars_names) - .DEF_SIMPLE_RO_PROPERTY(qmesh_names) - .DEF_SIMPLE_RO_PROPERTY(qvar_names) - .DEF_SIMPLE_RO_PROPERTY(ucdmesh_names) - .DEF_SIMPLE_RO_PROPERTY(ucdvar_names) - .DEF_SIMPLE_RO_PROPERTY(ptmesh_names) - .DEF_SIMPLE_RO_PROPERTY(ptvar_names) - .DEF_SIMPLE_RO_PROPERTY(mat_names) - .DEF_SIMPLE_RO_PROPERTY(matspecies_names) - .DEF_SIMPLE_RO_PROPERTY(var_names) - .DEF_SIMPLE_RO_PROPERTY(obj_names) - .DEF_SIMPLE_RO_PROPERTY(dir_names) - .DEF_SIMPLE_RO_PROPERTY(array_names) - .DEF_SIMPLE_RO_PROPERTY(mrgtree_names) - .DEF_SIMPLE_RO_PROPERTY(groupelmap_names) - .DEF_SIMPLE_RO_PROPERTY(mrgvar_names) + py::class_(m, "DBToc") + .DEF_SIMPLE_RO_MEMBER(curve_names) + .DEF_SIMPLE_RO_MEMBER(multimesh_names) + .DEF_SIMPLE_RO_MEMBER(multimeshadj_names) + .DEF_SIMPLE_RO_MEMBER(multivar_names) + .DEF_SIMPLE_RO_MEMBER(multimat_names) + .DEF_SIMPLE_RO_MEMBER(multimatspecies_names) + .DEF_SIMPLE_RO_MEMBER(csgmesh_names) + .DEF_SIMPLE_RO_MEMBER(csgvar_names) + .DEF_SIMPLE_RO_MEMBER(defvars_names) + .DEF_SIMPLE_RO_MEMBER(qmesh_names) + .DEF_SIMPLE_RO_MEMBER(qvar_names) + .DEF_SIMPLE_RO_MEMBER(ucdmesh_names) + .DEF_SIMPLE_RO_MEMBER(ucdvar_names) + .DEF_SIMPLE_RO_MEMBER(ptmesh_names) + .DEF_SIMPLE_RO_MEMBER(ptvar_names) + .DEF_SIMPLE_RO_MEMBER(mat_names) + .DEF_SIMPLE_RO_MEMBER(matspecies_names) + .DEF_SIMPLE_RO_MEMBER(var_names) + .DEF_SIMPLE_RO_MEMBER(obj_names) + .DEF_SIMPLE_RO_MEMBER(dir_names) + .DEF_SIMPLE_RO_MEMBER(array_names) + .DEF_SIMPLE_RO_MEMBER(mrgtree_names) + .DEF_SIMPLE_RO_MEMBER(groupelmap_names) + .DEF_SIMPLE_RO_MEMBER(mrgvar_names) ; } + { typedef std::vector cl; - class_("IntVector") - .def("__init__", make_constructor(construct_vector)) - .def("reserve", &cl::reserve, arg("advised_size")) - .def(vector_indexing_suite ()) + py::class_(m, "IntVector") + .def(py::init<>()) + .def("reserve", &cl::reserve, + py::arg("advised_size")) + .def("__len__", &cl::size) + .def("append", (void (std::vector::*)(const int &)) &cl::push_back, + py::arg("value")) + .def("extend", [](std::vector &self, const py::iterable &py_other) + { + for(const py::handle &item: py_other) + self.push_back(item.cast()); + }, + py::arg("iterable")) ; } #if PYVISFILE_SILO_VERSION_GE(4,6,1) - def("set_deprecate_warnings", DBSetDeprecateWarnings); + m.def("set_deprecate_warnings", DBSetDeprecateWarnings); #else - def("set_deprecate_warnings", set_dep_warning_dummy); + m.def("set_deprecate_warnings", set_dep_warning_dummy); #endif DEF_SIMPLE_FUNCTION(get_silo_version); } // }}} -// vim: foldmethod=marker +// vim: ts=2:sw=2:foldmethod=marker diff --git a/test/test_silo.py b/test/test_silo.py new file mode 100644 index 0000000000000000000000000000000000000000..3fd72a1984e302dddb25c17cb20a76e5db87c370 --- /dev/null +++ b/test/test_silo.py @@ -0,0 +1,410 @@ +import numpy as np + + +# {{{ mesh object thingy + + +class Mesh: + dimensions = 2 + + def __init__(self): + self.vertex_coordinates = np.array( + [ + [1.00000000e00, 1.00000000e00], + [-1.00000000e00, 1.00000000e00], + [-1.00000000e00, -1.00000000e00], + [1.00000000e00, -1.00000000e00], + [1.00000000e00, 0.00000000e00], + [5.00000000e-01, 0.00000000e00], + [4.04508497e-01, 2.93892626e-01], + [1.54508497e-01, 4.75528258e-01], + [-1.54508497e-01, 4.75528258e-01], + [-4.04508497e-01, 2.93892626e-01], + [-5.00000000e-01, 6.12323400e-17], + [-4.04508497e-01, -2.93892626e-01], + [-1.54508497e-01, -4.75528258e-01], + [1.54508497e-01, -4.75528258e-01], + [4.04508497e-01, -2.93892626e-01], + [5.00000000e-01, -1.22464680e-16], + [-1.00000000e00, 0.00000000e00], + [0.00000000e00, -1.00000000e00], + [0.00000000e00, 1.00000000e00], + [7.50000000e-01, -6.12323400e-17], + [3.76380160e-01, -6.92475869e-01], + [2.53742158e-01, 7.19073297e-01], + [6.28756830e-01, 4.63210153e-01], + [-5.74443055e-01, -3.53084198e-01], + [-6.18581756e-01, 2.31042725e-01], + [-2.26660566e-01, -6.52489609e-01], + [-1.38777878e-16, -7.15005157e-01], + [-8.32667268e-17, -4.75528258e-01], + [1.31420055e-01, -6.30214034e-01], + [3.52012743e-01, -5.60408551e-01], + [6.68920108e-01, -6.90243593e-01], + [-7.72542486e-02, -5.95266707e-01], + [3.23649069e-02, -5.81200949e-01], + [7.72542486e-02, -5.09659838e-01], + [-7.72542486e-02, -5.10475584e-01], + [-3.86612967e-01, -6.49034477e-01], + [-5.00000000e-01, -1.00000000e00], + [-2.65876650e-01, -4.97380593e-01], + [-2.79508497e-01, -3.84710442e-01], + [5.00000000e-01, -1.00000000e00], + [2.79508497e-01, -3.84710442e-01], + [2.49036745e-01, -4.74202452e-01], + [4.17444286e-01, -4.43129989e-01], + [3.66059344e-01, -3.72404685e-01], + [1.00000000e00, -5.00000000e-01], + [-2.17008497e-01, -4.30119350e-01], + [-4.29734374e-01, -4.60045845e-01], + [-3.74119094e-01, -3.83497979e-01], + [-1.00000000e00, -5.00000000e-01], + [5.57224765e-01, -3.55834603e-01], + [7.21409218e-01, -3.41603211e-01], + [-4.52254249e-01, -1.46946313e-01], + [1.85001438e-01, -8.57502578e-01], + [6.23193603e-01, -1.62706897e-01], + [4.52254249e-01, -1.46946313e-01], + [5.12185038e-01, -2.47648931e-01], + [4.28381373e-01, -2.20419470e-01], + [5.43214916e-01, -9.52713015e-02], + [-6.92549940e-01, -1.43793192e-01], + [-5.15515268e-01, -2.48730988e-01], + [-4.28381373e-01, -2.20419470e-01], + [-5.71866870e-01, -1.04580885e-01], + [-4.76127124e-01, -7.34731565e-02], + [-6.89960366e-01, 5.35552226e-02], + [-2.77500572e-01, -8.09255088e-01], + [-7.30529084e-01, 3.04896602e-01], + [-4.52254249e-01, 1.46946313e-01], + [-5.72946346e-01, 1.04931629e-01], + [-4.76127124e-01, 7.34731565e-02], + [-4.84687225e-01, 2.38714350e-01], + [-4.19217263e-01, 5.95504869e-01], + [-6.41386449e-01, 5.21452559e-01], + [-1.00000000e00, 5.00000000e-01], + [-5.29677214e-01, 7.27277579e-01], + [-2.79508497e-01, 3.84710442e-01], + [-3.98323250e-01, 4.16812142e-01], + [-3.42008497e-01, 3.39301534e-01], + [-2.72282842e-01, 5.06197960e-01], + [-2.17008497e-01, 4.30119350e-01], + [-5.00000000e-01, 1.00000000e00], + [7.72542486e-02, 7.19631585e-01], + [2.77555756e-17, 4.75528258e-01], + [-7.72542486e-02, 5.73039943e-01], + [-7.72542486e-02, 4.75528258e-01], + [7.72542486e-02, 5.85355142e-01], + [7.72542486e-02, 4.75528258e-01], + [4.28743328e-01, 7.41939961e-01], + [-1.00000000e00, -2.50000000e-01], + [2.79508497e-01, 3.84710442e-01], + [2.50009912e-01, 5.42623972e-01], + [5.00000000e-01, 1.00000000e00], + [2.37711541e-01, 4.58614646e-01], + [3.65111148e-01, 4.81894882e-01], + [3.75966372e-01, 3.86040540e-01], + [1.00000000e00, 5.00000000e-01], + [-5.43296861e-01, -7.92213176e-01], + [-7.96662390e-01, -3.40516303e-01], + [-6.52705475e-01, -6.10334816e-01], + [8.75000000e-01, -1.82460056e-01], + [-2.09778923e-01, 6.41770688e-01], + [-1.04175415e-01, 8.20467199e-01], + [-5.56672529e-01, 3.83610683e-01], + [-8.27449562e-01, 7.55663220e-01], + [-2.50000000e-01, 1.00000000e00], + [7.50000000e-01, 0.00000000e00], + [5.04937767e-01, 5.85487598e-01], + [7.87954754e-01, 7.48243953e-01], + [-8.66944614e-01, 1.53933167e-01], + [5.52449169e-01, 3.31115121e-01], + [4.52254249e-01, 1.46946313e-01], + [4.96110705e-01, 2.42426064e-01], + [5.77759442e-01, 1.47110460e-01], + [4.76127124e-01, 7.34731565e-02], + [6.25000000e-01, 0.00000000e00], + [8.06678337e-01, 2.72341866e-01], + [7.26562966e-01, 1.46946320e-01], + [7.50000000e-01, -1.00000000e00], + [7.97833359e-01, -5.31380557e-01], + [-3.36478386e-01, 8.08917810e-01], + [-8.88250684e-01, -7.50000000e-01], + [2.50000000e-01, 1.00000000e00], + ] + ) + self.elements = np.array( + [ + [50, 44, 98], + [25, 37, 35], + [99, 8, 82], + [25, 31, 12], + [98, 19, 53], + [21, 120, 80], + [98, 53, 50], + [60, 51, 59], + [73, 71, 70], + [44, 50, 117], + [9, 75, 101], + [69, 9, 101], + [106, 90, 86], + [105, 86, 92], + [44, 117, 3], + [49, 14, 42], + [56, 14, 55], + [13, 27, 33], + [26, 52, 28], + [118, 73, 70], + [108, 93, 6], + [30, 29, 20], + [92, 93, 108], + [23, 96, 97], + [35, 97, 95], + [89, 91, 92], + [24, 67, 69], + [14, 43, 42], + [73, 79, 102], + [119, 97, 48], + [64, 17, 26], + [26, 31, 25], + [32, 26, 28], + [52, 26, 17], + [32, 34, 31], + [28, 13, 33], + [58, 16, 87], + [17, 39, 52], + [39, 20, 52], + [49, 50, 53], + [28, 52, 20], + [25, 12, 37], + [46, 35, 37], + [34, 32, 27], + [26, 32, 31], + [27, 32, 33], + [28, 33, 32], + [27, 12, 34], + [12, 31, 34], + [47, 38, 11], + [26, 25, 64], + [38, 47, 37], + [17, 64, 36], + [46, 47, 23], + [45, 38, 37], + [58, 61, 63], + [97, 35, 46], + [28, 29, 41], + [40, 41, 42], + [3, 30, 116], + [41, 13, 28], + [40, 13, 41], + [19, 98, 4], + [29, 42, 41], + [14, 40, 43], + [40, 42, 43], + [42, 29, 30], + [49, 30, 117], + [37, 12, 45], + [64, 35, 95], + [23, 47, 11], + [37, 47, 46], + [48, 97, 96], + [35, 64, 25], + [42, 30, 49], + [28, 20, 29], + [39, 30, 20], + [49, 55, 14], + [10, 61, 62], + [23, 11, 59], + [57, 54, 55], + [15, 57, 19], + [49, 53, 55], + [19, 57, 53], + [57, 55, 53], + [55, 54, 56], + [15, 54, 57], + [36, 95, 119], + [61, 59, 51], + [58, 23, 59], + [101, 24, 69], + [59, 11, 60], + [59, 61, 58], + [9, 69, 66], + [61, 51, 62], + [63, 67, 24], + [87, 96, 58], + [46, 23, 97], + [63, 10, 67], + [68, 66, 67], + [10, 63, 61], + [69, 67, 66], + [63, 24, 65], + [102, 79, 1], + [67, 10, 68], + [70, 71, 101], + [118, 70, 99], + [70, 101, 75], + [118, 79, 73], + [72, 65, 71], + [100, 82, 80], + [99, 77, 8], + [8, 77, 78], + [70, 75, 77], + [63, 107, 16], + [76, 74, 75], + [75, 74, 77], + [89, 21, 84], + [75, 9, 76], + [103, 118, 100], + [85, 7, 84], + [77, 74, 78], + [99, 70, 77], + [80, 84, 21], + [83, 81, 82], + [84, 82, 81], + [80, 18, 100], + [103, 100, 18], + [84, 7, 89], + [82, 8, 83], + [82, 84, 80], + [89, 7, 91], + [84, 81, 85], + [86, 90, 120], + [87, 48, 96], + [109, 112, 111], + [89, 86, 21], + [92, 86, 89], + [106, 105, 22], + [105, 106, 86], + [7, 88, 91], + [92, 91, 88], + [93, 92, 88], + [18, 80, 120], + [88, 6, 93], + [111, 115, 108], + [111, 108, 110], + [95, 97, 119], + [101, 71, 65], + [1, 72, 102], + [16, 58, 63], + [58, 96, 23], + [64, 95, 36], + [44, 4, 98], + [102, 71, 73], + [63, 65, 107], + [100, 118, 99], + [24, 101, 65], + [72, 71, 102], + [82, 100, 99], + [115, 111, 113], + [108, 114, 22], + [108, 105, 92], + [22, 94, 106], + [94, 0, 106], + [90, 106, 0], + [65, 72, 107], + [72, 16, 107], + [22, 105, 108], + [110, 108, 6], + [6, 109, 110], + [109, 111, 110], + [104, 115, 113], + [4, 94, 114], + [114, 115, 4], + [112, 113, 111], + [113, 112, 5], + [94, 22, 114], + [4, 115, 104], + [108, 115, 114], + [49, 117, 50], + [30, 39, 116], + [3, 117, 30], + [79, 118, 103], + [48, 2, 119], + [119, 2, 36], + [86, 120, 21], + ] + ) + + def __len__(self): + return len(self.elements) + + +# }}} + + +# {{{ add_to_silo_file + + +def add_to_silo_file( + silo, + mesh, + cell_data=[], + point_data=[], + line_integral_rules=[], + mesh_name="mesh", + real_only=False, +): + zonelist_name = mesh_name + "_zonelist" + + from pyvisfile.silo import IntVector + + nodelist = IntVector() + nodelist.extend(int(i) for i in mesh.elements.flat) + + shapetypes = IntVector() + from pyvisfile.silo import DB_ZONETYPE_TRIANGLE + + shapetypes.append(DB_ZONETYPE_TRIANGLE) + + shapesizes = IntVector() + shapesizes.append(3) + + shapecounts = IntVector() + shapecounts.append(len(mesh)) + + silo.put_zonelist_2( + zonelist_name, + len(mesh), + mesh.dimensions, + nodelist, + 0, + 0, + shapetypes, + shapesizes, + shapecounts, + ) + + silo.put_ucdmesh( + mesh_name, + [], + np.asarray(mesh.vertex_coordinates.T, order="C"), + len(mesh), + zonelist_name, + None, + ) + + from pyvisfile.silo import DB_NODECENT, DB_ZONECENT + + silo.put_ucdvar1( + "myvar", + mesh_name, + np.arange(mesh.vertex_coordinates.shape[0], dtype=np.double), + DB_NODECENT, + ) + silo.put_ucdvar1( + "myvar2", mesh_name, np.arange(len(mesh), dtype=np.double), DB_ZONECENT + ) + + +# }}} + + +def test_silo_unstructured(): + from pyvisfile.silo import SiloFile + + silo = SiloFile("out.silo") + add_to_silo_file(silo, Mesh()) + silo.close() + + +# vim: foldmethod=marker diff --git a/test/test_vtk.py b/test/test_vtk.py new file mode 100644 index 0000000000000000000000000000000000000000..f9f1120e81cee996f40160925a96bad208f99824 --- /dev/null +++ b/test/test_vtk.py @@ -0,0 +1,60 @@ +import numpy as np +from pyvisfile.vtk import ( + UnstructuredGrid, DataArray, + AppendedDataXMLGenerator, + VTK_VERTEX, VF_LIST_OF_VECTORS, VF_LIST_OF_COMPONENTS) + +from pyvisfile.vtk import write_structured_grid + + +def test_vtk_unstructured_points(): + n = 5000 + points = np.random.randn(n, 3) + + data = [ + ("p", np.random.randn(n)), + ("vel", np.random.randn(3, n)), + ] + file_name = "points.vtu" + compressor = None + + grid = UnstructuredGrid( + (n, DataArray("points", points, vector_format=VF_LIST_OF_VECTORS)), + cells=np.arange(n, dtype=np.uint32), + cell_types=np.asarray([VTK_VERTEX] * n, dtype=np.uint8)) + + for name, field in data: + grid.add_pointdata(DataArray(name, field, + vector_format=VF_LIST_OF_COMPONENTS)) + + from os.path import exists + if exists(file_name): + raise RuntimeError("output file '%s' already exists" + % file_name) + + outf = open(file_name, "w") + AppendedDataXMLGenerator(compressor)(grid).write(outf) + outf.close() + + +def test_vtk_structured_grid(): + angle_mesh = np.mgrid[1:2:10j, 0:2*np.pi:20j, 0:np.pi:30j] + + r = angle_mesh[0, np.newaxis] + phi = angle_mesh[1, np.newaxis] + theta = angle_mesh[2, np.newaxis] + mesh = np.vstack(( + r*np.sin(theta)*np.cos(phi), + r*np.sin(theta)*np.sin(phi), + r*np.cos(theta), + )) + + from pytools.obj_array import make_obj_array + vec = make_obj_array([ + np.sin(theta)*np.cos(phi), + np.sin(theta)*np.sin(phi), + np.cos(theta), + ]) + + write_structured_grid("yo.vts", mesh, + point_data=[("phi", phi), ("vec", vec)])