xref: /libCEED/examples/python/tutorial-5-operator.ipynb (revision 7d38c034d40a24f4b961cafe9ae1ebfab6a4cf3f)
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