From 34d9ed6ad41df56e49fdd9a6bd11ada93af19eb5 Mon Sep 17 00:00:00 2001 From: Tomas Skrivan Date: Mon, 5 Aug 2019 09:28:13 +0200 Subject: [PATCH] THINK & DRINK - scenes backup --- houdini/hip/examples.hipnc | Bin 1184541 -> 2591297 bytes houdini/include/affine_map.h | 128 ++++++++++++++++ houdini/include/fem.h | 216 +++++++++++++++++++++++++++ houdini/include/houfem.h | 6 + houdini/include/integrator.h | 44 ++++++ houdini/include/simplex.h | 236 ++++++++++++++++++++++++++++++ houdini/include/simplex_gm_rule.h | 30 ++++ houdini/lib/libhoufem.a | Bin 0 -> 18842 bytes houdini/lib/libsimplex.a | Bin 0 -> 18842 bytes 9 files changed, 660 insertions(+) create mode 100644 houdini/include/affine_map.h create mode 100644 houdini/include/fem.h create mode 100644 houdini/include/houfem.h create mode 100644 houdini/include/integrator.h create mode 100644 houdini/include/simplex.h create mode 100644 houdini/include/simplex_gm_rule.h create mode 100644 houdini/lib/libhoufem.a create mode 100644 houdini/lib/libsimplex.a diff --git a/houdini/hip/examples.hipnc b/houdini/hip/examples.hipnc index ad53f926515a8d43ac0584621f9ff3ad399425b5..bbae225525c48c015e26543ba2fba2d4ea23c8fa 100644 GIT binary patch delta 126488 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 z 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

