From 43ebb29d212e578a3960f54340e7f4275c68db8d Mon Sep 17 00:00:00 2001
From: JanHab <Jan.Habscheid@web.de>
Date: Mon, 19 Aug 2024 19:08:50 +0200
Subject: [PATCH] Eq02 now really eq02, before by accident Eq04

---
 ...ncompressibleValidationAnalyticalMethod.py |  21 ++-
 .../ValidationSimplifiedSystem.py             |  84 +++++++++++
 src/Eq02.py                                   | 141 ++++++------------
 src/Helper_DoubleLayerCapacity.py             |  11 +-
 src/__pycache__/Eq02.cpython-312.pyc          | Bin 20555 -> 16214 bytes
 ...Helper_DoubleLayerCapacity.cpython-312.pyc | Bin 10503 -> 10327 bytes
 6 files changed, 150 insertions(+), 107 deletions(-)
 create mode 100644 examples/ReproducableCode/ValidationSimplifiedSystem.py

diff --git a/examples/ReproducableCode/DoubleLayerCapacity/IncompressibleValidationAnalyticalMethod.py b/examples/ReproducableCode/DoubleLayerCapacity/IncompressibleValidationAnalyticalMethod.py
index f2cfffa..c17780a 100644
--- a/examples/ReproducableCode/DoubleLayerCapacity/IncompressibleValidationAnalyticalMethod.py
+++ b/examples/ReproducableCode/DoubleLayerCapacity/IncompressibleValidationAnalyticalMethod.py
@@ -36,7 +36,7 @@ NA = 6.022e+23 # [1/mol] - Avogadro constant
 nR_mol = 55
 nR_m = nR_mol * NA * 1/(1e-3)# [1/m^3]
 pR = 1.01325 * 1e+5 # [Pa]
-LR = 20e-8
+LR = 20e-9
 chi = 80 # [-]
 
 # Parameter and bcs for the electrolyte
@@ -54,12 +54,13 @@ p_right = 0
 number_cells = 1024
 relax_param = 0.03
 p_right = 0
+rtol = 1e-4 # ! Change back to 1e-8
 
 
 # phi^L domain
-Vol_start = 0
+Vol_start = 0.1 # ! Change back to 0
 Volt_end = 0.75
-n_Volts = 5#0
+n_Volts = 25#0
 
 phi_left = np.linspace(Vol_start, Volt_end, n_Volts) * e0/(k*T)
 
@@ -68,7 +69,7 @@ phi_left = np.linspace(Vol_start, Volt_end, n_Volts) * e0/(k*T)
 # Solution vectors
 y_A_num, y_C_num, y_S_num, phi_num, p_num, x_num = [], [], [], [], [], []
 for i, phi_bcs in enumerate(phi_left):
-    y_A_, y_C_, phi_, p_, x_ = solve_System_2eq(phi_bcs, phi_right, p_right, z_A, z_C, y_R, y_R, K, Lambda2, a2, number_cells, solvation=kappa, refinement_style='hard_log', rtol=1e-10, max_iter=2500, return_type='Vector', relax_param=relax_param)
+    y_A_, y_C_, phi_, p_, x_ = solve_System_2eq(phi_bcs, phi_right, p_right, z_A, z_C, y_R, y_R, K, Lambda2, a2, number_cells, solvation=kappa, refinement_style='hard_log', rtol=rtol, max_iter=2500, return_type='Vector', relax_param=relax_param)
     y_S_ = 1 - y_A_ - y_C_
     y_A_num.append(y_A_)
     y_C_num.append(y_C_)
@@ -82,9 +83,9 @@ for j in range(len(phi_left)):
     Q_num.append(Q_num_(y_A_num[j], y_C_num[j], n(p_num[j], K), x_num[j]))
 Q_num = np.array(Q_num)
 
-# dx_ = phi_left[1] - phi_left[0] # [1/V], Assumption: phi^L is uniformly distributed
-# C_DL_num = (Q_num[1:] - Q_num[:-1])/dx_ # [µAs/cm³]
-# C_DL_num = np.array(C_DL_num)
+dx_ = phi_left[1] - phi_left[0] # [1/V], Assumption: phi^L is uniformly distributed
+C_DL_num = (Q_num[1:] - Q_num[:-1])/dx_ # [µAs/cm³]
+C_DL_num = np.array(C_DL_num)
 C_dl_num = C_dl(Q_num, phi_left)
 
 
