1edab6123Sjeremylt{ 2edab6123Sjeremylt "cells": [ 3edab6123Sjeremylt { 4edab6123Sjeremylt "cell_type": "markdown", 5edab6123Sjeremylt "metadata": {}, 6edab6123Sjeremylt "source": [ 7edab6123Sjeremylt "# libCEED for Python examples\n", 8edab6123Sjeremylt "\n", 9edab6123Sjeremylt "This is a tutorial to illustrate the main feautures of the Python interface for [libCEED](https://github.com/CEED/libCEED/), the low-level API library for efficient high-order discretization methods developed by the co-design [Center for Efficient Exascale Discretizations](https://ceed.exascaleproject.org/) (CEED) of the [Exascale Computing Project](https://www.exascaleproject.org/) (ECP).\n", 10edab6123Sjeremylt "\n", 1113964f07SJed Brown "While libCEED's focus is on high-order finite/spectral element method implementations, the approach is mostly algebraic and thus applicable to other discretizations in factored form, as explained in the [user manual](https://libceed.org/)." 12edab6123Sjeremylt ] 13edab6123Sjeremylt }, 14edab6123Sjeremylt { 15edab6123Sjeremylt "cell_type": "markdown", 16edab6123Sjeremylt "metadata": {}, 17edab6123Sjeremylt "source": [ 18edab6123Sjeremylt "## Setting up libCEED for Python\n", 19edab6123Sjeremylt "\n", 20edab6123Sjeremylt "Install libCEED for Python by running" 21edab6123Sjeremylt ] 22edab6123Sjeremylt }, 23edab6123Sjeremylt { 24edab6123Sjeremylt "cell_type": "code", 25edab6123Sjeremylt "execution_count": null, 26edab6123Sjeremylt "metadata": {}, 27edab6123Sjeremylt "outputs": [], 28edab6123Sjeremylt "source": [ 29edab6123Sjeremylt "! python -m pip install libceed" 30edab6123Sjeremylt ] 31edab6123Sjeremylt }, 32edab6123Sjeremylt { 33edab6123Sjeremylt "cell_type": "markdown", 34edab6123Sjeremylt "metadata": {}, 35edab6123Sjeremylt "source": [ 36edab6123Sjeremylt "## CeedOperator\n", 37edab6123Sjeremylt "\n", 3813964f07SJed Brown "Here we show some basic examples to illustrate the `libceed.Operator` class. In libCEED, a `libceed.Operator` defines the finite/spectral element operator associated to a `libceed.QFunction` (see [the API documentation](https://libceed.org/en/latest/libCEEDapi.html#finite-element-operator-decomposition))." 39edab6123Sjeremylt ] 40edab6123Sjeremylt }, 41edab6123Sjeremylt { 42edab6123Sjeremylt "cell_type": "markdown", 43edab6123Sjeremylt "metadata": {}, 44edab6123Sjeremylt "source": [ 45edab6123Sjeremylt "* In the following example, we create and apply a CeedOperator for the mass matrix in 1D. By applying this operator to a vector of 1's, we compute the length of this 1D domain, similar to Ex1-Volume in the [tutorial-6-shell tutorial](./tutorial-6-shell.ipynb)" 46edab6123Sjeremylt ] 47edab6123Sjeremylt }, 48edab6123Sjeremylt { 49edab6123Sjeremylt "cell_type": "code", 50edab6123Sjeremylt "execution_count": null, 51edab6123Sjeremylt "metadata": {}, 52edab6123Sjeremylt "outputs": [], 53edab6123Sjeremylt "source": [ 54edab6123Sjeremylt "import libceed\n", 55edab6123Sjeremylt "import numpy as np\n", 56edab6123Sjeremylt "\n", 57edab6123Sjeremylt "ceed = libceed.Ceed()\n", 58edab6123Sjeremylt "\n", 59*235e4399SJeremy L Thompson "num_elem = 15\n", 60edab6123Sjeremylt "p = 5\n", 61edab6123Sjeremylt "q = 8\n", 62*235e4399SJeremy L Thompson "num_x = num_elem + 1\n", 63*235e4399SJeremy L Thompson "num_u = num_elem*(p-1) + 1\n", 64edab6123Sjeremylt "\n", 65edab6123Sjeremylt "# Vectors\n", 66*235e4399SJeremy L Thompson "x = ceed.Vector(num_x)\n", 67*235e4399SJeremy L Thompson "x_array = np.zeros(num_x)\n", 68*235e4399SJeremy L Thompson "for i in range(num_x):\n", 69*235e4399SJeremy L Thompson " x_array[i] = i / (num_x - 1.0)\n", 70edab6123Sjeremylt "x.set_array(x_array, cmode=libceed.USE_POINTER)\n", 71edab6123Sjeremylt "\n", 72*235e4399SJeremy L Thompson "q_data = ceed.Vector(num_elem*q)\n", 73*235e4399SJeremy L Thompson "u = ceed.Vector(num_u)\n", 74*235e4399SJeremy L Thompson "v = ceed.Vector(num_u)\n", 75edab6123Sjeremylt "\n", 76edab6123Sjeremylt "# Restrictions\n", 77*235e4399SJeremy L Thompson "indices_x = np.zeros(num_x*2, dtype=\"int32\")\n", 78*235e4399SJeremy L Thompson "for i in range(num_x):\n", 79*235e4399SJeremy L Thompson " indices_x[2*i+0] = i\n", 80*235e4399SJeremy L Thompson " indices_x[2*i+1] = i+1\n", 81*235e4399SJeremy L Thompson "restriction_x = ceed.ElemRestriction(num_elem, 2, 1, 1, num_x, indices_x, cmode=libceed.USE_POINTER)\n", 82edab6123Sjeremylt "\n", 83*235e4399SJeremy L Thompson "indices_u = np.zeros(num_elem*p, dtype=\"int32\")\n", 84*235e4399SJeremy L Thompson "for i in range(num_elem):\n", 85edab6123Sjeremylt " for j in range(p):\n", 86*235e4399SJeremy L Thompson " indices_u[p*i+j] = i*(p-1) + j\n", 87*235e4399SJeremy L Thompson "restriction_u = ceed.ElemRestriction(num_elem, p, 1, 1, num_u, indices_u, cmode=libceed.USE_POINTER)\n", 88edab6123Sjeremylt "strides = np.array([1, q, q], dtype=\"int32\")\n", 89*235e4399SJeremy L Thompson "restriction_q_data = ceed.StridedElemRestriction(num_elem, q, 1, q*num_elem, strides)\n", 90edab6123Sjeremylt "\n", 91edab6123Sjeremylt "# Bases\n", 92*235e4399SJeremy L Thompson "basis_x = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS)\n", 93*235e4399SJeremy L Thompson "basis_u = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS)\n", 94edab6123Sjeremylt "\n", 95edab6123Sjeremylt "# QFunctions\n", 96edab6123Sjeremylt "qf_setup = ceed.QFunctionByName(\"Mass1DBuild\")\n", 97edab6123Sjeremylt "qf_mass = ceed.QFunctionByName(\"MassApply\")\n", 98edab6123Sjeremylt "\n", 99edab6123Sjeremylt "# Setup operator\n", 100edab6123Sjeremylt "op_setup = ceed.Operator(qf_setup)\n", 101*235e4399SJeremy L Thompson "op_setup.set_field(\"dx\", restriction_x, basis_x, libceed.VECTOR_ACTIVE)\n", 102*235e4399SJeremy L Thompson "op_setup.set_field(\"weights\", libceed.ELEMRESTRICTION_NONE, basis_x,\n", 103edab6123Sjeremylt " libceed.VECTOR_NONE)\n", 104*235e4399SJeremy L Thompson "op_setup.set_field(\"qdata\", restriction_q_data, libceed.BASIS_NONE,\n", 105edab6123Sjeremylt " libceed.VECTOR_ACTIVE)\n", 10628d09c20SJeremy L Thompson "op_setup.check()\n", 107edab6123Sjeremylt "print('Setup operator: ', op_setup)\n", 108edab6123Sjeremylt "\n", 109edab6123Sjeremylt "# Mass operator\n", 110edab6123Sjeremylt "op_mass = ceed.Operator(qf_mass)\n", 111*235e4399SJeremy L Thompson "op_mass.set_field(\"u\", restriction_u, basis_u, libceed.VECTOR_ACTIVE)\n", 112*235e4399SJeremy L Thompson "op_mass.set_field(\"qdata\", restriction_q_data, libceed.BASIS_NONE, q_data)\n", 113*235e4399SJeremy L Thompson "op_mass.set_field(\"v\", restriction_u, basis_u, libceed.VECTOR_ACTIVE)\n", 11428d09c20SJeremy L Thompson "op_mass.check()\n", 115edab6123Sjeremylt "print('Mass operator: ', op_mass)\n", 116edab6123Sjeremylt "\n", 117edab6123Sjeremylt "# Setup\n", 118*235e4399SJeremy L Thompson "op_setup.apply(x, q_data)\n", 119edab6123Sjeremylt "\n", 120edab6123Sjeremylt "# Apply mass matrix\n", 121edab6123Sjeremylt "u.set_value(1)\n", 122edab6123Sjeremylt "op_mass.apply(u, v)\n", 123edab6123Sjeremylt "\n", 124edab6123Sjeremylt "# Check\n", 125edab6123Sjeremylt "with v.array_read() as v_array:\n", 126edab6123Sjeremylt " print('The length of the domain is l = %4.2f'%np.sum(v_array))" 127edab6123Sjeremylt ] 1282fc995f6SJeremy L Thompson }, 1292fc995f6SJeremy L Thompson { 1302fc995f6SJeremy L Thompson "cell_type": "markdown", 1312fc995f6SJeremy L Thompson "metadata": {}, 1322fc995f6SJeremy L Thompson "source": [ 1332fc995f6SJeremy L Thompson "* In the next example, we create and apply a CeedOperator for the Poisson operator in 1D. By applying this operator to a vector with a linear function, we compute the 'surface area' of this 1D domain, similar to Ex2-Surface in the [tutorial-6-shell tutorial](./tutorial-6-shell.ipynb)" 1342fc995f6SJeremy L Thompson ] 1352fc995f6SJeremy L Thompson }, 1362fc995f6SJeremy L Thompson { 1372fc995f6SJeremy L Thompson "cell_type": "code", 1382fc995f6SJeremy L Thompson "execution_count": null, 1392fc995f6SJeremy L Thompson "metadata": {}, 1402fc995f6SJeremy L Thompson "outputs": [], 1412fc995f6SJeremy L Thompson "source": [ 1422fc995f6SJeremy L Thompson "import libceed\n", 1432fc995f6SJeremy L Thompson "import numpy as np\n", 1442fc995f6SJeremy L Thompson "\n", 1452fc995f6SJeremy L Thompson "ceed = libceed.Ceed()\n", 1462fc995f6SJeremy L Thompson "\n", 147*235e4399SJeremy L Thompson "num_elem = 15\n", 1482fc995f6SJeremy L Thompson "p = 5\n", 1492fc995f6SJeremy L Thompson "q = 8\n", 150*235e4399SJeremy L Thompson "num_x = num_elem + 1\n", 151*235e4399SJeremy L Thompson "num_u = num_elem*(p-1) + 1\n", 1522fc995f6SJeremy L Thompson "\n", 1532fc995f6SJeremy L Thompson "# Vectors\n", 154*235e4399SJeremy L Thompson "x = ceed.Vector(num_x)\n", 155*235e4399SJeremy L Thompson "x_array = np.zeros(num_x)\n", 156*235e4399SJeremy L Thompson "for i in range(num_x):\n", 157*235e4399SJeremy L Thompson " x_array[i] = i / (num_x - 1.0)\n", 1582fc995f6SJeremy L Thompson "x.set_array(x_array, cmode=libceed.USE_POINTER)\n", 1592fc995f6SJeremy L Thompson "\n", 160*235e4399SJeremy L Thompson "q_data = ceed.Vector(num_elem*q)\n", 161*235e4399SJeremy L Thompson "u = ceed.Vector(num_u)\n", 162*235e4399SJeremy L Thompson "v = ceed.Vector(num_u)\n", 1632fc995f6SJeremy L Thompson "\n", 1642fc995f6SJeremy L Thompson "# Restrictions\n", 165*235e4399SJeremy L Thompson "indices_x = np.zeros(num_x*2, dtype=\"int32\")\n", 166*235e4399SJeremy L Thompson "for i in range(num_x):\n", 167*235e4399SJeremy L Thompson " indices_x[2*i+0] = i\n", 168*235e4399SJeremy L Thompson " indices_x[2*i+1] = i+1\n", 169*235e4399SJeremy L Thompson "restriction_x = ceed.ElemRestriction(num_elem, 2, 1, 1, num_x, indices_x, cmode=libceed.USE_POINTER)\n", 1702fc995f6SJeremy L Thompson "\n", 171*235e4399SJeremy L Thompson "indices_u = np.zeros(num_elem*p, dtype=\"int32\")\n", 172*235e4399SJeremy L Thompson "for i in range(num_elem):\n", 1732fc995f6SJeremy L Thompson " for j in range(p):\n", 174*235e4399SJeremy L Thompson " indices_u[p*i+j] = i*(p-1) + j\n", 175*235e4399SJeremy L Thompson "restriction_u = ceed.ElemRestriction(num_elem, p, 1, 1, num_u, indices_u, cmode=libceed.USE_POINTER)\n", 1762fc995f6SJeremy L Thompson "strides = np.array([1, q, q], dtype=\"int32\")\n", 177*235e4399SJeremy L Thompson "restriction_q_data = ceed.StridedElemRestriction(num_elem, q, 1, q*num_elem, strides)\n", 1782fc995f6SJeremy L Thompson "\n", 1792fc995f6SJeremy L Thompson "# Bases\n", 180*235e4399SJeremy L Thompson "basis_x = ceed.BasisTensorH1Lagrange(1, 1, 2, q, libceed.GAUSS)\n", 181*235e4399SJeremy L Thompson "basis_u = ceed.BasisTensorH1Lagrange(1, 1, p, q, libceed.GAUSS)\n", 1822fc995f6SJeremy L Thompson "\n", 1832fc995f6SJeremy L Thompson "# QFunctions\n", 1842fc995f6SJeremy L Thompson "qf_setup = ceed.QFunctionByName(\"Poisson1DBuild\")\n", 1852fc995f6SJeremy L Thompson "qf_mass = ceed.QFunctionByName(\"Poisson1DApply\")\n", 1862fc995f6SJeremy L Thompson "\n", 1872fc995f6SJeremy L Thompson "# Setup operator\n", 1882fc995f6SJeremy L Thompson "op_setup = ceed.Operator(qf_setup)\n", 189*235e4399SJeremy L Thompson "op_setup.set_field(\"dx\", restriction_x, basis_x, libceed.VECTOR_ACTIVE)\n", 190*235e4399SJeremy L Thompson "op_setup.set_field(\"weights\", libceed.ELEMRESTRICTION_NONE, basis_x,\n", 1912fc995f6SJeremy L Thompson " libceed.VECTOR_NONE)\n", 192*235e4399SJeremy L Thompson "op_setup.set_field(\"qdata\", restriction_q_data, libceed.BASIS_NONE,\n", 1932fc995f6SJeremy L Thompson " libceed.VECTOR_ACTIVE)\n", 1942fc995f6SJeremy L Thompson "op_setup.check()\n", 1952fc995f6SJeremy L Thompson "print('Setup operator: ', op_setup)\n", 1962fc995f6SJeremy L Thompson "\n", 1972fc995f6SJeremy L Thompson "# Poisson operator\n", 1982fc995f6SJeremy L Thompson "op_poisson = ceed.Operator(qf_mass)\n", 199*235e4399SJeremy L Thompson "op_poisson.set_field(\"du\", restriction_u, basis_u, libceed.VECTOR_ACTIVE)\n", 200*235e4399SJeremy L Thompson "op_poisson.set_field(\"qdata\", restriction_q_data, libceed.BASIS_NONE, q_data)\n", 201*235e4399SJeremy L Thompson "op_poisson.set_field(\"dv\", restriction_u, basis_u, libceed.VECTOR_ACTIVE)\n", 2022fc995f6SJeremy L Thompson "op_poisson.check()\n", 2032fc995f6SJeremy L Thompson "print('Poisson operator: ', op_poisson)\n", 2042fc995f6SJeremy L Thompson "\n", 2052fc995f6SJeremy L Thompson "# Setup\n", 206*235e4399SJeremy L Thompson "op_setup.apply(x, q_data)\n", 2072fc995f6SJeremy L Thompson "\n", 2082fc995f6SJeremy L Thompson "# Apply Poisson operator\n", 2092fc995f6SJeremy L Thompson "with u.array_write() as u_array:\n", 2102fc995f6SJeremy L Thompson " [points, _] = ceed.lobatto_quadrature(p)\n", 211*235e4399SJeremy L Thompson " for elem in range(num_elem):\n", 2122fc995f6SJeremy L Thompson " for point in range(p):\n", 213*235e4399SJeremy L Thompson " u_array[elem * (p - 1) + point] = (1.0 + 2.0 * elem + points[point])/(2.0 * num_elem)\n", 2142fc995f6SJeremy L Thompson "op_poisson.apply(u, v)\n", 2152fc995f6SJeremy L Thompson "\n", 2162fc995f6SJeremy L Thompson "# Check\n", 2172fc995f6SJeremy L Thompson "with v.array_read() as v_array:\n", 2182fc995f6SJeremy L Thompson " print('The surface area of the domain is dl = %4.2f'%np.sum(abs(v_array)))" 2192fc995f6SJeremy L Thompson ] 220edab6123Sjeremylt } 221edab6123Sjeremylt ], 222edab6123Sjeremylt "metadata": { 223edab6123Sjeremylt "kernelspec": { 2242fc995f6SJeremy L Thompson "display_name": "Python 3 (ipykernel)", 225edab6123Sjeremylt "language": "python", 226edab6123Sjeremylt "name": "python3" 227edab6123Sjeremylt }, 228edab6123Sjeremylt "language_info": { 229edab6123Sjeremylt "codemirror_mode": { 230edab6123Sjeremylt "name": "ipython", 231edab6123Sjeremylt "version": 3 232edab6123Sjeremylt }, 233edab6123Sjeremylt "file_extension": ".py", 234edab6123Sjeremylt "mimetype": "text/x-python", 235edab6123Sjeremylt "name": "python", 236edab6123Sjeremylt "nbconvert_exporter": "python", 237edab6123Sjeremylt "pygments_lexer": "ipython3", 2382fc995f6SJeremy L Thompson "version": "3.13.2" 239edab6123Sjeremylt } 240edab6123Sjeremylt }, 241edab6123Sjeremylt "nbformat": 4, 242edab6123Sjeremylt "nbformat_minor": 4 243edab6123Sjeremylt} 244