3HHR# 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 delta 21711 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 aTC*`dguL$Em}bc9KQ^XaYi<9S(EkNb57AKo diff --git a/houdini/include/affine_map.h b/houdini/include/affine_map.h new file mode 100644 index 0000000..8e6bb06 --- /dev/null +++ b/houdini/include/affine_map.h @@ -0,0 +1,128 @@ +#pragma once + +#include + +namespace houfem { + +namespace internal { + +template struct EigenVector { + using type = Eigen::Matrix; +}; + +template struct EigenVector { using type = Real; }; + +} // namespace internal + +template +using EigenVector = typename internal::EigenVector::type; + +// ___ _ _ __ __ +// / __|___ _ _ __| |_ __ _ _ _| |_ | \/ |__ _ _ __ +// | (__/ _ \ ' \(_-< _/ _` | ' \ _| | |\/| / _` | '_ \ +// \___\___/_||_/__/\__\__,_|_||_\__| |_| |_\__,_| .__/ +// |_| + +template struct constant_map { + + Target operator()(const Source &) const { return value; } + +public: + Target value; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +// _ _ __ __ +// | | (_)_ _ ___ __ _ _ _ | \/ |__ _ _ __ +// | |__| | ' \/ -_) _` | '_| | |\/| / _` | '_ \ +// |____|_|_||_\___\__,_|_| |_| |_\__,_| .__/ +// |_| + +template +struct linear_map { + + using Matrix = Eigen::Matrix; + using TargetVector = EigenVector; + using SourceVector = EigenVector; + + TargetVector operator()(const SourceVector &x) const { return A * x; } + + linear_map inverse() const { return {A.inverse()}; } + + constant_map derivative() const { return {A}; } + +public: + Matrix A; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +// _ __ __ _ __ __ +// /_\ / _|/ _(_)_ _ ___ | \/ |__ _ _ __ +// / _ \| _| _| | ' \/ -_) | |\/| / _` | '_ \ +// /_/ \_\_| |_| |_|_||_\___| |_| |_\__,_| .__/ +// |_| + +template +struct affine_map { + + using Matrix = Eigen::Matrix; + using TargetVector = EigenVector; + using SourceVector = EigenVector; + + TargetVector operator()(const SourceVector &x) const { return A * x + b; } + + affine_map inverse() const { + Matrix iA = A.inverse(); + TargetVector ib = -iA * b; + return {iA, ib}; + } + + constant_map derivative() { return {A}; } + +public: + Matrix A; + TargetVector b; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +// ___ _ _ _ +// / __|___ _ __ _ __ ___ __(_) |_(_)___ _ _ ___ +// | (__/ _ \ ' \| '_ \/ _ (_-< | _| / _ \ ' \(_-< +// \___\___/_|_|_| .__/\___/__/_|\__|_\___/_||_/__/ +// |_| + +template +affine_map +operator|(affine_map const &f, + affine_map const &g) { + return {f.A * g.A, f.A * g.b + f.b}; +} + +template +affine_map +operator|(linear_map const &f, + affine_map const &g) { + return {f.A * g.A, f.A * g.b}; +} + +template +affine_map +operator|(affine_map const &f, + linear_map const &g) { + return {f.A * g.A, f.b}; +} + +template +linear_map +operator|(linear_map const &f, + linear_map const &g) { + return {f.A * g.A}; +} + +} // namespace simplex diff --git a/houdini/include/fem.h b/houdini/include/fem.h new file mode 100644 index 0000000..a32ff7f --- /dev/null +++ b/houdini/include/fem.h @@ -0,0 +1,216 @@ +#pragma once + +#include +#include +#include + +//#include "../hougen/hougen.h" +#include "simplex.h" + +#include +#include + +namespace houfem { + +EmbeddedSimplex<2, 3> get_triangle(const GA_Detail *geo, + const GA_Index prim_index) { + + const GA_Primitive *prim = geo->getPrimitiveByIndex(prim_index); + + // Load points + Eigen::Matrix3d points; + for (int j = 0; j < 3; j++) { + auto posj = prim->getPos3(j); + for (int i = 0; i < 3; i++) { + points(i, j) = posj[i]; + } + } + + return EmbeddedSimplex<2, 3>(points); +} + +// _____ ___ __ __ __ __ _ _ +// | _ \ \ / / | | \/ |__ _ ______ | \/ |__ _| |_ _ _(_)_ __ +// | _/\ \/\/ /| |__ | |\/| / _` (_-<_-< | |\/| / _` | _| '_| \ \ / +// |_| \_/\_/ |____| |_| |_\__,_/__/__/ |_| |_\__,_|\__|_| |_/_\_\ + +// Standard mass matrix for piece-wise linear basis functions + +Eigen::SparseMatrix mass_matrix_pwl(const GA_Detail *geo) { + + using SpMat = Eigen::SparseMatrix; + using T = Eigen::Triplet; + + const int N = geo->getNumPoints(); + + SpMat M(N, N); + std::vector coefficients; + coefficients.reserve(6 * N); + + Eigen::Matrix unit_mass_matrix = Simplex<2>::unit_mass_matrix(); + + // iterate over primitives + const int nprimitives = geo->getNumPrimitives(); + for (int I = 0; I < nprimitives; I++) { + + const GA_Primitive *prim = geo->getPrimitiveByIndex(I); + + // global indices of primitive points + auto id = std::array{prim->getPointIndex(0), prim->getPointIndex(1), + prim->getPointIndex(2)}; + + const double area = prim->calcArea(); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + coefficients.emplace_back( + T{(int)id[i], (int)id[j], 2 * area * unit_mass_matrix(i, j)}); + } + } + } + + M.setFromTriplets(coefficients.begin(), coefficients.end()); + M.makeCompressed(); + + return M; +} + +// _____ _____ __ __ __ __ _ _ +// | _ \ \ / / __| | \/ |__ _ ______ | \/ |__ _| |_ _ _(_)_ __ +// | _/\ \/\/ / (__ | |\/| / _` (_-<_-< | |\/| / _` | _| '_| \ \ / +// |_| \_/\_/ \___| |_| |_\__,_/__/__/ |_| |_\__,_|\__|_| |_/_\_\ + +// Mass matrix for piece-wise constant matrix, i.e. it is just a diagonal matrix +// with triangle areas on the diagonal + +Eigen::DiagonalMatrix +mass_matrix_pwc(const GA_Detail *geo) { + + const int N = geo->getNumPrimitives(); + + Eigen::VectorXd areas(N); + + for (int I = 0; I < N; I++) { + + const GA_Primitive *prim = geo->getPrimitiveByIndex(I); + + areas(I) = prim->calcArea(); + } + + return areas.asDiagonal(); +} + +// ___ _ _ __ __ __ __ _ _ +// / __| |_(_)/ _|/ _|_ _ ___ ______ | \/ |__ _| |_ _ _(_)_ __ +// \__ \ _| | _| _| ' \/ -_|_-<_-< | |\/| / _` | _| '_| \ \ / +// |___/\__|_|_| |_| |_||_\___/__/__/ |_| |_\__,_|\__|_| |_/_\_\ + +Eigen::SparseMatrix stiffness_matrix(const GA_Detail *geo) { + + using SpMat = Eigen::SparseMatrix; + using T = Eigen::Triplet; + + const int N = geo->getNumPoints(); + + SpMat S(N, N); + std::vector coefficients; + coefficients.reserve(6 * N); + + // iterate over primitives + const int nprimitives = geo->getNumPrimitives(); + for (int I = 0; I < nprimitives; I++) { + + // global indices of primitive points + const GA_Primitive *prim = geo->getPrimitiveByIndex(I); + auto id = std::array{prim->getPointIndex(0), prim->getPointIndex(1), + prim->getPointIndex(2)}; + + // embeded triangle in 3-space + const auto embedded_triangle = get_triangle(geo, I); + const auto &triangle = embedded_triangle.local_simplex; + + auto localS = triangle.stiffness_matrix(); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + coefficients.emplace_back(T{(int)id[i], (int)id[j], localS(i, j)}); + } + } + } + + S.setFromTriplets(coefficients.begin(), coefficients.end()); + S.makeCompressed(); + + return S; +} + +// ___ _ _ _ __ __ _ _ +// / __|_ _ __ _ __| (_)___ _ _| |_ | \/ |__ _| |_ _ _(_)__ ___ ___ +// | (_ | '_/ _` / _` | / -_) ' \ _| | |\/| / _` | _| '_| / _/ -_|_-< +// \___|_| \__,_\__,_|_\___|_||_\__| |_| |_\__,_|\__|_| |_\__\___/__/ + +std::array, 3> +gradient_matrices(const GA_Detail *geo) { + + const int N = geo->getNumPrimitives(); + const int M = geo->getNumPoints(); + + std::array, 3> D; + D[0].resize(N, M); + D[1].resize(N, M); + D[2].resize(N, M); + + D[0].reserve(Eigen::VectorXi::Constant(N, 3)); + D[1].reserve(Eigen::VectorXi::Constant(N, 3)); + D[2].reserve(Eigen::VectorXi::Constant(N, 3)); + + for (int I = 0; I < N; I++) { + + // global indices of primitive points + const GA_Primitive *prim = geo->getPrimitiveByIndex(I); + auto id = std::array{prim->getPointIndex(0), prim->getPointIndex(1), + prim->getPointIndex(2)}; + + // embeded triangle in 3-space + const auto embedded_triangle = get_triangle(geo, I); + const auto &triangle = embedded_triangle.local_simplex; + + for (int j = 0; j < 3; j++) { + + auto phi = triangle.barycentric_coordinate(j) | + embedded_triangle.global_to_local; + auto grad = phi.derivative().value; + + D[0].insert(I, id[j]) = grad(0); + D[1].insert(I, id[j]) = grad(1); + D[2].insert(I, id[j]) = grad(2); + } + } + + return D; +} + +Eigen::SparseMatrix prim_to_point(const GA_Detail *geo) { + + const int N = geo->getNumPoints(); + const int M = geo->getNumPrimitives(); + + Eigen::SparseMatrix A(N, M); + A.reserve(Eigen::VectorXi::Constant(M, 3)); + + const int nprimitives = geo->getNumPrimitives(); + for (int I = 0; I < nprimitives; I++) { + + // global indices of primitive points + const GA_Primitive *prim = geo->getPrimitiveByIndex(I); + auto id = std::array{prim->getPointIndex(0), prim->getPointIndex(1), + prim->getPointIndex(2)}; + + A.insert(id[0], I) = 1.0; + A.insert(id[1], I) = 1.0; + A.insert(id[2], I) = 1.0; + } + + return A; +} +} // namespace houfem diff --git a/houdini/include/houfem.h b/houdini/include/houfem.h new file mode 100644 index 0000000..17ee853 --- /dev/null +++ b/houdini/include/houfem.h @@ -0,0 +1,6 @@ +#pragma once + +#include "affine_map.h" +#include "integrator.h" +#include "simplex.h" +#include "fem.h" diff --git a/houdini/include/integrator.h b/houdini/include/integrator.h new file mode 100644 index 0000000..b133605 --- /dev/null +++ b/houdini/include/integrator.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include "affine_map.h" +#include "simplex_gm_rule.h" + +namespace houfem{ + +template struct Integrator { + using Vector = Eigen::Matrix; + + template double operator()(Fun const &fun) { + double out = 0; + for (int i = 0; i < weights.size(); i++) { + out += weights(i) * fun(integration_nodes.col(i).eval()); + } + return out; + } + + Eigen::Matrix weights; + Eigen::Matrix integration_nodes; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +template +Integrator pushforward(affine_map const &map, + Integrator integrator) { + + auto &weights = integrator.weights; + auto &nodes = integrator.integration_nodes; + + weights *= abs(map.A.determinant()); + + for (int i = 0; i < nodes.cols(); i++) { + nodes.col(i) = map(nodes.col(i)); + } + + return integrator; +} + +} diff --git a/houdini/include/simplex.h b/houdini/include/simplex.h new file mode 100644 index 0000000..95eb314 --- /dev/null +++ b/houdini/include/simplex.h @@ -0,0 +1,236 @@ +#pragma once + +#include +#include + +#include "integrator.h" + +namespace houfem { + +constexpr int factorial(int n) { return n > 0 ? n * factorial(n - 1) : 1; } + +// _ _ _ _ ___ _ _ +// | | | |_ _ (_) |_ / __(_)_ __ _ __| |_____ __ +// | |_| | ' \| | _| \__ \ | ' \| '_ \ / -_) \ / +// \___/|_||_|_|\__| |___/_|_|_|_| .__/_\___/_\_\ +// |_| + +template +Integrator unit_simplex_integrator(const int rule) { + const int N = gm_rule_size(rule, Dim); + + std::vector weights(N); + std::vector nodes(N * Dim); + + // Compute integration rules on an unit simplex + gm_unit_rule_set(rule, Dim, N, &weights[0], &(nodes[0])); + + Integrator out; + + out.weights.resize(N); + out.integration_nodes.resize(Dim, N); + + for (int i = 0; i < N; i++) { + for (int j = 0; j < Dim; j++) { + out.integration_nodes(j, i) = nodes[j + i * Dim]; + } + out.weights(i) = weights[i]; + } + + return out; +} + +// ___ _ _ +// / __(_)_ __ _ __| |_____ __ +// \__ \ | ' \| '_ \ / -_) \ / +// |___/_|_|_|_| .__/_\___/_\\_ +// |_| + +template struct Simplex { +public: + Simplex() {} + + Simplex(const Eigen::Matrix &points) { + + using Matrix = Eigen::Matrix; + Matrix S = Matrix::Zero(); // Input simplex + Matrix U = Matrix::Zero(); // Unit simplex + + S.template block(0, 0) = points; + U.template block(0, 1).setIdentity(); + S.row(Dim).setConstant(1.0); + U.row(Dim).setConstant(1.0); + + Matrix from_unit_simplex_matrix = S * U.inverse(); + Matrix to_unit_simplex_matrix = U * S.inverse(); + + from_unit_simplex.A = + from_unit_simplex_matrix.template block(0, 0); + from_unit_simplex.b = + from_unit_simplex_matrix.template block(0, Dim); + + to_unit_simplex.A = to_unit_simplex_matrix.template block(0, 0); + to_unit_simplex.b = to_unit_simplex_matrix.template block(0, Dim); + } + + static affine_map<1, Dim> unit_barycentric_coordinate(const int i) { + using Vector = Eigen::Matrix; + if (i == 0) { + Vector E = Vector::Constant(-1); + return {E, 1}; + } else { + Vector E = Vector::Zero(); + E(i - 1) = 1; + return {E, 0}; + } + } + + static Eigen::Matrix unit_mass_matrix() { + + Eigen::Matrix M; + + auto integrator = unit_simplex_integrator(1); + + for (int i = 0; i < Dim + 1; i++) { + for (int j = i; j < Dim + 1; j++) { + + auto phi_i = unit_barycentric_coordinate(i); + auto phi_j = unit_barycentric_coordinate(j); + + double value = integrator([&](Eigen::Matrix x) { + return phi_i(x) * phi_j(x); + }); + + if (i == j) { + M(i, j) = value; + } else { + M(i, j) = value; + M(j, i) = value; + } + } + } + + return M; + } + + Eigen::Matrix point(const int i) const { + using Vector = Eigen::Matrix; + + Vector E = Vector::Zero(); + if (i > 0) + E(i - 1) = 1; + + return from_unit_simplex(E); + } + + affine_map<1, Dim> barycentric_coordinate(const int i) const { + return unit_barycentric_coordinate(i) | to_unit_simplex; + } + + Integrator integrator(const int rule) const { + return pushforward(from_unit_simplex, unit_simplex_integrator(rule)); + } + + double volume() const { + return abs(from_unit_simplex.A.determinant()) / factorial(Dim); + } + + std::array angles() const { + if constexpr (Dim != 2) { + std::cout << "Angle computation is supported only in 2D!" << std::endl; + return {}; + } else { + + auto e0 = (point(2) - point(1)).normalized().eval(); + auto e1 = (point(1) - point(0)).normalized().eval(); + auto e2 = (point(2) - point(0)).normalized().eval(); + + return {acos(e1.dot(e2)), acos(e0.dot(-e1)), acos(e2.dot(e0))}; + } + } + + Eigen::Matrix mass_matrix() const { + return factorial(Dim) * volume() * unit_mass_matrix(); + } + + Eigen::Matrix stiffness_matrix() const { + auto integrate = integrator(0); + + auto phi = std::array{barycentric_coordinate(0), barycentric_coordinate(1), + barycentric_coordinate(2)}; + + Eigen::Matrix S; + + for (int i = 0; i < Dim + 1; i++) { + for (int j = i; j < Dim + 1; j++) { + + using Vector = Eigen::Matrix; + const double val = integrate([&](Vector const &x) { + return phi[i].derivative()(x).dot(phi[j].derivative()(x)); + }); + + S(i, j) = val; + if (i != j) + S(j, i) = val; + } + } + return S; + } + +public: + affine_map from_unit_simplex; + affine_map to_unit_simplex; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +// ___ _ _ _ _ ___ _ _ +// | __|_ __ | |__ ___ __| |__| |___ __| | / __(_)_ __ _ __| |_____ __ +// | _|| ' \| '_ \/ -_) _` / _` / -_) _` | \__ \ | ' \| '_ \ / -_) \ / +// |___|_|_|_|_.__/\___\__,_\__,_\___\__,_| |___/_|_|_|_| .__/_\___/_\_\ +// |_| + +template struct EmbeddedSimplex { + + EmbeddedSimplex( + const Eigen::Matrix &points) { + + using Matrix = Eigen::Matrix; + Matrix M = points.template block(0, 1); + M.colwise() -= points.col(0); + + Eigen::JacobiSVD svd(M, Eigen::ComputeFullU | Eigen::ComputeFullV); + + auto U = svd.matrixU().eval(); + Matrix adjV = Matrix::Zero(); + adjV.template block(0, 0) = svd.matrixV().adjoint(); + + Matrix P = U * adjV; + + local_to_global.A = P; + local_to_global.b = points.col(0); + + global_to_local.A = P.transpose(); + global_to_local.b = -P.transpose() * points.col(0); + + // Transform points to local coordinates + Eigen::Matrix + local_points; // Points of a simplex in local coordinates + for (int i = 0; i < SimplexDim + 1; i++) { + local_points.col(i) = global_to_local(points.col(i)); + } + + local_simplex = Simplex{local_points}; + } + +public: + Simplex local_simplex; + affine_map global_to_local; + affine_map local_to_global; + +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +} // namespace houfem diff --git a/houdini/include/simplex_gm_rule.h b/houdini/include/simplex_gm_rule.h new file mode 100644 index 0000000..107d676 --- /dev/null +++ b/houdini/include/simplex_gm_rule.h @@ -0,0 +1,30 @@ +namespace houfem { + +void comp_next(int n, int k, int a[], bool &more, int &h, int &t); +void gm_general_rule_set(int rule, int m, int n, double t[], double w[], + double x[]); +int gm_rule_size(int rule, int dim_num); +void gm_unit_rule_set(int rule, int dim_num, int point_num, double w[], + double x[]); +int i4_choose(int n, int k); +int i4_huge(); +int i4_max(int i1, int i2); +int i4_min(int i1, int i2); +int i4_power(int i, int j); +double *monomial_value(int dim_num, int point_num, int expon[], double x[]); +double r8_factorial(int n); +double r8ge_det(int n, double a_lu[], int pivot[]); +int r8ge_fa(int n, double a[], int pivot[]); +double r8vec_dot_product(int n, double a1[], double a2[]); +double *r8vec_uniform_01_new(int n, int &seed); +double simplex_general_volume(int m, double t[]); +double simplex_unit_monomial_integral(int dim_num, int expon[]); +double simplex_unit_monomial_quadrature(int dim_num, int expon[], int point_num, + double x[], double w[]); +double *simplex_unit_sample(int dim_num, int n, int &seed); +void simplex_unit_to_general(int dim_num, int point_num, double t[], + double ref[], double phy[]); +double simplex_unit_volume(int dim_num); +void timestamp(); + +} // namespace simplex diff --git a/houdini/lib/libhoufem.a b/houdini/lib/libhoufem.a new file mode 100644 index 0000000000000000000000000000000000000000..097283d5f29d7ea19989e1892a49ed06f678aaf8 GIT binary patch literal 18842 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