@@ -115,4 +116,8 @@ plt.legend()
 plt.xlabel('$\delta \\varphi$ [-]')
 plt.ylabel('$C_{dl,num} - C_{dl,ana} [-]$')
 plt.tight_layout()
-plt.show()
\ No newline at end of file
+plt.show()
+
+print('phi_left:', phi_left)
+print('Q_num:', Q_num)
+print('Q_ana:', Q_ana)
\ No newline at end of file
diff --git a/examples/ReproducableCode/ValidationSimplifiedSystem.py b/examples/ReproducableCode/ValidationSimplifiedSystem.py
new file mode 100644
index 0000000..d8a2d83
--- /dev/null
+++ b/examples/ReproducableCode/ValidationSimplifiedSystem.py
@@ -0,0 +1,84 @@
+'''
+Jan Habscheid
+Jan.Habscheid@rwth-aachen.de
+
+This script is used to validate the simplification of the system of four equations to a system of two equations in the one-dimensional equilibrium case.
+'''
+
+# import the src file needed to solve the system of equations
+import sys
+import os
+
+# Add the src directory to the sys.path
+src_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../..', 'src')
+sys.path.insert(0, src_path)
+
+from Eq04 import solve_System_4eq
+from Eq02 import solve_System_2eq
+
+# Remove the src directory from sys.path after import
+del sys.path[0]
+
+# Further imports
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+
+# Define the parameters and boundary conditions
+phi_left = 4.0
+phi_right = 0.0
+p_right = 0.0
+y_A_R = 0.01
+y_C_R = 0.01
+z_A = -1.0
+z_C = 1.0
+K = 'incompressible'
+Lambda2 = 8.553e-6
+a2 = 7.5412e-4
+solvation = 15
+number_cells = 1024#*4
+refinement_style = 'log'
+rtol = 1e-8
+
+# solve the complete system
+y_A_4eq, y_C_4eq, phi_4eq, p_4eq, x_4eq = solve_System_4eq(phi_left, phi_right, p_right, z_A, z_C, y_A_R, y_C_R, K, Lambda2, a2, number_cells, solvation=solvation, relax_param=0.05, refinement_style='hard_log', return_type='Vector', max_iter=1_000, rtol=rtol)
+
+# solve the simplified system
+y_A_2eq, y_C_2eq, phi_2eq, p_2eq, x_2eq = solve_System_2eq(phi_left, phi_right, p_right, z_A, z_C, y_A_R, y_C_R, K, Lambda2, a2, number_cells, solvation=solvation, relax_param=0.05, refinement_style='hard_log', return_type='Vector', max_iter=1_000, rtol=rtol)
+
+# Evaluate the difference
+plt.figure()
+# plt.plot(x_4eq, y_A_4eq, label='y_A_4eq')
+# plt.plot(x_2eq, y_A_2eq, label='y_A_2eq')
+plt.plot(x_4eq, y_A_4eq - y_A_2eq, label='y_A_4eq - y_A_2eq')
+plt.grid()
+plt.xlim(0, 0.05)
+plt.legend()
+plt.show()
+
+plt.figure()
+# plt.plot(x_4eq, y_C_4eq, label='y_C_4eq')
+# plt.plot(x_2eq, y_C_2eq, label='y_C_2eq')
+plt.plot(x_4eq, y_C_4eq - y_C_2eq, label='y_C_4eq - y_C_2eq')
+plt.grid()
+plt.xlim(0, 0.05)
+plt.legend()
+plt.show()
+
+plt.figure()
+# plt.plot(x_4eq, phi_4eq, label='phi_4eq')
+# plt.plot(x_2eq, phi_2eq, label='phi_2eq')
+plt.plot(x_4eq, phi_4eq - phi_2eq, label='phi_4eq - phi_2eq')
+plt.grid()
+plt.xlim(0, 0.05)
+plt.legend()
+plt.show()
+
+plt.figure()
+# plt.plot(x_4eq, p_4eq, label='p_4eq')
+# plt.plot(x_2eq, p_2eq, label='p_2eq')
+plt.plot(x_4eq, p_4eq - p_2eq, label='p_4eq - p_2eq')
+plt.grid()
+plt.xlim(0, 0.05)
+plt.legend()
+plt.show()
\ No newline at end of file
diff --git a/src/Eq02.py b/src/Eq02.py
index 45901a1..7ecd7d0 100644
--- a/src/Eq02.py
+++ b/src/Eq02.py
@@ -8,7 +8,7 @@ from mpi4py import MPI
 from dolfinx import mesh, fem, log
 from dolfinx.fem.petsc import NonlinearProblem
 from dolfinx.nls.petsc import NewtonSolver
