.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_how_to/example_sample_line.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_how_to_example_sample_line.py: Sample a field along a line =========================== Define a uniformly-spaced line with :class:`pybFoam.sampling.UniformSetConfig`, create the set via ``sampledSet.New``, and read scalar / vector values along it. Tutorial T4 (:doc:`/auto_tutorials/example_04_run_and_sample`) shows how to do this *inside a time loop*. This page is the static (single-shot) version — useful for inspecting an existing result. Prerequisite: a sourced OpenFOAM environment. .. GENERATED FROM PYTHON SOURCE LINES 17-19 Set up case + mesh ------------------ .. GENERATED FROM PYTHON SOURCE LINES 19-28 .. code-block:: Python from pybFoam import Time, argList, clone_example, dictionary, fvMesh from pybFoam.meshing import generate_blockmesh case = clone_example("case") time = Time(argList([str(case), "-case", str(case)])) generate_blockmesh(time, dictionary.read(str(case / "system" / "blockMeshDict"))) mesh = fvMesh(time) .. GENERATED FROM PYTHON SOURCE LINES 29-34 Seed analytic ``p_rgh`` ----------------------- The shipped IC for ``examples/case/`` is uniform zero, which would leave the sampled line flat. We seed a sinusoidal pressure profile in place so the recipe has something to plot. .. GENERATED FROM PYTHON SOURCE LINES 34-55 .. code-block:: Python import numpy as np from pybFoam import volScalarField, volVectorField, write p_rgh_seed = volScalarField.read_field(mesh, "p_rgh") U_seed = volVectorField.read_field(mesh, "U") C = np.asarray(mesh.C()["internalField"]) L = 0.584 # case extent in x and y (scale 0.146 × 4) np.asarray(p_rgh_seed["internalField"])[:] = ( 1000.0 * np.sin(np.pi * C[:, 0] / L) * np.sin(np.pi * C[:, 1] / L) ) np.asarray(U_seed["internalField"])[:] = np.column_stack( [np.sin(np.pi * C[:, 1] / L), -np.sin(np.pi * C[:, 0] / L), np.zeros_like(C[:, 0])] ) p_rgh_seed.correctBoundaryConditions() U_seed.correctBoundaryConditions() write(p_rgh_seed) write(U_seed) .. GENERATED FROM PYTHON SOURCE LINES 56-62 Define a uniform line --------------------- A ``meshSearch`` is required once per mesh and passed into every ``sampledSet.New`` call. The line endpoints below are in the scaled coordinate frame of ``examples/case/`` (the dam-break geometry) and cross the central column at mid-height in z. .. GENERATED FROM PYTHON SOURCE LINES 62-78 .. code-block:: Python from pybFoam import Word from pybFoam.sampling import UniformSetConfig, meshSearch, sampledSet search = meshSearch(mesh) cfg = UniformSetConfig( axis="distance", start=[0.1, 0.5, 0.005], end=[0.9, 0.5, 0.005], nPoints=50, ) line = sampledSet.New(Word("xLine"), mesh, search, cfg.to_foam_dict()) print(f"points : {line.nPoints()}") print(f"axis : {line.axis()}") .. rst-class:: sphx-glr-script-out .. code-block:: none points : 30 axis : distance .. GENERATED FROM PYTHON SOURCE LINES 79-81 Inspect the line geometry ------------------------- .. GENERATED FROM PYTHON SOURCE LINES 81-90 .. code-block:: Python points = np.asarray(line.points()) distance = np.asarray(line.distance()) cells = line.cells() print(f"points.shape : {points.shape}") print(f"distance[0..3] : {distance[:3]}") print(f"valid cells : {sum(1 for c in cells if c >= 0)}/{len(cells)}") .. rst-class:: sphx-glr-script-out .. code-block:: none points.shape : (30, 3) distance[0..3] : [0. 0.01632653 0.03265306] valid cells : 30/30 .. GENERATED FROM PYTHON SOURCE LINES 91-93 Interpolate a scalar field on the set ------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 93-109 .. code-block:: Python from pybFoam.sampling import OUT_OF_MESH, interpolationScalar, sampleSetScalar p_rgh = p_rgh_seed # already loaded and seeded above interp = interpolationScalar.New(Word("cellPoint"), p_rgh) sampled = sampleSetScalar(line, interp) values = np.asarray(sampled) # pybFoam.sampling.OUT_OF_MESH is the sentinel returned for sample # points that did not land in any cell. Anything well below it is a # real interpolated value. valid_mask = values < OUT_OF_MESH / 10 valid_values = values[valid_mask] print(f"p_rgh along xLine — min={valid_values.min():.3e} max={valid_values.max():.3e}") .. rst-class:: sphx-glr-script-out .. code-block:: none p_rgh along xLine — min=2.478e+01 max=4.364e+02 .. GENERATED FROM PYTHON SOURCE LINES 110-114 Reuse the same set for a vector field ------------------------------------- A ``sampledSet`` is independent of the field — build it once, then drive multiple interpolators against it. .. GENERATED FROM PYTHON SOURCE LINES 114-125 .. code-block:: Python from pybFoam.sampling import interpolationVector, sampleSetVector U = U_seed # already loaded and seeded above interp_U = interpolationVector.New(Word("cellPoint"), U) sampled_U = sampleSetVector(line, interp_U) U_values = np.asarray(sampled_U) U_mag = np.linalg.norm(U_values, axis=1) print(f"U along xLine shape: {U_values.shape}") .. rst-class:: sphx-glr-script-out .. code-block:: none U along xLine shape: (30, 3) .. GENERATED FROM PYTHON SOURCE LINES 126-131 Plot the sampled line --------------------- Two y-axes: ``p_rgh`` on the left (matches the field magnitude), ``|U|`` on the right (so we can see both on the same x-axis even when the units differ). Off-mesh sentinel values are masked out. .. GENERATED FROM PYTHON SOURCE LINES 131-153 .. code-block:: Python import matplotlib.pyplot as plt p_plot = np.where(valid_mask, values, np.nan) u_plot = np.where(valid_mask, U_mag, np.nan) fig, ax_p = plt.subplots(figsize=(7, 3.2)) (line_p,) = ax_p.plot(distance, p_plot, color="steelblue", label=r"$p_{rgh}$") ax_p.set_xlabel("distance along xLine [m]") ax_p.set_ylabel(r"$p_{rgh}$ [Pa]", color="steelblue") ax_p.tick_params(axis="y", labelcolor="steelblue") ax_u = ax_p.twinx() (line_u,) = ax_u.plot(distance, u_plot, color="crimson", label=r"$|U|$", linestyle="--") ax_u.set_ylabel(r"$|U|$ [m/s]", color="crimson") ax_u.tick_params(axis="y", labelcolor="crimson") ax_p.set_title("p_rgh and |U| sampled along xLine") fig.legend(handles=[line_p, line_u], loc="upper right", bbox_to_anchor=(0.9, 0.9)) fig.tight_layout() plt.show() .. image-sg:: /auto_how_to/images/sphx_glr_example_sample_line_001.png :alt: p_rgh and |U| sampled along xLine :srcset: /auto_how_to/images/sphx_glr_example_sample_line_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 154-161 See also -------- - :doc:`/auto_tutorials/example_04_run_and_sample` — same sampling pattern inside an icoFoam time loop. - :doc:`example_sample_plane` — sample on a 2-D plane instead of a line. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.204 seconds) .. _sphx_glr_download_auto_how_to_example_sample_line.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_sample_line.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_sample_line.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_sample_line.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_