xref: /libCEED/examples/python/tutorial-4-qfunction.ipynb (revision f5066b3615781dbcd74af2f846f96d7648d0187d)
1{
2 "cells": [
3  {
4   "cell_type": "markdown",
5   "metadata": {},
6   "source": [
7    "# libCEED for Python examples\n",
8    "\n",
9    "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",
10    "\n",
11    "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.readthedocs.io/)."
12   ]
13  },
14  {
15   "cell_type": "markdown",
16   "metadata": {},
17   "source": [
18    "## Setting up libCEED for Python\n",
19    "\n",
20    "Install libCEED for Python by running"
21   ]
22  },
23  {
24   "cell_type": "code",
25   "execution_count": null,
26   "metadata": {},
27   "outputs": [],
28   "source": [
29    "! python -m pip install libceed"
30   ]
31  },
32  {
33   "cell_type": "markdown",
34   "metadata": {},
35   "source": [
36    "## CeedQFunction\n",
37    "\n",
38    "Here we show some basic examples to illustrate the `libceed.QFunction` class. In libCEED, QFunctions represent the spatial terms of the point-wise functions describing the physics at the quadrature points (see [the API documentation](https://libceed.readthedocs.io/en/latest/libCEEDapi.html#api-description)). As shown in the following sketch, QFunctions (such as the one depicted, which defines the Laplacian) are point-wise functions defined at quadrature points. Hence, QFunctions are independent from element shape, resolution and order.\n",
39    "\n",
40    "![alt text][QFunctionSchematic]\n",
41    "\n",
42    "[QFunctionSchematic]: ./img/QFunctionSketch.svg \"Schematic of point-wise QFunctions, defined at quadrature points, belonging to elements that can have different shape, resolution and order.\""
43   ]
44  },
45  {
46   "cell_type": "markdown",
47   "metadata": {},
48   "source": [
49    "* In the following example, we create and view two QFunctions (for the setup and apply, respectively, of the mass operator in 1D) from the gallery of available built-in QFunctions in libCEED"
50   ]
51  },
52  {
53   "cell_type": "code",
54   "execution_count": null,
55   "metadata": {},
56   "outputs": [],
57   "source": [
58    "import libceed\n",
59    "import numpy as np\n",
60    "\n",
61    "ceed = libceed.Ceed()\n",
62    "\n",
63    "qf_setup = ceed.QFunctionByName(\"Mass1DBuild\")\n",
64    "qf_mass = ceed.QFunctionByName(\"MassApply\")\n",
65    "\n",
66    "print(qf_setup)\n",
67    "print(qf_mass)"
68   ]
69  },
70  {
71   "cell_type": "markdown",
72   "metadata": {},
73   "source": [
74    "* In the following example, we create and evaluate a built-in identity QFunction."
75   ]
76  },
77  {
78   "cell_type": "code",
79   "execution_count": null,
80   "metadata": {},
81   "outputs": [],
82   "source": [
83    "qf = ceed.IdentityQFunction(1, libceed.EVAL_INTERP, libceed.EVAL_INTERP)\n",
84    "\n",
85    "q = 8\n",
86    "\n",
87    "u_array = np.zeros(q, dtype=\"float64\")\n",
88    "for i in range(q):\n",
89    "  u_array[i] = i*i\n",
90    "\n",
91    "u = ceed.Vector(q)\n",
92    "u.set_array(u_array, cmode=libceed.USE_POINTER)\n",
93    "v = ceed.Vector(q)\n",
94    "v.set_value(0)\n",
95    "\n",
96    "inputs = [ u ]\n",
97    "outputs = [ v ]\n",
98    "qf.apply(q, inputs, outputs)\n",
99    "\n",
100    "print('v =', v)"
101   ]
102  },
103  {
104   "cell_type": "markdown",
105   "metadata": {},
106   "source": [
107    "* In the following example, we create and evaluate a QFunction (for the mass operator in 1D) from the gallery of available built-in QFunctions in libCEED."
108   ]
109  },
110  {
111   "cell_type": "code",
112   "execution_count": null,
113   "metadata": {},
114   "outputs": [],
115   "source": [
116    "qf_setup = ceed.QFunctionByName(\"Mass1DBuild\")\n",
117    "qf_mass = ceed.QFunctionByName(\"MassApply\")\n",
118    "\n",
119    "q = 8\n",
120    "\n",
121    "j_array = np.zeros(q, dtype=\"float64\")\n",
122    "w_array = np.zeros(q, dtype=\"float64\")\n",
123    "u_array = np.zeros(q, dtype=\"float64\")\n",
124    "v_true  = np.zeros(q, dtype=\"float64\")\n",
125    "for i in range(q):\n",
126    "  x = 2.*i/(q-1) - 1\n",
127    "  j_array[i] = 1\n",
128    "  w_array[i] = 1 - x*x\n",
129    "  u_array[i] = 2 + 3*x + 5*x*x\n",
130    "  v_true[i]  = w_array[i] * u_array[i]\n",
131    "\n",
132    "j = ceed.Vector(q)\n",
133    "j.set_array(j_array, cmode=libceed.USE_POINTER)\n",
134    "w = ceed.Vector(q)\n",
135    "w.set_array(w_array, cmode=libceed.USE_POINTER)\n",
136    "u = ceed.Vector(q)\n",
137    "u.set_array(u_array, cmode=libceed.USE_POINTER)\n",
138    "v = ceed.Vector(q)\n",
139    "v.set_value(0)\n",
140    "qdata = ceed.Vector(q)\n",
141    "qdata.set_value(0)\n",
142    "\n",
143    "inputs = [ j, w ]\n",
144    "outputs = [ qdata ]\n",
145    "qf_setup.apply(q, inputs, outputs)\n",
146    "\n",
147    "inputs = [ w, u ]\n",
148    "outputs = [ v ]\n",
149    "qf_mass.apply(q, inputs, outputs)\n",
150    "\n",
151    "print('v =', v)"
152   ]
153  },
154  {
155   "cell_type": "markdown",
156   "metadata": {},
157   "source": [
158    "* In the following example, we create and evaluate a built-in identity QFunction 3 fields per quadrature point."
159   ]
160  },
161  {
162   "cell_type": "code",
163   "execution_count": null,
164   "metadata": {},
165   "outputs": [],
166   "source": [
167    "fields = 3\n",
168    "\n",
169    "qf = ceed.IdentityQFunction(fields, libceed.EVAL_INTERP, libceed.EVAL_INTERP)\n",
170    "\n",
171    "q = 8\n",
172    "\n",
173    "u_array = np.zeros(q*fields, dtype=\"float64\")\n",
174    "for i in range(q*fields):\n",
175    "  u_array[i] = i*i\n",
176    "\n",
177    "u = ceed.Vector(q*fields)\n",
178    "u.set_array(u_array, cmode=libceed.USE_POINTER)\n",
179    "v = ceed.Vector(q*fields)\n",
180    "v.set_value(0)\n",
181    "\n",
182    "inputs = [ u ]\n",
183    "outputs = [ v ]\n",
184    "qf.apply(q, inputs, outputs)\n",
185    "\n",
186    "print('v =', v)"
187   ]
188  }
189 ],
190 "metadata": {
191  "kernelspec": {
192   "display_name": "Python 3",
193   "language": "python",
194   "name": "python3"
195  },
196  "language_info": {
197   "codemirror_mode": {
198    "name": "ipython",
199    "version": 3
200   },
201   "file_extension": ".py",
202   "mimetype": "text/x-python",
203   "name": "python",
204   "nbconvert_exporter": "python",
205   "pygments_lexer": "ipython3",
206   "version": "3.8.5"
207  }
208 },
209 "nbformat": 4,
210 "nbformat_minor": 4
211}
212