-from ufl import TestFunctions, split, dot, grad, dx, inner, ln, Mesh
+from ufl import TestFunctions, split, dot, grad, dx, inner, Mesh, exp
 from basix.ufl import element, mixed_element
 import matplotlib.pyplot as plt
 
@@ -51,7 +51,7 @@ def create_refined_mesh(refinement_style:str, number_cells:int) -> Mesh:
     msh = mesh.create_mesh(MPI.COMM_WORLD, cells_np, coordinates_np_, domain)
     return msh
 
-def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float, z_C:float, y_A_R:float, y_C_R:float, K:float|str, Lambda2:float, a2:float, number_cells:int, solvation:float = 0, PoissonBoltzmann:bool=False, relax_param:float=None, x0:float=0, x1:float=1, refinement_style:str='uniform', return_type:str='Scalar', rtol:float=1e-8, max_iter:float=500):
+def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float, z_C:float, y_A_R:float, y_C_R:float, K:float|str, Lambda2:float, a2:float, number_cells:int, solvation:float = 0, relax_param:float=None, x0:float=0, x1:float=1, refinement_style:str='uniform', return_type:str='Scalar', rtol:float=1e-8, max_iter:float=500):
     '''
     Solve the simplified dimensionless system of equations presented in: Numerical Treatment of a Thermodynamically Consistent Electrolyte Model, B.Sc. Thesis Habscheid 2024
 
@@ -96,8 +96,6 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
         Number of cells in the mesh
     solvation : float, optional
         solvation number, by default 0
-    PoissonBoltzmann : bool, optional
-        Solve classical Nernst-Planck model with the use of the Poisson-Boltzmann formulation if True, else solve the presented model by Dreyer, Guhlke, Müller, by default False
     relax_param : float, optional
         Relaxation parameter for the Newton solver
         xₙ₊₁ = γ xₙ f(xₙ)/f'(xₙ) with γ the relaxation parameter
@@ -122,6 +120,8 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
         Returns atomic fractions for species A and C, electric potential, pressure, and the mesh
         If return_type is 'Vector', the solution is returned as numpy arrays
     '''
+    if return_type == 'Scalar':
+        raise NotImplementedError('Scalar return type is not implemented yet')
     # Define boundaries of the domain
     x0 = 0
     x1 = 1
@@ -143,20 +143,18 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
     CG1_elem = element('Lagrange', msh.basix_cell(), 1)
 
     # Define Mixed Function Space
-    W_elem = mixed_element([CG1_elem, CG1_elem, CG1_elem, CG1_elem])
+    W_elem = mixed_element([CG1_elem, CG1_elem])#, CG1_elem, CG1_elem])
     W = fem.functionspace(msh, W_elem)
 
     # Define Trial- and Testfunctions
     u = fem.Function(W)
-    y_A, y_C, phi, p = split(u)
-    (v_A, v_C, v_1, v_2) = TestFunctions(W)
+    phi, p = split(u)
+    (v_1, v_2) = TestFunctions(W)
 
     # Collapse function space for bcs
     W0, _ = W.sub(0).collapse()
     W1, _ = W.sub(1).collapse()
-    W2, _ = W.sub(2).collapse()
-    W3, _ = W.sub(3).collapse()
-
+    
     # Define boundary conditions values
     def phi_left_(x):
         return np.full_like(x[0], phi_left)
@@ -164,42 +162,36 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
         return np.full_like(x[0], phi_right)
     def p_right_(x):
         return np.full_like(x[0], p_right)