2ooI{-<$>%1b z7x&3!5E2)WosJ_%EW_y;y$^Q3<^o$;yyW$fs6a(XC$2X^KDKU zlyKrD?vpE|^9a#%_odkXDnaU(um9Z=y=>1)N&AC4<8|AR$J^|Dhj?p?HPw~i*p7?D zdVFD}lx%BnS4!|dHK0J`z7pIN%0=8HPP8dWG&ePVBi8hwjN!7PEuLuQ5ZzJQS5^~j zqV2dnluKZV|3PDCtQkTyx5Q&5tJiM$3cK^*Okz7C4Q+L}toYYS97i;@#FZ{b`FWQMR#VRxDzhaq9aflO={%Ow<{R{o?05((q9{z{h65d{9ne!h-#Z3JV z&d~o2pv~<6Az*Zb$(+9`-oKy+2}_yfT|j5*e=Fah#5igEWQwA_z`qNO#?Oxfc(c=1 z-hY(wX+yhb!y4*lI rZf6tEO!;S$orw3|W;Yq-ffmJQq|40y$tGv&e>Zm=6&VXNv;Y4M>@MT1 literal 0 HcmV?d00001 diff --git a/houdini/lib/libsimplex.a b/houdini/lib/libsimplex.a new file mode 100644 index 0000000000000000000000000000000000000000..097283d5f29d7ea19989e1892a49ed06f678aaf8 GIT binary patch literal 18842 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

2ooI{-<$>%1b z7x&3!5E2)WosJ_%EW_y;y$^Q3<^o$;yyW$fs6a(XC$2X^KDKU zlyKrD?vpE|^9a#%_odkXDnaU(um9Z=y=>1)N&AC4<8|AR$J^|Dhj?p?HPw~i*p7?D zdVFD}lx%BnS4!|dHK0J`z7pIN%0=8HPP8dWG&ePVBi8hwjN!7PEuLuQ5ZzJQS5^~j zqV2dnluKZV|3PDCtQkTyx5Q&5tJiM$3cK^*Okz7C4Q+L}toYYS97i;@#FZ{b`FWQMR#VRxDzhaq9aflO={%Ow<{R{o?05((q9{z{h65d{9ne!h-#Z3JV z&d~o2pv~<6Az*Zb$(+9`-oKy+2}_yfT|j5*e=Fah#5igEWQwA_z`qNO#?Oxfc(c=1 z-hY(wX+yhb!y4*lI rZf6tEO!;S$orw3|W;Yq-ffmJQq|40y$tGv&e>Zm=6&VXNv;Y4M>@MT1 literal 0 HcmV?d00001