.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_tutorials/example_02_scalar_fields.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_tutorials_example_02_scalar_fields.py: Build and operate on a scalarField ================================== By the end of this tutorial you will: - construct a :class:`pybFoam.scalarField` from a NumPy array, - view it back as a NumPy array (zero-copy), - apply OpenFOAM elementwise operators (``sin``, ``*``, ``+``, in-place ``+=``) to it, and - plot the result with matplotlib. The point of this page is to show that ``scalarField`` is a real OpenFOAM primitive, not a NumPy wrapper. The same operators dispatch the same templated math that ``volScalarField`` uses inside a solver. Prerequisites ------------- - Finished :doc:`example_01_dictionaries`. .. GENERATED FROM PYTHON SOURCE LINES 24-30 Build a scalarField from NumPy ------------------------------ Constructing :class:`pybFoam.scalarField` from a NumPy array copies the data into OpenFOAM's memory once. From that point on, ``np.asarray(field)`` is a zero-copy view back to the same buffer — any in-place edit is visible to OpenFOAM. .. GENERATED FROM PYTHON SOURCE LINES 30-41 .. code-block:: Python import numpy as np from pybFoam import scalarField x = np.linspace(0.0, 1.0, 200) field = scalarField(x) print(f"len(field) = {len(field)}") print(f"np.asarray(field) = {np.asarray(field)[:5]} ...") .. rst-class:: sphx-glr-script-out .. code-block:: none len(field) = 200 np.asarray(field) = [0. 0.00502513 0.01005025 0.01507538 0.0201005 ] ... .. GENERATED FROM PYTHON SOURCE LINES 42-44 Confirm zero-copy: edit through the view, see the update on the field side. .. GENERATED FROM PYTHON SOURCE LINES 44-50 .. code-block:: Python field_view = np.asarray(field) field_view[0] = 99.0 print(f"field[0] after view edit = {field[0]}") field_view[0] = x[0] # restore .. rst-class:: sphx-glr-script-out .. code-block:: none field[0] after view edit = 99.0 .. GENERATED FROM PYTHON SOURCE LINES 51-56 Elementwise operators are real OpenFOAM ops ------------------------------------------- Top-level functions like :func:`pybFoam.sin` take a ``scalarField`` and return a new one. ``+``, ``-``, ``*``, ``/`` are bound directly, and there are in-place variants (``+=``, ``*=``) too. .. GENERATED FROM PYTHON SOURCE LINES 56-65 .. code-block:: Python import pybFoam y = pybFoam.sin(field * np.pi) * 2.0 + 1.0 y_np = np.asarray(y) print(f"y range : {y_np.min():.4f} … {y_np.max():.4f}") print(f"y[50] : {y_np[50]:.4f} (analytic: {2 * np.sin(np.pi * x[50]) + 1:.4f})") .. rst-class:: sphx-glr-script-out .. code-block:: none y range : 1.0000 … 2.9999 y[50] : 2.4198 (analytic: 2.4198) .. GENERATED FROM PYTHON SOURCE LINES 66-71 The min should sit close to ``-1`` (at :math:`x = 1.5/\pi`) and the max close to ``3`` (at :math:`x = 0.5`). The point-wise check at the middle of the range matches the analytic formula :math:`2\sin(\pi x) + 1` to round-off — proof the operator chain evaluated and not just round-tripped. .. GENERATED FROM PYTHON SOURCE LINES 73-77 In-place variants ----------------- Operators like ``+=`` modify the field's storage directly without allocating a new buffer. .. GENERATED FROM PYTHON SOURCE LINES 77-83 .. code-block:: Python z = scalarField(np.zeros_like(x)) z += pybFoam.cos(field * np.pi) print(f"z[0] = {np.asarray(z)[0]:.4f} (cos 0 = 1)") print(f"z[-1] = {np.asarray(z)[-1]:.4f} (cos π = -1)") .. rst-class:: sphx-glr-script-out .. code-block:: none z[0] = 1.0000 (cos 0 = 1) z[-1] = -1.0000 (cos π = -1) .. GENERATED FROM PYTHON SOURCE LINES 84-89 Plot the result --------------- A 1-D matplotlib line plot makes the shape of the operation obvious. A flat or zero curve here would mean an operator did not evaluate. .. GENERATED FROM PYTHON SOURCE LINES 89-103 .. code-block:: Python import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(6, 3)) ax.plot(x, y_np, label=r"$2\sin(\pi x) + 1$") ax.plot(x, np.asarray(z), label=r"$\cos(\pi x)$", linestyle="--") ax.axhline(0.0, color="k", lw=0.5) ax.set_xlabel("x") ax.set_ylabel("scalarField value") ax.set_title("scalarField after pybFoam operators") ax.legend() ax.grid(alpha=0.3) fig.tight_layout() plt.show() .. image-sg:: /auto_tutorials/images/sphx_glr_example_02_scalar_fields_001.png :alt: scalarField after pybFoam operators :srcset: /auto_tutorials/images/sphx_glr_example_02_scalar_fields_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.174 seconds) .. _sphx_glr_download_auto_tutorials_example_02_scalar_fields.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_02_scalar_fields.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_02_scalar_fields.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_02_scalar_fields.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_