-    def y_A_right_(x):
-        return np.full_like(x[0], y_A_R)
-    def y_C_right_(x):
-        return np.full_like(x[0], y_C_R)
-
+    
     # Interpolate bcs functions
-    phi_left_bcs = fem.Function(W2)
+    phi_left_bcs = fem.Function(W0)
     phi_left_bcs.interpolate(phi_left_)
-    phi_right_bcs = fem.Function(W2)
+    phi_right_bcs = fem.Function(W0)
     phi_right_bcs.interpolate(phi_right_)
-    p_right_bcs = fem.Function(W3)
+    p_right_bcs = fem.Function(W1)
     p_right_bcs.interpolate(p_right_)
-    y_A_right_bcs = fem.Function(W0)
-    y_A_right_bcs.interpolate(y_A_right_)
-    y_C_right_bcs = fem.Function(W1)
-    y_C_right_bcs.interpolate(y_C_right_)
-
+    
     # Identify dofs for boundary conditions
     # Define boundary conditions
-    facet_left_dofs = fem.locate_dofs_geometrical((W.sub(2), W.sub(2).collapse()[0]), Left)
-    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(2), W.sub(2).collapse()[0]), Right)
-    bc_left_phi = fem.dirichletbc(phi_left_bcs, facet_left_dofs, W.sub(2))
-    bc_right_phi = fem.dirichletbc(phi_right_bcs, facet_right_dofs, W.sub(2))
-
-    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(3), W.sub(3).collapse()[0]), Right)
-    bc_right_p = fem.dirichletbc(p_right_bcs, facet_right_dofs, W.sub(3))
-
+    facet_left_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Left)
     facet_right_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Right)
-    bc_right_y_A = fem.dirichletbc(y_A_right_bcs, facet_right_dofs, W.sub(0))
+    bc_left_phi = fem.dirichletbc(phi_left_bcs, facet_left_dofs, W.sub(0))
+    bc_right_phi = fem.dirichletbc(phi_right_bcs, facet_right_dofs, W.sub(0))
 
     facet_right_dofs = fem.locate_dofs_geometrical((W.sub(1), W.sub(1).collapse()[0]), Right)
-    bc_right_y_C = fem.dirichletbc(y_C_right_bcs, facet_right_dofs, W.sub(1))
+    bc_right_p = fem.dirichletbc(p_right_bcs, facet_right_dofs, W.sub(1))
 
+    
     # Combine boundary conditions into list
-    bcs = [bc_left_phi, bc_right_phi, bc_right_p, bc_right_y_A, bc_right_y_C]
-        
+    bcs = [bc_left_phi, bc_right_phi, bc_right_p]
+
+    def y_A(phi, p):
+        D_A = y_A_R / exp(-(solvation + 1) * a2 * p_right - z_A * phi_right)
+        return D_A * exp(-(solvation + 1) * a2 * p - z_A * phi)
+    
+    def y_C(phi, p):
+        D_C = y_C_R / exp(-(solvation + 1) * a2 * p_right - z_C * phi_right)
+        return D_C * exp(-(solvation + 1) * a2 * p - z_C * phi)
     
 
     # Define variational problem
@@ -207,30 +199,6 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
         # total free charge density
         def nF(y_A, y_C):
             return (z_C * y_C + z_A * y_A)
-        
-        # Diffusion fluxes for species A and C
-        def J_A(y_A, y_C, phi, p):
-            return ln(y_A) + a2 * (p - 1) * (solvation + 1) + z_A * phi
-        
-        def J_C(y_A, y_C, phi, p):
-            return ln(y_C) + a2 * (p - 1) * (solvation + 1) + z_C * phi
-        
-        # Variational Form
-        A = (
-            inner(grad(phi), grad(v_1)) * dx
-            - 1 / Lambda2 * nF(y_A, y_C) * v_1 * dx
-        ) + (
-            inner(grad(p), grad(v_2)) * dx
-            + 1 / a2 * nF(y_A, y_C) * dot(grad(phi), grad(v_2)) * dx
-        ) + (
-            inner(grad(J_A(y_A, y_C, phi, p)), grad(v_A)) * dx
-            + inner(grad(J_C(y_A, y_C, phi, p)), grad(v_C)) * dx
-        )
-        if PoissonBoltzmann:
-            A += (
-                inner(grad(- a2 * (p - 1) * (solvation + 1)), grad(v_A)) * dx
-                + inner(grad(- a2 * (p - 1) * (solvation + 1)), grad(v_C)) * dx
-            )
     else: 
         # total number density
         def n(p):
