diff --git a/comparing_elements.ipynb b/comparing_elements.ipynb
index 2ffea19..a15dda5 100644
--- a/comparing_elements.ipynb
+++ b/comparing_elements.ipynb
@@ -1,1283 +1,1283 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "51e6f0eb",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "# The Stokes equations"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "12afe587-a28c-.x.petsc_vecc0..x.petsc_vec_vecc_vec8a4be7",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "Authors: J.S. Dokken, M.W. Scroggs, S. Roggendorf"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "120e279b",
- "metadata": {
- "tags": []
- },
- "source": [
- "\\begin{align*}\n",
- "-\\Delta \\mathbf{u} + \\nabla p &= \\mathbf{f} &&\\text{in } \\Omega,\\\\\n",
- "\\nabla \\cdot \\mathbf{u} &= 0 &&\\text{in } \\Omega,\\\\\n",
- "\\mathbf{u} &= \\mathbf{0}&&\\text{on } \\partial\\Omega.\n",
- "\\end{align*}"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6ad7e66d-a6e9-4670-bb9c-a3d2fddff7cf",
- "metadata": {
- "slideshow": {
- "slide_type": "fragment"
- },
- "tags": []
- },
- "source": [
- "In this tutorial you will learn how to:\n",
- "\n",
- "- Create manufactured solutions with UFL\n",
- "- Use block-preconditioners"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "1d0f852b-1099-4f9d-b60a-045a17cbb1c2",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "## Imports"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "026d6390",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "We start by importing most of the modules we will use in this tutorial."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "eb7ac5d2",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "from mpi4py import MPI\n",
- "from petsc4py import PETSc\n",
- "\n",
- "import matplotlib.pylab as plt\n",
- "import numpy as np\n",
- "\n",
- "import basix.ufl\n",
- "import dolfinx.fem.petsc\n",
- "from dolfinx import fem, mesh"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "56b7f168",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "However, we pay special attention to `UFL`, the unified form language package, which is used to represent variational forms.\n",
- "As we will dependend on many functions from this package, we import the components that we will use in this code explicitly"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "f735fd97-942e-42d9-8886-372210271d3d",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "from ufl import (\n",
- " SpatialCoordinate,\n",
- " TestFunction,\n",
- " TrialFunction,\n",
- " as_vector,\n",
- " cos,\n",
- " div,\n",
- " dx,\n",
- " grad,\n",
- " inner,\n",
- " pi,\n",
- " sin,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "62b9c8f6-8d86-4757-bb82-d1086adbf5fc",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "## Defining a manufactured solution"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "340615e7-94c3-4779-bba5-04d99d9ba826",
- "metadata": {
- "slideshow": {
- "slide_type": "notes"
- },
- "tags": []
- },
- "source": [
- "We will use a known analytical solution to the Stokes equations in this tutorial. We define the exact velocity and pressure as the following:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "db2a77d6-95c7-49d3-b39c-3750b6a7f8e4",
- "metadata": {},
- "outputs": [],
- "source": [
- "def u_ex(x):\n",
- " sinx = sin(pi * x[0])\n",
- " siny = sin(pi * x[1])\n",
- " cosx = cos(pi * x[0])\n",
- " cosy = cos(pi * x[1])\n",
- " c_factor = 2 * pi * sinx * siny\n",
- " return c_factor * as_vector((cosy * sinx, -cosx * siny))\n",
- "\n",
- "\n",
- "def p_ex(x):\n",
- " return sin(2 * pi * x[0]) * sin(2 * pi * x[1])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c4e4f304-5fca-4860-a40f-ae292242dc7c",
- "metadata": {
- "slideshow": {
- "slide_type": "notes"
- },
- "tags": []
- },
- "source": [
- "Here, the input to each function is the coordinates (x,y) of the problem. These will be defined by using `x = ufl.SpatialCoordinate(domain)`.\n",
- "\n",
- "We use the strong formulation of the PDE to compute the source function $\\mathbf{f}$ using UFL operators"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "b53ef52c-7761-48d5-8964-c26b4279b9f7",
- "metadata": {
- "slideshow": {
- "slide_type": "fragment"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def source(x):\n",
- " u, p = u_ex(x), p_ex(x)\n",
- " return -div(grad(u)) + grad(p)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "9e101f42-0048-408d-a460-f3321797d432",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "## Defining the variational form"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "84d10fa8-adbb-4f2d-90b2-ed1122b98d6a",
- "metadata": {
- "slideshow": {
- "slide_type": "notes"
- },
- "tags": []
- },
- "source": [
- "We will solve the PDE by creating a set of variational forms, one for each component of the problem. This leads to a blocked discrete system:"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "51df1510-3a4e-4241-9240-7f1710a51597",
- "metadata": {},
- "source": [
- "$$\\begin{align}\n",
- "A w &= b,\\\\\n",
- "\\begin{pmatrix}\n",
- "A_{\\mathbf{u},\\mathbf{u}} & A_{\\mathbf{u},p} \\\\\n",
- "A_{p,\\mathbf{u}} & 0\n",
- "\\end{pmatrix}\n",
- "\\begin{pmatrix} u\\\\ p \\end{pmatrix}\n",
- "&= \\begin{pmatrix}\\mathbf{f}\\\\ 0 \\end{pmatrix}\n",
- "\\end{align}$$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "b71c05e1-4f5e-489c-98e6-3b8acda98c61",
- "metadata": {
- "slideshow": {
- "slide_type": "fragment"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def create_bilinear_form(V, Q):\n",
- " u, p = TrialFunction(V), TrialFunction(Q)\n",
- " v, q = TestFunction(V), TestFunction(Q)\n",
- " a_uu = inner(grad(u), grad(v)) * dx\n",
- " a_up = inner(p, div(v)) * dx\n",
- " a_pu = inner(div(u), q) * dx\n",
- " return fem.form([[a_uu, a_up], [a_pu, None]])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "d2708400-9078-420f-ae26-2209b5beb610",
- "metadata": {
- "slideshow": {
- "slide_type": "fragment"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def create_linear_form(V, Q):\n",
- " v, q = TestFunction(V), TestFunction(Q)\n",
- " domain = V.mesh\n",
- " x = SpatialCoordinate(domain)\n",
- " f = source(x)\n",
- " return fem.form([inner(f, v) * dx, inner(fem.Constant(domain, 0.0), q) * dx])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "63a64795-4ef8-48f5-85a9-f1062d35ef20",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "## Boundary conditions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "d9a592d2-d725-4cea-b53a-e433d7379fdc",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def create_velocity_bc(V):\n",
- " domain = V.mesh\n",
- " g = fem.Constant(domain, [0.0, 0.0])\n",
- " tdim = domain.topology.dim\n",
- " domain.topology.create_connectivity(tdim - 1, tdim)\n",
- " bdry_facets = mesh.exterior_facet_indices(domain.topology)\n",
- " dofs = fem.locate_dofs_topological(V, tdim - 1, bdry_facets)\n",
- " return [fem.dirichletbc(g, dofs, V)]"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a26e672b-4739-4e40-841b-6b09c2bb26c2",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "In the problem description above, we have only added a boundary condition for the velocity.\n",
- "This means that the problem is singular, ie the pressure is only determined up to a constant. We therefore create a PETSc nullspace operator for the pressure."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "3a71da5c-9500-4a1a-b55c-669bb9a14f04",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def create_nullspace(rhs_form):\n",
- " null_vec = fem.petsc.create_vector_nest(rhs_form)\n",
- " null_vecs = null_vec.getNestSubVecs()\n",
- " null_vecs[0].set(0.0)\n",
- " null_vecs[1].set(1.0)\n",
- " null_vec.normalize()\n",
- " nsp = PETSc.NullSpace().create(vectors=[null_vec])\n",
- " return nsp"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "59ca9b22-0867-4846-ae05-cbb7925bc430",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "## Create a block preconditioner"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "60b998bd-b6d9-420a-bc6b-53c5bd5ca146",
- "metadata": {
- "slideshow": {
- "slide_type": "notes"
- },
- "tags": []
- },
- "source": [
- "We create a nested matrix `P` to use as the preconditioner.\n",
- "The top-left block of `P` is the top-left block of `A`. \n",
- "The bottom-right diagonal entry is a mass matrix."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "id": "08769ee5-fb56-4260-a958-326164f31d31",
- "metadata": {},
- "outputs": [],
- "source": [
- "def create_preconditioner(Q, a, bcs):\n",
- " p, q = TrialFunction(Q), TestFunction(Q)\n",
- " a_p11 = fem.form(inner(p, q) * dx)\n",
- " a_p = fem.form([[a[0][0], None], [None, a_p11]])\n",
- " P = dolfinx.fem.petsc.assemble_matrix_nest(a_p, bcs)\n",
- " P.assemble()\n",
- " return P"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f730e936-1263-401f-8983-0ce0888ddf9d",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "## Assemble the nested system"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "a29fb3b0-f7ec-4e96-94eb-bda28adebd2c",
- "metadata": {},
- "outputs": [],
- "source": [
- "def assemble_system(lhs_form, rhs_form, bcs):\n",
- " A = fem.petsc.assemble_matrix_nest(lhs_form, bcs=bcs)\n",
- " A.assemble()\n",
- "\n",
- " b = dolfinx.fem.petsc.assemble_vector_nest(rhs_form)\n",
- " dolfinx.fem.petsc.apply_lifting_nest(b, lhs_form, bcs=bcs)\n",
- " for b_sub in b.getNestSubVecs():\n",
- " b_sub.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)\n",
- " spaces = fem.extract_function_spaces(rhs_form)\n",
- " bcs0 = fem.bcs_by_block(spaces, bcs)\n",
- " dolfinx.fem.petsc.set_bc_nest(b, bcs0)\n",
- " return A, b"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "64ae9638-0bc7-4988-bda1-9255bbb5d374",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "## PETSc Krylov Subspace solver"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "7f4b0865-ebd8-44c1-bf0f-80ce8aa1b26e",
- "metadata": {
- "slideshow": {
- "slide_type": "notes"
- },
- "tags": []
- },
- "source": [
- "In legacy DOLFIN, convenience functions were provided to interact with linear algebra packages such as PETSc.\n",
- "In DOLFINx, we instead supply users with the appropriate data types, so that the user can access all of the features of the linear package rather than being constrained to functions in our wrapper. One can also leverage the detailed documentation of PETSc. For blocked systems, see: https://petsc.org/release/docs/manual/ksp/?highlight=matnest#solving-block-matrices"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "6a474fb2-0f70-4d6d-aa55-cfc2402f8110",
- "metadata": {},
- "outputs": [],
- "source": [
- "def create_block_solver(A, b, P, comm):\n",
- " ksp = PETSc.KSP().create(comm)\n",
- " ksp.setOperators(A, P)\n",
- " ksp.setType(\"minres\")\n",
- " ksp.setTolerances(rtol=1e-9)\n",
- " ksp.getPC().setType(\"fieldsplit\")\n",
- " ksp.getPC().setFieldSplitType(PETSc.PC.CompositeType.ADDITIVE)\n",
- "\n",
- " nested_IS = P.getNestISs()\n",
- " ksp.getPC().setFieldSplitIS((\"u\", nested_IS[0][0]), (\"p\", nested_IS[0][1]))\n",
- "\n",
- " # Set the preconditioners for each block\n",
- " ksp_u, ksp_p = ksp.getPC().getFieldSplitSubKSP()\n",
- " ksp_u.setType(\"preonly\")\n",
- " ksp_u.getPC().setType(\"gamg\")\n",
- " ksp_p.setType(\"preonly\")\n",
- " ksp_p.getPC().setType(\"jacobi\")\n",
- "\n",
- " # Monitor the convergence of the KSP\n",
- " ksp.setFromOptions()\n",
- " return ksp"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ce65797c-f9d5-4b64-b46d-32c2102f6487",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "## Compute error estimates"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "b50a0186-9307-44ce-928c-843bbef57de4",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "In DOLFINx, assembling a scalar value does require any MPI-communication. `dolfinx.fem.petsc.assemble_scalar` will only integrate over the cells owned by the process.\n",
- "It is up to the user to gather the results, which can be gathered on for instance all processes, or a single process for outputting."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "c51b9d07-c380-48fe-8b41-911b93094438",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def assemble_scalar(J, comm: MPI.Comm):\n",
- " scalar_form = fem.form(J)\n",
- " local_J = fem.assemble_scalar(scalar_form)\n",
- " return comm.allreduce(local_J, op=MPI.SUM)\n",
- "\n",
- "\n",
- "def compute_errors(u, p):\n",
- " domain = u.function_space.mesh\n",
- " x = SpatialCoordinate(domain)\n",
- " error_u = u - u_ex(x)\n",
- " H1_u = inner(error_u, error_u) * dx\n",
- " H1_u += inner(grad(error_u), grad(error_u)) * dx\n",
- " velocity_error = np.sqrt(assemble_scalar(H1_u, domain.comm))\n",
- "\n",
- " error_p = -p - p_ex(x)\n",
- " L2_p = fem.form(error_p * error_p * dx)\n",
- " pressure_error = np.sqrt(assemble_scalar(L2_p, domain.comm))\n",
- " return velocity_error, pressure_error"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e2a17eaa-fce6-4390-8f57-6ede013f65c4",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- },
- "tags": []
- },
- "source": [
- "## Solving the Stokes problem with a block-preconditioner"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "id": "12d85f47",
- "metadata": {},
- "outputs": [],
- "source": [
- "def solve_stokes(u_element, p_element, domain):\n",
- " V = fem.functionspace(domain, u_element)\n",
- " Q = fem.functionspace(domain, p_element)\n",
- "\n",
- " lhs_form = create_bilinear_form(V, Q)\n",
- " rhs_form = create_linear_form(V, Q)\n",
- "\n",
- " bcs = create_velocity_bc(V)\n",
- " nsp = create_nullspace(rhs_form)\n",
- " A, b = assemble_system(lhs_form, rhs_form, bcs)\n",
- " assert nsp.test(A)\n",
- " A.setNullSpace(nsp)\n",
- "\n",
- " P = create_preconditioner(Q, lhs_form, bcs)\n",
- " ksp = create_block_solver(A, b, P, domain.comm)\n",
- "\n",
- " u, p = fem.Function(V), fem.Function(Q)\n",
- " w = PETSc.Vec().createNest([u.vector, p.vector])\n",
- " ksp.solve(b, w)\n",
- " assert ksp.getConvergedReason() > 0\n",
- " u.x.scatter_forward()\n",
- " p.x.scatter_forward()\n",
- " return compute_errors(u, p)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e325a904",
- "metadata": {
- "lines_to_next_cell": 0,
- "slideshow": {
- "slide_type": "notes"
- },
- "tags": []
- },
- "source": [
- "We now use the Stokes solver we have defined to experiment with a range of element pairs that can be used. First, we define a function that takes a pair of elements as input and plots a graph showing the error as $h$ is decreased."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "id": "9ec19416",
- "metadata": {
- "lines_to_next_cell": 0,
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [],
- "source": [
- "def error_plot(element_u, element_p, convergence_u=None, convergence_p=None, refinements=5, N0=7):\n",
- " hs = np.zeros(refinements)\n",
- " u_errors = np.zeros(refinements)\n",
- " p_errors = np.zeros(refinements)\n",
- " comm = MPI.COMM_WORLD\n",
- " for i in range(refinements):\n",
- " N = N0 * 2**i\n",
- " domain = mesh.create_unit_square(comm, N, N, mesh.CellType.triangle)\n",
- " u_errors[i], p_errors[i] = solve_stokes(element_u, element_p, domain)\n",
- " hs[i] = 1.0 / N\n",
- " legend = []\n",
- "\n",
- " if convergence_u is not None:\n",
- " y_value = u_errors[-1] * 1.4\n",
- " plt.plot(\n",
- " [hs[0], hs[-1]],\n",
- " [y_value * (hs[0] / hs[-1]) ** convergence_u, y_value],\n",
- " \"k--\",\n",
- " )\n",
- " legend.append(f\"order {convergence_u}\")\n",
- " if convergence_p is not None:\n",
- " y_value = p_errors[-1] * 1.4\n",
- " plt.plot(\n",
- " [hs[0], hs[-1]],\n",
- " [y_value * (hs[0] / hs[-1]) ** convergence_p, y_value],\n",
- " \"k--\",\n",
- " )\n",
- " legend.append(f\"order {convergence_p}\")\n",
- "\n",
- " plt.plot(hs, u_errors, \"bo-\")\n",
- " plt.plot(hs, p_errors, \"ro-\")\n",
- " legend += [r\"$H^1(\\mathbf{u_h}-\\mathbf{u}_{ex})$\", r\"$L^2(p_h-p_ex)$\"]\n",
- " plt.legend(legend)\n",
- " plt.xscale(\"log\")\n",
- " plt.yscale(\"log\")\n",
- " plt.axis(\"equal\")\n",
- " plt.ylabel(\"Error in energy norm\")\n",
- " plt.xlabel(\"$h$\")\n",
- " plt.xlim(plt.xlim()[::-1])\n",
- " plt.grid(True)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "5089c8cf",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "## Piecewise constant pressure spaces"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "859895f1-dfb1-4fbc-be34-f7ec01a65ac8",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "For our first element, we pair piecewise linear elements with piecewise constants."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f8de7f59",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a09fbb43-76c9-454e-be51-2b09b1cf2d3b",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "source": [
- "Using these elements, we do not converge to the solution."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "id": "0a7d18cc",
- "metadata": {
- "slideshow": {
- "slide_type": "skip"
- },
- "tags": []
- },
- "outputs": [
- {
- "data": {
- "image/png": "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de3aVVOmTPHp51oedHr27HnKJRtuv/123X777R77zNTUVKWmpsrpdHpsnwAQUMpCzpo1hJzTcOmll6pdu3aaM2fOSbfZtGmTnE6nYmNjy7VPnz5dw4YNC4qQI0n333+/Lr/8ct10001q2LChzz7Xr8foeEtycrKysrK0ceNGq0sBAN+zY8hxOs3jeest87sP/iNbWlqqzZs368ILLzzpNgcOHNDYsWMrBKGCggLNnTtXN954o7fL9Bvt27dXq1at9Prrr/v0c4My6ABA0LJjyElLk+LipF69pNGjze9xcWa7F3333XfKz88/adApLCzU8OHDNXXqVF1yySXlXluyZIlq166ti477t9+7d68cDodmzZqlCy64QBEREWrXrp0++eQTrx7H8U6nhrfeekt16tRRdna2q238+PHq2LGjDh06JEkaMmSI3n77ba/VXxmCDgAEixNDjh3urkpLk0aOlHbtKt++e7fZ7sWwk5GRobCwMHXs2LHCa4ZhaNy4cerdu7fGjBlT4fX09HR17ty5XFvZnHAvv/yyUlJSlJmZqRYtWui6667z2Vpgp1PDNddco/POO0+PP/64JOmhhx7SypUrtXTpUtelqm7dumnDhg3l1p30NsvH6AAAfKCykOOP03QYhlRQUL1tnU5p4kTzPZXtx+GQJk2S+vSRjlsQ8qQiI833VFNGRobi4+MrXb7i008/1fz589WxY0ctWrRIkvTaa6+5Zu7/5Zdf1Lx583Lv2bx5s8LDw/X++++7xu089thj6tKli3bv3l1hjI83nE4NDodD06dP18iRI9WsWTPNnj1b6enpOvvss13bNG/eXEVFRdq7d69atmzp7cORRNABAPvLz5eGDPH/kCOZIadePc/syzDMnp7qDnzNy5PcuP07IyPjpJetLrvssip7QI4cOVIhIGVmZioxMbHc4OQTF6x8//33tXr1aqWkpJx031OnTtWTTz5ZZe3ffPON2rZtW6G9OjVUZfDgwYqPj9c///lPrVixQu3atSv3ep06dSSZY5R8haADAHZWFnJWr/b/kBNgMjMzddVVV9XovVFRUfrjjz8q7C8pKalc2/r16xUVFeXqFdmyZYsSEhKq3PeUKVM0bty4Krf5y1/+Uml7dWqoyrJly/Ttt99Wuk6lZA7OlqSzzjrrlPvyFIIOANhVIIacyEizZ6U61q2TBg489XZL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U0pKiuu5w+FQXl6eHnroIQ3kFyjgPwxD+sc/pOeeM+fE+e9/JaaGABBk3L509fTTT6t///6Kj4/X0aNHNXr0aG3fvl1RUVF66623vFEjgJr45z+lp54yHz//vHT99dbWAwAWcDvoxMTEaPPmzXr77be1ZcsW5eXl6cYbb9R1111XbnAyAAs99ZT08MPm42eekSZMsLQcALBKjebRCQsL0/X87xDwT6mp0t//bj6ePl26805LywEAK9Uo6Gzfvl2rV69WTk6OSktLy7324IMPeqQwADXwyivS7bebj++91/wCgCDmdtB58cUXdeuttyoqKkrNmjWTo2zhP5kDkwk6gEXmzzdvI5ekSZOkxx6zth4A8ANuB53HHntM06dP1z/+8Q9v1AOgJj74wBxsXFoq3XyzOS7nuP+EAECwcvv28j/++EOjRo3yRi0AamLFCmnUKKmkRLruOuk//yHkAMCf3A46o0aN0ooVK7xRCwB3rVsnDR8uFRVJiYnmxICsOA4ALm5fujr33HP1wAMP6PPPP1eHDh0UHh5e7vWJEyd6rDgAVfjiC2nQIOnIEXO247feksJqdH8BANiW278V58yZo3r16mnt2rVau3ZtudccDgdBB/CFzEzpyiulvDypd29p4ULphPXnAAA1CDo7duzwRh0Aquubb6S+faWDB6VLLpHef19isk4AqJTbY3TKFBUV6bvvvlNJSYkn6wFQhbrZ2Qq78kpp/37pwgulJUukevWsLgsA/JbbQaegoEA33nijIiMj1a5dO/3666+SpDvuuEMzZszweIEA/vTrr7rkwQflyM6W2rWTli+XGja0uioA8GtuB51p06Zp8+bNWrNmjSIiIlztffr00fz58z1aHIA//dmTE/nbbzLOPVdauVKKirK6KgDwe26P0Vm0aJHmz5+viy66qNysyO3atdOPP/7o0eIAyLxM1aePHD/8oIKzzlL48uUKb9bM6qoAICC43aPz22+/qUmTJhXa8/PzywUfAB5w8KDUr5+UlSWjeXN9+uijUmys1VUBQMBwO+h06dJFixcvdj0vCzcvvfSSLr74Ys9VBgS7w4elAQOkr76SzjpLJcuWqYCeHABwi9uXrh5//HENGDBAWVlZKikp0axZs5SVlaXPPvuswrw6AGroyBFp6FDp88+lM86QPvpIattW+uknqysDgIDido/OZZddpszMTJWUlKhDhw5asWKFmjRpovXr16tz587eqBEILoWF5nIOa9ZI9etLy5ZJnTpZXRUABKQazRffqlUrvfjii56upUZ27typMWPGKCcnR2FhYXrggQdYdBSBq6REuvZaM9zUqSMtXix162Z1VQAQsAJ+YZywsDClpKQoISFBe/fuVefOnTVw4EDVrVvX6tIA9zidUlKS9N575nIO778v9ehhdVUAENACPuhER0crOjpaktSsWTNFRUXpwIEDBB0EFsOQbrlFevNNc2HOhQvNZR4AAKelxktAeMq6des0ZMgQNW/eXA6HQ4sWLaqwTWpqquLi4hQREaHu3btrw4YNle5r06ZNcjqdiuX2WwQSw5DuvFN66SUpJER64w1pyBCrqwIAW7A86OTn56tTp05KTU2t9PX58+dr8uTJeuihh5SRkaFOnTqpf//+ysnJKbfdgQMHNHbsWM2ZM8cXZQOeYRjSvfdK//63+fzll6W//c3amgDARiy/dDVgwAANGDDgpK/PnDlTN998s8aPHy9Jev7557V48WK9/PLLmjp1qiSpsLBQw4cP19SpU3XJJZecdF+FhYUqLCx0Pc/NzZUkFRcXl/sO+ErI448r9M814pyzZ6t09GjpJOch5ykCAecpfMGd88vtoJOfn68ZM2Zo1apVysnJUWlpabnXf/LgPB9FRUXatGmTpk2b5moLCQlRnz59tH79ekmSYRgaN26cevfurTFjxlS5vyeeeEKPPPJIhfbVq1crMjJSH330kcdqB07lLx98oA4vvyxJ2jZunH6MjTVXIz8FzlMEAs5TeFNBQUG1t3U76Nx0001au3atxowZo+joaK8u+7B//345nU41bdq0XHvTpk317bffSpI+/fRTzZ8/Xx07dnSN73nttdfUoUOHCvubNm2aJk+e7Hqem5ur2NhY9erVS1988YX69u2r8PBwrx0PUCbkxRcV+mfIcT74oNrcf7/anOI9xcXF+uijjzhP4dc4T+ELZVdkqsPtoLN06VItXrxYl156qbtv9YrLLrusQq/SydSuXVu1a9eu0F72wxgeHs4PJrzv1Vel2283H//97wp9+GGFuvEfBs5TBALOU3iTO+eW24ORzzjjDDVu3Njdt9VIVFSUQkNDtW/fvnLt+/btUzPW/EEgeucdafx4cxDy7bdLM2ZILIYLAF7jdtB59NFH9eCDD7p1faym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",
- "text/plain": [
- "