@@ -239,37 +207,16 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
         # total free charge density
         def nF(y_A, y_C, p):
             return (z_C * y_C + z_A * y_A) * n(p)
-        
-        # Diffusion fluxes for species A and C
-        def J_A(y_A, y_C, phi, p):
-            return ln(y_A) + a2 * (solvation + 1) * K * ln(1 + 1/K * (p-1)) + z_A * phi
-        
-        def J_C(y_A, y_C, phi, p):
-            return ln(y_C) + a2 * (solvation + 1)* K * ln(1 + 1/K * (p-1)) + z_C * phi
-
-        A = (
-            inner(grad(phi), grad(v_1)) * dx
-            - 1 / Lambda2 * nF(y_A, y_C, p) * v_1 * dx
-        ) + (
-            inner(grad(p), grad(v_2)) * dx
-            + 1 / a2 * nF(y_A, y_C, p) * dot(grad(phi), grad(v_2)) * dx
-        ) + (
-            inner(grad(J_A(y_A, y_C, phi, p)), grad(v_A)) * dx
-            + inner(grad(J_C(y_A, y_C, phi, p)), grad(v_C)) * dx
-        )
+            # Variational Form
+    A = (
+        inner(grad(phi), grad(v_1)) * dx
+        - 1 / Lambda2 * nF(y_A(phi, p), y_C(phi, p)) * v_1 * dx
+    ) + (
+        inner(grad(p), grad(v_2)) * dx
+        + 1 / a2 * nF(y_A(phi, p), y_C(phi, p)) * dot(grad(phi), grad(v_2)) * dx
+    )
     F = A
 
-    # Initialize initial guess for u
-    y_C_init = fem.Function(W1)
-    y_A_init = fem.Function(W0)
-    y_C_init.interpolate(lambda x: np.full_like(x[0], y_C_R))
-    y_A_init.interpolate(lambda x: np.full_like(x[0], y_A_R))
-
-    with u.vector.localForm() as u_loc:
-        u_loc.set(0)
-    u.sub(0).interpolate(y_A_init)
-    u.sub(1).interpolate(y_C_init)
-
     # Define Nonlinear Problem
     problem = NonlinearProblem(F, u, bcs=bcs)
 
@@ -294,20 +241,22 @@ def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float,
     print(f"Number of interations: {n:d}")
 
     # Split the mixed function space into the individual components    
-    y_A, y_C, phi, p = u.split()
+    phi, p = u.split()
     
     # Return the solution
     if return_type=='Vector':
         x_vals = np.array(msh.geometry.x[:,0])
-        y_A_vals = np.array(u.sub(0).collapse().x.array)
-        y_C_vals = np.array(u.sub(1).collapse().x.array)
-        phi_vals = np.array(u.sub(2).collapse().x.array)
-        p_vals = np.array(u.sub(3).collapse().x.array)
+        phi_vals = np.array(u.sub(0).collapse().x.array)
+        p_vals = np.array(u.sub(1).collapse().x.array)
+
+        # Calculate the atomic fractions
+        D_A = y_A_R / np.exp(-(solvation + 1) * a2 * p_right - z_A * phi_right)
+        y_A_vals = D_A * np.exp(-(solvation + 1) * a2 * p_vals - z_A * phi_vals)
+    
+        D_C = y_C_R / np.exp(-(solvation + 1) * a2 * p_right - z_C * phi_right)
+        y_C_vals = D_C * np.exp(-(solvation + 1) * a2 * p_vals - z_C * phi_vals)
         
         return y_A_vals, y_C_vals, phi_vals, p_vals, x_vals
-    elif return_type=='Scalar':
-        return y_A, y_C, phi, p, msh
-    
     
 if __name__ == '__main__':
     # Define the parameters
diff --git a/src/Helper_DoubleLayerCapacity.py b/src/Helper_DoubleLayerCapacity.py
index d8bd697..4da01eb 100644
--- a/src/Helper_DoubleLayerCapacity.py
+++ b/src/Helper_DoubleLayerCapacity.py
@@ -157,10 +157,15 @@ def Q_DL_dimless_ana(y_A_R:float, y_C_R:float, y_N_R:float, z_A:float, z_C:float
         D_C = y_C_R / (np.exp(-(solvation+1)*a2*p_R-z_C*phi_R))
         D_N = y_N_R / (np.exp(-(solvation+1)*a2*p_R-z_N*phi_R))
         E_p = p_R
-        CLambda_L = np.log(D_A * np.exp(-z_A * phi_L - (solvation+1) * E_p) + D_C * np.exp(-z_C * phi_L - (solvation+1) * E_p) + D_N * np.exp(-z_N * phi_L - (solvation+1) * E_p))
-        CLambda_R = np.log(D_A * np.exp(-z_A * phi_R + E_p * a2) + D_C * np.exp(-z_C * phi_R + E_p * a2) + D_N * np.exp(-z_N * phi_R + E_p * a2))
+
+        CLambda_L = np.log(D_A * np.exp(-z_A * phi_L) + D_C * np.exp(-z_C * phi_L) + D_N * np.exp(-z_N * phi_L))
+        CLambda_R = np.log(D_A * np.exp(-z_A * phi_R) + D_C * np.exp(-z_C * phi_R) + D_N * np.exp(-z_N * phi_R))
+
+        # dx_Phi_L = np.sqrt((CLambda_L - (solvation+1) * a2 * E_p) * 2 / (solvation + 1))
+        # dx_Phi_R = np.sqrt((CLambda_R - (solvation+1) * a2 * E_p) * 2 / (solvation + 1))
+        # Q_DL = Lambda2 * (dx_Phi_L - dx_Phi_R)
         Lambda = np.sqrt(Lambda2)
-        Q_DL = (phi_L-phi_R) / np.abs(phi_L-phi_R) * Lambda * np.sqrt(2/(solvation+1)) * (np.sqrt(CLambda_L) - np.sqrt(CLambda_R))
+        Q_DL = (phi_L-phi_R) / np.abs(phi_L-phi_R) * Lambda * np.sqrt(2/(solvation+1)) * (np.sqrt(CLambda_L + E_p * a2) - np.sqrt(CLambda_R + E_p * a2))
     else:
         C_A = y_A_R / ((K + p_R  - 1)**(-(solvation+1)*a2*K)*np.exp(-z_A*phi_R))
         C_C = y_C_R / ((K + p_R  - 1)**(-(solvation+1)*a2*K)*np.exp(-z_C*phi_R))
diff --git a/src/__pycache__/Eq02.cpython-312.pyc b/src/__pycache__/Eq02.cpython-312.pyc
index 0a43f005f31a0dc1160dbe3957614a55dd0419bd..99acdd38417e0f045265675a551c6f42a3df0a2d 100644
GIT binary patch
delta 4920
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
BBKH6Q

delta 8057
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
O$3D1lY>u-1!w3Mg6P%O)

diff --git a/src/__pycache__/Helper_DoubleLayerCapacity.cpython-312.pyc b/src/__pycache__/Helper_DoubleLayerCapacity.cpython-312.pyc
index 0520aeca0b59a17e6054ae07e36af289020f6477..ec8a8993fff2cb48986394c354c67b2ed42ec555 100644
GIT binary patch
delta 1001
zcmZn<x*ouLnwOW0fq{YHU*+MnCmVTR@>*~f=jW6qmSpDVCG&t}pqPV!fq|KUf#LHe
zb_Ry&3@MDYJT)9COxYR?3=<fOZqzVLzQ8ZP*^^J2adL%#;pC;lVw2DFYfgS5EHGI>
zkaM!Kfahcd5#GtI0-BRA2=Pun&95<8Usz}|ui$x}8i5+FDpm%DDh39I$#(=bPy{x!
z2ywD7I&9_>+slk_+GIx6)Xk<+sf>)QlV?jS)N`&-T*y5mZ$;2WIsFaH7v+pMIPYNH
z=y_4j_OiI$MLzou<{Ny%Q;MdSO)OhLZMA|O%#2Sa^T~=iUsg1|C~dlfc~8>*w4G@O
zk`IKOa6K4v*)Hg!MbJg*pbMc9SE6IDM<-s4PP~wub|ES4LT28@q`b?~`4>a;FG}ZM
z7Acs_Ei36o1#>z$zi=@KiA>%uYg8|JAvolu^uhegc3~I!!>&ZdT#rh;7?pS-Df>cR
z;f0d2i+N=ilgchfm0zi<`Od&l&FIAR5kh@nU~p#gVfw(p;Lj8UqC%O%L2~{O%9$yg
z=`%=W1V}KN5ljh0GIg+gP-5T_Xz>0Z&%iHIKZ9|G^Gx;yhBJ9qXl`&^sl9@4L(xSI
z%N>drHLNd++w2M2AGR~>K=1*V6QT#bF5CKF6!*W#7XXejYG~CZ$=c25<Zd%Ep5DwS
z7R<EyuhM@;M55cwsLIXAxO+0Mnifm?W$uj4)@qX&T|5{W1!kCjU;xo8SRwR=PzZeh
z%0B^>zYq}%k+_hW1!WYJeqivJET|!71v20R1A{L(q@kQ}rWhuO!Ve4#8BDndP7zZ%
o(`T@yA3`Q4YV=6CFncn8U@&GB_`ty6#~jT31;j4mWnf?c0A06XOaK4?

delta 1162
zcmcZ}&>qBlnwOW0fq{X+CgpG%&qm&tye6#Ki3J6T$vhxYDCT5fU|?ooVEFunoq=IG
zLkeRpPYp*3Q?>>J!vw~npEV4V9r)!p`|?RM3e<3?Fjp}!Fw_WCu`)1JaZR=mFcxJ6
zu`y)w1k7>BT;osSsu8H+0%@yam~0_nfy~VlutDao5V*&-ni1sE$vT1xOf^EAj|p<J
zFxqUsAi9?s;+e^TDyf@)OQte1)=y59R;XuPkhqY2M%D_UnYk;RFUsj}VBX-mk@KRQ
z<z;cJi+t7{%s2RirxZ;un^?Ahx=IB*nD2;)O=gx6so%l6BXKAD0ppGJ7d6~2E4p8l
zc0ZwfB_QZ}K-k5AunQ5<7s8`2#3f%0Pri_zb0IhHVtU?%qSA|Lr5D3XF9(!e^eVe3
zU3Q_e<_iOZ1CtZecM#>q^btaRU|{fI@@D$Lz~By{{Fs74a_&sQAi;2^7)KBt%M=F^
z4QGl2@sgNQLA)>s<<6AK^ciGY8c48;5lqRXfy6}9nL0S{OlFi3tKU$(BWPpAMGgDQ
ziVhd09S#_u5jrn+QtU!t$c2EA3*j*r17a@3CtXNQzZjo>F(Cc2XU0Y6jEmA47qauN
z6c%4EEWcP-exb7FLPgC7kX^1IyDAx7LC%4Cz>g^aB<KO5Dj5SnE+}FQ1PSJdKxmmj
zkf3M~$XSBIllRIP8H%1LJSl!K`?6ioMgE{GVG-BEVlRfpUWiM-9F}n<JNJ5a(Z%ed
z3&k~;vuiJg)n4SUo17pkS+BZ*ai#hSt_?;jc{e1k<i99xu}5gX*iNwn!UtFmgdXI&
zZ0UVb-1{P*4>*a;V4UGRlYN2VOr90g(I|t@%FR-8w;36aZ@wTJ%rseFoOAMAC8^1_
z61<x$mCiFl()s2<6>dhxZIfeFwOEobbEj<XR-MG?;>^e>FvIi%1BhP13ZXZILg)if
z{t2l3g@{;)#D&x>D5IeC1B3JAM0GJMkO3bU7<`$6m>_Z=7#PBtVi24Zrc4AUkExjH
nGuYA(UXwSf_eeP~yE1=ZFlH3^z`)?e?9coK#4h4xU|;|M6R3R2

-- 
GitLab