From cd653dda853802fcad0ed47237d8d674bf302c1a Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Wed, 4 Feb 2026 09:05:51 +0100 Subject: [PATCH 01/52] operators: new namespace with differential operators After this revision, it is now possible to implement 'geomertry-aware' differential operators. Before this change, since {differential.h} was within {fields}, there would be a cyclic dependency between fields->geometry->fields. --- .cmake/mito_benchmarks_mito_lib.cmake | 4 +-- .cmake/mito_tests_mito_lib.cmake | 10 ++++--- .../{fields => operators}/laplacian.cc | 8 +++--- lib/mito/fem/elements/externals.h | 3 +++ lib/mito/fem/elements/seg1/ShapeSegmentP1.h | 2 +- lib/mito/fem/elements/tri1/ShapeTriangleP1.h | 2 +- lib/mito/fem/elements/tri2/ShapeTriangleP2.h | 4 +-- lib/mito/fem/norms.h | 4 +-- lib/mito/fields/public.h | 2 -- lib/mito/operators.h | 14 ++++++++++ lib/mito/operators/api.h | 15 +++++++++++ lib/mito/{fields => operators}/differential.h | 10 +++---- lib/mito/operators/externals.h | 16 ++++++++++++ lib/mito/operators/factories.h | 15 +++++++++++ lib/mito/operators/forward.h | 16 ++++++++++++ lib/mito/operators/public.h | 26 +++++++++++++++++++ tests/mito.lib/fem/localize_field.cc | 2 +- .../integration/divergence_theorem.cc | 2 +- .../calculus_identities.cc | 6 ++--- .../calculus_scalar_field.cc | 6 ++--- .../calculus_vector_field.cc | 6 ++--- .../gradient_non_square.cc | 4 +-- 22 files changed, 141 insertions(+), 36 deletions(-) rename benchmarks/mito.lib/{fields => operators}/laplacian.cc (91%) create mode 100644 lib/mito/operators.h create mode 100644 lib/mito/operators/api.h rename lib/mito/{fields => operators}/differential.h (95%) create mode 100644 lib/mito/operators/externals.h create mode 100644 lib/mito/operators/factories.h create mode 100644 lib/mito/operators/forward.h create mode 100644 lib/mito/operators/public.h rename tests/mito.lib/{fields => operators}/calculus_identities.cc (86%) rename tests/mito.lib/{fields => operators}/calculus_scalar_field.cc (89%) rename tests/mito.lib/{fields => operators}/calculus_vector_field.cc (91%) rename tests/mito.lib/{fields => operators}/gradient_non_square.cc (95%) diff --git a/.cmake/mito_benchmarks_mito_lib.cmake b/.cmake/mito_benchmarks_mito_lib.cmake index dd48e04c..19c3b988 100644 --- a/.cmake/mito_benchmarks_mito_lib.cmake +++ b/.cmake/mito_benchmarks_mito_lib.cmake @@ -17,8 +17,8 @@ mito_benchmark_driver(benchmarks/mito.lib/tensor/wedge.cc) # integration mito_benchmark_driver(benchmarks/mito.lib/integration/integration.cc) -# fields -mito_benchmark_driver(benchmarks/mito.lib/fields/laplacian.cc) +# operators +mito_benchmark_driver(benchmarks/mito.lib/operators/laplacian.cc) if(WITH_PETSC) # poisson boundary value problem diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index c4d6f232..572f1c14 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -96,10 +96,6 @@ mito_test_driver(tests/mito.lib/tensor/tensor_product_forms.cc) # fields mito_test_driver(tests/mito.lib/fields/fields.cc) mito_test_driver(tests/mito.lib/fields/fields_traits.cc) -mito_test_driver(tests/mito.lib/fields/calculus_identities.cc) -mito_test_driver(tests/mito.lib/fields/calculus_scalar_field.cc) -mito_test_driver(tests/mito.lib/fields/calculus_vector_field.cc) -mito_test_driver(tests/mito.lib/fields/gradient_non_square.cc) mito_test_driver(tests/mito.lib/fields/polar_metric_field.cc) mito_test_driver(tests/mito.lib/fields/spherical_metric_field.cc) @@ -151,6 +147,12 @@ if(WITH_METIS) endif() endif() +# operators +mito_test_driver(tests/mito.lib/operators/calculus_identities.cc) +mito_test_driver(tests/mito.lib/operators/calculus_scalar_field.cc) +mito_test_driver(tests/mito.lib/operators/calculus_vector_field.cc) +mito_test_driver(tests/mito.lib/operators/gradient_non_square.cc) + # topology mito_test_driver(tests/mito.lib/topology/cell_edges.cc) mito_test_driver(tests/mito.lib/topology/erase_element_check_vertices.cc) diff --git a/benchmarks/mito.lib/fields/laplacian.cc b/benchmarks/mito.lib/operators/laplacian.cc similarity index 91% rename from benchmarks/mito.lib/fields/laplacian.cc rename to benchmarks/mito.lib/operators/laplacian.cc index 65c6d3b2..aed401d6 100644 --- a/benchmarks/mito.lib/fields/laplacian.cc +++ b/benchmarks/mito.lib/operators/laplacian.cc @@ -6,8 +6,8 @@ // get the benchmark library #include -// get the mito materials -#include +// get the mito differential operators +#include // the type of coordinates @@ -50,10 +50,10 @@ laplacian_mito(const coordinates_t & x) constexpr auto f = mito::functions::pow<4>(x0 * x1); // the gradient of {f} - constexpr auto gradient = mito::fields::gradient(f); + constexpr auto gradient = mito::operators::gradient(f); // the laplacian (divergence of gradient) - constexpr auto laplacian = mito::fields::divergence(gradient); + constexpr auto laplacian = mito::operators::divergence(gradient); // evaluate the laplacian at {x} auto result = laplacian(x); diff --git a/lib/mito/fem/elements/externals.h b/lib/mito/fem/elements/externals.h index a09caf75..e9eabdd5 100644 --- a/lib/mito/fem/elements/externals.h +++ b/lib/mito/fem/elements/externals.h @@ -6,5 +6,8 @@ // code guard #pragma once +// support +#include "../../operators.h" + // end of file diff --git a/lib/mito/fem/elements/seg1/ShapeSegmentP1.h b/lib/mito/fem/elements/seg1/ShapeSegmentP1.h index 978203e2..67905bdf 100644 --- a/lib/mito/fem/elements/seg1/ShapeSegmentP1.h +++ b/lib/mito/fem/elements/seg1/ShapeSegmentP1.h @@ -30,7 +30,7 @@ namespace mito::fem { // the gradients of the shape functions static constexpr auto dphi = - std::make_tuple(fields::gradient(phi_0), fields::gradient(phi_1)); + std::make_tuple(operators::gradient(phi_0), operators::gradient(phi_1)); public: // get the a-th shape function as a function of parametric coordinates diff --git a/lib/mito/fem/elements/tri1/ShapeTriangleP1.h b/lib/mito/fem/elements/tri1/ShapeTriangleP1.h index aaf64430..e143aac8 100644 --- a/lib/mito/fem/elements/tri1/ShapeTriangleP1.h +++ b/lib/mito/fem/elements/tri1/ShapeTriangleP1.h @@ -33,7 +33,7 @@ namespace mito::fem { // the gradients of the shape functions static constexpr auto dphi = std::make_tuple( - fields::gradient(phi_0), fields::gradient(phi_1), fields::gradient(phi_2)); + operators::gradient(phi_0), operators::gradient(phi_1), operators::gradient(phi_2)); public: // get the a-th shape function as a function of parametric coordinates diff --git a/lib/mito/fem/elements/tri2/ShapeTriangleP2.h b/lib/mito/fem/elements/tri2/ShapeTriangleP2.h index b51d43d0..f77df475 100644 --- a/lib/mito/fem/elements/tri2/ShapeTriangleP2.h +++ b/lib/mito/fem/elements/tri2/ShapeTriangleP2.h @@ -36,8 +36,8 @@ namespace mito::fem { // the gradients of the shape functions static constexpr auto dphi = std::make_tuple( - fields::gradient(phi_0), fields::gradient(phi_1), fields::gradient(phi_2), - fields::gradient(phi_3), fields::gradient(phi_4), fields::gradient(phi_5)); + operators::gradient(phi_0), operators::gradient(phi_1), operators::gradient(phi_2), + operators::gradient(phi_3), operators::gradient(phi_4), operators::gradient(phi_5)); public: // get the a-th shape function as a function of parametric coordinates diff --git a/lib/mito/fem/norms.h b/lib/mito/fem/norms.h index 79ea71a1..2d4ad2d1 100644 --- a/lib/mito/fem/norms.h +++ b/lib/mito/fem/norms.h @@ -59,9 +59,9 @@ namespace mito::fem { // localize {u2} on this element auto u2_local = localize(u2, element); // assemble the gradient of the solution field on this element - auto u1_local_gradient = fields::gradient(u1_local); + auto u1_local_gradient = operators::gradient(u1_local); // localize the gradient of the exact solution on this element - auto u2_local_gradient = fields::gradient(u2_local); + auto u2_local_gradient = operators::gradient(u2_local); // compute the elementary contributions to the H1 norm norm += blocks::l2_norm_block(u1_local - u2_local) .compute(element) diff --git a/lib/mito/fields/public.h b/lib/mito/fields/public.h index d5e6891d..b8592ad3 100644 --- a/lib/mito/fields/public.h +++ b/lib/mito/fields/public.h @@ -21,8 +21,6 @@ // algebraic operations on fields #include "fields_algebra.h" -// differential calculus on fields -#include "differential.h" // end of file diff --git a/lib/mito/operators.h b/lib/mito/operators.h new file mode 100644 index 00000000..a37d166d --- /dev/null +++ b/lib/mito/operators.h @@ -0,0 +1,14 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +// publish the interface +#include "operators/public.h" + + +// end of file diff --git a/lib/mito/operators/api.h b/lib/mito/operators/api.h new file mode 100644 index 00000000..a28b756e --- /dev/null +++ b/lib/mito/operators/api.h @@ -0,0 +1,15 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::operators { + +} + + +// end of file diff --git a/lib/mito/fields/differential.h b/lib/mito/operators/differential.h similarity index 95% rename from lib/mito/fields/differential.h rename to lib/mito/operators/differential.h index 4161ddf2..063957bf 100644 --- a/lib/mito/fields/differential.h +++ b/lib/mito/operators/differential.h @@ -8,10 +8,10 @@ // Differential operators on Fields -namespace mito::fields { +namespace mito::operators { // function to compute the gradient of a scalar field - template + template constexpr auto gradient(const F & field) { // the type of coordinate @@ -32,7 +32,7 @@ namespace mito::fields { } // function to compute the gradient of a vector field - template + template constexpr auto gradient(const F & field) { // the type of coordinate @@ -65,7 +65,7 @@ namespace mito::fields { } // function to compute the divergence of a vector field - template + template constexpr auto divergence(const F & field) { // the type of coordinate @@ -87,7 +87,7 @@ namespace mito::fields { } // function to compute the divergence of a tensor field - template + template constexpr auto divergence(const F & field) { // the type of coordinate diff --git a/lib/mito/operators/externals.h b/lib/mito/operators/externals.h new file mode 100644 index 00000000..b715a10f --- /dev/null +++ b/lib/mito/operators/externals.h @@ -0,0 +1,16 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +// externals + +// support +#include "../geometry.h" + + +// end of file diff --git a/lib/mito/operators/factories.h b/lib/mito/operators/factories.h new file mode 100644 index 00000000..a28b756e --- /dev/null +++ b/lib/mito/operators/factories.h @@ -0,0 +1,15 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::operators { + +} + + +// end of file diff --git a/lib/mito/operators/forward.h b/lib/mito/operators/forward.h new file mode 100644 index 00000000..93f74479 --- /dev/null +++ b/lib/mito/operators/forward.h @@ -0,0 +1,16 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::operators { + + +} + + +// end of file diff --git a/lib/mito/operators/public.h b/lib/mito/operators/public.h new file mode 100644 index 00000000..6d15c6db --- /dev/null +++ b/lib/mito/operators/public.h @@ -0,0 +1,26 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +// external packages +#include "externals.h" + +// get the forward declarations +#include "forward.h" + +// published type factories; this is the file you are looking for... +#include "api.h" + +// factories implementation +#include "factories.h" + +// differential calculus on fields +#include "differential.h" + + +// end of file diff --git a/tests/mito.lib/fem/localize_field.cc b/tests/mito.lib/fem/localize_field.cc index e1321821..956d6581 100644 --- a/tests/mito.lib/fem/localize_field.cc +++ b/tests/mito.lib/fem/localize_field.cc @@ -49,7 +49,7 @@ TEST(Fem, LocalizeField) EXPECT_DOUBLE_EQ(value, (x * y)({ 1.0 / 3.0, 1.0 / 3.0 })); // compute the gradient of the localized field with respect to the barycentric coordinates - auto gradient = mito::fields::gradient(localized_field); + auto gradient = mito::operators::gradient(localized_field); // evaluate the localized field gradient at the center of the triangle auto value_gradient = gradient({ 1.0 / 3.0, 1.0 / 3.0 }); diff --git a/tests/mito.lib/integration/divergence_theorem.cc b/tests/mito.lib/integration/divergence_theorem.cc index b9de4ead..1a1f60bd 100644 --- a/tests/mito.lib/integration/divergence_theorem.cc +++ b/tests/mito.lib/integration/divergence_theorem.cc @@ -32,7 +32,7 @@ TEST(DivergenceTheorem, Mesh2D) constexpr auto f = x0 * x1 * e0 + x0 * x0 * e1; // build a scalar field with divergence of field - constexpr auto div = mito::fields::divergence(f); + constexpr auto div = mito::operators::divergence(f); /** * Mesh with four cells: diff --git a/tests/mito.lib/fields/calculus_identities.cc b/tests/mito.lib/operators/calculus_identities.cc similarity index 86% rename from tests/mito.lib/fields/calculus_identities.cc rename to tests/mito.lib/operators/calculus_identities.cc index 60f92ff5..27b90f08 100644 --- a/tests/mito.lib/fields/calculus_identities.cc +++ b/tests/mito.lib/operators/calculus_identities.cc @@ -4,7 +4,7 @@ // #include -#include +#include // the type of coordinates @@ -43,10 +43,10 @@ TEST(Identities, DivGrad) // the divergence of the gradient transposed of {f} constexpr auto div_grad_T = - mito::fields::divergence(mito::functions::transpose(mito::fields::gradient(f))); + mito::operators::divergence(mito::functions::transpose(mito::operators::gradient(f))); // the gradient of the divergence of {f} - constexpr auto grad_div = mito::fields::gradient(mito::fields::divergence(f)); + constexpr auto grad_div = mito::operators::gradient(mito::operators::divergence(f)); // check result static_assert(div_grad_T(x) == grad_div(x)); diff --git a/tests/mito.lib/fields/calculus_scalar_field.cc b/tests/mito.lib/operators/calculus_scalar_field.cc similarity index 89% rename from tests/mito.lib/fields/calculus_scalar_field.cc rename to tests/mito.lib/operators/calculus_scalar_field.cc index 63656e72..ba8ff9af 100644 --- a/tests/mito.lib/fields/calculus_scalar_field.cc +++ b/tests/mito.lib/operators/calculus_scalar_field.cc @@ -4,7 +4,7 @@ // #include -#include +#include // the type of coordinates @@ -34,7 +34,7 @@ TEST(Laplacian, ScalarFields) constexpr auto f = sin(x0 * x1); // the gradient of {f} - constexpr auto gradient = mito::fields::gradient(f); + constexpr auto gradient = mito::operators::gradient(f); // a point in space constexpr auto x = mito::geometry::coordinates({ pi_sixth, 1.0 }); @@ -43,7 +43,7 @@ TEST(Laplacian, ScalarFields) static_assert(gradient(x) == (cos(x0 * x1) * x1 * e_0 + cos(x0 * x1) * x0 * e_1)(x)); // the laplacian (divergence of gradient) - constexpr auto laplacian = mito::fields::divergence(gradient); + constexpr auto laplacian = mito::operators::divergence(gradient); // check result static_assert(laplacian(x) == (-sin(x0 * x1) * x1 * x1 - sin(x0 * x1) * x0 * x0)(x)); diff --git a/tests/mito.lib/fields/calculus_vector_field.cc b/tests/mito.lib/operators/calculus_vector_field.cc similarity index 91% rename from tests/mito.lib/fields/calculus_vector_field.cc rename to tests/mito.lib/operators/calculus_vector_field.cc index 03020c49..9e873f63 100644 --- a/tests/mito.lib/fields/calculus_vector_field.cc +++ b/tests/mito.lib/operators/calculus_vector_field.cc @@ -4,7 +4,7 @@ // #include -#include +#include // the type of coordinates @@ -48,7 +48,7 @@ TEST(Laplacian, VectorFields) constexpr auto x = mito::geometry::coordinates({ pi_sixth, pi_fourth }); // the gradient of {g} - constexpr auto gradient = mito::fields::gradient(g); + constexpr auto gradient = mito::operators::gradient(g); // check result static_assert( @@ -57,7 +57,7 @@ TEST(Laplacian, VectorFields) - sin(x0 * x1) * x0 * e_11)(x)); // the laplacian (divergence of gradient) - constexpr auto laplacian = mito::fields::divergence(gradient); + constexpr auto laplacian = mito::operators::divergence(gradient); // check result static_assert(laplacian(x) == (-(x0 * x0 + x1 * x1) * g)(x)); diff --git a/tests/mito.lib/fields/gradient_non_square.cc b/tests/mito.lib/operators/gradient_non_square.cc similarity index 95% rename from tests/mito.lib/fields/gradient_non_square.cc rename to tests/mito.lib/operators/gradient_non_square.cc index 94c6a042..4645bbb4 100644 --- a/tests/mito.lib/fields/gradient_non_square.cc +++ b/tests/mito.lib/operators/gradient_non_square.cc @@ -4,7 +4,7 @@ // #include -#include +#include // the type of coordinates @@ -53,7 +53,7 @@ TEST(Gradient, NonSquare) constexpr auto x = mito::geometry::coordinates({ pi_sixth, pi_fourth, 1.0 }); // the gradient of {f} - constexpr auto gradient = mito::fields::gradient(f); + constexpr auto gradient = mito::operators::gradient(f); // create a channel journal::info_t channel("tests.gradient_non_square"); From 8aca8435ec8d9975a5214137cfd359f286d52e3d Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Wed, 4 Feb 2026 09:12:03 +0100 Subject: [PATCH 02/52] utilities: add {unordered_map} stl header --- lib/mito/utilities/externals.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/mito/utilities/externals.h b/lib/mito/utilities/externals.h index 53b64ecb..970be342 100644 --- a/lib/mito/utilities/externals.h +++ b/lib/mito/utilities/externals.h @@ -18,6 +18,7 @@ #include #include #include +#include // support #include "../journal.h" From f7d92942ec5773c2c90df5795bb1637da2beab0c Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Sun, 22 Mar 2026 11:05:06 +0100 Subject: [PATCH 03/52] geometry: rename (euclidean) metric into {euclidean_metric} throughout --- lib/mito/geometry/cartesian/api.h | 5 +++-- lib/mito/geometry/cartesian/metric.h | 4 ++-- lib/mito/geometry/metric.h | 4 ++-- lib/mito/geometry/metric_space.h | 2 +- lib/mito/geometry/polar/api.h | 4 ++-- lib/mito/geometry/polar/metric.h | 4 ++-- lib/mito/geometry/spherical/api.h | 4 ++-- lib/mito/geometry/spherical/metric.h | 4 ++-- tests/mito.lib/geometry/metric.cc | 12 ++++++------ 9 files changed, 22 insertions(+), 21 deletions(-) diff --git a/lib/mito/geometry/cartesian/api.h b/lib/mito/geometry/cartesian/api.h index 25e4626b..c443956a 100644 --- a/lib/mito/geometry/cartesian/api.h +++ b/lib/mito/geometry/cartesian/api.h @@ -13,9 +13,10 @@ namespace mito::geometry::cartesian { template using coordinates_t = geometry::coordinates_t; - // the metric tensor field + // the Euclidean metric tensor field template - constexpr auto metric = geometry::metric>::field(); + constexpr auto euclidean_metric = + geometry::euclidean_metric>::field(); // factory for cartesian coordinates template diff --git a/lib/mito/geometry/cartesian/metric.h b/lib/mito/geometry/cartesian/metric.h index 15cc46e9..015b9bad 100644 --- a/lib/mito/geometry/cartesian/metric.h +++ b/lib/mito/geometry/cartesian/metric.h @@ -9,9 +9,9 @@ namespace mito::geometry { - // specialization for the Euclidean metric + // specialization for the Euclidean metric in cartesian coordinates template - struct metric> { + struct euclidean_metric> { static constexpr auto field() { // return the identity field diff --git a/lib/mito/geometry/metric.h b/lib/mito/geometry/metric.h index 78d51c24..d6499da7 100644 --- a/lib/mito/geometry/metric.h +++ b/lib/mito/geometry/metric.h @@ -9,9 +9,9 @@ namespace mito::geometry { - // the metric tensor field in {coordsT} coordinates + // the Euclidean metric tensor field in {coordsT} coordinates template - struct metric {}; + struct euclidean_metric {}; } diff --git a/lib/mito/geometry/metric_space.h b/lib/mito/geometry/metric_space.h index e6e53432..9a08ebfb 100644 --- a/lib/mito/geometry/metric_space.h +++ b/lib/mito/geometry/metric_space.h @@ -33,7 +33,7 @@ namespace mito::geometry { static constexpr auto e = basis::template e(); // the metric field in coordinates {coordinates_type} - static constexpr auto g = metric::field(); + static constexpr auto g = euclidean_metric::field(); // the inverse metric field in coordinates {coordinates_type} static constexpr auto g_inv = functions::inverse(g); diff --git a/lib/mito/geometry/polar/api.h b/lib/mito/geometry/polar/api.h index da879ae1..3000d8ba 100644 --- a/lib/mito/geometry/polar/api.h +++ b/lib/mito/geometry/polar/api.h @@ -13,8 +13,8 @@ namespace mito::geometry::polar { template using coordinates_t = geometry::coordinates_t; - // the metric tensor field - constexpr auto metric = geometry::metric::field(); + // the Euclidean metric tensor field + constexpr auto euclidean_metric = geometry::euclidean_metric::field(); // factory for polar coordinates constexpr auto coordinates = &geometry::coordinates; diff --git a/lib/mito/geometry/polar/metric.h b/lib/mito/geometry/polar/metric.h index 84290211..335df53f 100644 --- a/lib/mito/geometry/polar/metric.h +++ b/lib/mito/geometry/polar/metric.h @@ -9,9 +9,9 @@ namespace mito::geometry { - // specialization for the polar metric in 2D + // specialization for the Euclidean metric in polar coordinates template <> - struct metric { + struct euclidean_metric { static constexpr auto field() { // the function extracting the x_0 component of a 2D vector diff --git a/lib/mito/geometry/spherical/api.h b/lib/mito/geometry/spherical/api.h index cd405497..88c704a4 100644 --- a/lib/mito/geometry/spherical/api.h +++ b/lib/mito/geometry/spherical/api.h @@ -13,8 +13,8 @@ namespace mito::geometry::spherical { template using coordinates_t = geometry::coordinates_t; - // the metric tensor field - constexpr auto metric = geometry::metric::field(); + // the Euclidean metric tensor field + constexpr auto euclidean_metric = geometry::euclidean_metric::field(); // factory for spherical coordinates constexpr auto coordinates = &geometry::coordinates; diff --git a/lib/mito/geometry/spherical/metric.h b/lib/mito/geometry/spherical/metric.h index f548b489..a50a4ae6 100644 --- a/lib/mito/geometry/spherical/metric.h +++ b/lib/mito/geometry/spherical/metric.h @@ -9,9 +9,9 @@ namespace mito::geometry { - // specialization for the spherical metric in 3D + // specialization for the Euclidean metric in spherical coordinates template <> - struct metric { + struct euclidean_metric { static constexpr auto field() { // the function extracting the x_0 component of a 3D vector diff --git a/tests/mito.lib/geometry/metric.cc b/tests/mito.lib/geometry/metric.cc index 572ed73f..f63159ff 100644 --- a/tests/mito.lib/geometry/metric.cc +++ b/tests/mito.lib/geometry/metric.cc @@ -12,8 +12,8 @@ TEST(Metric, Cartesian) // a point in space constexpr auto point = mito::geometry::cartesian::coordinates<2>({ 2.0, 1.0 }); - // the Euclidean metric - constexpr auto euclidean_metric = mito::geometry::cartesian::metric<2>; + // the Euclidean metric in cartesian coordinates + constexpr auto euclidean_metric = mito::geometry::cartesian::euclidean_metric<2>; // check that the metric field at a point is the identity static_assert(euclidean_metric(point) == mito::tensor::diagonal_matrix_t<2>({ 1.0, 1.0 })); @@ -27,8 +27,8 @@ TEST(Metric, Polar) // a point in space constexpr auto point = mito::geometry::polar::coordinates({ r, 3.0 }); - // the polar metric - constexpr auto polar_metric = mito::geometry::polar::metric; + // the Euclidean metric in polar coordinates + constexpr auto polar_metric = mito::geometry::polar::euclidean_metric; // check that the metric field at a point is e_rr + r^2 e_tt static_assert(polar_metric(point) == mito::tensor::diagonal_matrix_t<2>({ 1.0, r * r })); @@ -44,8 +44,8 @@ TEST(Metric, Spherical) // a point in space constexpr auto point = mito::geometry::spherical::coordinates({ r, theta, 3.0 }); - // the spherical metric - constexpr auto spherical_metric = mito::geometry::spherical::metric; + // the Euclidean metric in spherical coordinates + constexpr auto spherical_metric = mito::geometry::spherical::euclidean_metric; // check that the metric field at a point is e_rr + r^2 e_tt + r^2 * sin^2(t) * e_pp static_assert( From 295e58c55ac2c001cfe826ff8b1c08fefea1436f Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Sun, 22 Mar 2026 11:16:32 +0100 Subject: [PATCH 04/52] geometry: cleanup redundancy in {coordinates_t} definition in api --- lib/mito/geometry/cartesian/api.h | 2 +- lib/mito/geometry/polar/api.h | 5 ++--- lib/mito/geometry/spherical/api.h | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/mito/geometry/cartesian/api.h b/lib/mito/geometry/cartesian/api.h index c443956a..5dd64efd 100644 --- a/lib/mito/geometry/cartesian/api.h +++ b/lib/mito/geometry/cartesian/api.h @@ -11,7 +11,7 @@ namespace mito::geometry::cartesian { // the type of cartesian coordinates in {D} dimensions template - using coordinates_t = geometry::coordinates_t; + using coordinates_t = cartesian_coordinates_t; // the Euclidean metric tensor field template diff --git a/lib/mito/geometry/polar/api.h b/lib/mito/geometry/polar/api.h index 3000d8ba..ba022b23 100644 --- a/lib/mito/geometry/polar/api.h +++ b/lib/mito/geometry/polar/api.h @@ -9,9 +9,8 @@ namespace mito::geometry::polar { - // the type of cartesian coordinates in {D} dimensions - template - using coordinates_t = geometry::coordinates_t; + // polar coordinates + using coordinates_t = polar_coordinates_t; // the Euclidean metric tensor field constexpr auto euclidean_metric = geometry::euclidean_metric::field(); diff --git a/lib/mito/geometry/spherical/api.h b/lib/mito/geometry/spherical/api.h index 88c704a4..156945c6 100644 --- a/lib/mito/geometry/spherical/api.h +++ b/lib/mito/geometry/spherical/api.h @@ -9,9 +9,8 @@ namespace mito::geometry::spherical { - // the type of cartesian coordinates in {D} dimensions - template - using coordinates_t = geometry::coordinates_t; + // spherical coordinates + using coordinates_t = spherical_coordinates_t; // the Euclidean metric tensor field constexpr auto euclidean_metric = geometry::euclidean_metric::field(); From 5ba5feec13da55dd6618714bc751ddf778db5157 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Sun, 22 Mar 2026 11:34:31 +0100 Subject: [PATCH 05/52] geometry: add concept of metric being compatible with a type of coordinates --- lib/mito/geometry/forward.h | 7 +++++++ tests/mito.lib/geometry/metric.cc | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/mito/geometry/forward.h b/lib/mito/geometry/forward.h index 67dee48e..f7d402c2 100644 --- a/lib/mito/geometry/forward.h +++ b/lib/mito/geometry/forward.h @@ -69,6 +69,13 @@ namespace mito::geometry { [](const PointCloud &) { }(c); }; + + // concept of a metric compatible with a given coordinate system + template + concept compatible_metric_c = + coordinates_c && requires(const metricT & g, const coordsT & x) { + { g(x) }; + }; } diff --git a/tests/mito.lib/geometry/metric.cc b/tests/mito.lib/geometry/metric.cc index f63159ff..37d6ced9 100644 --- a/tests/mito.lib/geometry/metric.cc +++ b/tests/mito.lib/geometry/metric.cc @@ -15,6 +15,11 @@ TEST(Metric, Cartesian) // the Euclidean metric in cartesian coordinates constexpr auto euclidean_metric = mito::geometry::cartesian::euclidean_metric<2>; + // check that the metric is compatible with the type of coordinates + using coordinates_type = mito::geometry::cartesian::coordinates_t<2>; + static_assert( + mito::geometry::compatible_metric_c); + // check that the metric field at a point is the identity static_assert(euclidean_metric(point) == mito::tensor::diagonal_matrix_t<2>({ 1.0, 1.0 })); } @@ -30,6 +35,10 @@ TEST(Metric, Polar) // the Euclidean metric in polar coordinates constexpr auto polar_metric = mito::geometry::polar::euclidean_metric; + // check that the metric is compatible with the type of coordinates + using coordinates_type = mito::geometry::polar::coordinates_t; + static_assert(mito::geometry::compatible_metric_c); + // check that the metric field at a point is e_rr + r^2 e_tt static_assert(polar_metric(point) == mito::tensor::diagonal_matrix_t<2>({ 1.0, r * r })); } @@ -47,6 +56,11 @@ TEST(Metric, Spherical) // the Euclidean metric in spherical coordinates constexpr auto spherical_metric = mito::geometry::spherical::euclidean_metric; + // check that the metric is compatible with the type of coordinates + using coordinates_type = mito::geometry::spherical::coordinates_t; + static_assert( + mito::geometry::compatible_metric_c); + // check that the metric field at a point is e_rr + r^2 e_tt + r^2 * sin^2(t) * e_pp static_assert( spherical_metric(point) From 6b02af034d8a0b463890e4968788aa29099aa399 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 27 Apr 2026 19:35:35 +0200 Subject: [PATCH 06/52] fem: remove unused method {parametrization} of {IsoparametricSegmentP1} --- lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h index eee35058..9893b7fc 100644 --- a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h +++ b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h @@ -64,17 +64,6 @@ namespace mito::fem { return _connectivity; } - // get the isoparametric mapping from parametric coordinates to physical coordinates - constexpr auto parametrization() const - { - // get the shape functions - constexpr auto phi_0 = shape_functions.shape<0>(); - constexpr auto phi_1 = shape_functions.shape<1>(); - - // return the isoparametric mapping from parametric to physical coordinates - return mito::functions::linear_combination(std::array{ _x0, _x1 }, phi_0, phi_1); - } - // get the shape function associated with local node {a} template requires(a >= 0 && a < n_nodes) From f045343e01e93d2c7dd99a47182c14a455d6777b Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 27 Apr 2026 20:00:52 +0200 Subject: [PATCH 07/52] manifolds: remove unused method {coordinates} of {Manifold} class --- lib/mito/manifolds/Manifold.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/mito/manifolds/Manifold.h b/lib/mito/manifolds/Manifold.h index 55fb6bee..3fb1b0ae 100644 --- a/lib/mito/manifolds/Manifold.h +++ b/lib/mito/manifolds/Manifold.h @@ -77,12 +77,6 @@ namespace mito::manifolds { constexpr auto nElements() const noexcept -> int { return std::size(_mesh.cells()); } - constexpr auto coordinates(const node_type & v) const -> const coordinates_type & - { - // get the coordinates of the point attached to vertex {v} - return _coordinate_system.coordinates(v->point()); - } - constexpr auto print() const -> void { // make a channel From e75d529a53dbfb030d953c3fcaf7defdcd3736f6 Mon Sep 17 00:00:00 2001 From: Pawel024 Date: Tue, 31 Mar 2026 17:28:41 +0200 Subject: [PATCH 08/52] coordinates: publish the size of the underlying array in Coordinates.h --- lib/mito/coordinates/Coordinates.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/mito/coordinates/Coordinates.h b/lib/mito/coordinates/Coordinates.h index 73f7d8b4..c41607a2 100644 --- a/lib/mito/coordinates/Coordinates.h +++ b/lib/mito/coordinates/Coordinates.h @@ -38,6 +38,8 @@ namespace mito::geometry { using coordinates_type = Coordinates; // publish the dimension of the physical space static constexpr int dim = D; + // publish the size of the underlying array + static constexpr int size = array_t::size; public: // default constructor From 213785e5ac96eb2a1b9b4b2e91eb9cd67694ce1b Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Fri, 1 May 2026 21:22:42 +0200 Subject: [PATCH 09/52] tests/fem: adjust check of gradient vector in test gradient consistency Vectors of one component no longer cast to their atomic type after rev. 7736bfe of {pyre/tensor}. --- tests/mito.lib/fem/isoparametric_segment.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/mito.lib/fem/isoparametric_segment.cc b/tests/mito.lib/fem/isoparametric_segment.cc index 257f3456..cdd98bbe 100644 --- a/tests/mito.lib/fem/isoparametric_segment.cc +++ b/tests/mito.lib/fem/isoparametric_segment.cc @@ -78,8 +78,8 @@ test_gradient_consistency(const auto & element) return ((element.template gradient()(xi)) + ...); })(element, xi, mito::tensor::make_integer_sequence{}); - // check the sum of the shape functions gradients - EXPECT_NEAR(0.0, sum, 3.0e-16); + // check that the sum of the shape functions gradients is the zero vector + EXPECT_NEAR(0.0, mito::tensor::norm(sum), 3.0e-16); }); // all done From 9ecf38e5c1d044d8bd8e7e072e781ff9372d73fb Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 08:59:57 +0200 Subject: [PATCH 10/52] tests/geometry: add test of euclidean metric in 1D Trivial but had to be done. --- .cmake/mito_tests_mito_lib.cmake | 1 + .../mito.lib/geometry/euclidean_metric_1D.cc | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 tests/mito.lib/geometry/euclidean_metric_1D.cc diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 572f1c14..79f33620 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -28,6 +28,7 @@ mito_test_driver(tests/mito.lib/geometry/barycenter_triangle_3D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc) mito_test_driver(tests/mito.lib/geometry/cell_directors.cc) mito_test_driver(tests/mito.lib/geometry/point.cc) +mito_test_driver(tests/mito.lib/geometry/euclidean_metric_1D.cc) mito_test_driver(tests/mito.lib/geometry/euclidean_metric_2D.cc) mito_test_driver(tests/mito.lib/geometry/euclidean_metric_3D.cc) mito_test_driver(tests/mito.lib/geometry/euclidean_submanifold_metric_3D.cc) diff --git a/tests/mito.lib/geometry/euclidean_metric_1D.cc b/tests/mito.lib/geometry/euclidean_metric_1D.cc new file mode 100644 index 00000000..8b89d741 --- /dev/null +++ b/tests/mito.lib/geometry/euclidean_metric_1D.cc @@ -0,0 +1,64 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +#include +#include + + +// cartesian coordinates in 1D +using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; + +// the basis for vector fields +static constexpr auto e_x = mito::tensor::e_0<1>; + + +auto +area( + const auto & w, const mito::geometry::coordinate_system_t & coordinate_system, + const mito::geometry::node_t<1> & v0, const mito::geometry::node_t<1> & v1) + -> mito::tensor::scalar_t +{ + // get vertex coordinates + auto x0 = coordinate_system.coordinates(v0->point()); + auto x1 = coordinate_system.coordinates(v1->point()); + + // build director vectors + auto director0 = x1 - x0; + + // compute length of segment + auto length = w(director0); + + // all done + return length; +} + + +TEST(Tensor, EuclideanMetric1D) +{ + // the basis one-forms + constexpr auto dx = mito::tensor::one_form(e_x); + + // assert that at a(ny) point the basis for one-forms is dual to that of vectors + static_assert(dx(e_x) == 1.0); + + // the metric volume element + constexpr auto w = dx; + + // the coordinate system + auto coord_system = mito::geometry::coordinate_system(); + + // build nodes of a segment + auto node_0 = mito::geometry::node(coord_system, { 0.0 }); + auto node_1 = mito::geometry::node(coord_system, { 1.0 }); + + // check that even permutations of the vertices give a positive area + EXPECT_DOUBLE_EQ(area(w, coord_system, node_0, node_1), 1.0); + + // check that odd permutations of the vertices give a negative area + EXPECT_DOUBLE_EQ(area(w, coord_system, node_1, node_0), -1.0); +} + + +// end of file From 1cfaff8724fe25866c5bba0a44e2d2affa996175 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 13:53:29 +0200 Subject: [PATCH 11/52] =?UTF-8?q?tests/fem:=20remove=C2=A0test=20{localize?= =?UTF-8?q?=5Ffield}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first half of this test is trivial; the other half follows an incorrect logic. In fact this test checks that the gradient in parametric space equals the gradient in cartesian space, which of course is not true in general. --- .cmake/mito_tests_mito_lib.cmake | 1 - tests/mito.lib/fem/localize_field.cc | 66 ---------------------------- 2 files changed, 67 deletions(-) delete mode 100644 tests/mito.lib/fem/localize_field.cc diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 79f33620..7282db14 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -54,7 +54,6 @@ mito_test_driver(tests/mito.lib/fem/shape_functions_triangle_construction.cc) mito_test_driver(tests/mito.lib/fem/shape_functions_triangle_p1.cc) mito_test_driver(tests/mito.lib/fem/shape_functions_triangle_p2.cc) mito_test_driver(tests/mito.lib/fem/isoparametric_triangle.cc) -mito_test_driver(tests/mito.lib/fem/localize_field.cc) mito_test_driver(tests/mito.lib/fem/fem_field.cc) mito_test_driver(tests/mito.lib/fem/shape_functions_segment_p1.cc) mito_test_driver(tests/mito.lib/fem/isoparametric_segment.cc) diff --git a/tests/mito.lib/fem/localize_field.cc b/tests/mito.lib/fem/localize_field.cc deleted file mode 100644 index 956d6581..00000000 --- a/tests/mito.lib/fem/localize_field.cc +++ /dev/null @@ -1,66 +0,0 @@ -// -*- c++ -*- -// -// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved -// - -#include -#include - - -// cartesian coordinates in 2D -using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; -// the x scalar field in 2D -constexpr auto x = mito::functions::component; -// the y scalar field in 2D -constexpr auto y = mito::functions::component; - - -TEST(Fem, LocalizeField) -{ - // create a channel - journal::info_t channel("tests.localize_field"); - - // the coordinate system - auto coord_system = coord_system_t(); - - // create a field - auto field = x * y; - - // create some nodes - auto node_0 = mito::geometry::node(coord_system, { 1.0, 0.0 }); - auto node_1 = mito::geometry::node(coord_system, { 0.0, 1.0 }); - auto node_2 = mito::geometry::node(coord_system, { 0.0, 0.0 }); - - // create a geometric simplex - auto geometric_simplex = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); - - // an isoparametric triangle - auto element = mito::fem::IsoparametricTriangle(geometric_simplex, coord_system); - - // localize the field on the simplex - auto localized_field = mito::fem::localize(field, element); - - // evaluate the localized field at the center of the triangle - auto value = localized_field({ 1.0 / 3.0, 1.0 / 3.0 }); - - // check the value - EXPECT_DOUBLE_EQ(value, (x * y)({ 1.0 / 3.0, 1.0 / 3.0 })); - - // compute the gradient of the localized field with respect to the barycentric coordinates - auto gradient = mito::operators::gradient(localized_field); - - // evaluate the localized field gradient at the center of the triangle - auto value_gradient = gradient({ 1.0 / 3.0, 1.0 / 3.0 }); - - // check the value of the gradient at the center of the triangle - EXPECT_DOUBLE_EQ(value_gradient[0], y({ 1.0 / 3.0, 1.0 / 3.0 })); - EXPECT_DOUBLE_EQ(value_gradient[1], x({ 1.0 / 3.0, 1.0 / 3.0 })); - - // all done - return; -} - - -// end of file \ No newline at end of file From 95bd94d93a595f7d7304466b00aa021e754556f2 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 14:04:35 +0200 Subject: [PATCH 12/52] fem: fix segment orientation by correcting parametric coordinate ordering Align parametric coordinates with the standard reference-space convention. --- lib/mito/fem/elements/seg1/ShapeSegmentP1.h | 5 +++-- lib/mito/fem/elements/tri1/ShapeTriangleP1.h | 2 +- lib/mito/fem/elements/tri2/ShapeTriangleP2.h | 2 +- lib/mito/geometry/ReferenceSimplex.h | 15 ++++++++------- tests/mito.lib/fem/shape_functions_triangle_p1.cc | 6 +++--- tests/mito.lib/fem/shape_functions_triangle_p2.cc | 12 ++++++------ 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/mito/fem/elements/seg1/ShapeSegmentP1.h b/lib/mito/fem/elements/seg1/ShapeSegmentP1.h index 67905bdf..16a06eb2 100644 --- a/lib/mito/fem/elements/seg1/ShapeSegmentP1.h +++ b/lib/mito/fem/elements/seg1/ShapeSegmentP1.h @@ -20,10 +20,11 @@ namespace mito::fem { private: // linear shape functions on the reference segment in parametric coordinates static constexpr auto xi_0 = reference_element_type::xi<0>; + static constexpr auto xi_1 = reference_element_type::xi<1>; // linear shape functions on the segment - static constexpr auto phi_0 = 1.0 - xi_0; - static constexpr auto phi_1 = xi_0; + static constexpr auto phi_0 = xi_0; + static constexpr auto phi_1 = xi_1; // the shape functions static constexpr auto phi = std::make_tuple(phi_0, phi_1); diff --git a/lib/mito/fem/elements/tri1/ShapeTriangleP1.h b/lib/mito/fem/elements/tri1/ShapeTriangleP1.h index e143aac8..901bf01b 100644 --- a/lib/mito/fem/elements/tri1/ShapeTriangleP1.h +++ b/lib/mito/fem/elements/tri1/ShapeTriangleP1.h @@ -21,7 +21,7 @@ namespace mito::fem { // linear shape functions on the reference triangle in parametric coordinates static constexpr auto xi_0 = reference_element_type::xi<0>; static constexpr auto xi_1 = reference_element_type::xi<1>; - static constexpr auto xi_2 = 1.0 - xi_0 - xi_1; + static constexpr auto xi_2 = reference_element_type::xi<2>; // linear shape functions on the triangle static constexpr auto phi_0 = xi_0; diff --git a/lib/mito/fem/elements/tri2/ShapeTriangleP2.h b/lib/mito/fem/elements/tri2/ShapeTriangleP2.h index f77df475..90843797 100644 --- a/lib/mito/fem/elements/tri2/ShapeTriangleP2.h +++ b/lib/mito/fem/elements/tri2/ShapeTriangleP2.h @@ -21,7 +21,7 @@ namespace mito::fem { // get the parametric coordinates from the reference element static constexpr auto xi_0 = reference_element_type::xi<0>; static constexpr auto xi_1 = reference_element_type::xi<1>; - static constexpr auto xi_2 = 1.0 - xi_0 - xi_1; + static constexpr auto xi_2 = reference_element_type::xi<2>; // quadratic shape functions on the triangle static constexpr auto phi_3 = 4.0 * xi_0 * xi_1; diff --git a/lib/mito/geometry/ReferenceSimplex.h b/lib/mito/geometry/ReferenceSimplex.h index a565c15f..690b699b 100644 --- a/lib/mito/geometry/ReferenceSimplex.h +++ b/lib/mito/geometry/ReferenceSimplex.h @@ -23,22 +23,23 @@ namespace mito::geometry { template static constexpr auto _one_minus_xis(tensor::integer_sequence) { - return (1.0 - ... - xi); + return 1.0 - (functions::component + ...); } public: // the type of coordinates in the parametric space using parametric_coordinates_type = coordinates_t; - // the function extracting the I component of a parametric point + // the parametric coordinates template static constexpr auto xi = [] { - if constexpr (I < N) { - // I-th parametric coordinate - return functions::component; - } else { - // xi = 1 - xi<0> - xi<1> - ... - xi + static_assert(I >= 0 && I <= N); + if constexpr (I == 0) { + // the complementary of the sum of all parametric coordinates return _one_minus_xis(tensor::make_integer_sequence{}); + } else { + // (I-1)-th parametric coordinate + return functions::component; } }(); }; diff --git a/tests/mito.lib/fem/shape_functions_triangle_p1.cc b/tests/mito.lib/fem/shape_functions_triangle_p1.cc index 8a728982..db8e9ad2 100644 --- a/tests/mito.lib/fem/shape_functions_triangle_p1.cc +++ b/tests/mito.lib/fem/shape_functions_triangle_p1.cc @@ -19,11 +19,11 @@ TEST(Fem, ShapeTriangleP1) constexpr auto element = shape_t(); // node 0 in parametric coordinates - constexpr auto n0 = parametric_coordinates_type{ 1.0, 0.0 }; + constexpr auto n0 = parametric_coordinates_type{ 0.0, 0.0 }; // node 1 in parametric coordinates - constexpr auto n1 = parametric_coordinates_type{ 0.0, 1.0 }; + constexpr auto n1 = parametric_coordinates_type{ 1.0, 0.0 }; // node 2 in parametric coordinates - constexpr auto n2 = parametric_coordinates_type{ 0.0, 0.0 }; + constexpr auto n2 = parametric_coordinates_type{ 0.0, 1.0 }; // the shape function associated with local node {0} constexpr auto phi_0 = element.shape<0>(); diff --git a/tests/mito.lib/fem/shape_functions_triangle_p2.cc b/tests/mito.lib/fem/shape_functions_triangle_p2.cc index d272c1c2..48a4673a 100644 --- a/tests/mito.lib/fem/shape_functions_triangle_p2.cc +++ b/tests/mito.lib/fem/shape_functions_triangle_p2.cc @@ -19,17 +19,17 @@ TEST(Fem, ShapeTriangleP2) constexpr auto element = shape_t(); // node 0 in barycentric coordinates - constexpr auto n0 = barycentric_coordinates_t{ 1.0, 0.0 }; + constexpr auto n0 = barycentric_coordinates_t{ 0.0, 0.0 }; // node 1 in barycentric coordinates - constexpr auto n1 = barycentric_coordinates_t{ 0.0, 1.0 }; + constexpr auto n1 = barycentric_coordinates_t{ 1.0, 0.0 }; // node 2 in barycentric coordinates - constexpr auto n2 = barycentric_coordinates_t{ 0.0, 0.0 }; + constexpr auto n2 = barycentric_coordinates_t{ 0.0, 1.0 }; // node 3 in barycentric coordinates - constexpr auto n3 = barycentric_coordinates_t{ 0.5, 0.5 }; + constexpr auto n3 = barycentric_coordinates_t{ 0.5, 0.0 }; // node 4 in barycentric coordinates - constexpr auto n4 = barycentric_coordinates_t{ 0.0, 0.5 }; + constexpr auto n4 = barycentric_coordinates_t{ 0.5, 0.5 }; // node 5 in barycentric coordinates - constexpr auto n5 = barycentric_coordinates_t{ 0.5, 0.0 }; + constexpr auto n5 = barycentric_coordinates_t{ 0.0, 0.5 }; // the shape functions at node 0 constexpr auto phi_0 = element.shape<0>(); From 357cb68bb928e0bb3bd388798ff631a1ce615f5c Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 14:12:06 +0200 Subject: [PATCH 13/52] tests/quadrature: minor fix Use {1.0} instead of {1}. --- tests/mito.lib/quadrature/quadrature_segment_1D.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/mito.lib/quadrature/quadrature_segment_1D.cc b/tests/mito.lib/quadrature/quadrature_segment_1D.cc index 00a3f320..74ad8dbc 100644 --- a/tests/mito.lib/quadrature/quadrature_segment_1D.cc +++ b/tests/mito.lib/quadrature/quadrature_segment_1D.cc @@ -42,7 +42,9 @@ TEST(Quadrature, Segment) // integrate exp(-x) on (0, 1) auto integral = integrator.integrate(f_exp); - EXPECT_NEAR(integral, (std::exp(1) - 1) / std::exp(1), 1.e-13); + + // check result + EXPECT_NEAR(integral, (std::exp(1.0) - 1.0) / std::exp(1.0), 1.e-13); } // end of file From bb3715a688002310eb884477825ccd56725393a3 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 14:13:59 +0200 Subject: [PATCH 14/52] tensor: implement contraction of forms on tuple-like input --- lib/mito/tensor/Form.h | 25 ++++++++++++++++++++----- lib/mito/tensor/externals.h | 2 +- lib/mito/utilities/externals.h | 1 + lib/mito/utilities/utilities.h | 6 ++++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/mito/tensor/Form.h b/lib/mito/tensor/Form.h index aba0d8b3..7d9920cc 100644 --- a/lib/mito/tensor/Form.h +++ b/lib/mito/tensor/Form.h @@ -21,7 +21,6 @@ namespace mito::tensor { template concept vector_or_dummy_c = vector_c or std::is_same_v; - // class for P-forms template class Form { @@ -44,6 +43,14 @@ namespace mito::tensor { return _f(args...); } + // contraction from a tuple-like input + template + constexpr auto operator()(const tupleT & args) const + requires(utilities::tuple_like_c && utilities::tuple_size_v == P) + { + return std::apply([this](const auto &... args) { return (*this)(args...); }, args); + } + private: // the action of the form F _f; @@ -64,11 +71,19 @@ namespace mito::tensor { constexpr Form(F f) : _f{ f } {} // contraction with a vector - template - constexpr auto operator()(const X & x) const -> mito::tensor::scalar_t - requires(!std::is_same_v) + template + constexpr auto operator()(argsT... args) const + requires(sizeof...(argsT) == 1) + { + return _f(args...); + } + + // contraction from a tuple-like input + template + constexpr auto operator()(const tupleT & args) const + requires(utilities::tuple_like_c && utilities::tuple_size_v == 1) { - return _f(x); + return std::apply([this](const auto &... args) { return (*this)(args...); }, args); } // contraction with a dummy vector (do not perform contraction) diff --git a/lib/mito/tensor/externals.h b/lib/mito/tensor/externals.h index dca7be5c..b0cdb025 100644 --- a/lib/mito/tensor/externals.h +++ b/lib/mito/tensor/externals.h @@ -14,6 +14,6 @@ // support #include "../journal.h" - +#include "../utilities.h" // end of file diff --git a/lib/mito/utilities/externals.h b/lib/mito/utilities/externals.h index 970be342..4421bcd4 100644 --- a/lib/mito/utilities/externals.h +++ b/lib/mito/utilities/externals.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/lib/mito/utilities/utilities.h b/lib/mito/utilities/utilities.h index 48e5214f..3ba706c4 100644 --- a/lib/mito/utilities/utilities.h +++ b/lib/mito/utilities/utilities.h @@ -24,6 +24,12 @@ namespace mito::utilities { template using base_type = typename std::remove_cvref_t; + // tuple like concept + template + concept tuple_like_c = requires { typename std::tuple_size>::type; }; + + // use tuple sizeĀ as provided by the standard library + using std::tuple_size_v; } From 5b34647021c76e02d8c6cd832ddb9cca4cd3f275 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 14:58:08 +0200 Subject: [PATCH 15/52] tests/manifold: add test of segment embedded in 2D --- .cmake/mito_tests_mito_lib.cmake | 1 + tests/mito.lib/manifolds/segment_2D.cc | 43 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/mito.lib/manifolds/segment_2D.cc diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 7282db14..7359fc2d 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -103,6 +103,7 @@ mito_test_driver(tests/mito.lib/fields/spherical_metric_field.cc) mito_test_driver(tests/mito.lib/manifolds/euclidean_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) +mito_test_driver(tests/mito.lib/manifolds/segment_2D.cc) mito_test_driver(tests/mito.lib/manifolds/triangle_2D.cc) mito_test_driver(tests/mito.lib/manifolds/triangle_3D.cc) mito_test_driver(tests/mito.lib/manifolds/tetrahedron_3D.cc) diff --git a/tests/mito.lib/manifolds/segment_2D.cc b/tests/mito.lib/manifolds/segment_2D.cc new file mode 100644 index 00000000..98993bf0 --- /dev/null +++ b/tests/mito.lib/manifolds/segment_2D.cc @@ -0,0 +1,43 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +#include +#include + + +// cartesian coordinates in 2D +using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; + + +TEST(Manifolds, Segment2D) +{ + // the coordinate system + auto coord_system = mito::geometry::coordinate_system(); + + // an empty mesh of segments + auto mesh = mito::mesh::mesh>(); + + // construct a segment + auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); + auto node_1 = mito::geometry::node(coord_system, { 0.5, 0.5 }); + mesh.insert({ node_0, node_1 }); + + // the normal vector to the segment + constexpr auto v = mito::tensor::vector_t<2>{ 0.5, -0.5 }; + constexpr auto normal_vector = v / mito::tensor::norm(v); + constexpr auto normal_field = mito::functions::constant(normal_vector); + + // create a submanifold on {mesh} with the appropriate normal field + auto manifold = mito::manifolds::submanifold(mesh, coord_system, normal_field); + + // compute the length of the segment submanifold + auto length = manifold.volume(); + + // check that the length of the segment is correct + EXPECT_DOUBLE_EQ(0.5 * std::sqrt(2.0), length); +} + + +// end of file From bb799eaaeb6ae7be4f3cb9af4953b45be25ce938 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 15:53:23 +0200 Subject: [PATCH 16/52] geometry: implement free function {volume}, which computes volumes of geometric simplices given metric volume form and coordinate system --- .cmake/mito_tests_mito_lib.cmake | 4 +- lib/mito/geometry/utilities.h | 16 +++++ .../{manifolds => geometry}/tetrahedron_3D.cc | 66 +++++++++---------- .../{manifolds => geometry}/triangle_2D.cc | 28 ++++---- 4 files changed, 65 insertions(+), 49 deletions(-) rename tests/mito.lib/{manifolds => geometry}/tetrahedron_3D.cc (73%) rename tests/mito.lib/{manifolds => geometry}/triangle_2D.cc (73%) diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 7359fc2d..e06394b9 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -26,6 +26,8 @@ mito_test_driver(tests/mito.lib/geometry/barycenter_segment_3D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_triangle_2D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_triangle_3D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc) +mito_test_driver(tests/mito.lib/geometry/triangle_2D.cc) +mito_test_driver(tests/mito.lib/geometry/tetrahedron_3D.cc) mito_test_driver(tests/mito.lib/geometry/cell_directors.cc) mito_test_driver(tests/mito.lib/geometry/point.cc) mito_test_driver(tests/mito.lib/geometry/euclidean_metric_1D.cc) @@ -104,9 +106,7 @@ mito_test_driver(tests/mito.lib/manifolds/euclidean_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/segment_2D.cc) -mito_test_driver(tests/mito.lib/manifolds/triangle_2D.cc) mito_test_driver(tests/mito.lib/manifolds/triangle_3D.cc) -mito_test_driver(tests/mito.lib/manifolds/tetrahedron_3D.cc) mito_test_driver(tests/mito.lib/manifolds/tetra_rectangle_2D.cc) mito_test_driver(tests/mito.lib/manifolds/tetra_cube_3D.cc) mito_test_driver(tests/mito.lib/manifolds/volume_half_ball.cc) diff --git a/lib/mito/geometry/utilities.h b/lib/mito/geometry/utilities.h index 8002fb13..28fcac54 100644 --- a/lib/mito/geometry/utilities.h +++ b/lib/mito/geometry/utilities.h @@ -74,6 +74,22 @@ namespace mito::geometry { return _directors(simplex, coordinate_system, tensor::make_integer_sequence{}); } + // computes the volume of {cell} given a coordinate system and a volume form + template + requires(coordT::dim == D) + constexpr auto volume( + const geometric_simplex_t & simplex, const coordinate_system_t & coord_system, + const /*TOFIX: tensor::p_form_field_c*/ auto & volume_form) -> tensor::scalar_t + { + // get the director edges of this cell and the point where they stem from + auto [point, directors] = mito::geometry::directors(simplex, coord_system); + // compute the volume of a N-order simplicial cell as (1/N!) times the volume form + // contracted with the cell directors + auto volume = 1.0 / mito::tensor::factorial() * volume_form(point)(directors); + // all done + return volume; + } + // builds a geometric simplex based on a topological simplex {simplex} with the vertex-point // pairing as appears in {nodes} template diff --git a/tests/mito.lib/manifolds/tetrahedron_3D.cc b/tests/mito.lib/geometry/tetrahedron_3D.cc similarity index 73% rename from tests/mito.lib/manifolds/tetrahedron_3D.cc rename to tests/mito.lib/geometry/tetrahedron_3D.cc index 0c5a2ae7..071b49cd 100644 --- a/tests/mito.lib/manifolds/tetrahedron_3D.cc +++ b/tests/mito.lib/geometry/tetrahedron_3D.cc @@ -4,24 +4,24 @@ // #include -#include +#include // cartesian coordinates in 3D using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::CARTESIAN>; +// the metric space type +using metric_space_t = mito::geometry::metric_space; -TEST(Manifolds, Tetrahedron3D) + +TEST(Geometry, Tetrahedron3D) { + // the metric volume form + constexpr auto w = metric_space_t::w; + // the coordinate system auto coord_system = mito::geometry::coordinate_system(); - // an empty mesh of tetrahedra - auto mesh = mito::mesh::mesh>(); - - // create a manifold on {mesh} with Euclidean metric - auto manifold = mito::manifolds::manifold(mesh, coord_system); - // build nodes auto node_1 = mito::geometry::node(coord_system, { 0.0, 0.0, 0.0 }); auto node_2 = mito::geometry::node(coord_system, { 1.0, 0.0, 0.0 }); @@ -31,127 +31,127 @@ TEST(Manifolds, Tetrahedron3D) // build tetrahedron with a positive volume (reference tetrahedron) auto tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_2, node_3, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_2, node_3, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_3, node_4, node_2 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_4, node_2, node_3 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_1, node_4, node_3 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_3, node_1, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_4, node_3, node_1 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_1, node_2, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_2, node_4, node_1 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_4, node_1, node_2 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_1, node_3, node_2 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_2, node_1, node_3 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_3, node_2, node_1 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), 1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_2, node_4, node_3 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_3, node_2, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_4, node_3, node_2 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_1, node_3, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_3, node_4, node_1 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_4, node_1, node_3 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_1, node_4, node_2 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_2, node_1, node_4 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_4, node_2, node_1 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_1, node_2, node_3 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_2, node_3, node_1 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_3, node_1, node_2 }); // check that the volume of tetrahedron is correct - EXPECT_DOUBLE_EQ(manifold.volume(tetrahedron), -1.0 / 6.0); + EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); } diff --git a/tests/mito.lib/manifolds/triangle_2D.cc b/tests/mito.lib/geometry/triangle_2D.cc similarity index 73% rename from tests/mito.lib/manifolds/triangle_2D.cc rename to tests/mito.lib/geometry/triangle_2D.cc index 351abe5d..0377cef0 100644 --- a/tests/mito.lib/manifolds/triangle_2D.cc +++ b/tests/mito.lib/geometry/triangle_2D.cc @@ -4,58 +4,58 @@ // #include -#include +#include // cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the metric space type +using metric_space_t = mito::geometry::metric_space; -TEST(Manifolds, Triangle2D) + +TEST(Geometry, Triangle2D) { + // the metric volume form + constexpr auto w = metric_space_t::w; + // the coordinate system auto coord_system = mito::geometry::coordinate_system(); - // an empty mesh of triangles - auto mesh = mito::mesh::mesh>(); - // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); auto node_1 = mito::geometry::node(coord_system, { 1.0, 0.0 }); auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); - // create a manifold on {mesh} with Euclidean metric - auto manifold = mito::manifolds::manifold(mesh, coord_system); - // build triangle with a positive volume (reference triangle) auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); // check that the volume of triangle is correct - EXPECT_DOUBLE_EQ(manifold.volume(triangle), 0.5); + EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), 0.5); // create a triangle from an even permutation of the vertices with respect to the reference triangle = mito::geometry::triangle<2>({ node_1, node_2, node_0 }); // check that the volume of triangle is correct - EXPECT_DOUBLE_EQ(manifold.volume(triangle), 0.5); + EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), 0.5); // create a triangle from an even permutation of the vertices with respect to the reference triangle = mito::geometry::triangle<2>({ node_2, node_0, node_1 }); // check that the volume of triangle is correct - EXPECT_DOUBLE_EQ(manifold.volume(triangle), 0.5); + EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), 0.5); // create a triangle from an odd permutation of the vertices with respect to the reference triangle = mito::geometry::triangle<2>({ node_0, node_2, node_1 }); // check that the volume of triangle is correct - EXPECT_DOUBLE_EQ(manifold.volume(triangle), -0.5); + EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), -0.5); // create a triangle from an odd permutation of the vertices with respect to the reference triangle = mito::geometry::triangle<2>({ node_1, node_0, node_2 }); // check that the volume of triangle is correct - EXPECT_DOUBLE_EQ(manifold.volume(triangle), -0.5); + EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), -0.5); // create a triangle from an odd permutation of the vertices with respect to the reference triangle = mito::geometry::triangle<2>({ node_2, node_1, node_0 }); // check that the volume of triangle is correct - EXPECT_DOUBLE_EQ(manifold.volume(triangle), -0.5); + EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), -0.5); } From 6a9ce9821aa0f2c15841ed88abc6145f5e690a0d Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 15:57:17 +0200 Subject: [PATCH 17/52] functions: consistency fix with ref. 34f7721 --- lib/mito/functions/forward.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/mito/functions/forward.h b/lib/mito/functions/forward.h index 5f123798..e9261bd9 100644 --- a/lib/mito/functions/forward.h +++ b/lib/mito/functions/forward.h @@ -57,7 +57,9 @@ namespace mito::functions { // concept of a tensor-valued function template - concept tensor_valued_function_c = function_c and tensor::tensor_c; + concept tensor_valued_function_c = function_c + and (tensor::tensor_c + or geometry::coordinates_c); // concept of a tensor-valued function of tensors template From 276ab50f4646b69042892a764d719fee1b823527 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 16:42:20 +0200 Subject: [PATCH 18/52] tests/input: fix orientation of rectangle mesh --- tests/input/rectangle.geo | 10 +- tests/input/rectangle.summit | 11139 +++++++++++----------- tests/mito.lib/io/vtk_mesh_writer_2D.py | 4 +- 3 files changed, 5524 insertions(+), 5629 deletions(-) diff --git a/tests/input/rectangle.geo b/tests/input/rectangle.geo index 2617a6f6..7c56f9bb 100644 --- a/tests/input/rectangle.geo +++ b/tests/input/rectangle.geo @@ -6,11 +6,11 @@ Point(1) = {0.0,0.0,0.0,h}; Point(2) = {H,0.0,0.0,h}; Point(3) = {H,L,0.0,h}; Point(4) = {0,L,0.0,h}; -Line(1) = {4,3}; -Line(2) = {3,2}; -Line(3) = {2,1}; -Line(4) = {1,4}; -Line Loop(5) = {2,3,4,1}; +Line(1) = {1,2}; +Line(2) = {2,3}; +Line(3) = {3,4}; +Line(4) = {4,1}; +Line Loop(5) = {1,2,3,4}; Physical Line ("1") = {4}; Plane Surface(1) = {5}; Physical Surface("rectangle") = {1}; diff --git a/tests/input/rectangle.summit b/tests/input/rectangle.summit index 51f3b3fc..03ddb82c 100644 --- a/tests/input/rectangle.summit +++ b/tests/input/rectangle.summit @@ -1,5622 +1,5517 @@ -2 -1930 3690 1 -0.0 0.0 -0.05 0.0 -0.05 0.025 -0.0 0.025 -0.000892857142856 0.025 -0.00178571428571 0.025 -0.00267857142857 0.025 -0.00357142857142 0.025 -0.00446428571428 0.025 -0.00535714285713 0.025 -0.00624999999999 0.025 -0.00714285714284 0.025 -0.0080357142857 0.025 -0.00892857142855 0.025 -0.00982142857141 0.025 -0.0107142857143 0.025 -0.0116071428571 0.025 -0.0125 0.025 -0.0133928571428 0.025 -0.0142857142857 0.025 -0.0151785714285 0.025 -0.0160714285714 0.025 -0.0169642857142 0.025 -0.0178571428571 0.025 -0.01875 0.025 -0.0196428571428 0.025 -0.0205357142857 0.025 -0.0214285714285 0.025 -0.0223214285714 0.025 -0.0232142857142 0.025 -0.0241071428571 0.025 -0.0249999999999 0.025 -0.0258928571428 0.025 -0.0267857142857 0.025 -0.0276785714285 0.025 -0.0285714285714 0.025 -0.0294642857142 0.025 -0.0303571428571 0.025 -0.03125 0.025 -0.0321428571428 0.025 -0.0330357142857 0.025 -0.0339285714285 0.025 -0.0348214285714 0.025 -0.0357142857142 0.025 -0.0366071428571 0.025 -0.0375 0.025 -0.0383928571428 0.025 -0.0392857142857 0.025 -0.0401785714285 0.025 -0.0410714285714 0.025 -0.0419642857143 0.025 -0.0428571428571 0.025 -0.04375 0.025 -0.0446428571428 0.025 -0.0455357142857 0.025 -0.0464285714286 0.025 -0.0473214285714 0.025 -0.0482142857143 0.025 -0.0491071428571 0.025 -0.05 0.0241071428571 -0.05 0.0232142857143 -0.05 0.0223214285714 -0.05 0.0214285714286 -0.05 0.0205357142857 -0.05 0.0196428571429 -0.05 0.01875 -0.05 0.0178571428572 -0.05 0.0169642857143 -0.05 0.0160714285715 -0.05 0.0151785714286 -0.05 0.0142857142857 -0.05 0.0133928571429 -0.05 0.0125 -0.05 0.0116071428572 -0.05 0.0107142857143 -0.05 0.00982142857146 -0.05 0.0089285714286 -0.05 0.00803571428574 -0.05 0.00714285714288 -0.05 0.00625000000002 -0.05 0.00535714285716 -0.05 0.0044642857143 -0.05 0.00357142857144 -0.05 0.00267857142858 -0.05 0.00178571428572 -0.05 0.00089285714286 -0.0491071428571 0.0 -0.0482142857143 0.0 -0.0473214285714 0.0 -0.0464285714286 0.0 -0.0455357142857 0.0 -0.0446428571429 0.0 -0.04375 0.0 -0.0428571428572 0.0 -0.0419642857143 0.0 -0.0410714285715 0.0 -0.0401785714286 0.0 -0.0392857142857 0.0 -0.0383928571429 0.0 -0.0375 0.0 -0.0366071428572 0.0 -0.0357142857143 0.0 -0.0348214285715 0.0 -0.0339285714286 0.0 -0.0330357142858 0.0 -0.0321428571429 0.0 -0.0312500000001 0.0 -0.0303571428572 0.0 -0.0294642857143 0.0 -0.0285714285715 0.0 -0.0276785714286 0.0 -0.0267857142858 0.0 -0.0258928571429 0.0 -0.0250000000001 0.0 -0.0241071428572 0.0 -0.0232142857143 0.0 -0.0223214285715 0.0 -0.0214285714286 0.0 -0.0205357142858 0.0 -0.0196428571429 0.0 -0.0187500000001 0.0 -0.0178571428572 0.0 -0.0169642857143 0.0 -0.0160714285715 0.0 -0.0151785714286 0.0 -0.0142857142858 0.0 -0.0133928571429 0.0 -0.0125 0.0 -0.0116071428572 0.0 -0.0107142857143 0.0 -0.00982142857146 0.0 -0.0089285714286 0.0 -0.00803571428574 0.0 -0.00714285714288 0.0 -0.00625000000002 0.0 -0.00535714285716 0.0 -0.0044642857143 0.0 -0.00357142857144 0.0 -0.00267857142858 0.0 -0.00178571428572 0.0 -0.00089285714286 0.0 -0.0 0.000892857142855 -0.0 0.00178571428571 -0.0 0.00267857142857 -0.0 0.00357142857142 -0.0 0.00446428571428 -0.0 0.00535714285713 -0.0 0.00624999999999 -0.0 0.00714285714284 -0.0 0.00803571428569 -0.0 0.00892857142855 -0.0 0.0098214285714 -0.0 0.0107142857143 -0.0 0.0116071428571 -0.0 0.0125 -0.0 0.0133928571428 -0.0 0.0142857142857 -0.0 0.0151785714285 -0.0 0.0160714285714 -0.0 0.0169642857143 -0.0 0.0178571428571 -0.0 0.01875 -0.0 0.0196428571428 -0.0 0.0205357142857 -0.0 0.0214285714286 -0.0 0.0223214285714 -0.0 0.0232142857143 -0.0 0.0241071428571 -0.0255007735878 0.000797961733648 -0.0182825988823 0.0243933057245 -0.0334565159042 0.000799429319374 -0.0129132257664 0.0242115414058 -0.0298745860525 0.024159609133 -0.0370535714285 0.0242267630323 -0.022709124711 0.0241974192902 -0.0155914385856 0.000805344807737 -0.020110250148 0.000760389290652 -0.0492267630323 0.0120535714286 -0.000782068922936 0.012037603118 -0.0378276962026 0.000852670365673 -0.0112083771469 0.000835666734442 -0.000768710981486 0.0157212531318 -0.0334746547735 0.0241636690505 -0.0406789349935 0.0241487977901 -0.0263537573389 0.0242020382664 -0.00937499999998 0.0242267630323 -0.0299083753881 0.000791670930792 -0.0492267630323 0.015625 -0.0492267630323 0.00848214285717 -0.000773236967662 0.00848214285712 -0.0414901832888 0.000607007494506 -0.00758928571431 0.000773236967666 -0.0441939848537 0.0243021749546 -0.000773236967667 0.0191964285714 -0.00577405895542 0.0242681091121 -0.0492267630323 0.0191964285714 -0.0492267630323 0.00491071428574 -0.000773236967662 0.0049107142857 -0.0227408762303 0.000757659530477 -0.0156769084684 0.0243630785427 -0.0442128781235 0.000727622069563 -0.00502279803719 0.000848880951864 -0.046875 0.0242267630323 -0.000773236967667 0.021875 -0.0468903163805 0.000800321307772 -0.0491507023407 0.0219066632157 -0.00311678392945 0.0242066580172 -0.00313909776626 0.00075873588359 -0.0423585260708 0.0241793740628 -0.0174567780658 0.000900903949788 -0.0317054047229 0.0242148632417 -0.00937500000003 0.000773236967667 -0.0352869318188 0.0242215656115 -0.000773236967666 0.0138392857143 -0.0280813204261 0.0242033991048 -0.0138625445686 0.000725312121221 -0.0492267630323 0.0102678571429 -0.00766446004743 0.0241961466087 -0.0492267630323 0.00312500000002 -0.000798158229781 0.0173148457117 -0.0492267630323 0.00669642857145 -0.0388392857143 0.0242454401708 -0.000773236967663 0.00312499999999 -0.000773236967662 0.00669642857141 -0.0246438420089 0.0241952004282 -0.0209701426299 0.0243359632556 -0.0361328418044 0.000783577088755 -0.000773236967662 0.0102678571428 -0.0272321428572 0.000773236967663 -0.0315879219166 0.000829814837933 -0.0112528971946 0.024198213684 -0.0492267630323 0.0174107142857 -0.0492267630323 0.0138392857143 -0.0397022235066 0.0006996786085 -0.0492466997282 0.00137381708446 -0.00128137345349 0.000707373997843 -0.000753300271801 0.0236261829155 -0.0486261829155 0.0242466997282 -0.0492267630323 0.0111607142857 -0.0484535260647 0.0116071428572 -0.0484535260647 0.0125 -0.047680289097 0.0120535714286 -0.047680289097 0.0129464285715 -0.0469070521293 0.0125 -0.0469070521293 0.0133928571429 -0.0461338151617 0.0129464285715 -0.0461338151617 0.0138392857143 -0.045360578194 0.0133928571429 -0.045360578194 0.0125 -0.0445873412264 0.0129464285715 -0.0445873412264 0.0120535714286 -0.0438141042587 0.0125 -0.0438141042587 0.0133928571429 -0.043040867291 0.0129464285715 -0.043040867291 0.0120535714286 -0.0422676303234 0.0125 -0.0422676303234 0.0133928571429 -0.0414943933557 0.0129464285715 -0.0414943933557 0.0120535714286 -0.040721156388 0.0125 -0.040721156388 0.0133928571429 -0.0399479194204 0.0129464285715 -0.0399479194204 0.0120535714286 -0.0391746824527 0.0125 -0.0391746824527 0.0133928571429 -0.038401445485 0.0129464285715 -0.038401445485 0.0120535714286 -0.0376282085174 0.0125 -0.0376282085174 0.0116071428572 -0.0368549715497 0.0120535714286 -0.0368549715497 0.0129464285715 -0.0360817345821 0.0125 -0.0360817345821 0.0116071428572 -0.0353084976144 0.0120535714286 -0.0353084976144 0.0129464285715 -0.0345352606467 0.0125 -0.0345352606467 0.0116071428572 -0.0337620236791 0.0120535714286 -0.0337620236791 0.0129464285715 -0.0329887867114 0.0125 -0.0329887867114 0.0116071428572 -0.0322155497437 0.0120535714286 -0.0322155497437 0.0129464285715 -0.0314423127761 0.0125 -0.0314423127761 0.0116071428572 -0.0306690758084 0.0120535714286 -0.0306690758084 0.0129464285715 -0.0298958388407 0.0125 -0.0298958388407 0.0133928571429 -0.0291226018731 0.0129464285715 -0.0291226018731 0.0120535714286 -0.0283493649054 0.0125 -0.0283493649054 0.0133928571429 -0.0275761279378 0.0129464285715 -0.0275761279378 0.0120535714286 -0.0268028909701 0.0125 -0.0268028909701 0.0116071428572 -0.0260296540024 0.0120535714286 -0.0260296540024 0.0129464285715 -0.0252564170348 0.0125 -0.0252564170348 0.0116071428572 -0.0244831800671 0.0120535714286 -0.0244831800671 0.0129464285714 -0.0237099430994 0.0125 -0.0237099430994 0.0116071428572 -0.0229367061318 0.0120535714286 -0.0229367061318 0.0129464285714 -0.0221634691641 0.0125 -0.0221634691641 0.0133928571429 -0.0213902321964 0.0129464285714 -0.0213902321964 0.0120535714286 -0.0206169952288 0.0125 -0.0206169952288 0.0116071428572 -0.0198437582611 0.0120535714286 -0.0198437582611 0.0129464285714 -0.0190705212934 0.0125 -0.0190705212934 0.0133928571429 -0.0182972843258 0.0129464285714 -0.0182972843258 0.0120535714286 -0.0175240473581 0.0125 -0.0175240473581 0.0116071428572 -0.0167508103905 0.0120535714286 -0.0167508103905 0.0129464285714 -0.0159775734228 0.0125 -0.0159775734228 0.0116071428572 -0.0152043364551 0.0120535714286 -0.0152043364551 0.0129464285714 -0.0144310994875 0.0125 -0.0144310994875 0.0133928571429 -0.0136578625198 0.0129464285714 -0.0136578625198 0.0120535714286 -0.0128846255521 0.0125 -0.0128846255521 0.0133928571429 -0.0128846255521 0.0116071428572 -0.0121113885845 0.0129464285714 -0.0121113885845 0.0138392857143 -0.0113381516168 0.0133928571429 -0.0113381516168 0.0142857142857 -0.0105649146491 0.0138392857143 -0.0105649146491 0.0147321428572 -0.0113381516168 0.0151785714286 -0.0105649146491 0.015625 -0.0105649146491 0.0129464285714 -0.00979167768147 0.0142857142857 -0.0113381516168 0.0160714285714 -0.0105649146491 0.0165178571429 -0.0113381516168 0.0169642857143 -0.0105649146491 0.0174107142857 -0.00979167768148 0.0169642857143 -0.00979167768148 0.0178571428571 -0.00901844071382 0.0174107142857 -0.0113381516168 0.0178571428571 -0.0121113885845 0.0174107142857 -0.0121113885845 0.0183035714286 -0.0128846255521 0.0178571428572 -0.00901844071382 0.0183035714286 -0.00824520374615 0.0178571428571 -0.0128846255521 0.01875 -0.0136578625198 0.0183035714286 -0.00824520374615 0.01875 -0.00747196677849 0.0183035714286 -0.00747196677849 0.0174107142857 -0.00669872981082 0.0178571428571 -0.00669872981082 0.0169642857143 -0.00669872981082 0.01875 -0.0136578625198 0.0191964285714 -0.0144310994875 0.01875 -0.00901844071381 0.0191964285714 -0.00592549284316 0.0183035714286 -0.00592549284316 0.0191964285714 -0.0128846255521 0.0196428571429 -0.0144310994875 0.0178571428572 -0.0152043364551 0.0183035714286 -0.0152043364551 0.0191964285714 -0.0159775734228 0.01875 -0.0159775734228 0.0178571428572 -0.0167508103904 0.0183035714286 -0.0167508103904 0.0191964285714 -0.0175240473581 0.01875 -0.0175240473581 0.0196428571429 -0.0182972843258 0.0191964285714 -0.0182972843258 0.0183035714286 -0.0190705212934 0.01875 -0.0190705212934 0.0196428571429 -0.0198437582611 0.0191964285714 -0.0198437582611 0.0183035714286 -0.0206169952288 0.01875 -0.0206169952288 0.0196428571429 -0.0213902321964 0.0191964285714 -0.0213902321964 0.0183035714286 -0.0221634691641 0.01875 -0.0221634691641 0.0178571428572 -0.0229367061318 0.0183035714286 -0.0229367061318 0.0191964285714 -0.0237099430994 0.01875 -0.0237099430994 0.0178571428572 -0.0244831800671 0.0183035714286 -0.0244831800671 0.0191964285714 -0.0252564170347 0.01875 -0.0252564170347 0.0178571428572 -0.0260296540024 0.0183035714286 -0.0260296540024 0.0191964285714 -0.0268028909701 0.01875 -0.0268028909701 0.0196428571429 -0.0275761279377 0.0191964285714 -0.0275761279377 0.0183035714286 -0.0283493649054 0.01875 -0.0283493649054 0.0196428571429 -0.0291226018731 0.0191964285714 -0.0291226018731 0.0183035714286 -0.0298958388407 0.01875 -0.0298958388407 0.0196428571429 -0.0306690758084 0.0191964285714 -0.0306690758084 0.0183035714286 -0.0314423127761 0.01875 -0.0314423127761 0.0178571428572 -0.0322155497437 0.0183035714286 -0.0322155497437 0.0191964285714 -0.0329887867114 0.01875 -0.0329887867114 0.0178571428572 -0.0337620236791 0.0183035714286 -0.0337620236791 0.0191964285714 -0.0345352606467 0.01875 -0.0345352606467 0.0178571428572 -0.0353084976144 0.0183035714286 -0.0353084976144 0.0191964285714 -0.0360817345821 0.01875 -0.0360817345821 0.0178571428572 -0.0368549715497 0.0183035714286 -0.0368549715497 0.0191964285714 -0.0376282085174 0.01875 -0.0376282085174 0.0196428571429 -0.038401445485 0.0191964285714 -0.038401445485 0.0183035714286 -0.0391746824527 0.01875 -0.0391746824527 0.0196428571429 -0.0399479194204 0.0191964285714 -0.0399479194204 0.0183035714286 -0.040721156388 0.01875 -0.040721156388 0.0196428571429 -0.0414943933557 0.0191964285714 -0.0414943933557 0.0183035714286 -0.0422676303234 0.01875 -0.0422676303234 0.0196428571429 -0.043040867291 0.0191964285714 -0.043040867291 0.0183035714286 -0.0438141042587 0.01875 -0.0438141042587 0.0196428571429 -0.0445873412264 0.0191964285714 -0.0445873412264 0.0183035714286 -0.0445873412264 0.0200892857143 -0.0051522558755 0.01875 -0.00515225587549 0.0196428571429 -0.00592549284316 0.0200892857143 -0.00515225587549 0.0205357142857 -0.0306690758084 0.0138392857143 -0.0275761279377 0.0138392857143 -0.0306690758084 0.0111607142857 -0.0167508103904 0.0200892857143 -0.0198437582611 0.0138392857143 -0.0190705212934 0.0142857142857 -0.0229367061318 0.0138392857143 -0.038401445485 0.0138392857143 -0.0306690758084 0.0200892857143 -0.0136578625198 0.0200892857143 -0.0128846255521 0.0205357142857 -0.038401445485 0.0111607142857 -0.0275761279378 0.0111607142857 -0.0152043364551 0.0138392857143 -0.0167508103904 0.0174107142857 -0.0314423127761 0.0107142857143 -0.0306690758084 0.0102678571429 -0.0314423127761 0.00982142857146 -0.0306690758084 0.00937500000003 -0.0314423127761 0.0089285714286 -0.0306690758084 0.00848214285717 -0.0314423127761 0.00803571428575 -0.0306690758084 0.00758928571432 -0.0314423127761 0.00714285714289 -0.0322155497437 0.00758928571432 -0.0306690758084 0.00669642857146 -0.0298958388407 0.00714285714289 -0.0322155497437 0.00669642857146 -0.0329887867114 0.00714285714289 -0.0298958388407 0.00625000000003 -0.0291226018731 0.00669642857146 -0.0329887867114 0.00625000000004 -0.0337620236791 0.00669642857146 -0.0337620236791 0.00580357142861 -0.0345352606467 0.00625000000004 -0.0291226018731 0.0058035714286 -0.0283493649054 0.00625000000003 -0.0298958388407 0.00535714285717 -0.0345352606467 0.00535714285718 -0.0353084976144 0.00580357142861 -0.0353084976144 0.00669642857147 -0.0360817345821 0.00625000000004 -0.0360817345821 0.00535714285718 -0.0368549715497 0.00580357142861 -0.0283493649054 0.00535714285717 -0.0275761279378 0.0058035714286 -0.0275761279378 0.00669642857146 -0.0268028909701 0.00625000000003 -0.0268028909701 0.00535714285717 -0.0260296540024 0.0058035714286 -0.0260296540024 0.00669642857146 -0.0252564170348 0.00625000000003 -0.0252564170348 0.00535714285717 -0.0244831800671 0.0058035714286 -0.0244831800671 0.00669642857146 -0.0237099430994 0.00625000000003 -0.0237099430994 0.00714285714288 -0.0229367061318 0.00669642857146 -0.0229367061318 0.0058035714286 -0.0221634691641 0.00625000000003 -0.0221634691641 0.00535714285717 -0.0213902321964 0.0058035714286 -0.0213902321964 0.00669642857145 -0.0206169952288 0.00625000000002 -0.0206169952288 0.00714285714288 -0.0198437582611 0.00669642857145 -0.0198437582611 0.00580357142859 -0.0190705212935 0.00625000000002 -0.0190705212935 0.00535714285717 -0.0182972843258 0.00580357142859 -0.0182972843258 0.00669642857145 -0.0175240473581 0.00625000000002 -0.0175240473581 0.00535714285716 -0.0167508103905 0.00580357142859 -0.0167508103905 0.00669642857145 -0.0159775734228 0.00625000000002 -0.0159775734228 0.00535714285716 -0.0152043364551 0.00580357142859 -0.0152043364551 0.00669642857145 -0.0144310994875 0.00625000000002 -0.0144310994875 0.00535714285716 -0.0136578625198 0.00580357142859 -0.0136578625198 0.00669642857145 -0.0128846255521 0.00625000000002 -0.0128846255521 0.00535714285716 -0.0121113885845 0.00580357142859 -0.0121113885845 0.00669642857145 -0.0113381516168 0.00625000000002 -0.0113381516168 0.00714285714287 -0.0105649146491 0.00669642857144 -0.0105649146491 0.0075892857143 -0.00979167768147 0.00714285714287 -0.00979167768147 0.00803571428573 -0.00901844071381 0.0075892857143 -0.00901844071381 0.00848214285716 -0.00824520374614 0.00803571428573 -0.00824520374614 0.00892857142858 -0.00824520374614 0.00714285714287 -0.00747196677848 0.0075892857143 -0.00747196677848 0.00669642857144 -0.00669872981082 0.00714285714287 -0.00669872981082 0.00625000000001 -0.00747196677848 0.00580357142859 -0.00592549284315 0.00669642857144 -0.00592549284315 0.0075892857143 -0.00592549284315 0.00580357142859 -0.0113381516168 0.00535714285716 -0.0368549715497 0.00669642857147 -0.0376282085174 0.00625000000004 -0.0376282085174 0.00535714285718 -0.038401445485 0.00580357142861 -0.038401445485 0.00669642857147 -0.0391746824527 0.00625000000004 -0.0391746824527 0.0071428571429 -0.0399479194204 0.00669642857147 -0.0399479194204 0.00580357142861 -0.040721156388 0.00625000000004 -0.040721156388 0.0071428571429 -0.0414943933557 0.00669642857147 -0.0414943933557 0.00580357142862 -0.0422676303234 0.00625000000004 -0.0422676303234 0.0071428571429 -0.043040867291 0.00669642857147 -0.043040867291 0.00580357142862 -0.0438141042587 0.00625000000004 -0.0438141042587 0.0071428571429 -0.0438141042587 0.00535714285719 -0.0445873412264 0.00580357142862 -0.0445873412264 0.00491071428576 -0.0329887867114 0.00535714285718 -0.00515225587549 0.00714285714287 -0.00515225587549 0.00803571428573 -0.00979167768147 0.00892857142858 -0.0438141042587 0.00446428571433 -0.0244831800671 0.00758928571431 -0.0113381516168 0.00803571428573 -0.0322155497437 0.00937500000003 -0.0229367061318 0.0111607142857 -0.045360578194 0.0116071428572 -0.0298958388407 0.0142857142857 -0.0229367061318 0.00491071428574 -0.0221634691641 0.00446428571431 -0.0128846255521 0.0169642857143 -0.0152043364551 0.0111607142857 -0.0198437582611 0.0111607142857 -0.0391746824527 0.0142857142857 -0.0376282085174 0.0107142857143 -0.0368549715497 0.0200892857143 -0.0376282085174 0.0205357142857 -0.0337620236791 0.00758928571432 -0.0445873412264 0.0111607142857 -0.045360578194 0.0107142857143 -0.0298958388407 0.0205357142857 -0.0260296540024 0.0200892857143 -0.0268028909701 0.0205357142857 -0.0159775734228 0.0107142857143 -0.0438141042587 0.0205357142857 -0.045360578194 0.0142857142857 -0.0461338151617 0.0147321428572 -0.0298958388407 0.0089285714286 -0.0213902321964 0.0200892857143 -0.0206169952288 0.0205357142857 -0.0260296540024 0.0174107142857 -0.0152043364551 0.0102678571429 -0.0051522558755 0.0178571428571 -0.038401445485 0.00491071428576 -0.0376282085174 0.00446428571433 -0.0198437582611 0.00758928571431 -0.0206169952288 0.0107142857143 -0.0268028909701 0.0107142857143 -0.0229367061318 0.00758928571431 -0.0213902321964 0.0174107142857 -0.045360578194 0.01875 -0.045360578194 0.00535714285719 -0.045360578194 0.00446428571433 -0.045360578194 0.00625000000005 -0.0252564170347 0.0169642857143 -0.038401445485 0.0147321428572 -0.0175240473581 0.0205357142857 -0.0136578625198 0.0209821428571 -0.00437901890783 0.0200892857143 -0.00437901890783 0.0075892857143 -0.00437901890782 0.00848214285715 -0.00515225587549 0.00892857142858 -0.00437901890782 0.00937500000001 -0.00515225587549 0.00982142857144 -0.00437901890782 0.0102678571429 -0.00515225587549 0.0107142857143 -0.00437901890782 0.0111607142857 -0.00515225587549 0.0116071428571 -0.00437901890782 0.0120535714286 -0.00515225587549 0.0125 -0.00592549284315 0.0120535714286 -0.00437901890782 0.0129464285714 -0.00592549284315 0.0129464285714 -0.00669872981081 0.0125 -0.00669872981081 0.0133928571429 -0.00437901890783 0.00669642857144 -0.00592549284315 0.0138392857143 -0.00437901890783 0.0183035714286 -0.00437901890783 0.0174107142857 -0.0445873412264 0.0209821428572 -0.045360578194 0.0205357142857 -0.0368549715497 0.0209821428572 -0.0229367061318 0.00401785714288 -0.00592549284316 0.0209821428571 -0.0260296540024 0.0209821428572 -0.0213902321964 0.0209821428571 -0.038401445485 0.0040178571429 -0.00437901890783 0.0209821428571 -0.0167508103904 0.0209821428571 -0.0306690758084 0.0209821428572 -0.0221634691641 0.00357142857145 -0.00360578194017 0.0205357142857 -0.0121113885845 0.0200892857143 -0.0121113885845 0.0209821428571 -0.0159775734228 0.0169642857143 -0.0167508103904 0.0165178571429 -0.0159775734228 0.00982142857145 -0.038401445485 0.00758928571432 -0.0391746824527 0.00803571428575 -0.0221634691641 0.0169642857143 -0.00747196677849 0.0165178571429 -0.0237099430994 0.0107142857143 -0.045360578194 0.0151785714286 -0.0461338151617 0.015625 -0.0445873412264 0.0102678571429 -0.045360578194 0.00982142857146 -0.0391746824527 0.0151785714286 -0.0306690758084 0.0147321428572 -0.0298958388407 0.0151785714286 -0.0461338151617 0.00580357142862 -0.0461338151617 0.00669642857147 -0.0206169952288 0.0214285714286 -0.045360578194 0.0214285714286 -0.0461338151617 0.0209821428572 -0.0376282085174 0.00357142857147 -0.0438141042587 0.0214285714286 -0.0268028909701 0.0214285714286 -0.0144310994875 0.0142857142857 -0.0260296540024 0.0165178571429 -0.0252564170347 0.0160714285714 -0.00669872981081 0.0116071428571 -0.00747196677848 0.0120535714286 -0.0198437582611 0.0147321428572 -0.0368549715497 0.0174107142857 -0.0360817345821 0.0169642857143 -0.0376282085174 0.0214285714286 -0.0298958388407 0.0214285714286 -0.0175240473581 0.0214285714286 -0.00359033115021 0.0214018098754 -0.0190705212934 0.0151785714286 -0.00669872981082 0.0205357142857 -0.00669872981082 0.0214285714286 -0.00747196677849 0.0209821428571 -0.0275761279378 0.0102678571429 -0.0268028909701 0.00982142857145 -0.0113381516168 0.0205357142857 -0.0113388595979 0.0214297976878 -0.0182972843258 0.0147321428572 -0.010565032646 0.0209823472337 -0.00979167768147 0.00625000000002 -0.0213902321964 0.00401785714288 -0.0152043364551 0.00937500000002 -0.0144310994875 0.00982142857145 -0.0275761279378 0.00937500000003 -0.0198437582611 0.0102678571429 -0.047680289097 0.0111607142857 -0.0229367061318 0.0102678571429 -0.0206169952288 0.00803571428574 -0.0221634691641 0.0142857142857 -0.0229367061318 0.0147321428572 -0.00360578194016 0.00892857142858 -0.00360578194016 0.00714285714287 -0.00360578194016 0.00625000000001 -0.00360578194016 0.0107142857143 -0.00360578194016 0.0125 -0.00360578194016 0.0133928571429 -0.00360578194017 0.0178571428571 -0.00360578194017 0.0169642857143 -0.00437901890783 0.0165178571429 -0.00360578194017 0.0160714285714 -0.00431579790552 0.0219543110254 -0.0213902321964 0.021875 -0.0221634691641 0.0214285714286 -0.0383939545137 0.00313797474299 -0.0391734339575 0.00357359102863 -0.0213902321964 0.00312500000002 -0.0206169952288 0.00357142857145 -0.0260296540024 0.021875 -0.0252564170347 0.0214285714286 -0.0105657602933 0.0218764646986 -0.0167508103904 0.021875 -0.0368680255118 0.0218523898744 -0.0360839102424 0.0214248030743 -0.0229367061318 0.00312500000003 -0.0237099430994 0.00357142857146 -0.0237099430994 0.0026785714286 -0.0244831800671 0.00312500000003 -0.030677611202 0.0218602162646 -0.0314437353417 0.0214261074727 -0.0121022295344 0.0218936944339 -0.0461272072837 0.0218635548195 -0.00747196677849 0.021875 -0.00669872981081 0.0142857142857 -0.00747196677848 0.0138392857143 -0.0260296540024 0.015625 -0.0268028909701 0.0160714285714 -0.0469070521293 0.0151785714286 -0.0469070521293 0.0160714285715 -0.00979183828831 0.0214288496078 -0.0159775734228 0.0214285714286 -0.00592549284315 0.00937500000001 -0.0144310994875 0.00892857142859 -0.0136578625198 0.00937500000002 -0.0159775734228 0.0160714285714 -0.0159775734228 0.00892857142859 -0.0167508103905 0.00937500000002 -0.00747196677848 0.0111607142857 -0.00824520374614 0.0116071428571 -0.038401445485 0.00848214285718 -0.0391746824527 0.00892857142861 -0.0268028909701 0.0089285714286 -0.0260296540024 0.00937500000003 -0.0237099430994 0.00982142857145 -0.045360578194 0.0160714285715 -0.0445873412264 0.015625 -0.0252564170347 0.0151785714286 -0.0198437582611 0.015625 -0.0190705212934 0.0160714285714 -0.00592549284315 0.0147321428571 -0.0445873412264 0.00937500000004 -0.0438141042587 0.00982142857146 -0.038401445485 0.015625 -0.0376282085174 0.0151785714286 -0.0391746824527 0.0160714285715 -0.0399479194204 0.015625 -0.045360578194 0.00892857142861 -0.0461338151617 0.00937500000004 -0.0306690758084 0.015625 -0.0314423127761 0.0151785714286 -0.0298958388407 0.0160714285715 -0.0291226018731 0.015625 -0.0468733747618 0.0214266638985 -0.0469014392348 0.020535396364 -0.0469070521293 0.00625000000005 -0.0469070521293 0.0071428571429 -0.0469070521294 0.00535714285719 -0.00282996984084 0.0209776825983 -0.00284511817393 0.0218213877714 -0.00283211578389 0.0200885423378 -0.0028325449725 0.0165178571429 -0.0028325449725 0.015625 -0.00286715912413 0.0129464285714 -0.0376434381398 0.0222950500916 -0.0384039837555 0.0218706035867 -0.0453045978382 0.0222450733846 -0.0268028909701 0.0223214285714 -0.0275761279377 0.021875 -0.0206169952288 0.0223214285714 -0.0198437582611 0.021875 -0.0198437582611 0.0227678571429 -0.0376194690508 0.00269370862871 -0.036853514972 0.00312752286673 -0.00669872981082 0.0223214285714 -0.0361172042837 0.0222451498767 -0.0353197486908 0.0218530386691 -0.0175240473581 0.0223214285714 -0.0028325449725 0.00669642857144 -0.0028325449725 0.00580357142859 -0.00360578194016 0.00535714285716 -0.0028325449725 0.00491071428573 -0.00360578194016 0.0044642857143 -0.0028325449725 0.00401785714287 -0.00360578194016 0.00357142857145 -0.00437901890783 0.00401785714288 -0.0028325449725 0.00312500000002 -0.00437901890783 0.00312500000002 -0.00515225587549 0.00357142857145 -0.00515225587549 0.00267857142859 -0.00592549284316 0.00312500000002 -0.00592549284316 0.00223214285716 -0.00669849630521 0.00267897587217 -0.00669869089322 0.00357149597871 -0.00747168786901 0.00312548308541 -0.00205880728479 0.0205348470132 -0.0252564170347 0.0223214285714 -0.0244831800671 0.021875 -0.0468704066419 0.0222532898731 -0.0221634691641 0.0223214285714 -0.0298648637004 0.0224430571719 -0.039175086533 0.00271026653544 -0.0399479194204 0.00312500000005 -0.0206034484049 0.00263869803686 -0.0198415004571 0.00311835443473 -0.0213902321965 0.00223214285717 -0.00979184538997 0.0223217190511 -0.0159775734228 0.0223214285714 -0.0314525078296 0.0223037702208 -0.0322174860136 0.0218716462823 -0.0167508103904 0.015625 -0.00285206739246 0.0138392857143 -0.00360578194016 0.0151785714286 -0.00747196677848 0.0147321428571 -0.0244831800671 0.0209821428572 -0.0152043364551 0.021875 -0.0283493649054 0.00982142857146 -0.0283493649054 0.0089285714286 -0.0105649343153 0.020089319777 -0.0028325449725 0.0075892857143 -0.0298958388407 0.0107142857143 -0.0206169952288 0.0151785714286 -0.00283831399777 0.0120535714286 -0.0182972843258 0.0209821428571 -0.0244831800671 0.0165178571429 -0.0128846255521 0.0142857142857 -0.047680289097 0.0138392857143 -0.0152043364551 0.0209821428571 -0.0121113885845 0.015625 -0.0175240473581 0.0169642857143 -0.0353107354039 0.0209778545763 -0.034537508791 0.0214241964933 -0.0345121654436 0.0222457655331 -0.0376282085174 0.00803571428575 -0.0376282085174 0.00892857142861 -0.0368549715497 0.00848214285718 -0.0368549715497 0.00937500000003 -0.0360817345821 0.00892857142861 -0.0360817345821 0.00982142857146 -0.0353084976144 0.00937500000003 -0.00824520374614 0.0125 -0.0090184407138 0.0120535714286 -0.0090184407138 0.0111607142857 -0.00979167768147 0.0116071428572 -0.0152043364551 0.0165178571429 -0.0190705212934 0.0107142857143 -0.0190705212934 0.00982142857145 -0.032215835359 0.020981648157 -0.0399479194204 0.00848214285718 -0.0399479194204 0.00937500000004 -0.040721156388 0.00892857142861 -0.040721156388 0.00982142857147 -0.0414943933557 0.00937500000004 -0.00901844071381 0.0165178571429 -0.0167508103905 0.00848214285716 -0.0136578625198 0.00848214285716 -0.0128846255521 0.00892857142859 -0.0128846255521 0.00982142857145 -0.0121113885845 0.00937500000002 -0.0121113885845 0.0102678571429 -0.0113381516168 0.00982142857144 -0.0113381516168 0.0107142857143 -0.0399477113378 0.00401821755243 -0.0407211217076 0.00357148863973 -0.040721150608 0.00267858144 -0.0414943866123 0.00312501167999 -0.0244831800671 0.0102678571429 -0.043040867291 0.0209821428572 -0.0430386984473 0.0218712434525 -0.0422672688494 0.0214279453373 -0.04226503976 0.0223169415841 -0.0414939013495 0.0218741478202 -0.0438049643517 0.0223079538913 -0.0353084976144 0.00848214285718 -0.0345352606467 0.0089285714286 -0.0345352606467 0.00982142857146 -0.0182972843258 0.0102678571429 -0.0175240473581 0.00892857142859 -0.0445873412264 0.0165178571429 -0.0438141042587 0.0160714285715 -0.0438141042587 0.0151785714286 -0.043040867291 0.015625 -0.0291226018731 0.0209821428572 -0.045360578194 0.0178571428572 -0.0461338151617 0.0183035714286 -0.0414943864517 0.00401786910094 -0.0422676303234 0.00357142857148 -0.0422676291995 0.00267857337528 -0.0229367061318 0.00937500000002 -0.0221634691641 0.00982142857145 -0.043040867291 0.0165178571429 -0.0422676303234 0.0160714285715 -0.0422676303234 0.0151785714286 -0.0221634691641 0.00892857142859 -0.0206169952288 0.00982142857145 -0.00979167768147 0.0107142857143 -0.0221634691641 0.0151785714286 -0.0244831800671 0.00937500000002 -0.0260296540024 0.00848214285717 -0.00747191380731 0.00401794889165 -0.00824514843271 0.00357152437714 -0.00829176957337 0.00273968490013 -0.0090229087834 0.00313189946014 -0.00901917617317 0.00401902302051 -0.0097925449363 0.00357277279441 -0.00980197968602 0.00269624879556 -0.0105667761924 0.00312817026501 -0.0414943933557 0.0102678571429 -0.0399479194204 0.0102678571429 -0.0430408671037 0.00312500032449 -0.0260296540024 0.0147321428572 -0.0438141042587 0.00892857142861 -0.0198437582611 0.0165178571429 -0.00515225587549 0.0142857142857 -0.0314423127761 0.0160714285715 -0.0322155497437 0.015625 -0.0322155497437 0.0147321428572 -0.0329887867114 0.0151785714286 -0.0329887867114 0.0160714285715 -0.0337620236791 0.015625 -0.0337620236791 0.0147321428572 -0.0345352606467 0.0151785714286 -0.0291226018731 0.0165178571429 -0.038401445485 0.0165178571429 -0.0345352606467 0.0160714285715 -0.0237099430994 0.0142857142857 -0.0229367061318 0.015625 -0.0399479194204 0.0165178571429 -0.00979167768148 0.00446428571431 -0.045360578194 0.0071428571429 -0.0477370002672 0.0210897733822 -0.0476888054763 0.0201071711482 -0.00901856329037 0.00491090859867 -0.0353084976144 0.015625 -0.0353084976144 0.0147321428572 -0.047680289097 0.00580357142862 -0.047680289097 0.00491071428576 -0.0469070521294 0.00446428571433 -0.047680289097 0.0040178571429 -0.0469070521294 0.00357142857147 -0.047680289097 0.00312500000004 -0.0469070521294 0.00267857142861 -0.0461338151617 0.00312500000004 -0.0461338151617 0.00223214285719 -0.045360578194 0.00267857142862 -0.047680289097 0.00223214285717 -0.0430408670725 0.00223214323571 -0.00437901890783 0.00223214285716 -0.0322078868519 0.0227475806022 -0.0244680416067 0.00225836343975 -0.025253893958 0.0026829415257 -0.025255996522 0.00357215692097 -0.0260291634042 0.00312584974113 -0.0260179610906 0.00225239557462 -0.0268008603851 0.00268208850503 -0.0268024707729 0.00357215637438 -0.0275757194741 0.00312570747992 -0.0414938795941 0.0227669672817 -0.0407209887601 0.0223211382313 -0.040721046449 0.0214283810086 -0.0151958598223 0.0227531751842 -0.0144296867153 0.0223189815783 -0.0144209746205 0.0231967489303 -0.01365593958 0.0227645265133 -0.0275861263819 0.00225086885592 -0.0283509632355 0.00268181034171 -0.0283495632165 0.00357208630363 -0.0291229013133 0.00312564944091 -0.0283617026534 0.00180739701042 -0.036853272209 0.00223508620165 -0.0360812085956 0.00267948246381 -0.0360814041547 0.00357200088845 -0.0353083548788 0.00312524722541 -0.0353084976144 0.00223214285719 -0.0345388326199 0.00266329893246 -0.0345358321863 0.00356892435967 -0.0337627142645 0.00312203721538 -0.0198332990721 0.00222268846282 -0.0190684017946 0.00267588810199 -0.019069791743 0.00356987375614 -0.0182968094842 0.00312429364303 -0.0190680967205 0.00179271351329 -0.0105872123173 0.00227072684285 -0.011342178152 0.00268553047037 -0.0113391329632 0.00357311678925 -0.0121122232314 0.00312644120995 -0.0121121987815 0.00223354289912 -0.0128848996928 0.00267904497058 -0.0128848103501 0.00357174769677 -0.0136579390096 0.00312513211124 -0.0105792299078 0.0227788286015 -0.0453698308468 0.00180174035043 -0.02758653289 0.0227498352368 -0.00824520374614 0.0142857142857 -0.00824520374614 0.0151785714286 -0.0090184407138 0.0129464285714 -0.00669872981082 0.0160714285714 -0.0283493649054 0.0160714285715 -0.0438141042411 0.00267857145912 -0.0291226234679 0.0040179138542 -0.0298958923466 0.00357154626349 -0.0299004222171 0.00267086253008 -0.0306743731742 0.00311589804494 -0.0306699676203 0.00401635976571 -0.0314433443057 0.00356966201608 -0.0314423127761 0.00267857142861 -0.0314423962197 0.00446414410958 -0.0322157355726 0.00401753911621 -0.00901844071382 0.021875 -0.00901846748162 0.0209821892203 -0.00900836366516 0.0227504031826 -0.0128846255521 0.00803571428573 -0.0422676303234 0.00982142857147 -0.0422676303234 0.00892857142861 -0.00824520374615 0.0196428571429 -0.0190705212934 0.0169642857143 -0.047680289097 0.015625 -0.047680289097 0.0165178571429 -0.0190705212934 0.0223214285714 -0.0469075360435 0.0196457850616 -0.0476817891459 0.0191998974635 -0.0229367061318 0.021875 -0.0229367061318 0.0209821428572 -0.0229505635316 0.0227438554223 -0.0337622340332 0.00401694597682 -0.0244831800671 0.00491071428574 -0.0291226018731 0.00758928571432 -0.0159775734228 0.00803571428573 -0.0268028909701 0.00803571428574 -0.00592549284316 0.0165178571429 -0.0283493649054 0.0142857142857 -0.0275761279377 0.0147321428572 -0.0136578625198 0.0111607142857 -0.0113381516168 0.01875 -0.00669872981081 0.0107142857143 -0.0152043364551 0.015625 -0.0144310994875 0.0160714285714 -0.0345360083024 0.0205342704164 -0.0283361731928 0.0222925725529 -0.0206169952288 0.00446428571431 -0.00747196677848 0.0102678571429 -0.0422676303234 0.0107142857143 -0.0461338151617 0.0111607142857 -0.0422676291727 0.00446428770734 -0.0198437582611 0.00848214285717 -0.0190705212935 0.00803571428574 -0.0414943933557 0.015625 -0.0414943933557 0.0165178571429 -0.0283493649054 0.0169642857143 -0.00360578194017 0.01875 -0.00276711561689 0.0183035714286 -0.0144310994875 0.00803571428573 -0.0175240473581 0.00803571428573 -0.0337620236791 0.00937500000003 -0.0337620236791 0.0102678571429 -0.00669872199715 0.00446429924798 -0.0090184407138 0.0102678571429 -0.00515225587549 0.0151785714286 -0.0414943933557 0.0147321428572 -0.0182970835938 0.00401748028083 -0.0175239347625 0.00357124803494 -0.0175239494519 0.00267842361301 -0.0167507753068 0.00312494527467 -0.0167635460177 0.00225420624471 -0.0159881030177 0.00269681100114 -0.015979322508 0.00357445937932 -0.00515225587549 0.0044642857143 -0.0399478731592 0.0218749198733 -0.0399649171869 0.0227775017628 -0.038401445485 0.0102678571429 -0.039947893387 0.020982097766 -0.0360817345821 0.0151785714286 -0.0360817345821 0.0142857142857 -0.033762522979 0.0209811730564 -0.0329760798115 0.0222971343323 -0.0213902321964 0.0165178571429 -0.0469070521293 0.0169642857143 -0.047680289097 0.0174107142857 -0.0252564170348 0.0142857142857 -0.0368549715497 0.0165178571429 -0.0461338151617 0.00848214285718 -0.0469070521293 0.00892857142861 -0.0469070521293 0.00982142857146 -0.047680289097 0.00937500000004 -0.047680289097 0.00848214285718 -0.0484535260647 0.0205357142857 -0.0298958388407 0.0169642857143 -0.0136579060678 0.00401793234897 -0.0144311194938 0.00357146312434 -0.0144292288671 0.00271100999588 -0.038401445485 0.0227678571429 -0.0244680416067 0.0227416365603 -0.0337620236791 0.00223214285719 -0.032988901809 0.00267807763117 -0.00745737459563 0.0227425827408 -0.0229485785076 0.00222669735041 -0.00205930800484 0.0196428571429 -0.0251713203907 0.0233286706207 -0.0128711487328 0.00180968210684 -0.00209392215647 0.00714285714287 -0.00209969118174 0.00803571428572 -0.00209392215647 0.00535714285716 -0.00209392215647 0.00357142857145 -0.00209969118174 0.00267857142859 -0.0028325449725 0.00223214285716 -0.00206960301628 0.0125962531318 -0.00209659949592 0.0116231850458 -0.002081184129 0.01610931913 -0.0020451225331 0.0151526864769 -0.00205930800484 0.0169642857143 -0.00670134070724 0.0232048673187 -0.00597606688626 0.0227057103722 -0.00667426501283 0.00180301639139 -0.0222195445089 0.023334162547 -0.0190732450522 0.0232085463624 -0.0198779934224 0.0236083811986 -0.0422723265128 0.00179065761456 -0.0430820329819 0.00139066789744 -0.00210453424459 0.00180970201244 -0.0330039927031 0.00166124271636 -0.00589265426567 0.00135448630662 -0.0376044223368 0.0232559071498 -0.033003918232 0.0232889645662 -0.0120780122098 0.00135899154195 -0.0159937406502 0.0231520253515 -0.0268008637023 0.0233378461312 -0.00981743930026 0.00173776557263 -0.00132578452933 0.0201267002613 -0.00128607103717 0.00223214285716 -0.00128607103717 0.0165178571429 -0.00128607103717 0.0075892857143 -0.0160020247827 0.00169354303584 -0.0313318389638 0.023277407005 -0.0376728146225 0.00182367723534 -0.0284082241002 0.0232584055459 -0.0175120166368 0.00183996934869 -0.00137052839717 0.0209147570121 -0.0422907491138 0.0232136066996 -0.0415101838838 0.0236545979858 -0.0430754854444 0.0235650615572 -0.0129048644784 0.000853098701385 -0.0461162799517 0.00135474577673 -0.0452618493301 0.000860739695465 -0.0136776336812 0.023645169754 -0.0128854444958 0.0232271288019 -0.012087879485 0.02372734482 -0.0120736095922 0.0228510383077 -0.0143839900198 0.0240293844181 -0.0066771315882 0.000864468830735 -0.0369369884749 0.00134844804215 -0.0385309178882 0.00146982336326 -0.0275761279377 0.0165178571429 -0.044598135985 0.00225083993772 -0.00901844071381 0.0147321428571 -0.00901844071381 0.015625 -0.0283494015564 0.00446440478823 -0.0105649146491 0.0111607142857 -0.0105649146491 0.0120535714286 -0.0105649146491 0.0102678571429 -0.0105649146491 0.00937500000001 -0.00592549284316 0.015625 -0.0268028909701 0.0142857142857 -0.0322155946225 0.00491063768051 -0.0314423341631 0.00535710648885 -0.043040867291 0.0102678571429 -0.0484535260647 0.00357142857147 -0.0182972843258 0.0165178571429 -0.0291226018731 0.00491071428574 -0.00403466984323 0.000766205472308 -0.00359903597926 0.00165291542754 -0.045360578194 0.00357142857147 -0.0368549715497 0.0102678571429 -0.0272231308055 0.0242159777253 -0.0477621019145 0.024230085815 -0.0482075712812 0.0234574026444 -0.0491775358306 0.0235457229131 -0.0486533085723 0.0227108311904 -0.0476609762215 0.0226617353237 -0.0482086142993 0.0219143130364 -0.000737868485002 0.0147481850458 -0.00154647393533 0.0142857142857 -0.00150956214791 0.0133444506241 -0.000746680871471 0.0129735899917 -0.0252563469493 0.0044644071059 -0.00216657808537 0.000888275693991 -0.045088878428 0.024239331686 -0.0445641545462 0.0234982134972 -0.0455478222923 0.0235089778126 -0.0182820550339 0.0227397363954 -0.0275761340463 0.0049107341314 -0.0268028219553 0.00446441032241 -0.023681509839 0.000895175615121 -0.0218705031813 0.000752043337629 -0.0222545541783 0.00161889188038 -0.0209848874597 0.000748966025985 -0.0205884760649 0.00164388030558 -0.0246563654373 0.000829243474045 -0.0492267630323 0.00937500000003 -0.0484535260647 0.00535714285718 -0.0190705212934 0.0214285714286 -0.0128766185457 0.0223399932476 -0.0113423995036 0.0223287861271 -0.0255040478479 0.0242117211891 -0.0492267630323 0.0129464285715 -0.00360903567682 0.0142857142857 -0.00747196677849 0.0200892857143 -0.0121113885845 0.0111607142857 -0.0113381516168 0.0116071428572 -0.00848214285717 0.000773236967666 -0.00804453925632 0.00146989227936 -0.00887731601561 0.00152261070115 -0.0102705113072 0.000816101878534 -0.0322155497437 0.00223214285719 -0.0459840929772 0.0242380997659 -0.0464495852891 0.0235169330166 -0.049230085815 0.00223789808552 -0.0484574026444 0.00179242871882 -0.0485457229131 0.000822464169431 -0.047687530252 0.00133908865791 -0.0290014398733 0.0242074704731 -0.0294096555075 0.0233387535779 -0.0302757726737 0.0233512362058 -0.0308013024403 0.0241270182541 -0.0484535260647 0.0160714285715 -0.0484535260647 0.0151785714286 -0.046133895814 0.0191969165579 -0.0291226018731 0.00937500000003 -0.0144310994875 0.0205357142857 -0.0469073962319 0.0187511474662 -0.000769914185022 0.0227621019145 -0.00154259735558 0.0232075712812 -0.00145427708694 0.0241775358306 -0.002319710903 0.0236607142857 -0.002319710903 0.0227678571429 -0.00308147699001 0.0232795829363 -0.00394609010639 0.0236964404681 -0.00387411833613 0.0227893175327 -0.00465931197842 0.0232530196158 -0.0325892857142 0.0242267630323 -0.0339747903444 0.0234399886875 -0.0343943655347 0.0242078583903 -0.0348647727277 0.0235057635252 -0.0357660039796 0.0234928386191 -0.0484535260647 0.0107142857143 -0.0291226018731 0.0102678571429 -0.00824109220757 0.0223143071777 -0.00817080825252 0.0233278529514 -0.00283972172522 0.0111633879838 -0.00210133353043 0.0107174050287 -0.00128607103717 0.0111607142857 -0.00284074535222 0.010268822645 -0.00210229314069 0.00982210937419 -0.00284107589176 0.00937527438415 -0.00210923869514 0.0089287306264 -0.00128607103717 0.00937500000001 -0.0353084976144 0.0138392857143 -0.016485552144 0.00081194339565 -0.0150422887095 0.00144816770892 -0.00284095014142 0.00848217972637 -0.00824520820745 0.0205357220129 -0.018292706862 0.000635282352874 -0.0191193913477 0.000880006268139 -0.0397175359864 0.0242305048596 -0.0392375223652 0.0233789244404 -0.000777390511352 0.0182875933329 -0.00150715590025 0.0187109086086 -0.00146684483248 0.0179054635711 -0.047680289097 0.0147321428572 -0.0484535260647 0.0142857142857 -0.00154647393533 0.0223214285714 -0.0244830983007 0.0040179987664 -0.0260294089343 0.00401828245842 -0.0144310994875 0.0151785714286 -0.0136578625198 0.015625 -0.0213902321964 0.0147321428572 -0.0329888602217 0.00446406808132 -0.0469038342956 0.00177651513943 -0.0445873412264 0.0040178571429 -0.00360650782256 0.00982148236353 -0.0152043364551 0.0147321428572 -0.0159775734228 0.0142857142857 -0.0492267630323 0.00758928571431 -0.0484535260647 0.00714285714289 -0.0379464285714 0.0242267630323 -0.0366565977846 0.0234160875821 -0.0214059679592 0.0227719026353 -0.00210546020701 0.00625000000001 -0.00128607103717 0.00580357142859 -0.00979902054125 0.0233425040659 -0.00669872981082 0.00803571428573 -0.00747196677848 0.00848214285716 -0.023708803766 0.00183473772597 -0.0337620574725 0.00491057990491 -0.0345352606467 0.00446428571433 -0.00514171904178 0.0214417899328 -0.00979167768148 0.01875 -0.00979168095917 0.01964286282 -0.0345352606467 0.0142857142857 -0.0337620236791 0.0138392857143 -0.0329887867114 0.0142857142857 -0.0082453287047 0.00446454367181 -0.008245245002 0.00535721823557 -0.041479612852 0.00225992300182 -0.0407001768966 0.00182000276176 -0.0206061665371 0.0231460550118 -0.0322155497437 0.0138392857143 -0.0198437582611 0.0200892857143 -0.0190705212934 0.0205357142857 -0.0182947461105 0.0218703132088 -0.0174887685619 0.0232034288565 -0.0167508103904 0.0227678571429 -0.0167177988909 0.0235962125794 -0.0345352606467 0.0107142857143 -0.0252564170347 0.0205357142857 -0.0244831800671 0.0200892857143 -0.0275761279377 0.015625 -0.0268028909701 0.0169642857143 -0.0121113885845 0.0120535714286 -0.0275761279378 0.00848214285717 -0.0283493649054 0.00803571428574 -0.0445891403499 0.00312811618522 -0.0438083586126 0.00185689214494 -0.0159775734228 0.0196428571429 -0.0047965556588 0.0241753003048 -0.0438141042587 0.0178571428572 -0.0353084976144 0.0174107142857 -0.0167510772915 0.00401832306721 -0.0360817345821 0.00803571428575 -0.0422676303234 0.0178571428572 -0.0484535260647 0.0133928571429 -0.040721156388 0.0178571428572 -0.0128846255521 0.0107142857143 -0.0314423127761 0.0142857142857 -0.0291257383555 0.0022351198872 -0.029904965174 0.00175214938196 -0.029113725746 0.00134703161778 -0.030712364702 0.00130382280353 -0.0282659753717 0.000865110010187 -0.0306962231206 0.00218512233311 -0.0314593742541 0.00172086895223 -0.0175240473581 0.0133928571429 -0.0167508103905 0.0138392857143 -0.0175240473581 0.0142857142857 -0.0314423163406 0.00624999393865 -0.0322155613821 0.00580355158945 -0.030669079967 0.00580356435698 -0.00516953286533 0.0222963391636 -0.0206169952288 0.0133928571429 -0.0267967777553 0.00166211802888 -0.0453605916361 0.0196429384739 -0.0438141042587 0.0107142857143 -0.0182972843258 0.015625 -0.0175240473581 0.0151785714286 -0.0251788421702 0.00168187101976 -0.0391746824527 0.0116071428572 -0.0136578625198 0.0138392857143 -0.0368549715497 0.00491071428576 -0.0360816795108 0.00446438110049 -0.0461338151617 0.0165178571429 -0.0360817345821 0.0205357142857 -0.0298958388407 0.0116071428572 -0.0291226018731 0.0111607142857 -0.0391746824527 0.0178571428572 -0.0361105230091 0.0017496795893 -0.0352919257987 0.00129386737494 -0.0345568352215 0.00169383208346 -0.0414942786629 0.0209819442035 -0.00669872981082 0.0196428571429 -0.00210546020701 0.0044642857143 -0.00128607103717 0.00401785714287 -0.0136578625198 0.0102678571429 -0.0283493649054 0.0116071428572 -0.0376282085174 0.0178571428572 -0.00515225587549 0.00625000000001 -0.0144310994875 0.0196428571429 -0.0121113885845 0.0075892857143 -0.0121113885845 0.00848214285716 -0.0182972843258 0.0200892857143 -0.0221806287291 0.00264986010991 -0.0353084976144 0.0111607142857 -0.0414943933557 0.00848214285718 -0.0213902321964 0.00758928571431 -0.0121113885845 0.0147321428572 -0.0167508103905 0.0147321428572 -0.0461338151617 0.0040178571429 -0.0337620236791 0.00848214285718 -0.0128846255521 0.00714285714287 -0.0268028909701 0.0133928571429 -0.00979167768148 0.0151785714286 -0.0218544503902 0.0242353436641 -0.00669872981082 0.00892857142858 -0.0322155497437 0.00848214285717 -0.0244831800671 0.015625 -0.0252564170348 0.00714285714289 -0.0237099430994 0.00803571428574 -0.0306692426086 0.0049104338821 -0.0322155497437 0.0111607142857 -0.0322155497437 0.0102678571429 -0.0430408670993 0.00491071461793 -0.0399576098857 0.00225757020001 -0.0322155497437 0.0174107142857 -0.0105649146491 0.00580357142859 -0.0152043364551 0.0200892857143 -0.043040867291 0.0147321428572 -0.00360718280165 0.00803572043059 -0.0105649146491 0.0183035714286 -0.0314425974729 0.0205352211764 -0.0213902321964 0.0138392857143 -0.0182972843258 0.0138392857143 -0.0260296540024 0.0227678571429 -0.0121113885845 0.00491071428573 -0.0473050391177 0.0235113275327 -0.0190705212935 0.00714285714288 -0.0445873412264 0.00848214285718 -0.0337620236791 0.0174107142857 -0.0121113885845 0.0191964285714 -0.0198432603687 0.00401649041278 -0.00901844071381 0.00669642857144 -0.0159775734228 0.0133928571429 -0.00592548505461 0.00401787063303 -0.0384018685301 0.0209814101216 -0.040721156388 0.0116071428572 -0.00747196677849 0.0191964285714 -0.0376282085174 0.0142857142857 -0.0152043364551 0.00491071428573 -0.00592549284315 0.0111607142857 -0.0236852197466 0.0240895714551 -0.0198437582611 0.0209821428571 -0.0105655330066 0.00401889092717 -0.0252564170347 0.0196428571429 -0.0237099430994 0.0196428571429 -0.00671286509934 0.0241058773389 -0.0283493649054 0.0107142857143 -0.0237099430994 0.0133928571429 -0.0291226018731 0.0138392857143 -0.0399479194204 0.0147321428572 -0.0244831800671 0.0174107142857 -0.0237099430994 0.0169642857143 -0.0206169952288 0.0142857142857 -0.0368549715497 0.00758928571432 -0.0298958388407 0.00982142857146 -0.0353084976144 0.00758928571432 -0.0399479194204 0.0138392857143 -0.00360793956983 0.0116075884735 -0.00979167768147 0.0125 -0.00979167768147 0.0133928571429 -0.0344492673361 0.000826036019453 -0.0263617959725 0.000781483151834 -0.0461338151617 0.0200892857143 -0.0167508103905 0.0102678571429 -0.0360817345821 0.0196428571429 -0.0298960277929 0.00446401848474 -0.0136578625198 0.0174107142857 -0.0221634691641 0.00714285714288 -0.0461338151617 0.0120535714286 -0.0325892857143 0.000773236967663 -0.0221634691641 0.0107142857143 -0.0275760185036 0.0040182499 -0.0102678571428 0.0242267630323 -0.00852206078792 0.0242177437728 -0.0121113885845 0.0165178571429 -0.0376282085174 0.0133928571429 -0.0329887867114 0.0196428571429 -0.00824520374614 0.0107142857143 -0.0105649184731 0.0191964351947 -0.0221634691641 0.0196428571429 -0.00747196677848 0.0129464285714 -0.0291226018731 0.0200892857143 -0.0221634691641 0.0116071428572 -0.0407211147769 0.00446435778697 -0.0159775734228 0.0205357142857 -0.00592549284315 0.00848214285715 -0.036854664537 0.00401838890454 -0.0376282085174 0.0071428571429 -0.0391744396898 0.00446470619211 -0.0190705212934 0.0116071428572 -0.0229367061318 0.0174107142857 -0.0175240473581 0.0178571428572 -0.0244831800671 0.0111607142857 -0.0252564170348 0.0107142857143 -0.0152043364551 0.0174107142857 -0.00515225587549 0.0133928571429 -0.0175240473581 0.0160714285714 -0.00592549284315 0.0102678571429 -0.0438141042587 0.0116071428572 -0.0298958388407 0.00803571428575 -0.0144308640254 0.0214281635964 -0.0206169952288 0.0178571428572 -0.0384015159926 0.0200891635917 -0.0291226018731 0.0147321428572 -0.0306690758084 0.0165178571429 -0.0469070521293 0.0142857142857 -0.0492267630323 0.0147321428572 -0.0291226018731 0.00848214285717 -0.0492267630323 0.0165178571429 -0.0144310994875 0.0116071428572 -0.0406528517416 0.000871831595523 -0.0492267630323 0.0183035714286 -0.0484535260647 0.0178571428572 -0.0314423602255 0.019642774958 -0.043040867291 0.00758928571433 -0.0314423127761 0.0133928571429 -0.0136389649833 0.00226856920845 -0.0283493649054 0.0151785714286 -0.0152043364551 0.00848214285716 -0.034535385256 0.019642616498 -0.0461338151617 0.00491071428576 -0.0167508103905 0.0111607142857 -0.0113381555318 0.0196428639239 -0.0391746419922 0.00535721293682 -0.0237099430994 0.00535714285717 -0.00824520374614 0.0133928571429 -0.0275761279377 0.0200892857143 -0.0182787431506 0.00226892651115 -0.0136578625198 0.0075892857143 -0.00979167768148 0.0160714285714 -0.00437901890783 0.00580357142859 -0.00592549284316 0.0174107142857 -0.0113381516168 0.00178571428574 -0.0136559328231 0.0218770632036 -0.0445873412264 0.0138392857143 -0.0237099430994 0.0214285714286 -0.00593231596211 0.0218661883721 -0.0260296540024 0.0111607142857 -0.0353084976144 0.0102678571429 -0.0182972843258 0.0174107142857 -0.0182972843258 0.0111607142857 -0.0399479194204 0.00758928571433 -0.0213902321964 0.0111607142857 -0.00437901890783 0.0191964285714 -0.043040867291 0.00937500000004 -0.0283493649054 0.0205357142857 -0.0144310994875 0.0169642857143 -0.00515225587549 0.0160714285714 -0.00901844071381 0.0138392857143 -0.035308504832 0.00401759226235 -0.0445873412264 0.0147321428572 -0.0445768660854 0.0218588090522 -0.0221634691641 0.0205357142857 -0.0144310994875 0.0107142857143 -0.0445873412264 0.00669642857147 -0.043040867291 0.0200892857143 -0.0128814429266 0.0214351251475 -0.0237099294717 0.00446430931823 -0.0283493649054 0.00714285714289 -0.00824520374615 0.0169642857143 -0.0237097295893 0.0223130581876 -0.0190705212934 0.0178571428572 -0.0353084896388 0.00491068603669 -0.0097917324007 0.0205358090622 -0.00284351620407 0.0173728237272 -0.0461338151617 0.0102678571429 -0.0407343166048 0.023200711364 -0.0213902321964 0.00491071428574 -0.0213902321964 0.00937500000002 -0.0329887867114 0.0133928571429 -0.00514781610539 0.00178897164161 -0.0368549715497 0.0111607142857 -0.0229367061318 0.0200892857143 -0.0360817345821 0.00714285714289 -0.0353090159568 0.0200882902485 -0.0213902321964 0.0102678571429 -0.0275761279377 0.0209821428572 -0.0469070521293 0.0116071428572 -0.0260296540024 0.0102678571429 -0.00208952529731 0.0213801122573 -0.040721156388 0.00803571428575 -0.0136578625198 0.0165178571429 -0.00360465761335 0.00265643828556 -0.0206169952288 0.00535714285717 -0.0275761279378 0.00758928571431 -0.00437901890783 0.00491071428573 -0.0175240473581 0.0107142857143 -0.0051522558755 0.0169642857143 -0.0484535260647 0.0169642857143 -0.00901845558482 0.0200893114716 -0.00360571040873 0.0196427332468 -0.0152043364551 0.0075892857143 -0.00437956119727 0.0138392857143 -0.0252564170348 0.00982142857145 -0.0128846255521 0.0160714285714 -0.0322155765451 0.0200892392929 -0.0414943933557 0.00758928571433 -0.0376282085174 0.00982142857146 -0.0399478306008 0.00491086812569 -0.0252564170348 0.0089285714286 -0.0422675509623 0.0205355768282 -0.0260295899744 0.00491082617161 -0.0345352606467 0.00714285714289 -0.0128846255521 0.0151785714286 -0.0422676303234 0.00803571428576 -0.0167508103905 0.00758928571431 -0.0237099430994 0.0205357142857 -0.0136578625198 0.0147321428572 -0.0345352606467 0.00803571428575 -0.0438141042587 0.0142857142857 -0.0345352606467 0.0133928571429 -0.00669872981081 0.00982142857144 -0.019843675279 0.00491048649739 -0.0175240473581 0.00982142857145 -0.0337622522732 0.0200888433285 -0.0190703927937 0.00446398586773 -0.0113381516168 0.0125 -0.038401445485 0.00937500000004 -0.0329887867114 0.00803571428575 -0.0469070521293 0.0107142857143 -0.0283471662866 0.0214237620922 -0.0414943768545 0.0200892571334 -0.0182972843258 0.00937500000002 -0.00747196677848 0.00937500000001 -0.0407211346496 0.00535718050928 -0.0237042923849 0.0231513693963 -0.0182972843258 0.00491071428574 -0.0175240473581 0.00446428571431 -0.0182972843258 0.00758928571431 -0.0360817345821 0.0133928571429 -0.00515225587549 0.00535714285716 -0.043040867291 0.0138392857143 -0.0213902321964 0.015625 -0.0182972843258 0.00848214285716 -0.0368549715497 0.0138392857143 -0.0159775734228 0.0151785714286 -0.0337620236791 0.0111607142857 -0.0329887867114 0.0089285714286 -0.0268028909701 0.0178571428572 -0.0291226018731 0.021875 -0.0407211401607 0.0205356861792 -0.0175240473581 0.00714285714288 -0.043040867291 0.00848214285718 -0.0221634691641 0.0160714285714 -0.00284343275073 0.0192341745845 -0.041494381455 0.00491073489839 -0.0329887867114 0.00982142857146 -0.0190705212934 0.00892857142859 -0.00824520374614 0.00982142857144 -0.0422676303234 0.0142857142857 -0.0329887867114 0.0107142857143 -0.0159775734228 0.00714285714288 -0.040721156388 0.0142857142857 -0.0198437582611 0.00937500000002 -0.0399479143893 0.0200892770003 -0.0414943933557 0.0138392857143 -0.0329889105579 0.020535481749 -0.0206169952288 0.00892857142859 -0.00901844071381 0.00937500000001 -0.0399479194204 0.0111607142857 -0.0422676281162 0.00535714668015 -0.0268028909701 0.00714285714289 -0.016750854874 0.00491079193979 -0.0221634691641 0.00803571428574 -0.040721156388 0.0151785714286 -0.0484535260647 0.00803571428575 -0.0229367061318 0.00848214285717 -0.0213902321964 0.00848214285717 -0.0360817345821 0.0107142857143 -0.00979167768147 0.00982142857144 -0.0244831800671 0.00848214285717 -0.0144310994875 0.00714285714288 -0.0237099430994 0.0089285714286 -0.040721156388 0.0160714285715 -0.045360578194 0.0169642857143 -0.0391747595341 0.0205355628419 -0.0329871430667 0.0214236805962 -0.00824452369457 0.0214273935447 -0.0430408670361 0.00401785758451 -0.0252564170348 0.0133928571429 -0.00592549284315 0.00491071428573 -0.0337444881656 0.0218362786629 -0.0260296540024 0.0138392857143 -0.0368549715497 0.0147321428572 -0.0252564170348 0.00803571428574 -0.0438141042587 0.0169642857143 -0.0260296540024 0.00758928571431 -0.0422676303234 0.0116071428572 -0.0391751768031 0.0214276704602 -0.040721156388 0.0107142857143 -0.043814404036 0.00357194806843 -0.00669872850854 0.00535714511277 -0.043040867291 0.0111607142857 -0.0422676303234 0.0169642857143 -0.0268028909701 0.0151785714286 -0.0391746824527 0.00982142857146 -0.0159779168344 0.00446488144535 -0.0391884864591 0.0223495795444 -0.00747198413303 0.00491078776473 -0.0391746824527 0.0107142857143 -0.0322157718198 0.00312457027012 -0.0105649146491 0.00848214285716 -0.0376282085174 0.0160714285715 -0.0229367061318 0.0165178571429 -0.0414943933557 0.0174107142857 -0.0329890362868 0.00357053971517 -0.0198437582611 0.0174107142857 -0.0476805964556 0.0183043408216 -0.0414943933557 0.0111607142857 -0.00824521062212 0.00625001256309 -0.043040867291 0.0174107142857 -0.0275761279377 0.0174107142857 -0.0206169952288 0.0169642857143 -0.0445873412264 0.0174107142857 -0.0484538272993 0.0187507063809 -0.0376282085174 0.0169642857143 -0.0206169952288 0.0160714285714 -0.0283493649054 0.0178571428572 -0.0438141042587 0.00803571428575 -0.0484552456751 0.0196465339273 -0.00286859090495 0.0147278286985 -0.0291226018731 0.0174107142857 -0.0298958388407 0.0178571428572 -0.0445873412264 0.00758928571433 -0.00901846916521 0.00580361847099 -0.040721156388 0.0169642857143 -0.047680289097 0.0102678571429 -0.0469071607062 0.0178574623337 -0.0461338332578 0.0174107675318 -0.0492270496341 0.0200898985117 -0.0237099430994 0.0160714285714 -0.00437965157884 0.0147321428571 -0.00669872981082 0.0151785714286 -0.00747196677848 0.015625 -0.0097917028528 0.00535718308305 -0.0322155497437 0.0165178571429 -0.0399479194204 0.0174107142857 -0.00824520374614 0.0160714285714 -0.0237099430994 0.0151785714286 -0.004379124353 0.015625 -0.0329887867114 0.0169642857143 -0.0391746824527 0.0169642857143 -0.0314423127761 0.0169642857143 -0.038401445485 0.0174107142857 -0.0244831800671 0.0147321428572 -0.0306690758084 0.0174107142857 -0.0368549715497 0.015625 -0.0337620236791 0.0165178571429 -0.0244831800671 0.0138392857143 -0.045360578194 0.00803571428575 -0.0492304220446 0.0209593105019 -0.0121114753882 0.00401800675732 -0.0345352606467 0.0169642857143 -0.0105650219039 0.00491089328743 -0.0461338151617 0.00758928571433 -0.0353084976144 0.0165178571429 -0.0113381516168 0.00892857142859 -0.0128846780771 0.00446437637195 -0.0360817345821 0.0160714285715 -0.0136578666879 0.00491072148168 -0.0113384505772 0.00446479415068 -0.0484535260647 0.00982142857146 -0.0469070521293 0.00803571428576 -0.0484535260647 0.0089285714286 -0.0144311107745 0.0044643052068 -0.0152046904202 0.00401847057359 -0.0152145462979 0.00314863095075 -0.047680289097 0.00758928571432 -0.047680289097 0.00669642857147 -0.0492267630323 0.0058035714286 -0.0484535260647 0.00625000000003 -0.0484535260647 0.00446428571432 -0.0492267630323 0.00401785714288 -0.0484547259584 0.00268064970551 -0.00756820397282 0.00218698411648 -0.0174330909807 0.0241535969225 -0.0191628678508 0.0242065568967 -0.0423707627677 0.000791242867713 -0.0430353018748 0.0227323528796 -0.0361807555971 0.0242262091408 -0.0147107613143 0.00070287759852 -0.0113539622691 0.0233369893826 -0.0388369845508 0.000717246504846 -0.000742237816188 0.00142599320655 -0.0353186001739 0.0227427154265 -0.0460433768493 0.0227571029723 -0.0384141230969 0.00229313439646 -0.0152137091469 0.00229180659312 -0.0152587986558 0.0236736798578 -0.0307204529585 0.0226562851898 -0.0437907529569 0.023089981162 -0.0445634408413 0.00143874735926 -0.0214177306161 0.00139918488135 -0.0212533308246 0.0236108462048 -0.0383994713019 0.0235703794525 -0.0392270845025 0.00190553681357 -0.00907491741663 0.00232996337589 -0.0445283923965 0.0226561462539 -0.032167666897 0.0235511156895 -0.00443780048845 0.00145063247482 -0.00895781071336 0.0235557000445 -0.0143673532134 0.0019065355861 -0.0276385576515 0.0235525828496 -0.0276485450039 0.00147174617461 -0.0321712248664 0.00144346126627 -0.0259625102062 0.00145558218081 -0.0259625102061 0.0235444178192 -0.0433162456078 0.0243325475405 -0.0053217017347 0.0236415933609 -0.0027650531367 0.00146270611311 -0.0337328552007 0.0226622440621 -0.0106130369697 0.0235373515173 -0.0338457269688 0.00144253659917 -0.0197560207477 0.00146456526858 -0.0433035714286 0.000621003121787 -0.0168439835294 0.00150011319494 -0.0200892857142 0.0243822559788 -0.0368874666168 0.0226527559092 -0.0399478103732 0.00146693239638 -0.0165085274647 0.0243540794887 -0.0370267155303 0.000603318189792 -0.0400581739369 0.0235438529259 -0.0136178715763 0.00147393371135 -0.0230440637063 0.0235071122908 -0.00582212955158 0.000607307828996 -0.00734136974043 0.0235154653917 -0.049401899124 0.0227678571429 -0.00224226069075 0.0244037427576 -0.0477584859494 0.000596610338446 -0.0120535714286 0.000596486082695 -0.0415178571428 0.0244045563664 -0.0290283036748 0.0226415577697 -0.0290647581583 0.000600762511751 -0.0243540373469 0.00149894424202 -0.0243510592496 0.0235018900059 -0.00351716034472 0.0221035543591 -0.041425312261 0.00146345742996 -0.0230597799658 0.00145995987765 -0.0182252513109 0.00147208276827 -0.0182250297703 0.0235375908531 -0.00397902879607 0.024415679758 -0.046036086998 0.000615698716367 -0.0485512542284 0.0212593012837 -0.0474700744383 0.0218691551028 -0.0308035714286 0.000574481362574 -0.0137306841792 0.0243772191156 -0.0015089522811 0.00491071428572 -0.000565552057866 0.00580357142856 -0.0015089522811 0.00669642857144 -0.00151086178378 0.00848217469671 -0.000565552057866 0.00758928571427 -0.000565552057865 0.00401785714285 -0.00150779847604 0.00312500000001 -0.000565552057864 0.00937499999998 -0.000560309164205 0.0022494843556 -0.00150980114262 0.0102686171663 -0.000565552057863 0.0111607142857 -0.00151958165094 0.0120360345414 -0.00131329739545 0.0151596178783 -0.000565552057864 0.0165178571428 -0.000720518979307 0.0205357142857 -0.00208011024125 0.0183042441197 -0.00218530975512 0.0135496411022 -0.0022902214786 0.0143037978356 -0.00732681252978 0.00144026724319 -0.00596528171711 0.0234791241358 -0.00148685563179 0.00143268411919 -0.0120584281633 0.0244525403697 -0.0493463832075 0.0243463832075 -0.0493463832075 0.000653616792475 -0.000653616792474 0.0243463832075 -0.0352729929673 0.000548942818265 -0.000631948455853 0.000637662529921 -0.0106563951299 0.00150655132959 -0.00141633839576 0.0194193633831 -0.00219000832974 0.0220996514467 -0.00141677136207 0.0216532228753 -0.00146840326072 0.0172153585715 -0.00149887721524 0.015732146752 -0.00216202201482 0.0189622230378 -0.000658639840881 0.0198743123717 -0.000660599824308 0.0211958661298 -0.00216274099263 0.0176472284477 -0.0013511329986 0.0126346597299 -0.00296325512778 0.0225316687983 -0.00456751531915 0.022605254398 -0.00837134924695 0.0020498270746 -0.0143040103075 0.00123844095324 -0.0451290186004 0.0229368465357 -0.0392536154652 0.00123981912607 -0.0361631340246 0.0229483386455 -0.046875 0.0229750453639 -0.0437881246818 0.0237575957423 -0.0344238438874 0.0229604998635 -0.0437165792324 0.0011731118092 -0.0205125246078 0.0238289206327 -0.00527656841683 0.0229968401744 -0.016031154826 0.023827815164 -0.0149567965716 0.0244132285637 -3 1179 180 1195 1 -3 1162 1809 1868 1 -3 92 201 1188 1 -3 1027 1307 1870 1 -3 1143 225 1248 1 -3 169 1242 1399 1 -3 1809 191 1868 1 -3 1808 1160 1871 1 -3 1180 1265 1266 1 -3 1239 851 1424 1 -3 1307 1306 1870 1 -3 1180 215 1265 1 -3 225 1143 1866 1 -3 1399 1242 1865 1 -3 1292 218 1505 1 -3 170 1808 1871 1 -3 1178 1267 1268 1 -3 1195 180 1852 1 -3 846 1266 1267 1 -3 1136 1309 1729 1 -3 175 1159 1435 1 -3 111 229 1383 1 -3 1167 174 1329 1 -3 849 851 1241 1 -3 176 1177 1302 1 -3 1166 202 1602 1 -3 1165 171 1501 1 -3 183 1168 1284 1 -3 1334 186 1504 1 -3 1394 229 1493 1 -3 1171 185 1218 1 -3 218 1292 1857 1 -3 993 1215 1614 1 -3 1283 1281 1369 1 -3 130 131 1257 1 -3 174 1167 1330 1 -3 1215 1150 1614 1 -3 1168 183 1285 1 -3 230 1382 1385 1 -3 1159 175 1855 1 -3 1169 181 1564 1 -3 1023 849 1241 1 -3 1267 1178 1821 1 -3 211 1178 1268 1 -3 1309 1114 1729 1 -3 1188 201 1823 1 -3 1141 1239 1424 1 -3 91 92 1188 1 -3 1266 173 1267 1 -3 202 1166 1856 1 -3 209 1183 1184 1 -3 851 1239 1824 1 -3 1265 173 1266 1 -3 1369 1281 1872 1 -3 1247 1036 1813 1 -3 110 111 1383 1 -3 1302 1177 1847 1 -3 1227 1226 1894 1 -3 1894 1226 1895 1 -3 60 61 1221 1 -3 87 88 1263 1 -3 5 6 1277 1 -3 212 1172 1257 1 -3 1382 230 1876 1 -3 1177 176 1303 1 -3 184 1184 1598 1 -3 1411 1410 1492 1 -3 180 1179 1196 1 -3 131 212 1257 1 -3 181 130 1257 1 -3 38 39 1268 1 -3 1383 229 1835 1 -3 1172 212 1256 1 -3 171 1165 1844 1 -3 1266 846 1863 1 -3 1309 1136 1826 1 -3 1164 1230 1898 1 -3 1334 1504 1843 1 -3 1394 1493 1837 1 -3 185 1171 1838 1 -3 210 1181 1870 1 -3 1355 1807 1871 1 -3 174 1330 1811 1 -3 127 128 1186 1 -3 1264 205 1322 1 -3 1222 206 1224 1 -3 1278 207 1280 1 -3 757 1192 1246 1 -3 134 135 1194 1 -3 216 127 1186 1 -3 846 1267 1821 1 -3 1542 1349 1868 1 -3 181 1169 1861 1 -3 229 1394 1835 1 -3 1171 1218 1834 1 -3 1241 851 1824 1 -3 1183 209 1185 1 -3 1380 187 1381 1 -3 1330 1288 1811 1 -3 60 1221 1900 1 -3 87 1263 1901 1 -3 5 1277 1902 1 -3 186 1334 1832 1 -3 231 1191 1813 1 -3 1409 227 1410 1 -3 1284 1168 1830 1 -3 172 1190 1191 1 -3 1019 1410 1411 1 -3 1280 207 1281 1 -3 187 1380 1382 1 -3 1192 1247 1813 1 -3 1165 1501 1836 1 -3 205 1187 1322 1 -3 1657 1472 1866 1 -3 1237 1337 1865 1 -3 1019 1409 1410 1 -3 1138 1020 1411 1 -3 1191 231 1899 1 -3 209 1184 1862 1 -3 173 38 1268 1 -3 39 211 1268 1 -3 172 1189 1190 1 -3 1230 236 1898 1 -3 1162 1163 1809 1 -3 1306 210 1870 1 -3 1161 1160 1808 1 -3 1355 1357 1807 1 -3 1195 227 1409 1 -3 1492 1410 1903 1 -3 1224 976 1875 1 -3 976 1224 1874 1 -3 1807 170 1871 1 -3 1020 1019 1411 1 -3 1156 1477 1857 1 -3 1215 993 1831 1 -3 1192 1190 1246 1 -3 192 134 1194 1 -3 42 43 1286 1 -3 191 1542 1868 1 -3 1192 757 1247 1 -3 1167 1329 1826 1 -3 1174 1815 1886 1 -3 1047 1048 1384 1 -3 1472 1657 1855 1 -3 1282 738 1867 1 -3 1051 1258 1385 1 -3 1184 184 1862 1 -3 1435 1159 1825 1 -3 1267 173 1268 1 -3 1815 1174 1898 1 -3 1349 1542 1850 1 -3 1285 183 1286 1 -3 1384 1051 1385 1 -3 1181 210 1847 1 -3 190 1300 1881 1 -3 228 1295 1887 1 -3 1295 228 1888 1 -3 1300 190 1885 1 -3 224 1176 1880 1 -3 1176 224 1882 1 -3 198 1333 1878 1 -3 1333 198 1879 1 -3 1154 1226 1890 1 -3 1226 1154 1895 1 -3 223 1415 1884 1 -3 1415 223 1883 1 -3 1175 182 1891 1 -3 1174 223 1884 1 -3 223 1174 1886 1 -3 1415 198 1878 1 -3 198 1415 1883 1 -3 1333 224 1880 1 -3 224 1333 1879 1 -3 1176 190 1881 1 -3 190 1176 1882 1 -3 220 1175 1891 1 -3 1300 228 1887 1 -3 228 1300 1885 1 -3 1295 179 1889 1 -3 179 1295 1888 1 -3 1151 1227 1894 1 -3 1307 1027 1845 1 -3 1178 211 1830 1 -3 43 213 1286 1 -3 183 42 1286 1 -3 1285 1286 1287 1 -3 1602 202 1831 1 -3 1292 1505 1832 1 -3 215 1180 1834 1 -3 184 1598 1853 1 -3 1472 225 1866 1 -3 1242 1237 1865 1 -3 1194 135 1856 1 -3 1230 1164 1841 1 -3 169 1399 1837 1 -3 1143 1248 1838 1 -3 1380 1047 1384 1 -3 1048 1051 1384 1 -3 1191 1190 1192 1 -3 1280 1281 1282 1 -3 1337 1237 1869 1 -3 1564 181 1905 1 -3 1224 206 1874 1 -3 738 1282 1917 1 -3 1382 1380 1384 1 -3 1477 1156 1897 1 -3 1175 220 1909 1 -3 182 1175 1910 1 -3 1227 1151 1915 1 -3 1303 176 1812 1 -3 1135 1819 1833 1 -3 1822 1232 1829 1 -3 1818 847 1827 1 -3 1183 1185 1810 1 -3 714 747 1247 1 -3 1282 1281 1283 1 -3 180 1196 1814 1 -3 206 1222 1858 1 -3 207 1278 1859 1 -3 205 1264 1860 1 -3 1477 218 1857 1 -3 747 1036 1247 1 -3 757 714 1247 1 -3 1180 1266 1863 1 -3 1286 213 1287 1 -3 1382 1384 1385 1 -3 1806 947 1918 1 -3 1287 213 1288 1 -3 1255 1806 1918 1 -3 1261 1262 1805 1 -3 991 1262 1264 1 -3 991 1264 1322 1 -3 1262 991 1805 1 -3 1591 899 1769 1 -3 1434 1200 1561 1 -3 1199 1200 1434 1 -3 339 343 1491 1 -3 344 1199 1434 1 -3 343 1490 1491 1 -3 1199 344 1580 1 -3 1200 899 1561 1 -3 344 339 1491 1 -3 344 1491 1580 1 -3 1253 1203 1648 1 -3 343 1203 1490 1 -3 591 1733 1788 1 -3 189 1697 1795 1 -3 1203 343 1648 1 -3 786 1103 1206 1 -3 1206 1103 1579 1 -3 1361 1077 1726 1 -3 899 1200 1769 1 -3 907 1202 1253 1 -3 1202 1203 1253 1 -3 83 219 1804 1 -3 907 906 1204 1 -3 1202 907 1204 1 -3 1205 588 1701 1 -3 989 987 1322 1 -3 81 197 1801 1 -3 808 858 1752 1 -3 1204 1205 1701 1 -3 763 1197 1361 1 -3 1197 763 1362 1 -3 1198 1044 1366 1 -3 1321 585 1338 1 -3 585 1208 1390 1 -3 155 156 1228 1 -3 1208 585 1321 1 -3 179 155 1228 1 -3 763 1361 1726 1 -3 1051 1050 1732 1 -3 1209 1389 1390 1 -3 1208 1209 1390 1 -3 902 1057 1422 1 -3 1057 1421 1422 1 -3 491 493 1213 1 -3 1044 1198 1367 1 -3 1213 493 1497 1 -3 1187 989 1322 1 -3 710 759 1709 1 -3 1212 1397 1528 1 -3 500 491 1213 1 -3 875 1212 1528 1 -3 1204 906 1205 1 -3 500 1201 1235 1 -3 1323 1366 1722 1 -3 1201 500 1213 1 -3 493 1441 1497 1 -3 858 1250 1752 1 -3 178 239 240 1 -3 1291 1140 1292 1 -3 987 991 1322 1 -3 1001 1236 1503 1 -3 1697 1130 1795 1 -3 1579 1103 1771 1 -3 178 74 239 1 -3 1233 1259 1260 1 -3 1711 303 1780 1 -3 759 1140 1291 1 -3 678 1591 1769 1 -3 219 1261 1805 1 -3 1236 1235 1503 1 -3 1231 55 1259 1 -3 1070 1321 1338 1 -3 1733 1205 1788 1 -3 1236 1001 1317 1 -3 990 1198 1366 1 -3 240 239 1289 1 -3 1389 1209 1391 1 -3 493 1391 1441 1 -3 736 1579 1771 1 -3 630 1216 1323 1 -3 1060 1305 1621 1 -3 1258 1051 1732 1 -3 169 114 1242 1 -3 114 115 1242 1 -3 1314 233 1375 1 -3 1042 678 1765 1 -3 1233 1231 1259 1 -3 763 696 1362 1 -3 696 618 1362 1 -3 904 902 1422 1 -3 1429 1326 1667 1 -3 32 33 1248 1 -3 1124 956 1714 1 -3 1711 1124 1714 1 -3 1765 678 1769 1 -3 219 1211 1804 1 -3 185 34 1218 1 -3 788 1210 1396 1 -3 1206 1042 1764 1 -3 214 157 1225 1 -3 73 74 178 1 -3 138 208 1214 1 -3 58 238 1219 1 -3 723 240 1289 1 -3 1764 1042 1765 1 -3 233 1249 1375 1 -3 273 1603 1700 1 -3 1077 1207 1726 1 -3 140 236 1230 1 -3 225 32 1248 1 -3 1214 208 1215 1 -3 1421 1057 1432 1 -3 1219 238 1220 1 -3 856 1398 1429 1 -3 119 177 1240 1 -3 535 538 1703 1 -3 214 1225 1226 1 -3 759 1291 1709 1 -3 136 137 202 1 -3 278 277 1668 1 -3 538 1432 1560 1 -3 1229 997 1316 1 -3 1298 728 1304 1 -3 1210 788 1576 1 -3 1391 1209 1441 1 -3 1240 177 1241 1 -3 116 199 1237 1 -3 1063 1123 1620 1 -3 75 217 239 1 -3 1060 1251 1305 1 -3 1061 1212 1571 1 -3 1235 1201 1503 1 -3 1397 1398 1528 1 -3 1432 1057 1560 1 -3 823 1234 1354 1 -3 1343 1301 1642 1 -3 1220 1223 1457 1 -3 1072 1365 1539 1 -3 156 214 1228 1 -3 1146 1299 1304 1 -3 1219 1220 1457 1 -3 1347 1346 1730 1 -3 73 178 1249 1 -3 1234 823 1355 1 -3 1299 1298 1304 1 -3 1365 863 1539 1 -3 54 55 1231 1 -3 56 57 203 1 -3 1269 188 1270 1 -3 788 957 1576 1 -3 997 754 1316 1 -3 485 481 1391 1 -3 985 988 1430 1 -3 1251 1060 1468 1 -3 138 139 208 1 -3 1212 875 1571 1 -3 332 334 1363 1 -3 1216 990 1366 1 -3 1061 1571 1593 1 -3 1398 856 1528 1 -3 1305 1055 1621 1 -3 1137 843 1592 1 -3 695 1401 1639 1 -3 956 1207 1714 1 -3 334 1252 1363 1 -3 33 185 1248 1 -3 997 1229 1317 1 -3 504 501 1235 1 -3 501 500 1235 1 -3 1216 630 1430 1 -3 1001 998 1317 1 -3 1314 1270 1538 1 -3 233 72 1249 1 -3 869 1245 1353 1 -3 1358 277 1425 1 -3 695 1318 1325 1 -3 588 1205 1733 1 -3 1366 1044 1722 1 -3 33 34 185 1 -3 754 752 1316 1 -3 133 192 1254 1 -3 197 1244 1801 1 -3 72 73 1249 1 -3 1323 1216 1366 1 -3 1270 188 1538 1 -3 1318 1081 1325 1 -3 1254 192 1255 1 -3 115 1237 1242 1 -3 1207 956 1726 1 -3 1413 1251 1468 1 -3 188 1269 1540 1 -3 156 157 214 1 -3 1301 275 1642 1 -3 239 217 1289 1 -3 1271 1065 1274 1 -3 178 241 1249 1 -3 77 189 1243 1 -3 602 1217 1603 1 -3 1345 1344 1601 1 -3 1065 1066 1274 1 -3 58 59 238 1 -3 1358 1425 1570 1 -3 872 1314 1375 1 -3 74 75 239 1 -3 1245 869 1354 1 -3 843 860 1567 1 -3 1220 238 1221 1 -3 615 1272 1486 1 -3 219 84 1261 1 -3 140 141 236 1 -3 602 1115 1629 1 -3 752 660 1589 1 -3 1272 1290 1486 1 -3 115 116 1237 1 -3 132 133 1254 1 -3 75 76 217 1 -3 1234 1064 1354 1 -3 1121 677 1675 1 -3 233 1314 1538 1 -3 1262 235 1263 1 -3 37 173 1265 1 -3 178 240 241 1 -3 1254 1255 1256 1 -3 1262 1263 1264 1 -3 748 853 1356 1 -3 757 1246 1588 1 -3 579 1444 1692 1 -3 856 1429 1667 1 -3 35 215 1218 1 -3 1217 602 1629 1 -3 872 1313 1314 1 -3 998 997 1317 1 -3 158 182 1225 1 -3 1273 873 1448 1 -3 1664 867 1748 1 -3 35 36 215 1 -3 1103 1763 1771 1 -3 728 1298 1324 1 -3 335 332 1363 1 -3 1290 866 1486 1 -3 988 1216 1430 1 -3 116 117 199 1 -3 1087 1719 1724 1 -3 450 929 1745 1 -3 277 1358 1668 1 -3 1276 237 1277 1 -3 1211 1803 1804 1 -3 217 76 1243 1 -3 1749 410 1753 1 -3 1316 752 1589 1 -3 1123 1544 1620 1 -3 204 166 1275 1 -3 123 124 1302 1 -3 1252 334 1377 1 -3 1355 1356 1357 1 -3 1318 695 1639 1 -3 531 534 1683 1 -3 1249 241 1375 1 -3 1293 731 1296 1 -3 1094 1197 1743 1 -3 1629 1115 1649 1 -3 398 1360 1475 1 -3 1065 1271 1494 1 -3 214 1226 1227 1 -3 493 485 1391 1 -3 1353 1245 1473 1 -3 481 1389 1391 1 -3 1210 1087 1724 1 -3 1344 279 1601 1 -3 1261 235 1262 1 -3 1056 1291 1292 1 -3 843 1567 1592 1 -3 1064 1245 1354 1 -3 1603 1217 1700 1 -3 642 640 1324 1 -3 860 1360 1638 1 -3 41 42 183 1 -3 1220 1221 1222 1 -3 1276 1279 1315 1 -3 691 800 1494 1 -3 1275 1276 1315 1 -3 177 120 1307 1 -3 1296 731 1324 1 -3 118 119 1240 1 -3 204 1275 1315 1 -3 203 57 1219 1 -3 85 235 1261 1 -3 983 985 1430 1 -3 49 184 1308 1 -3 121 122 1306 1 -3 1746 1066 1751 1 -3 85 86 235 1 -3 866 1290 1407 1 -3 1590 502 1616 1 -3 34 35 1218 1 -3 199 117 1238 1 -3 1338 494 1339 1 -3 41 183 1284 1 -3 863 1272 1539 1 -3 56 203 1259 1 -3 1137 1592 1657 1 -3 1392 1157 1568 1 -3 1269 1063 1620 1 -3 39 40 211 1 -3 157 158 1225 1 -3 504 1235 1236 1 -3 137 138 1214 1 -3 220 1310 1312 1 -3 1275 237 1276 1 -3 1304 728 1450 1 -3 139 140 1230 1 -3 1276 1277 1278 1 -3 853 1170 1356 1 -3 210 123 1302 1 -3 1273 635 1532 1 -3 1236 1317 1633 1 -3 1340 1392 1568 1 -3 220 161 1310 1 -3 1070 1338 1339 1 -3 505 504 1633 1 -3 1487 1373 1605 1 -3 208 139 1230 1 -3 1664 1121 1675 1 -3 1365 1590 1616 1 -3 1400 1691 1731 1 -3 1310 1311 1312 1 -3 558 1347 1730 1 -3 1163 992 1367 1 -3 731 1293 1489 1 -3 1377 1078 1416 1 -3 202 137 1214 1 -3 214 1227 1228 1 -3 57 58 1219 1 -3 1365 1072 1590 1 -3 158 159 182 1 -3 1083 876 1606 1 -3 1246 1565 1588 1 -3 167 168 237 1 -3 55 56 1259 1 -3 167 237 1275 1 -3 705 823 1354 1 -3 1420 1273 1448 1 -3 538 1560 1703 1 -3 334 1078 1377 1 -3 1361 1043 1549 1 -3 1576 957 1674 1 -3 1352 1353 1473 1 -3 454 708 1413 1 -3 1238 118 1240 1 -3 640 728 1324 1 -3 1404 1706 1760 1 -3 1565 635 1588 1 -3 199 1238 1239 1 -3 823 748 1356 1 -3 215 36 1265 1 -3 867 1320 1484 1 -3 129 130 181 1 -3 1050 1053 1732 1 -3 1154 808 1752 1 -3 1360 398 1476 1 -3 203 1219 1457 1 -3 1387 1326 1429 1 -3 117 118 1238 1 -3 119 120 177 1 -3 736 656 1619 1 -3 869 705 1354 1 -3 731 642 1324 1 -3 800 1065 1494 1 -3 1320 1453 1484 1 -3 992 1044 1367 1 -3 446 1370 1742 1 -3 37 38 173 1 -3 985 986 987 1 -3 1342 864 1510 1 -3 1272 615 1539 1 -3 1301 1118 1661 1 -3 708 1251 1413 1 -3 1532 635 1565 1 -3 47 48 222 1 -3 988 987 989 1 -3 126 127 216 1 -3 1259 203 1260 1 -3 1317 1229 1633 1 -3 1077 1361 1549 1 -3 245 247 1537 1 -3 661 455 1340 1 -3 1567 860 1638 1 -3 873 1273 1532 1 -3 720 1416 1585 1 -3 1732 1053 1737 1 -3 1444 1089 1692 1 -3 1436 1335 1517 1 -3 212 1254 1256 1 -3 985 987 988 1 -3 728 638 1450 1 -3 739 815 1331 1 -3 1332 1147 1333 1 -3 212 132 1254 1 -3 504 1236 1633 1 -3 1037 1187 1188 1 -3 1313 872 1537 1 -3 1326 1387 1464 1 -3 983 984 985 1 -3 836 834 1465 1 -3 1351 283 1547 1 -3 825 1147 1332 1 -3 1355 823 1356 1 -3 48 49 1308 1 -3 1079 1510 1554 1 -3 1310 194 1311 1 -3 1223 1222 1224 1 -3 174 46 1329 1 -3 1147 827 1414 1 -3 1378 1351 1547 1 -3 1398 1388 1429 1 -3 1305 710 1709 1 -3 869 1353 1423 1 -3 1661 1118 1666 1 -3 451 658 1395 1 -3 496 1487 1605 1 -3 834 1112 1465 1 -3 975 631 1586 1 -3 1485 879 1519 1 -3 1053 1321 1737 1 -3 753 754 995 1 -3 1327 221 1328 1 -3 83 84 219 1 -3 84 85 1261 1 -3 860 746 1359 1 -3 222 1308 1309 1 -3 365 1413 1468 1 -3 753 752 754 1 -3 552 551 1336 1 -3 291 288 1406 1 -3 996 999 1399 1 -3 1298 1296 1324 1 -3 646 644 1489 1 -3 966 1343 1344 1 -3 494 495 1594 1 -3 1331 815 1350 1 -3 1360 1359 1475 1 -3 671 757 1588 1 -3 1171 813 1455 1 -3 160 161 220 1 -3 768 1436 1517 1 -3 1353 384 1423 1 -3 746 662 1359 1 -3 977 976 1131 1 -3 1279 1278 1280 1 -3 1747 1418 1775 1 -3 1260 203 1457 1 -3 817 1161 1350 1 -3 1453 1393 1484 1 -3 43 44 213 1 -3 972 942 1675 1 -3 1094 1743 1749 1 -3 189 78 1327 1 -3 47 222 1329 1 -3 291 1406 1407 1 -3 910 1348 1349 1 -3 966 967 1343 1 -3 644 731 1489 1 -3 1540 1269 1620 1 -3 1151 868 1152 1 -3 1339 494 1594 1 -3 665 738 1340 1 -3 800 799 976 1 -3 589 1323 1722 1 -3 751 752 753 1 -3 162 194 1310 1 -3 131 132 212 1 -3 708 661 709 1 -3 995 754 996 1 -3 455 665 1340 1 -3 1407 1290 1478 1 -3 946 945 1346 1 -3 166 167 1275 1 -3 990 989 1037 1 -3 1352 384 1353 1 -3 1017 1403 1518 1 -3 1510 864 1554 1 -3 691 799 800 1 -3 660 596 1589 1 -3 710 709 759 1 -3 995 996 1399 1 -3 910 911 1348 1 -3 751 660 752 1 -3 76 77 1243 1 -3 36 37 1265 1 -3 988 989 990 1 -3 454 661 708 1 -3 1037 989 1187 1 -3 1431 920 1640 1 -3 815 817 1350 1 -3 1152 1293 1294 1 -3 872 245 1537 1 -3 563 1485 1519 1 -3 860 1359 1360 1 -3 708 709 710 1 -3 1416 1078 1585 1 -3 165 166 204 1 -3 222 48 1308 1 -3 658 691 1494 1 -3 1000 1010 1394 1 -3 10 11 195 1 -3 456 685 1378 1 -3 1341 368 1342 1 -3 996 998 999 1 -3 1387 323 1464 1 -3 356 368 1341 1 -3 842 746 843 1 -3 800 976 977 1 -3 786 1206 1764 1 -3 685 796 1378 1 -3 487 585 1390 1 -3 1386 1388 1454 1 -3 454 455 661 1 -3 745 662 746 1 -3 424 425 1371 1 -3 556 560 1335 1 -3 122 210 1306 1 -3 852 1056 1334 1 -3 582 584 589 1 -3 1152 1294 1295 1 -3 1388 715 1454 1 -3 842 843 1137 1 -3 1146 1145 1176 1 -3 370 454 1413 1 -3 845 739 1331 1 -3 665 706 738 1 -3 1344 1343 1642 1 -3 1368 1448 1516 1 -3 385 384 1352 1 -3 295 292 1417 1 -3 917 915 1412 1 -3 999 998 1000 1 -3 1074 778 1364 1 -3 1362 618 1670 1 -3 46 47 1329 1 -3 241 240 242 1 -3 1695 939 1698 1 -3 987 986 991 1 -3 962 1345 1351 1 -3 402 399 1475 1 -3 1014 1379 1381 1 -3 1403 1402 1518 1 -3 715 1388 1398 1 -3 193 1231 1232 1 -3 1069 845 1159 1 -3 120 121 1307 1 -3 759 820 1140 1 -3 443 446 1374 1 -3 1406 866 1407 1 -3 375 374 1368 1 -3 999 1000 1394 1 -3 113 114 169 1 -3 79 221 1327 1 -3 753 995 1337 1 -3 338 341 1428 1 -3 966 1344 1345 1 -3 1551 1083 1606 1 -3 468 295 1417 1 -3 803 982 983 1 -3 1014 1011 1379 1 -3 745 746 842 1 -3 1448 873 1516 1 -3 1341 1342 1510 1 -3 1417 1407 1478 1 -3 435 438 1408 1 -3 1152 868 1293 1 -3 945 839 1101 1 -3 350 1341 1451 1 -3 374 1420 1448 1 -3 1422 591 1788 1 -3 607 1088 1597 1 -3 876 750 1405 1 -3 310 1393 1453 1 -3 985 984 986 1 -3 1085 744 1462 1 -3 865 824 1145 1 -3 40 41 1284 1 -3 809 732 868 1 -3 527 530 1673 1 -3 1294 1296 1297 1 -3 974 949 978 1 -3 663 617 689 1 -3 1356 1170 1357 1 -3 584 630 1323 1 -3 1363 1253 1648 1 -3 978 1346 1347 1 -3 150 151 190 1 -3 315 460 1393 1 -3 1232 1231 1233 1 -3 616 388 617 1 -3 949 946 1346 1 -3 498 1402 1403 1 -3 1297 1299 1300 1 -3 1159 845 1331 1 -3 161 162 1310 1 -3 1379 1380 1381 1 -3 701 429 1418 1 -3 865 1145 1146 1 -3 1293 868 1489 1 -3 950 974 1474 1 -3 587 586 637 1 -3 739 689 815 1 -3 370 453 454 1 -3 498 499 1402 1 -3 729 865 1450 1 -3 1414 1148 1415 1 -3 456 1378 1547 1 -3 546 545 547 1 -3 556 559 560 1 -3 538 539 1432 1 -3 465 1273 1420 1 -3 1108 1111 1372 1 -3 548 547 549 1 -3 560 559 586 1 -3 990 1037 1198 1 -3 546 547 548 1 -3 933 992 1162 1 -3 1351 1345 1601 1 -3 1389 483 1390 1 -3 366 465 1420 1 -3 1065 977 1066 1 -3 447 450 1370 1 -3 296 299 1433 1 -3 695 329 1401 1 -3 962 963 1345 1 -3 81 82 197 1 -3 544 545 546 1 -3 815 816 817 1 -3 808 737 858 1 -3 1005 917 1412 1 -3 162 163 194 1 -3 691 758 799 1 -3 729 824 865 1 -3 592 473 1443 1 -3 911 933 1348 1 -3 281 278 1668 1 -3 11 12 1477 1 -3 439 441 442 1 -3 341 874 1428 1 -3 1335 560 1517 1 -3 446 445 447 1 -3 585 489 1338 1 -3 79 80 221 1 -3 318 1386 1454 1 -3 929 628 930 1 -3 729 730 824 1 -3 1019 1016 1409 1 -3 442 443 1374 1 -3 506 507 1439 1 -3 1088 594 1500 1 -3 554 556 1335 1 -3 1071 508 1229 1 -3 550 549 551 1 -3 1326 1325 1667 1 -3 865 1304 1450 1 -3 1386 323 1387 1 -3 458 285 471 1 -3 439 442 1376 1 -3 1421 591 1422 1 -3 809 868 1151 1 -3 473 471 1443 1 -3 720 770 1416 1 -3 589 584 1323 1 -3 662 609 1359 1 -3 77 78 189 1 -3 438 437 439 1 -3 356 360 368 1 -3 483 487 1390 1 -3 978 949 1346 1 -3 211 40 1284 1 -3 817 1064 1160 1 -3 450 628 929 1 -3 285 282 1442 1 -3 683 607 1597 1 -3 1397 715 1398 1 -3 442 441 443 1 -3 829 1148 1414 1 -3 471 1442 1443 1 -3 548 549 550 1 -3 1162 992 1163 1 -3 637 653 729 1 -3 827 829 1414 1 -3 1401 871 1639 1 -3 825 827 1147 1 -3 443 445 446 1 -3 640 638 728 1 -3 435 437 438 1 -3 133 134 192 1 -3 447 449 450 1 -3 883 881 1373 1 -3 663 689 739 1 -3 996 997 998 1 -3 617 1352 1473 1 -3 1000 1002 1010 1 -3 438 439 1376 1 -3 388 385 1352 1 -3 264 263 1400 1 -3 243 872 1375 1 -3 450 449 628 1 -3 658 690 691 1 -3 446 447 1370 1 -3 732 646 1489 1 -3 617 388 1352 1 -3 544 543 545 1 -3 1014 1381 1383 1 -3 479 483 1389 1 -3 1251 710 1305 1 -3 705 748 823 1 -3 616 617 663 1 -3 702 701 1125 1 -3 550 551 552 1 -3 1368 374 1448 1 -3 764 1062 1313 1 -3 560 586 587 1 -3 634 666 705 1 -3 939 934 1698 1 -3 312 315 1393 1 -3 933 1162 1348 1 -3 282 281 1442 1 -3 967 980 1343 1 -3 747 852 1036 1 -3 1294 1293 1296 1 -3 1010 1011 1014 1 -3 817 1160 1161 1 -3 1062 1269 1270 1 -3 1036 852 1334 1 -3 1297 1298 1299 1 -3 551 554 1336 1 -3 759 709 820 1 -3 471 285 1442 1 -3 417 420 1446 1 -3 542 543 544 1 -3 380 459 634 1 -3 1340 738 1392 1 -3 434 435 1408 1 -3 539 541 542 1 -3 638 637 1450 1 -3 294 296 1433 1 -3 963 966 1345 1 -3 305 302 1524 1 -3 320 323 1386 1 -3 1062 1063 1269 1 -3 980 1118 1301 1 -3 396 1482 1483 1 -3 847 848 1445 1 -3 839 836 1465 1 -3 458 471 472 1 -3 1220 1222 1223 1 -3 579 582 1444 1 -3 735 656 736 1 -3 428 701 702 1 -3 764 1313 1537 1 -3 556 557 559 1 -3 824 825 1332 1 -3 614 681 764 1 -3 429 431 1418 1 -3 843 746 860 1 -3 1140 820 1156 1 -3 399 398 1475 1 -3 276 274 277 1 -3 350 356 1341 1 -3 397 400 1482 1 -3 634 459 666 1 -3 472 471 473 1 -3 815 689 816 1 -3 877 876 1083 1 -3 803 983 1552 1 -3 247 614 1537 1 -3 1043 798 1549 1 -3 983 982 984 1 -3 905 1252 1377 1 -3 336 338 1428 1 -3 428 429 701 1 -3 903 904 905 1 -3 366 371 465 1 -3 380 378 459 1 -3 431 434 1418 1 -3 1015 818 1179 1 -3 587 637 638 1 -3 692 741 818 1 -3 389 616 1511 1 -3 817 816 1064 1 -3 764 765 1062 1 -3 544 591 1421 1 -3 464 667 1452 1 -3 816 689 1473 1 -3 507 510 1439 1 -3 688 631 975 1 -3 1252 907 1253 1 -3 379 378 380 1 -3 554 555 556 1 -3 1386 1387 1388 1 -3 707 715 1397 1 -3 523 526 1458 1 -3 395 394 1476 1 -3 958 785 1061 1 -3 1025 1026 1105 1 -3 431 433 434 1 -3 542 541 543 1 -3 1127 794 1128 1 -3 905 906 907 1 -3 449 451 1395 1 -3 1379 1047 1380 1 -3 443 444 445 1 -3 53 54 193 1 -3 499 565 1402 1 -3 910 1349 1445 1 -3 848 910 1445 1 -3 451 657 658 1 -3 1062 765 1063 1 -3 425 428 1371 1 -3 384 381 1423 1 -3 705 666 748 1 -3 1160 1064 1234 1 -3 535 537 538 1 -3 121 1306 1307 1 -3 930 1271 1274 1 -3 1015 1179 1195 1 -3 329 330 1401 1 -3 307 308 309 1 -3 1149 1164 1174 1 -3 315 316 317 1 -3 770 902 903 1 -3 667 756 1452 1 -3 1108 1110 1111 1 -3 1145 824 1332 1 -3 1000 1001 1002 1 -3 290 288 291 1 -3 347 346 348 1 -3 49 50 184 1 -3 51 52 209 1 -3 559 561 1419 1 -3 582 589 1444 1 -3 312 314 315 1 -3 280 278 281 1 -3 903 905 1377 1 -3 465 466 635 1 -3 307 462 1479 1 -3 460 317 461 1 -3 469 1326 1464 1 -3 1106 1108 1372 1 -3 853 1006 1170 1 -3 1010 1002 1011 1 -3 905 904 906 1 -3 756 855 893 1 -3 288 286 1406 1 -3 327 469 1464 1 -3 1011 1013 1379 1 -3 1035 1034 1133 1 -3 721 862 863 1 -3 967 979 980 1 -3 447 448 449 1 -3 534 1623 1683 1 -3 454 453 455 1 -3 520 725 1427 1 -3 480 477 1437 1 -3 1197 1043 1361 1 -3 374 367 1420 1 -3 698 1080 1471 1 -3 366 358 371 1 -3 980 1117 1118 1 -3 345 342 346 1 -3 1245 816 1473 1 -3 531 533 534 1 -3 963 965 966 1 -3 477 475 1437 1 -3 822 750 876 1 -3 294 295 296 1 -3 345 346 347 1 -3 12 218 1477 1 -3 439 440 441 1 -3 784 707 785 1 -3 309 310 1453 1 -3 368 360 1060 1 -3 425 427 428 1 -3 637 586 653 1 -3 744 850 1462 1 -3 396 397 1482 1 -3 1388 1387 1429 1 -3 1013 1047 1379 1 -3 474 473 475 1 -3 544 546 591 1 -3 671 714 757 1 -3 819 818 1015 1 -3 347 348 352 1 -3 378 375 1368 1 -3 481 479 1389 1 -3 320 322 323 1 -3 341 342 345 1 -3 465 371 466 1 -3 420 421 1460 1 -3 327 328 329 1 -3 338 340 341 1 -3 476 475 477 1 -3 605 1431 1640 1 -3 330 332 333 1 -3 469 329 695 1 -3 472 473 474 1 -3 668 660 751 1 -3 124 176 1302 1 -3 489 494 1338 1 -3 850 1024 1025 1 -3 670 371 1461 1 -3 434 433 435 1 -3 661 1340 1568 1 -3 478 477 479 1 -3 1297 1296 1298 1 -3 324 326 327 1 -3 692 664 741 1 -3 542 544 1421 1 -3 1061 785 1212 1 -3 462 971 1479 1 -3 538 537 539 1 -3 796 962 1378 1 -3 609 402 1475 1 -3 622 664 692 1 -3 721 711 862 1 -3 302 301 1524 1 -3 269 267 467 1 -3 310 312 1393 1 -3 927 926 1449 1 -3 241 243 1375 1 -3 933 955 992 1 -3 307 309 462 1 -3 1373 881 1485 1 -3 474 475 476 1 -3 903 902 904 1 -3 367 366 1420 1 -3 421 424 1460 1 -3 487 488 489 1 -3 476 477 478 1 -3 421 423 424 1 -3 491 485 493 1 -3 551 553 554 1 -3 333 336 871 1 -3 919 883 1373 1 -3 327 329 469 1 -3 371 358 1461 1 -3 469 695 1325 1 -3 824 730 825 1 -3 881 879 1485 1 -3 1133 1034 1789 1 -3 1252 1253 1363 1 -3 260 259 1467 1 -3 417 419 420 1 -3 996 754 997 1 -3 21 22 200 1 -3 289 288 290 1 -3 377 375 378 1 -3 714 716 747 1 -3 112 113 1493 1 -3 268 267 269 1 -3 359 358 366 1 -3 27 28 226 1 -3 487 489 585 1 -3 291 1407 1417 1 -3 483 484 487 1 -3 489 490 494 1 -3 193 54 1231 1 -3 1393 460 1484 1 -3 527 529 530 1 -3 1013 1046 1047 1 -3 292 291 1417 1 -3 1364 863 1365 1 -3 905 907 1252 1 -3 274 273 1425 1 -3 1016 1015 1409 1 -3 764 681 765 1 -3 315 317 460 1 -3 747 766 852 1 -3 852 1054 1056 1 -3 729 653 730 1 -3 341 340 342 1 -3 479 480 483 1 -3 478 479 481 1 -3 475 592 1437 1 -3 1395 658 1494 1 -3 354 1079 1461 1 -3 871 336 1428 1 -3 416 417 1446 1 -3 600 891 1521 1 -3 756 893 1452 1 -3 796 961 962 1 -3 318 320 1386 1 -3 364 362 678 1 -3 863 862 1272 1 -3 124 125 176 1 -3 267 264 1400 1 -3 462 309 726 1 -3 700 461 707 1 -3 304 306 307 1 -3 930 628 1271 1 -3 637 729 1450 1 -3 1451 1341 1510 1 -3 725 623 1090 1 -3 704 608 928 1 -3 735 736 737 1 -3 373 367 374 1 -3 748 767 853 1 -3 1033 1031 1034 1 -3 784 785 958 1 -3 315 314 316 1 -3 1048 1050 1051 1 -3 277 274 1425 1 -3 269 467 602 1 -3 414 415 416 1 -3 460 461 700 1 -3 829 832 1148 1 -3 294 292 295 1 -3 520 623 725 1 -3 610 609 662 1 -3 671 713 714 1 -3 708 710 1251 1 -3 354 352 1079 1 -3 770 903 1416 1 -3 944 778 1074 1 -3 518 520 1427 1 -3 510 590 1439 1 -3 952 950 1474 1 -3 1008 1189 1193 1 -3 510 512 590 1 -3 45 46 174 1 -3 874 345 1506 1 -3 353 352 354 1 -3 355 354 358 1 -3 694 662 745 1 -3 632 697 870 1 -3 465 635 1273 1 -3 1029 952 1030 1 -3 877 1083 1119 1 -3 891 922 1572 1 -3 1099 920 1431 1 -3 950 949 974 1 -3 263 260 1467 1 -3 327 326 328 1 -3 554 1335 1336 1 -3 565 621 622 1 -3 634 869 1423 1 -3 323 322 324 1 -3 333 335 336 1 -3 548 550 588 1 -3 1094 1043 1197 1 -3 1207 457 1433 1 -3 692 818 819 1 -3 330 333 1401 1 -3 703 811 1466 1 -3 912 1524 1525 1 -3 266 264 267 1 -3 523 525 526 1 -3 226 28 1435 1 -3 1000 998 1001 1 -3 262 260 263 1 -3 885 883 919 1 -3 712 711 721 1 -3 938 927 1449 1 -3 602 467 1115 1 -3 359 366 367 1 -3 518 1427 1499 1 -3 479 477 480 1 -3 307 306 308 1 -3 822 876 877 1 -3 336 337 338 1 -3 778 721 1364 1 -3 1271 1395 1494 1 -3 1336 1335 1436 1 -3 780 679 912 1 -3 1011 1012 1013 1 -3 482 481 485 1 -3 639 638 640 1 -3 692 819 1518 1 -3 475 473 592 1 -3 466 670 671 1 -3 1047 1046 1048 1 -3 365 370 1413 1 -3 870 697 1438 1 -3 800 977 1065 1 -3 148 149 224 1 -3 1124 1711 1780 1 -3 644 642 731 1 -3 428 702 1371 1 -3 495 497 498 1 -3 341 345 874 1 -3 622 621 664 1 -3 1077 457 1207 1 -3 113 169 1493 1 -3 411 413 414 1 -3 435 436 437 1 -3 942 726 1320 1 -3 348 350 1451 1 -3 468 1417 1478 1 -3 428 427 429 1 -3 590 512 1440 1 -3 1004 917 1005 1 -3 457 294 1433 1 -3 968 798 1043 1 -3 980 979 1117 1 -3 309 308 310 1 -3 338 339 340 1 -3 980 1301 1343 1 -3 323 324 1464 1 -3 853 861 1006 1 -3 276 277 278 1 -3 499 564 565 1 -3 29 175 1435 1 -3 377 378 379 1 -3 700 707 784 1 -3 10 195 1369 1 -3 486 485 491 1 -3 1113 1005 1116 1 -3 317 318 1454 1 -3 697 783 1438 1 -3 296 295 297 1 -3 750 659 1405 1 -3 1015 1195 1409 1 -3 467 267 1400 1 -3 534 533 535 1 -3 962 1351 1378 1 -3 903 1377 1416 1 -3 1018 1016 1019 1 -3 565 622 1402 1 -3 634 705 869 1 -3 1461 1079 1554 1 -3 1139 1138 1165 1 -3 727 726 942 1 -3 272 270 273 1 -3 268 269 270 1 -3 266 267 268 1 -3 721 863 1364 1 -3 868 732 1489 1 -3 487 484 488 1 -3 373 374 375 1 -3 740 739 845 1 -3 582 583 584 1 -3 1071 1229 1316 1 -3 380 634 1423 1 -3 1058 953 1087 1 -3 707 461 715 1 -3 195 11 1477 1 -3 539 542 1432 1 -3 398 395 1476 1 -3 850 1025 1462 1 -3 286 285 458 1 -3 1022 1020 1138 1 -3 489 488 490 1 -3 1482 870 1483 1 -3 300 302 303 1 -3 317 316 318 1 -3 776 675 879 1 -3 1579 736 1619 1 -3 420 419 421 1 -3 324 327 1464 1 -3 840 839 945 1 -3 948 946 949 1 -3 1018 1019 1020 1 -3 966 965 967 1 -3 329 328 330 1 -3 333 871 1401 1 -3 783 956 1124 1 -3 1139 1165 1258 1 -3 1276 1278 1279 1 -3 539 540 541 1 -3 625 468 711 1 -3 459 378 1368 1 -3 297 295 468 1 -3 1022 1138 1139 1 -3 1055 1595 1621 1 -3 347 352 353 1 -3 684 792 1481 1 -3 780 912 943 1 -3 1006 1007 1008 1 -3 333 332 335 1 -3 862 711 1478 1 -3 897 895 954 1 -3 400 618 632 1 -3 447 445 448 1 -3 483 480 484 1 -3 78 79 1327 1 -3 726 309 1453 1 -3 1052 1049 1441 1 -3 293 294 457 1 -3 296 298 299 1 -3 632 696 697 1 -3 819 1015 1016 1 -3 1035 1133 1134 1 -3 152 153 228 1 -3 389 388 616 1 -3 355 358 359 1 -3 443 441 444 1 -3 520 521 623 1 -3 353 354 355 1 -3 783 762 956 1 -3 842 1137 1143 1 -3 911 932 933 1 -3 275 274 276 1 -3 492 491 500 1 -3 358 354 1461 1 -3 1105 1026 1106 1 -3 962 961 963 1 -3 379 380 381 1 -3 1101 839 1465 1 -3 251 249 594 1 -3 1039 1040 1199 1 -3 797 686 798 1 -3 819 1017 1518 1 -3 1013 1045 1046 1 -3 1122 765 1404 1 -3 679 305 1524 1 -3 1062 1270 1313 1 -3 565 566 621 1 -3 875 470 1523 1 -3 584 629 630 1 -3 785 707 1397 1 -3 272 273 274 1 -3 462 726 727 1 -3 416 415 417 1 -3 424 423 425 1 -3 928 608 1513 1 -3 383 381 384 1 -3 1008 1009 1189 1 -3 597 596 660 1 -3 396 1483 1522 1 -3 689 617 1473 1 -3 727 942 972 1 -3 16 17 231 1 -3 697 762 783 1 -3 865 1146 1304 1 -3 498 497 499 1 -3 258 256 259 1 -3 678 362 1591 1 -3 518 519 520 1 -3 641 640 642 1 -3 262 263 264 1 -3 469 1325 1326 1 -3 1199 1040 1200 1 -3 919 1373 1487 1 -3 1313 1270 1314 1 -3 1290 862 1478 1 -3 606 682 1396 1 -3 400 632 1482 1 -3 790 633 1469 1 -3 629 687 1552 1 -3 1048 1049 1050 1 -3 770 901 902 1 -3 898 1059 1426 1 -3 1090 623 1091 1 -3 864 1342 1595 1 -3 287 288 289 1 -3 547 545 717 1 -3 1030 952 1474 1 -3 494 490 495 1 -3 682 787 788 1 -3 407 409 410 1 -3 1038 813 1171 1 -3 880 879 881 1 -3 364 678 1042 1 -3 551 549 553 1 -3 698 774 1080 1 -3 1444 589 1710 1 -3 1359 609 1475 1 -3 304 307 1479 1 -3 9 10 1369 1 -3 478 481 482 1 -3 290 291 292 1 -3 530 529 531 1 -3 512 626 1440 1 -3 741 742 847 1 -3 439 437 440 1 -3 838 836 839 1 -3 1320 726 1453 1 -3 853 767 861 1 -3 712 721 778 1 -3 748 666 767 1 -3 633 463 1469 1 -3 697 696 762 1 -3 885 919 920 1 -3 1643 1086 1655 1 -3 671 670 713 1 -3 565 564 566 1 -3 458 472 866 1 -3 254 252 255 1 -3 632 618 696 1 -3 1025 1024 1026 1 -3 1033 1034 1035 1 -3 639 640 641 1 -3 466 371 670 1 -3 1006 861 1007 1 -3 1092 938 1104 1 -3 798 686 1535 1 -3 279 278 280 1 -3 261 1684 1687 1 -3 711 468 1478 1 -3 630 629 1552 1 -3 324 325 326 1 -3 512 513 626 1 -3 352 348 1451 1 -3 645 647 648 1 -3 684 791 792 1 -3 482 485 486 1 -3 297 468 625 1 -3 303 302 304 1 -3 1202 889 1203 1 -3 921 920 1099 1 -3 718 744 1085 1 -3 336 335 337 1 -3 720 769 770 1 -3 312 313 314 1 -3 751 753 1141 1 -3 614 680 681 1 -3 372 367 373 1 -3 724 679 780 1 -3 1013 1012 1045 1 -3 320 321 322 1 -3 387 385 388 1 -3 1039 859 1040 1 -3 1058 1087 1210 1 -3 1079 352 1451 1 -3 526 525 527 1 -3 1634 605 1640 1 -3 293 292 294 1 -3 391 389 1511 1 -3 1067 845 1069 1 -3 1011 1002 1012 1 -3 1524 301 1525 1 -3 1403 1017 1581 1 -3 714 713 716 1 -3 368 1060 1621 1 -3 542 1421 1432 1 -3 628 449 1395 1 -3 761 859 1039 1 -3 601 684 1481 1 -3 652 760 761 1 -3 700 784 867 1 -3 898 897 953 1 -3 338 337 339 1 -3 799 758 844 1 -3 381 380 1423 1 -3 1017 1016 1018 1 -3 29 30 175 1 -3 1074 1364 1616 1 -3 747 716 766 1 -3 594 249 1500 1 -3 515 517 518 1 -3 474 476 615 1 -3 615 1531 1539 1 -3 587 638 639 1 -3 820 709 1568 1 -3 579 580 582 1 -3 456 289 595 1 -3 882 881 883 1 -3 414 413 415 1 -3 461 317 1454 1 -3 876 1405 1606 1 -3 99 100 180 1 -3 299 298 300 1 -3 339 337 343 1 -3 967 970 979 1 -3 28 29 1435 1 -3 627 677 1121 1 -3 848 909 910 1 -3 1272 862 1290 1 -3 600 722 891 1 -3 884 883 885 1 -3 287 289 456 1 -3 606 1396 1530 1 -3 632 870 1482 1 -3 547 717 1463 1 -3 601 1481 1488 1 -3 968 1043 1094 1 -3 1053 1208 1321 1 -3 559 557 561 1 -3 241 242 243 1 -3 507 505 508 1 -3 289 290 1480 1 -3 431 432 433 1 -3 340 339 344 1 -3 404 402 609 1 -3 556 555 557 1 -3 1441 1049 1497 1 -3 1050 1052 1053 1 -3 1799 1328 1800 1 -3 937 927 938 1 -3 988 990 1216 1 -3 499 563 564 1 -3 393 391 394 1 -3 593 1502 1514 1 -3 342 340 1434 1 -3 1212 785 1397 1 -3 1209 1052 1441 1 -3 674 611 1495 1 -3 280 281 282 1 -3 348 349 350 1 -3 648 651 698 1 -3 495 496 497 1 -3 887 886 1041 1 -3 1053 1052 1208 1 -3 898 953 1058 1 -3 1079 1451 1510 1 -3 1082 1318 1319 1 -3 495 498 1594 1 -3 625 711 712 1 -3 691 690 758 1 -3 1029 1030 1031 1 -3 1653 440 1672 1 -3 520 519 521 1 -3 1203 889 1490 1 -3 648 698 1471 1 -3 1076 457 1077 1 -3 797 798 968 1 -3 310 311 312 1 -3 1080 774 1086 1 -3 703 810 811 1 -3 462 727 971 1 -3 834 831 1112 1 -3 460 700 1484 1 -3 330 331 332 1 -3 247 613 614 1 -3 648 650 651 1 -3 724 934 935 1 -3 866 472 1486 1 -3 1695 1427 1699 1 -3 1064 816 1245 1 -3 885 920 921 1 -3 303 304 1479 1 -3 340 344 1434 1 -3 773 674 1495 1 -3 535 536 537 1 -3 459 1368 1516 1 -3 775 699 886 1 -3 776 879 880 1 -3 486 491 492 1 -3 1048 1046 1049 1 -3 318 319 320 1 -3 376 375 377 1 -3 359 367 372 1 -3 604 703 1466 1 -3 672 771 890 1 -3 775 886 887 1 -3 891 892 922 1 -3 296 297 298 1 -3 641 642 643 1 -3 429 430 431 1 -3 890 1081 1082 1 -3 503 501 504 1 -3 101 102 227 1 -3 287 286 288 1 -3 1063 1122 1123 1 -3 392 393 1522 1 -3 1490 1041 1491 1 -3 243 245 872 1 -3 685 795 796 1 -3 521 523 1458 1 -3 554 553 555 1 -3 619 719 720 1 -3 1189 1009 1190 1 -3 258 259 260 1 -3 887 1041 1490 1 -3 250 249 251 1 -3 1050 1049 1052 1 -3 595 289 1480 1 -3 762 696 763 1 -3 386 387 1533 1 -3 943 912 1625 1 -3 293 457 1076 1 -3 700 867 1484 1 -3 353 355 598 1 -3 345 347 1506 1 -3 658 657 690 1 -3 724 780 934 1 -3 543 562 1447 1 -3 852 766 1054 1 -3 761 760 859 1 -3 880 881 882 1 -3 1008 1007 1009 1 -3 248 246 249 1 -3 673 470 875 1 -3 593 679 724 1 -3 875 1523 1571 1 -3 265 264 266 1 -3 898 1058 1059 1 -3 361 365 1468 1 -3 513 511 514 1 -3 596 514 1556 1 -3 515 518 1499 1 -3 909 908 1515 1 -3 512 511 513 1 -3 774 699 775 1 -3 900 773 923 1 -3 765 681 1404 1 -3 796 960 961 1 -3 154 155 179 1 -3 513 514 515 1 -3 1021 1020 1022 1 -3 698 651 699 1 -3 356 357 360 1 -3 888 941 1102 1 -3 350 351 356 1 -3 677 392 1522 1 -3 286 458 1406 1 -3 963 964 965 1 -3 992 955 1044 1 -3 626 513 1499 1 -3 676 675 776 1 -3 16 231 1504 1 -3 229 112 1493 1 -3 698 699 774 1 -3 488 484 605 1 -3 789 633 790 1 -3 615 476 1531 1 -3 772 674 773 1 -3 896 895 897 1 -3 304 305 306 1 -3 390 392 627 1 -3 449 448 451 1 -3 510 511 512 1 -3 1531 1072 1539 1 -3 935 934 939 1 -3 13 14 1505 1 -3 649 646 732 1 -3 495 490 496 1 -3 724 935 1502 1 -3 882 883 884 1 -3 933 932 955 1 -3 715 461 1454 1 -3 645 648 1471 1 -3 663 739 740 1 -3 896 897 898 1 -3 741 664 742 1 -3 1581 1339 1594 1 -3 1056 1054 1291 1 -3 425 426 427 1 -3 1373 1485 1605 1 -3 300 301 302 1 -3 779 778 944 1 -3 1153 808 1154 1 -3 593 305 679 1 -3 393 394 395 1 -3 1018 1020 1021 1 -3 15 16 1504 1 -3 567 564 1519 1 -3 623 521 1458 1 -3 879 675 1519 1 -3 1063 765 1122 1 -3 300 298 301 1 -3 373 375 376 1 -3 464 1452 1545 1 -3 775 887 888 1 -3 1112 831 1617 1 -3 347 353 1506 1 -3 889 887 1490 1 -3 564 563 1519 1 -3 271 270 272 1 -3 417 418 419 1 -3 543 541 562 1 -3 284 282 285 1 -3 243 242 244 1 -3 290 292 293 1 -3 400 401 618 1 -3 472 474 1486 1 -3 104 105 171 1 -3 324 322 325 1 -3 569 567 675 1 -3 254 255 256 1 -3 749 659 750 1 -3 921 1099 1100 1 -3 1595 1342 1621 1 -3 499 497 563 1 -3 821 750 822 1 -3 643 645 1471 1 -3 902 901 1057 1 -3 290 293 1480 1 -3 348 346 349 1 -3 1546 1636 1674 1 -3 528 1658 1659 1 -3 819 1016 1017 1 -3 421 422 423 1 -3 531 532 533 1 -3 912 679 1524 1 -3 18 19 172 1 -3 648 647 650 1 -3 1108 1109 1110 1 -3 651 650 652 1 -3 890 771 1081 1 -3 621 566 1555 1 -3 622 692 1518 1 -3 805 804 1611 1 -3 518 517 519 1 -3 1082 1081 1318 1 -3 593 724 1502 1 -3 393 395 396 1 -3 891 722 892 1 -3 103 104 1492 1 -3 513 515 1499 1 -3 1004 1005 1113 1 -3 144 145 223 1 -3 353 598 1506 1 -3 849 743 851 1 -3 261 260 262 1 -3 363 362 364 1 -3 627 392 677 1 -3 410 409 411 1 -3 539 537 540 1 -3 855 994 1120 1 -3 910 909 911 1 -3 1511 1584 1604 1 -3 888 887 889 1 -3 1471 1080 1529 1 -3 643 642 644 1 -3 595 1480 1535 1 -3 511 509 1556 1 -3 921 1100 1358 1 -3 792 791 973 1 -3 718 1085 1599 1 -3 576 578 579 1 -3 1045 1201 1213 1 -3 466 671 1588 1 -3 586 559 1419 1 -3 455 636 665 1 -3 527 528 529 1 -3 886 699 1512 1 -3 1208 1052 1209 1 -3 272 274 275 1 -3 383 384 385 1 -3 948 949 950 1 -3 847 742 848 1 -3 397 399 400 1 -3 770 769 901 1 -3 886 1512 1557 1 -3 566 564 567 1 -3 1157 820 1568 1 -3 1075 1042 1206 1 -3 516 514 596 1 -3 882 884 1217 1 -3 387 390 1533 1 -3 509 1071 1556 1 -3 1021 1022 1070 1 -3 1141 753 1337 1 -3 796 795 960 1 -3 24 25 170 1 -3 435 433 436 1 -3 756 854 855 1 -3 1017 1018 1581 1 -3 888 1102 1509 1 -3 433 432 1534 1 -3 967 965 970 1 -3 840 945 946 1 -3 393 396 1522 1 -3 699 651 1512 1 -3 1045 1012 1201 1 -3 722 624 940 1 -3 1106 1107 1108 1 -3 549 547 1463 1 -3 394 391 1511 1 -3 476 478 1531 1 -3 396 395 397 1 -3 1190 1009 1246 1 -3 106 107 230 1 -3 376 377 470 1 -3 568 570 571 1 -3 379 381 382 1 -3 1049 1046 1497 1 -3 478 482 1531 1 -3 1091 623 1458 1 -3 807 737 808 1 -3 397 395 398 1 -3 361 363 365 1 -3 456 595 685 1 -3 1021 1070 1339 1 -3 332 331 334 1 -3 652 761 1512 1 -3 639 641 768 1 -3 925 782 926 1 -3 314 313 600 1 -3 403 405 406 1 -3 861 767 873 1 -3 941 889 1202 1 -3 751 1141 1424 1 -3 659 603 1405 1 -3 308 306 1514 1 -3 900 923 1098 1 -3 896 898 1426 1 -3 600 624 722 1 -3 1650 1437 1669 1 -3 1012 1002 1503 1 -3 306 305 593 1 -3 365 369 370 1 -3 320 319 321 1 -3 370 452 453 1 -3 580 578 581 1 -3 745 842 1455 1 -3 983 1430 1552 1 -3 105 106 1501 1 -3 572 574 575 1 -3 312 311 313 1 -3 545 543 1447 1 -3 643 644 645 1 -3 482 486 1072 1 -3 1402 622 1518 1 -3 598 355 1498 1 -3 425 423 426 1 -3 372 373 1526 1 -3 242 240 723 1 -3 248 249 250 1 -3 767 666 1516 1 -3 681 781 1404 1 -3 894 777 895 1 -3 1046 1045 1497 1 -3 355 359 1498 1 -3 963 961 964 1 -3 675 567 1519 1 -3 1469 463 1507 1 -3 1002 1001 1503 1 -3 888 889 941 1 -3 310 308 311 1 -3 720 719 769 1 -3 788 787 957 1 -3 268 270 271 1 -3 429 427 430 1 -3 523 524 525 1 -3 382 381 383 1 -3 733 732 809 1 -3 676 776 777 1 -3 1201 1012 1503 1 -3 97 98 234 1 -3 1480 1076 1535 1 -3 685 595 686 1 -3 774 775 1509 1 -3 1512 761 1557 1 -3 813 745 1455 1 -3 672 673 771 1 -3 328 326 1541 1 -3 716 713 864 1 -3 610 662 694 1 -3 666 459 1516 1 -3 652 654 760 1 -3 326 325 599 1 -3 521 522 523 1 -3 712 778 779 1 -3 508 505 1633 1 -3 376 470 672 1 -3 330 328 331 1 -3 667 755 756 1 -3 250 251 252 1 -3 255 252 1530 1 -3 772 773 900 1 -3 12 13 218 1 -3 318 316 319 1 -3 838 839 840 1 -3 672 470 673 1 -3 795 686 797 1 -3 243 244 245 1 -3 569 675 676 1 -3 937 938 1092 1 -3 108 109 187 1 -3 359 372 1498 1 -3 560 587 1517 1 -3 614 613 680 1 -3 668 751 1424 1 -3 266 268 1507 1 -3 474 615 1486 1 -3 276 278 279 1 -3 392 391 393 1 -3 458 866 1406 1 -3 262 264 265 1 -3 1086 774 1509 1 -3 251 594 606 1 -3 293 1076 1480 1 -3 651 652 1512 1 -3 771 673 856 1 -3 874 1626 1635 1 -3 672 890 1526 1 -3 600 313 624 1 -3 941 1202 1204 1 -3 431 430 432 1 -3 925 926 927 1 -3 935 1600 1607 1 -3 822 877 878 1 -3 1403 1581 1594 1 -3 421 419 422 1 -3 445 444 1587 1 -3 417 415 418 1 -3 314 600 1521 1 -3 681 680 781 1 -3 873 767 1516 1 -3 373 376 1526 1 -3 1127 1128 1129 1 -3 1587 444 1632 1 -3 1119 1083 1646 1 -3 535 533 536 1 -3 304 302 305 1 -3 401 399 402 1 -3 797 968 1132 1 -3 685 686 795 1 -3 1007 861 1532 1 -3 645 646 647 1 -3 842 1143 1455 1 -3 936 927 937 1 -3 1523 382 1571 1 -3 652 650 654 1 -3 404 609 610 1 -3 604 1466 1534 1 -3 287 456 1547 1 -3 509 508 1071 1 -3 306 593 1514 1 -3 245 244 246 1 -3 1082 1319 1613 1 -3 781 782 924 1 -3 326 599 1541 1 -3 811 810 1136 1 -3 390 391 392 1 -3 400 399 401 1 -3 871 1428 1635 1 -3 257 256 258 1 -3 363 364 1563 1 -3 576 574 577 1 -3 673 875 1528 1 -3 482 1072 1531 1 -3 364 1042 1075 1 -3 411 412 413 1 -3 775 888 1509 1 -3 541 540 1456 1 -3 734 656 735 1 -3 492 500 501 1 -3 894 895 896 1 -3 694 745 813 1 -3 387 388 389 1 -3 761 1039 1557 1 -3 587 639 1517 1 -3 676 777 894 1 -3 533 532 1470 1 -3 825 826 827 1 -3 342 1434 1561 1 -3 390 627 1533 1 -3 1032 1031 1033 1 -3 265 266 463 1 -3 682 788 1396 1 -3 423 422 1551 1 -3 265 463 601 1 -3 397 398 399 1 -3 601 633 684 1 -3 1035 1134 1135 1 -3 569 676 1573 1 -3 684 789 791 1 -3 268 271 1507 1 -3 655 620 656 1 -3 1119 1646 1688 1 -3 31 32 225 1 -3 772 900 1073 1 -3 406 405 407 1 -3 1271 628 1395 1 -3 890 1082 1578 1 -3 254 256 257 1 -3 597 660 668 1 -3 470 377 1523 1 -3 641 643 1529 1 -3 527 525 528 1 -3 566 568 1555 1 -3 1541 599 1585 1 -3 1045 1213 1497 1 -3 311 308 1514 1 -3 665 669 706 1 -3 740 845 1067 1 -3 111 112 229 1 -3 1060 360 1468 1 -3 301 298 1569 1 -3 749 750 821 1 -3 325 322 1553 1 -3 346 342 1561 1 -3 521 519 522 1 -3 619 674 719 1 -3 1525 301 1569 1 -3 383 385 386 1 -3 334 331 1078 1 -3 719 674 772 1 -3 253 252 254 1 -3 1514 1502 1574 1 -3 901 769 1097 1 -3 316 314 1521 1 -3 795 797 1536 1 -3 599 611 619 1 -3 578 577 1546 1 -3 619 611 674 1 -3 684 633 789 1 -3 925 927 936 1 -3 1088 1500 1609 1 -3 386 385 387 1 -3 171 105 1501 1 -3 682 683 787 1 -3 1120 994 1168 1 -3 247 248 613 1 -3 376 672 1526 1 -3 531 529 532 1 -3 861 873 1532 1 -3 931 909 1515 1 -3 572 570 573 1 -3 1511 616 1584 1 -3 687 803 1552 1 -3 247 246 248 1 -3 104 171 1492 1 -3 607 594 1088 1 -3 1412 915 1632 1 -3 619 720 1585 1 -3 258 260 261 1 -3 614 764 1537 1 -3 1658 1105 1659 1 -3 1476 394 1604 1 -3 855 854 994 1 -3 1054 766 1055 1 -3 1028 952 1029 1 -3 284 285 286 1 -3 686 595 1535 1 -3 377 379 1523 1 -3 639 768 1517 1 -3 781 680 782 1 -3 1156 820 1157 1 -3 850 1023 1024 1 -3 1041 886 1557 1 -3 419 418 1508 1 -3 426 423 1551 1 -3 643 1471 1529 1 -3 706 804 805 1 -3 848 742 908 1 -3 269 602 1603 1 -3 322 321 1553 1 -3 510 509 511 1 -3 1009 1007 1565 1 -3 599 325 611 1 -3 246 244 1500 1 -3 430 427 1496 1 -3 942 1320 1664 1 -3 601 463 633 1 -3 851 743 1424 1 -3 1430 630 1552 1 -3 390 389 391 1 -3 579 578 580 1 -3 693 914 918 1 -3 1274 1739 1759 1 -3 1148 832 1149 1 -3 331 328 1541 1 -3 653 586 1419 1 -3 645 644 646 1 -3 280 282 283 1 -3 106 230 1501 1 -3 515 516 517 1 -3 379 382 1523 1 -3 1274 1066 1739 1 -3 69 70 188 1 -3 937 1092 1093 1 -3 432 604 1534 1 -3 1039 1199 1580 1 -3 670 1461 1554 1 -3 284 286 287 1 -3 566 567 568 1 -3 604 659 703 1 -3 1521 891 1572 1 -3 451 612 657 1 -3 514 511 1556 1 -3 650 647 1527 1 -3 350 349 351 1 -3 791 789 969 1 -3 245 246 247 1 -3 432 430 603 1 -3 1106 1026 1107 1 -3 71 72 233 1 -3 422 419 1508 1 -3 760 654 786 1 -3 1108 1107 1109 1 -3 848 908 909 1 -3 581 578 1546 1 -3 407 408 409 1 -3 1425 273 1700 1 -3 515 514 516 1 -3 249 246 1500 1 -3 387 389 390 1 -3 411 409 412 1 -3 960 795 1536 1 -3 70 71 1538 1 -3 250 252 253 1 -3 571 570 572 1 -3 735 737 807 1 -3 576 577 578 1 -3 427 426 1496 1 -3 575 574 576 1 -3 797 1132 1536 1 -3 911 909 931 1 -3 95 96 191 1 -3 756 755 854 1 -3 603 430 1496 1 -3 273 270 1603 1 -3 1110 1109 1177 1 -3 1495 611 1553 1 -3 436 433 1534 1 -3 356 351 357 1 -3 709 661 1568 1 -3 798 1535 1549 1 -3 1584 1068 1604 1 -3 825 730 826 1 -3 283 1351 1601 1 -3 768 641 1529 1 -3 67 68 232 1 -3 951 950 952 1 -3 265 601 1488 1 -3 413 412 464 1 -3 703 659 749 1 -3 432 603 604 1 -3 924 782 925 1 -3 68 69 1540 1 -3 1128 794 1597 1 -3 536 533 1470 1 -3 786 654 959 1 -3 916 915 917 1 -3 523 522 524 1 -3 604 603 659 1 -3 1004 1113 1114 1 -3 568 567 569 1 -3 1076 1077 1549 1 -3 693 918 1583 1 -3 864 713 1554 1 -3 911 931 932 1 -3 507 508 509 1 -3 1003 917 1004 1 -3 1021 1339 1581 1 -3 351 349 899 1 -3 690 657 1583 1 -3 297 625 1569 1 -3 856 673 1528 1 -3 713 670 1554 1 -3 492 501 502 1 -3 65 66 196 1 -3 364 1075 1563 1 -3 261 262 1488 1 -3 803 981 982 1 -3 1029 1031 1032 1 -3 552 1336 1655 1 -3 994 854 1178 1 -3 464 412 608 1 -3 794 683 1597 1 -3 1574 1502 1607 1 -3 122 123 210 1 -3 664 621 1520 1 -3 1058 1210 1576 1 -3 553 549 1463 1 -3 597 668 718 1 -3 568 571 1555 1 -3 703 749 810 1 -3 1557 1039 1580 1 -3 463 266 1507 1 -3 372 1526 1578 1 -3 146 147 198 1 -3 611 325 1553 1 -3 947 946 948 1 -3 1136 810 1167 1 -3 827 828 829 1 -3 957 787 1459 1 -3 582 580 583 1 -3 502 501 503 1 -3 584 583 629 1 -3 1246 1009 1565 1 -3 1041 1557 1580 1 -3 687 801 803 1 -3 793 683 794 1 -3 1078 1541 1585 1 -3 452 369 620 1 -3 401 402 403 1 -3 455 453 636 1 -3 572 573 574 1 -3 717 545 1447 1 -3 349 346 1561 1 -3 66 67 1543 1 -3 409 408 1513 1 -3 787 793 1459 1 -3 928 1513 1577 1 -3 921 1358 1570 1 -3 319 316 1521 1 -3 1032 1033 1144 1 -3 298 297 1569 1 -3 506 505 507 1 -3 1007 1532 1565 1 -3 1075 1206 1579 1 -3 951 1028 1172 1 -3 1018 1021 1581 1 -3 562 541 1456 1 -3 283 282 284 1 -3 1032 1144 1169 1 -3 772 1073 1550 1 -3 361 357 362 1 -3 516 596 597 1 -3 365 363 369 1 -3 503 504 505 1 -3 916 1003 1183 1 -3 914 913 915 1 -3 360 357 361 1 -3 415 413 1545 1 -3 407 405 408 1 -3 1487 1634 1640 1 -3 517 516 1599 1 -3 837 1158 1166 1 -3 1024 1023 1027 1 -3 663 740 1584 1 -3 647 646 649 1 -3 413 464 1545 1 -3 616 663 1584 1 -3 655 734 1095 1 -3 885 921 1570 1 -3 97 234 1542 1 -3 1059 1058 1576 1 -3 1491 1041 1580 1 -3 14 15 186 1 -3 687 631 688 1 -3 693 612 913 1 -3 667 608 704 1 -3 613 248 1566 1 -3 1072 486 1590 1 -3 1109 1107 1181 1 -3 1028 1029 1564 1 -3 667 704 755 1 -3 1033 1035 1548 1 -3 453 452 1575 1 -3 1169 1144 1186 1 -3 1498 372 1578 1 -3 403 402 404 1 -3 507 509 510 1 -3 744 849 850 1 -3 557 555 558 1 -3 932 931 1089 1 -3 262 265 1488 1 -3 733 809 857 1 -3 1520 621 1555 1 -3 1485 563 1605 1 -3 1078 331 1541 1 -3 283 284 1547 1 -3 676 894 1573 1 -3 1526 890 1578 1 -3 1405 603 1496 1 -3 464 608 667 1 -3 412 409 1513 1 -3 1535 1076 1549 1 -3 840 946 947 1 -3 948 950 951 1 -3 568 569 570 1 -3 654 650 1527 1 -3 786 959 1103 1 -3 943 1625 1631 1 -3 503 505 506 1 -3 693 913 914 1 -3 755 704 846 1 -3 275 1301 1661 1 -3 403 404 405 1 -3 360 361 1468 1 -3 899 349 1561 1 -3 649 732 733 1 -3 718 668 743 1 -3 96 97 1542 1 -3 361 362 363 1 -3 769 719 1550 1 -3 837 836 838 1 -3 1613 1319 1626 1 -3 719 772 1550 1 -3 884 885 1570 1 -3 716 864 1595 1 -3 1025 1105 1647 1 -3 1097 769 1550 1 -3 635 466 1588 1 -3 792 973 1705 1 -3 498 1403 1594 1 -3 807 808 1153 1 -3 951 952 1028 1 -3 1546 577 1636 1 -3 14 186 1505 1 -3 655 656 734 1 -3 451 448 612 1 -3 1057 901 1560 1 -3 452 620 655 1 -3 841 1173 1182 1 -3 657 612 693 1 -3 758 690 812 1 -3 1600 940 1607 1 -3 284 287 1547 1 -3 718 743 744 1 -3 418 415 1545 1 -3 833 835 993 1 -3 814 813 1038 1 -3 680 613 1582 1 -3 486 492 1590 1 -3 570 569 1573 1 -3 804 841 1611 1 -3 624 313 1574 1 -3 321 319 1572 1 -3 801 688 802 1 -3 252 251 1530 1 -3 1029 1032 1564 1 -3 1024 1027 1559 1 -3 404 610 1558 1 -3 251 606 1530 1 -3 874 1506 1626 1 -3 279 1344 1642 1 -3 793 794 1126 1 -3 1144 1033 1548 1 -3 1068 1067 1567 1 -3 370 369 452 1 -3 733 857 1250 1 -3 7 8 207 1 -3 647 649 1527 1 -3 613 1566 1582 1 -3 534 535 1703 1 -3 1502 935 1607 1 -3 624 1574 1607 1 -3 1026 1024 1559 1 -3 1452 893 1627 1 -3 1035 1135 1548 1 -3 656 620 1619 1 -3 1449 926 1641 1 -3 606 607 682 1 -3 573 570 1573 1 -3 1080 1086 1643 1 -3 908 742 1520 1 -3 1569 625 1610 1 -3 730 653 1562 1 -3 92 93 201 1 -3 742 664 1520 1 -3 835 834 836 1 -3 608 412 1513 1 -3 787 683 793 1 -3 629 583 631 1 -3 311 1514 1574 1 -3 1513 408 1577 1 -3 740 1067 1068 1 -3 914 915 916 1 -3 901 1097 1560 1 -3 1183 1003 1184 1 -3 657 693 1583 1 -3 492 502 1590 1 -3 313 311 1574 1 -3 620 369 1563 1 -3 827 826 828 1 -3 959 654 1527 1 -3 1442 281 1682 1 -3 1067 1069 1592 1 -3 218 13 1505 1 -3 803 801 981 1 -3 916 917 1003 1 -3 563 497 1605 1 -3 1166 1158 1194 1 -3 830 828 831 1 -3 833 831 834 1 -3 405 404 1558 1 -3 629 631 687 1 -3 766 716 1595 1 -3 280 283 1601 1 -3 1095 734 1096 1 -3 516 597 1599 1 -3 369 363 1563 1 -3 850 849 1023 1 -3 383 386 1593 1 -3 807 1153 1155 1 -3 248 250 1566 1 -3 694 813 814 1 -3 812 690 1583 1 -3 636 453 1575 1 -3 408 1558 1577 1 -3 1710 589 1722 1 -3 1481 792 1696 1 -3 712 779 1610 1 -3 599 619 1585 1 -3 837 838 1158 1 -3 1495 1553 1618 1 -3 186 15 1504 1 -3 30 31 1472 1 -3 1739 1066 1746 1 -3 1055 766 1595 1 -3 782 680 1582 1 -3 829 828 830 1 -3 829 830 832 1 -3 882 1217 1629 1 -3 687 688 801 1 -3 665 636 669 1 -3 897 954 1721 1 -3 735 807 1596 1 -3 926 782 1582 1 -3 1572 922 1618 1 -3 89 90 205 1 -3 319 1521 1572 1 -3 935 939 1600 1 -3 1084 1038 1180 1 -3 1107 1026 1559 1 -3 1487 496 1634 1 -3 835 836 837 1 -3 175 30 1472 1 -3 1612 1426 1628 1 -3 279 280 1601 1 -3 71 233 1538 1 -3 69 188 1540 1 -3 682 607 683 1 -3 740 1068 1584 1 -3 841 806 1142 1 -3 1155 1153 1175 1 -3 448 445 1587 1 -3 1626 1319 1635 1 -3 1578 1082 1613 1 -3 1644 1462 1647 1 -3 982 981 1244 1 -3 1525 1569 1610 1 -3 580 581 1586 1 -3 597 718 1599 1 -3 1032 1169 1564 1 -3 833 834 835 1 -3 1003 1004 1598 1 -3 62 63 206 1 -3 1071 1316 1589 1 -3 986 984 1211 1 -3 188 70 1538 1 -3 596 1556 1589 1 -3 814 1038 1084 1 -3 631 583 1586 1 -3 1500 244 1609 1 -3 744 743 849 1 -3 734 735 1596 1 -3 1325 1081 1667 1 -3 830 831 833 1 -3 335 1363 1648 1 -3 362 357 1591 1 -3 896 1426 1612 1 -3 1181 1107 1559 1 -3 408 405 1558 1 -3 807 1155 1596 1 -3 232 68 1540 1 -3 522 519 1615 1 -3 382 383 1593 1 -3 1660 526 1673 1 -3 1543 232 1544 1 -3 606 594 607 1 -3 1577 1558 1608 1 -3 1004 1114 1598 1 -3 67 232 1543 1 -3 496 490 1634 1 -3 826 730 1562 1 -3 270 269 1603 1 -3 625 712 1610 1 -3 743 668 1424 1 -3 351 899 1591 1 -3 1723 558 1730 1 -3 653 1419 1562 1 -3 706 669 804 1 -3 1553 321 1618 1 -3 655 1095 1575 1 -3 1772 1460 1779 1 -3 196 66 1543 1 -3 1571 382 1593 1 -3 1126 794 1127 1 -3 972 1675 1735 1 -3 923 773 1645 1 -3 244 242 1609 1 -3 1106 1372 1659 1 -3 452 655 1575 1 -3 804 669 806 1 -3 1098 923 1665 1 -3 497 496 1605 1 -3 1599 1085 1615 1 -3 841 1142 1173 1 -3 1498 1578 1613 1 -3 488 605 1634 1 -3 940 624 1607 1 -3 912 1525 1625 1 -3 524 1644 1647 1 -3 1556 1071 1589 1 -3 1088 1609 1651 1 -3 191 96 1542 1 -3 573 1612 1628 1 -3 250 253 1566 1 -3 519 517 1615 1 -3 1610 779 1625 1 -3 1431 1650 1669 1 -3 804 806 841 1 -3 913 1587 1632 1 -3 598 1498 1613 1 -3 31 225 1472 1 -3 1125 701 1747 1 -3 357 351 1591 1 -3 189 1327 1697 1 -3 1364 1365 1616 1 -3 1680 1102 1690 1 -3 1515 908 1630 1 -3 920 919 1640 1 -3 837 1166 1602 1 -3 276 279 1642 1 -3 394 1511 1604 1 -3 426 1551 1606 1 -3 517 1599 1615 1 -3 1342 368 1621 1 -3 1558 610 1608 1 -3 1496 426 1606 1 -3 1431 605 1650 1 -3 777 776 1649 1 -3 1563 1075 1619 1 -3 1149 1150 1164 1 -3 573 1573 1612 1 -3 1567 1067 1592 1 -3 958 1061 1738 1 -3 1184 1003 1598 1 -3 577 574 1628 1 -3 522 1615 1644 1 -3 480 1437 1650 1 -3 894 896 1612 1 -3 1716 944 1718 1 -3 1073 900 1637 1 -3 1573 894 1612 1 -3 1436 1643 1655 1 -3 337 335 1648 1 -3 442 1374 1736 1 -3 1094 1749 1753 1 -3 1458 526 1660 1 -3 841 1182 1611 1 -3 1149 832 1150 1 -3 993 835 1602 1 -3 1068 1567 1638 1 -3 612 448 1587 1 -3 1527 649 1624 1 -3 598 1613 1626 1 -3 610 694 1608 1 -3 1412 1653 1672 1 -3 1075 1579 1619 1 -3 530 1637 1673 1 -3 583 580 1586 1 -3 1104 938 1681 1 -3 1663 257 1681 1 -3 418 1545 1627 1 -3 1419 561 1662 1 -3 1089 1677 1692 1 -3 1405 1496 1606 1 -3 871 1635 1639 1 -3 1121 1664 1748 1 -3 1096 734 1596 1 -3 908 1520 1630 1 -3 441 440 1653 1 -3 1660 1098 1665 1 -3 577 1628 1636 1 -3 1525 1610 1625 1 -3 1229 508 1633 1 -3 1520 1555 1630 1 -3 913 612 1587 1 -3 572 575 1656 1 -3 242 723 1609 1 -3 321 1572 1618 1 -3 835 837 1602 1 -3 1495 1618 1645 1 -3 1697 1328 1799 1 -3 1116 1005 1672 1 -3 1515 1630 1656 1 -3 1604 1068 1638 1 -3 1551 422 1646 1 -3 1319 1318 1639 1 -3 953 1721 1740 1 -3 605 484 1650 1 -3 923 1645 1654 1 -3 530 531 1683 1 -3 1428 874 1635 1 -3 1506 598 1626 1 -3 1073 1637 1683 1 -3 1426 1059 1636 1 -3 959 1527 1624 1 -3 254 257 1663 1 -3 525 524 1658 1 -3 1545 1452 1627 1 -3 1085 1462 1644 1 -3 694 814 1608 1 -3 1508 418 1627 1 -3 1360 1476 1638 1 -3 272 275 1661 1 -3 779 944 1631 1 -3 1081 771 1667 1 -3 880 882 1629 1 -3 831 828 1617 1 -3 1609 723 1651 1 -3 833 993 1614 1 -3 1628 1426 1636 1 -3 1127 1129 1130 1 -3 1074 1616 1693 1 -3 620 1563 1619 1 -3 259 1719 1740 1 -3 618 401 1670 1 -3 733 1250 1624 1 -3 1436 768 1643 1 -3 777 1649 1727 1 -3 1550 1073 1623 1 -3 574 573 1628 1 -3 490 488 1634 1 -3 1691 954 1731 1 -3 1625 779 1631 1 -3 900 1098 1637 1 -3 1652 1084 1671 1 -3 1582 1566 1641 1 -3 939 1695 1699 1 -3 1618 922 1645 1 -3 828 826 1617 1 -3 1097 1550 1623 1 -3 1101 1465 1712 1 -3 826 1562 1617 1 -3 403 406 1670 1 -3 1615 1085 1644 1 -3 919 1487 1640 1 -3 275 276 1642 1 -3 588 550 1690 1 -3 1630 571 1656 1 -3 649 733 1624 1 -3 832 830 1614 1 -3 830 833 1614 1 -3 915 913 1632 1 -3 1083 1551 1646 1 -3 263 1467 1691 1 -3 1449 1641 1663 1 -3 892 722 1685 1 -3 1476 1604 1638 1 -3 1684 1104 1687 1 -3 781 924 1706 1 -3 1243 189 1795 1 -3 1119 1688 1708 1 -3 636 1575 1622 1 -3 806 669 1622 1 -3 1696 792 1705 1 -3 958 1738 1744 1 -3 1098 1660 1673 1 -3 1320 867 1664 1 -3 928 1652 1671 1 -3 1466 811 1720 1 -3 232 1540 1620 1 -3 846 704 1671 1 -3 944 1074 1718 1 -3 942 1664 1675 1 -3 926 1582 1641 1 -3 1544 232 1620 1 -3 768 1529 1643 1 -3 1555 571 1630 1 -3 258 261 1687 1 -3 1499 1427 1695 1 -3 1679 892 1685 1 -3 1509 1102 1680 1 -3 1744 1121 1748 1 -3 1665 1654 1679 1 -3 1412 1632 1653 1 -3 1128 1597 1651 1 -3 1529 1080 1643 1 -3 1408 1768 1773 1 -3 669 636 1622 1 -3 1577 1608 1652 1 -3 1055 1305 1709 1 -3 1686 436 1707 1 -3 1150 832 1614 1 -3 502 503 1693 1 -3 529 528 1694 1 -3 437 436 1686 1 -3 1784 1371 1787 1 -3 526 527 1673 1 -3 576 579 1692 1 -3 343 337 1648 1 -3 1597 1088 1651 1 -3 1469 1507 1666 1 -3 1635 1319 1639 1 -3 1207 1433 1714 1 -3 880 1629 1649 1 -3 1488 1481 1684 1 -3 524 522 1644 1 -3 552 1655 1680 1 -3 1647 1105 1658 1 -3 1637 530 1683 1 -3 806 1622 1676 1 -3 444 441 1653 1 -3 776 880 1649 1 -3 1570 1425 1700 1 -3 773 1495 1645 1 -3 1677 575 1692 1 -3 1702 1631 1716 1 -3 422 1508 1646 1 -3 1608 814 1652 1 -3 1575 1095 1622 1 -3 1741 1463 1756 1 -3 552 1680 1690 1 -3 1566 253 1641 1 -3 922 892 1654 1 -3 811 1136 1729 1 -3 1462 1025 1647 1 -3 1622 1095 1676 1 -3 1654 892 1679 1 -3 1112 1617 1662 1 -3 1469 1666 1715 1 -3 814 1084 1652 1 -3 484 480 1650 1 -3 1336 1436 1655 1 -3 300 303 1711 1 -3 1592 1069 1657 1 -3 1632 444 1653 1 -3 1089 931 1677 1 -3 941 1204 1701 1 -3 1662 561 1712 1 -3 1616 502 1693 1 -3 1645 922 1654 1 -3 855 1120 1708 1 -3 934 780 1704 1 -3 281 1668 1682 1 -3 524 1647 1658 1 -3 1791 536 1796 1 -3 1372 1111 1728 1 -3 1105 1106 1659 1 -3 571 572 1656 1 -3 1376 1736 1757 1 -3 271 272 1661 1 -3 1099 1431 1669 1 -3 1636 1059 1674 1 -3 1074 1693 1718 1 -3 1358 1100 1668 1 -3 528 525 1658 1 -3 1100 1678 1682 1 -3 1346 945 1730 1 -3 1104 1681 1687 1 -3 1763 858 1771 1 -3 1720 811 1729 1 -3 1091 1458 1660 1 -3 271 1661 1666 1 -3 1449 1663 1681 1 -3 884 1570 1700 1 -3 253 254 1663 1 -3 1089 1444 1710 1 -3 1623 534 1703 1 -3 878 877 1713 1 -3 1321 1070 1737 1 -3 1659 1372 1694 1 -3 217 1243 1793 1 -3 1437 592 1669 1 -3 1641 253 1663 1 -3 440 437 1686 1 -3 932 1089 1710 1 -3 1507 271 1666 1 -3 196 1746 1751 1 -3 1656 575 1677 1 -3 1100 1099 1678 1 -3 259 256 1719 1 -3 771 856 1667 1 -3 929 1706 1745 1 -3 1099 1669 1678 1 -3 928 1577 1652 1 -3 954 895 1727 1 -3 1005 1412 1672 1 -3 592 1443 1678 1 -3 1054 1055 1709 1 -3 956 762 1726 1 -3 1678 1443 1682 1 -3 1562 1419 1662 1 -3 1118 1117 1715 1 -3 1649 1115 1727 1 -3 704 928 1671 1 -3 1443 1442 1682 1 -3 1534 1466 1707 1 -3 1396 1210 1724 1 -3 1544 1739 1746 1 -3 1617 1562 1662 1 -3 591 546 1733 1 -3 1666 1118 1715 1 -3 467 1400 1731 1 -3 1669 592 1678 1 -3 1090 1091 1679 1 -3 925 936 1717 1 -3 1688 893 1708 1 -3 1097 1623 1703 1 -3 1754 414 1777 1 -3 1129 1128 1758 1 -3 1091 1660 1665 1 -3 401 403 1670 1 -3 1142 806 1676 1 -3 548 588 1733 1 -3 981 1800 1802 1 -3 1086 1509 1680 1 -3 938 1449 1681 1 -3 1702 1440 1704 1 -3 931 1515 1677 1 -3 1133 1789 1791 1 -3 1095 1096 1676 1 -3 528 1659 1694 1 -3 1646 1508 1688 1 -3 937 1093 1725 1 -3 1066 977 1751 1 -3 725 1090 1689 1 -3 261 1488 1684 1 -3 1706 929 1760 1 -3 722 940 1685 1 -3 1070 1022 1737 1 -3 1631 944 1716 1 -3 1400 263 1691 1 -3 1116 1686 1707 1 -3 1059 1576 1674 1 -3 557 558 1723 1 -3 1116 1672 1686 1 -3 1655 1086 1680 1 -3 1092 1104 1696 1 -3 954 1691 1721 1 -3 1101 1712 1723 1 -3 1515 1656 1677 1 -3 257 258 1687 1 -3 954 1727 1731 1 -3 1637 1098 1673 1 -3 1101 1723 1730 1 -3 969 789 1734 1 -3 550 552 1690 1 -3 930 1274 1759 1 -3 1090 1679 1685 1 -3 1112 1662 1712 1 -3 1546 1674 1750 1 -3 1370 1717 1742 1 -3 677 1522 1735 1 -3 943 1702 1704 1 -3 1593 386 1738 1 -3 1530 1396 1724 1 -3 627 1121 1744 1 -3 588 1690 1701 1 -3 626 1695 1698 1 -3 923 1654 1665 1 -3 1689 1600 1699 1 -3 503 506 1693 1 -3 1627 893 1688 1 -3 1327 1328 1697 1 -3 575 576 1692 1 -3 626 1499 1695 1 -3 532 529 1694 1 -3 1623 1073 1683 1 -3 1750 1459 1755 1 -3 1091 1665 1679 1 -3 940 1600 1689 1 -3 1427 725 1699 1 -3 590 1440 1702 1 -3 725 1689 1699 1 -3 1762 1438 1770 1 -3 1719 1087 1740 1 -3 1129 1758 1793 1 -3 1090 1685 1689 1 -3 1061 1593 1738 1 -3 1347 558 1741 1 -3 924 1717 1745 1 -3 1440 626 1698 1 -3 957 1459 1750 1 -3 1672 440 1686 1 -3 1217 884 1700 1 -3 1102 941 1701 1 -3 867 784 1748 1 -3 1681 257 1687 1 -3 407 410 1749 1 -3 1685 940 1689 1 -3 1694 1372 1728 1 -3 1707 1466 1720 1 -3 1721 1467 1740 1 -3 1668 1100 1682 1 -3 1508 1627 1688 1 -3 1698 934 1704 1 -3 1717 1370 1745 1 -3 953 897 1721 1 -3 1600 939 1699 1 -3 1439 1716 1718 1 -3 558 555 1741 1 -3 1560 1097 1703 1 -3 780 943 1704 1 -3 553 1463 1741 1 -3 1684 1481 1696 1 -3 969 1747 1775 1 -3 1776 1124 1780 1 -3 1087 953 1740 1 -3 936 1725 1742 1 -3 893 855 1708 1 -3 1404 781 1706 1 -3 1693 506 1718 1 -3 1093 1092 1705 1 -3 955 932 1710 1 -3 1433 299 1714 1 -3 1708 1120 1713 1 -3 590 1702 1716 1 -3 1370 450 1745 1 -3 1543 1544 1746 1 -3 975 1586 1755 1 -3 299 300 1711 1 -3 1408 438 1768 1 -3 1465 1112 1712 1 -3 1725 1374 1742 1 -3 299 1711 1714 1 -3 1132 968 1753 1 -3 1291 1054 1709 1 -3 436 1534 1707 1 -3 1092 1696 1705 1 -3 1674 957 1750 1 -3 1374 1725 1736 1 -3 877 1119 1713 1 -3 506 1439 1718 1 -3 1104 1684 1696 1 -3 1439 590 1716 1 -3 943 1631 1702 1 -3 1675 677 1735 1 -3 972 1735 1762 1 -3 870 1438 1762 1 -3 532 1694 1728 1 -3 1374 446 1742 1 -3 1691 1467 1721 1 -3 1122 1404 1760 1 -3 1250 858 1763 1 -3 924 925 1717 1 -3 790 1469 1715 1 -3 737 736 1771 1 -3 424 1371 1784 1 -3 1113 1116 1720 1 -3 1719 255 1724 1 -3 955 1710 1722 1 -3 1418 434 1775 1 -3 256 255 1719 1 -3 783 1124 1776 1 -3 420 1460 1772 1 -3 1670 406 1743 1 -3 1044 955 1722 1 -3 971 727 1770 1 -3 964 961 1767 1 -3 1197 1362 1743 1 -3 1690 1102 1701 1 -3 561 557 1723 1 -3 255 1530 1724 1 -3 895 777 1727 1 -3 760 786 1764 1 -3 1736 1093 1757 1 -3 1734 1125 1747 1 -3 762 763 1726 1 -3 303 1479 1780 1 -3 936 937 1725 1 -3 1034 1031 1783 1 -3 1376 442 1736 1 -3 65 196 1761 1 -3 1113 1720 1729 1 -3 1470 532 1728 1 -3 970 965 1779 1 -3 1347 1741 1756 1 -3 1103 959 1763 1 -3 1781 1126 1786 1 -3 791 969 1773 1 -3 958 1744 1748 1 -3 1116 1707 1720 1 -3 1114 1113 1729 1 -3 1139 1258 1732 1 -3 1440 1698 1704 1 -3 945 1101 1730 1 -3 1132 1754 1777 1 -3 1362 1670 1743 1 -3 1115 467 1731 1 -3 1739 1123 1759 1 -3 793 1126 1781 1 -3 1139 1732 1737 1 -3 546 548 1733 1 -3 789 790 1734 1 -3 1712 561 1723 1 -3 964 1772 1779 1 -3 1727 1115 1731 1 -3 537 536 1791 1 -3 1022 1139 1737 1 -3 1544 1123 1739 1 -3 1522 1483 1735 1 -3 723 1289 1758 1 -3 701 1418 1747 1 -3 1119 1708 1713 1 -3 971 1770 1776 1 -3 410 411 1754 1 -3 802 688 1786 1 -3 386 1533 1738 1 -3 206 63 1782 1 -3 1725 1093 1736 1 -3 1125 1778 1790 1 -3 1706 924 1745 1 -3 411 414 1754 1 -3 1793 1243 1795 1 -3 1738 1533 1744 1 -3 1768 973 1773 1 -3 1467 259 1740 1 -3 555 553 1741 1 -3 975 1755 1781 1 -3 1783 1030 1792 1 -3 1624 1250 1763 1 -3 1717 936 1742 1 -3 1533 627 1744 1 -3 1705 973 1757 1 -3 977 1131 1751 1 -3 970 1784 1787 1 -3 1773 969 1775 1 -3 784 958 1748 1 -3 1651 723 1758 1 -3 1735 1483 1762 1 -3 969 1734 1747 1 -3 978 1347 1756 1 -3 196 1543 1746 1 -3 1127 1130 1794 1 -3 406 407 1749 1 -3 1734 790 1778 1 -3 581 1750 1755 1 -3 581 1546 1750 1 -3 929 930 1760 1 -3 1250 857 1752 1 -3 968 1094 1753 1 -3 1125 1734 1778 1 -3 978 1756 1766 1 -3 1778 1117 1790 1 -3 1133 1791 1796 1 -3 974 978 1766 1 -3 1463 717 1756 1 -3 972 1762 1770 1 -3 1132 1753 1754 1 -3 1743 406 1749 1 -3 1456 540 1789 1 -3 1456 1783 1792 1 -3 802 1786 1794 1 -3 1586 581 1755 1 -3 1123 1122 1759 1 -3 414 416 1777 1 -3 1371 702 1787 1 -3 196 1751 1761 1 -3 1474 974 1785 1 -3 1787 702 1790 1 -3 1128 1651 1758 1 -3 1756 717 1766 1 -3 702 1125 1790 1 -3 1761 1131 1782 1 -3 971 1776 1780 1 -3 1205 906 1788 1 -3 416 1446 1774 1 -3 1758 1289 1793 1 -3 64 65 1761 1 -3 974 1766 1785 1 -3 1446 420 1772 1 -3 1483 870 1762 1 -3 1111 1110 1798 1 -3 859 760 1764 1 -3 1040 859 1765 1 -3 438 1376 1768 1 -3 1200 1040 1769 1 -3 961 960 1767 1 -3 858 737 1771 1 -3 1040 1765 1769 1 -3 970 1779 1784 1 -3 727 972 1770 1 -3 859 1764 1765 1 -3 1474 1785 1792 1 -3 416 1774 1777 1 -3 717 1447 1766 1 -3 964 1767 1772 1 -3 434 1408 1775 1 -3 1755 1459 1781 1 -3 1715 1117 1778 1 -3 973 791 1773 1 -3 1438 783 1776 1 -3 1753 410 1754 1 -3 1376 1757 1768 1 -3 1767 960 1774 1 -3 959 1624 1763 1 -3 960 1536 1774 1 -3 1536 1132 1777 1 -3 1479 971 1780 1 -3 965 964 1779 1 -3 1030 1474 1792 1 -3 1446 1767 1774 1 -3 64 1761 1782 1 -3 1774 1536 1777 1 -3 975 1781 1786 1 -3 1459 793 1781 1 -3 63 64 1782 1 -3 1766 1447 1785 1 -3 1031 1030 1783 1 -3 1460 424 1784 1 -3 1093 1705 1757 1 -3 906 904 1788 1 -3 1447 562 1785 1 -3 904 1422 1788 1 -3 979 1787 1790 1 -3 1770 1438 1776 1 -3 688 975 1786 1 -3 979 970 1787 1 -3 1034 1783 1789 1 -3 1117 979 1790 1 -3 1785 562 1792 1 -3 540 537 1791 1 -3 1751 1131 1761 1 -3 1134 1133 1796 1 -3 1408 1773 1775 1 -3 1289 217 1793 1 -3 790 1715 1778 1 -3 562 1456 1792 1 -3 930 1759 1760 1 -3 1134 1796 1797 1 -3 1211 219 1805 1 -3 1126 1127 1794 1 -3 1759 1122 1760 1 -3 1728 1111 1797 1 -3 1757 973 1768 1 -3 1803 197 1804 1 -3 1786 1126 1794 1 -3 1783 1456 1789 1 -3 1789 540 1791 1 -3 1244 197 1803 1 -3 1767 1446 1772 1 -3 1779 1460 1784 1 -3 536 1470 1796 1 -3 1129 1793 1795 1 -3 1796 1470 1797 1 -3 981 801 1800 1 -3 1130 1129 1795 1 -3 80 81 1801 1 -3 982 1244 1803 1 -3 82 83 1804 1 -3 986 1211 1805 1 -3 1211 984 1803 1 -3 1800 1328 1802 1 -3 1470 1728 1797 1 -3 1135 1134 1798 1 -3 1797 1111 1798 1 -3 1134 1797 1798 1 -3 1794 1130 1799 1 -3 221 1801 1802 1 -3 802 1799 1800 1 -3 1801 1244 1802 1 -3 801 802 1800 1 -3 1130 1697 1799 1 -3 1328 221 1802 1 -3 221 80 1801 1 -3 984 982 1803 1 -3 197 82 1804 1 -3 1244 981 1802 1 -3 991 986 1805 1 -3 802 1794 1799 1 -3 1233 1817 1920 1 -3 1158 838 1806 1 -3 840 947 1806 1 -3 838 840 1806 1 -3 1170 1820 1929 1 -3 1813 1036 1843 1 -3 1150 1215 1841 1 -3 1367 1823 1926 1 -3 23 24 1807 1 -3 1233 1260 1817 1 -3 1196 1179 1818 1 -3 25 26 1808 1 -3 1168 1285 1842 1 -3 1177 1303 1819 1 -3 216 1186 1854 1 -3 1232 1822 1924 1 -3 94 95 1809 1 -3 916 1183 1810 1 -3 918 914 1810 1 -3 24 170 1807 1 -3 1288 213 1811 1 -3 213 44 1811 1 -3 45 174 1811 1 -3 126 216 1812 1 -3 176 125 1812 1 -3 1381 187 1864 1 -3 170 25 1808 1 -3 1283 1369 1840 1 -3 1825 1350 1927 1 -3 1186 128 1861 1 -3 230 1385 1836 1 -3 1820 200 1929 1 -3 99 180 1814 1 -3 234 98 1814 1 -3 175 1472 1855 1 -3 95 191 1809 1 -3 914 916 1810 1 -3 1330 1167 1849 1 -3 822 878 1816 1 -3 1819 1303 1833 1 -3 1196 1818 1827 1 -3 1823 201 1926 1 -3 1185 209 1839 1 -3 44 45 1811 1 -3 1287 1288 1816 1 -3 125 126 1812 1 -3 1191 1192 1813 1 -3 844 758 1817 1 -3 1411 1492 1844 1 -3 1166 1194 1856 1 -3 741 847 1818 1 -3 1179 818 1818 1 -3 226 1825 1927 1 -3 1110 1177 1819 1 -3 1135 1798 1819 1 -3 1170 1006 1820 1 -3 1008 1193 1820 1 -3 1178 854 1821 1 -3 755 846 1821 1 -3 94 1809 1846 1 -3 1280 1282 1916 1 -3 1281 207 1872 1 -3 1172 1256 1828 1 -3 187 1382 1876 1 -3 1367 1198 1823 1 -3 1037 1188 1823 1 -3 1240 1241 1824 1 -3 1239 1238 1824 1 -3 222 1309 1826 1 -3 947 948 1828 1 -3 951 1172 1828 1 -3 1817 812 1920 1 -3 1542 234 1850 1 -3 812 1583 1829 1 -3 1168 994 1830 1 -3 1808 26 1848 1 -3 1223 844 1923 1 -3 1334 1056 1832 1 -3 1394 1010 1835 1 -3 1014 1383 1835 1 -3 1038 1171 1834 1 -3 98 99 1814 1 -3 172 1191 1899 1 -3 1410 227 1903 1 -3 23 1807 1851 1 -3 999 1394 1837 1 -3 1171 1455 1838 1 -3 53 193 1839 1 -3 209 52 1839 1 -3 1257 1172 1905 1 -3 1120 1168 1842 1 -3 878 1713 1842 1 -3 210 1302 1847 1 -3 1331 1350 1825 1 -3 1809 1163 1846 1 -3 193 1232 1924 1 -3 201 93 1846 1 -3 142 143 1815 1 -3 1023 1241 1845 1 -3 1177 1109 1847 1 -3 1161 1808 1848 1 -3 227 1195 1852 1 -3 27 226 1848 1 -3 749 821 1849 1 -3 1167 810 1849 1 -3 1807 1357 1851 1 -3 200 22 1851 1 -3 821 822 1816 1 -3 177 1307 1845 1 -3 180 100 1852 1 -3 101 227 1852 1 -3 1308 184 1853 1 -3 1186 1144 1854 1 -3 1069 1159 1855 1 -3 136 202 1856 1 -3 1292 1140 1857 1 -3 7 207 1859 1 -3 62 206 1858 1 -3 89 205 1860 1 -3 129 181 1861 1 -3 51 209 1862 1 -3 184 50 1862 1 -3 846 1671 1863 1 -3 1084 1180 1863 1 -3 1165 1138 1844 1 -3 995 1399 1865 1 -3 1143 1137 1866 1 -3 738 706 1867 1 -3 181 1257 1905 1 -3 1348 1162 1868 1 -3 1237 199 1869 1 -3 1559 1027 1870 1 -3 1160 1234 1871 1 -3 9 1369 1872 1 -3 207 8 1872 1 -3 1193 20 1930 1 -3 1214 1215 1831 1 -3 976 799 1875 1 -3 1131 976 1874 1 -3 206 1782 1874 1 -3 1897 1157 1928 1 -3 230 107 1876 1 -3 108 187 1876 1 -3 1300 1299 1881 1 -3 1226 1225 1890 1 -3 1414 1415 1878 1 -3 1333 1147 1878 1 -3 1332 1333 1880 1 -3 1146 1176 1881 1 -3 1176 1145 1880 1 -3 1415 1148 1884 1 -3 182 159 1891 1 -3 1149 1174 1884 1 -3 1295 1294 1887 1 -3 148 224 1879 1 -3 1297 1300 1887 1 -3 224 149 1882 1 -3 190 151 1885 1 -3 160 220 1891 1 -3 150 190 1882 1 -3 1152 1295 1889 1 -3 223 145 1883 1 -3 198 147 1879 1 -3 152 228 1885 1 -3 146 198 1883 1 -3 154 179 1888 1 -3 144 223 1886 1 -3 228 153 1888 1 -3 809 1151 1894 1 -3 1154 1752 1895 1 -3 1492 171 1844 1 -3 1816 878 1925 1 -3 1036 1334 1843 1 -3 1138 1411 1844 1 -3 1504 231 1843 1 -3 231 17 1899 1 -3 18 172 1899 1 -3 59 3 1900 1 -3 86 2 1901 1 -3 2 87 1901 1 -3 3 60 1900 1 -3 168 4 1902 1 -3 4 5 1902 1 -3 1221 238 1900 1 -3 1263 235 1901 1 -3 1277 237 1902 1 -3 103 1492 1903 1 -3 227 102 1903 1 -3 1172 1028 1905 1 -3 20 21 1930 1 -3 1840 1897 1928 1 -3 179 1228 1915 1 -3 163 164 1912 1 -3 1153 1154 1910 1 -3 164 165 1913 1 -3 1096 1596 1914 1 -3 1676 1096 1911 1 -3 1457 1223 1923 1 -3 195 1477 1897 1 -3 1187 205 1873 1 -3 844 1223 1875 1 -3 187 109 1864 1 -3 1258 1165 1836 1 -3 758 812 1817 1 -3 208 1230 1841 1 -3 141 1 1904 1 -3 1 142 1904 1 -3 1169 1186 1861 1 -3 1136 1167 1826 1 -3 1114 1309 1853 1 -3 1248 185 1838 1 -3 1493 169 1837 1 -3 818 741 1818 1 -3 918 1822 1829 1 -3 1501 230 1836 1 -3 1218 215 1834 1 -3 231 1813 1843 1 -3 1287 1816 1925 1 -3 1798 1110 1819 1 -3 1505 186 1832 1 -3 1006 1008 1820 1 -3 1159 1331 1825 1 -3 854 755 1821 1 -3 202 1214 1831 1 -3 211 1284 1830 1 -3 918 1810 1822 1 -3 1282 1867 1916 1 -3 1385 1258 1836 1 -3 1198 1037 1823 1 -3 1238 1240 1824 1 -3 226 1435 1825 1 -3 1329 222 1826 1 -3 847 1445 1827 1 -3 205 90 1873 1 -3 1223 1224 1875 1 -3 948 951 1828 1 -3 1815 143 1886 1 -3 1215 208 1841 1 -3 1583 918 1829 1 -3 994 1178 1830 1 -3 1189 172 1877 1 -3 993 1602 1831 1 -3 1056 1292 1832 1 -3 1239 1141 1869 1 -3 1548 1135 1833 1 -3 1180 1038 1834 1 -3 1010 1014 1835 1 -3 1810 1185 1822 1 -3 192 1194 1896 1 -3 20 1193 1877 1 -3 1285 1287 1925 1 -3 1827 1445 1850 1 -3 1399 999 1837 1 -3 1455 1143 1838 1 -3 1194 1158 1896 1 -3 1221 61 1858 1 -3 1263 88 1860 1 -3 1277 6 1859 1 -3 172 19 1877 1 -3 91 1188 1873 1 -3 110 1383 1864 1 -3 52 53 1839 1 -3 1369 195 1840 1 -3 1164 1150 1841 1 -3 1713 1120 1842 1 -3 1548 1833 1854 1 -3 1816 1288 1922 1 -3 19 20 1877 1 -3 1241 177 1845 1 -3 1849 821 1922 1 -3 1027 1023 1845 1 -3 1156 1157 1897 1 -3 93 94 1846 1 -3 1158 1806 1896 1 -3 1598 1114 1853 1 -3 1109 1181 1847 1 -3 1141 1337 1869 1 -3 90 91 1873 1 -3 1806 1255 1896 1 -3 26 27 1848 1 -3 810 749 1849 1 -3 1445 1349 1850 1 -3 1288 1330 1922 1 -3 22 23 1851 1 -3 1889 179 1915 1 -3 1892 164 1913 1 -3 1893 1096 1914 1 -3 164 1892 1912 1 -3 1154 1890 1910 1 -3 1096 1893 1911 1 -3 100 101 1852 1 -3 1309 1308 1853 1 -3 1144 1548 1854 1 -3 844 1817 1923 1 -3 1657 1069 1855 1 -3 109 110 1864 1 -3 1820 1193 1930 1 -3 135 136 1856 1 -3 1140 1156 1857 1 -3 61 62 1858 1 -3 88 89 1860 1 -3 6 7 1859 1 -3 1222 1221 1858 1 -3 1264 1263 1860 1 -3 1278 1277 1859 1 -3 128 129 1861 1 -3 50 51 1862 1 -3 1671 1084 1863 1 -3 878 1842 1925 1 -3 1383 1381 1864 1 -3 1337 995 1865 1 -3 1137 1657 1866 1 -3 1827 1850 1921 1 -3 821 1816 1922 1 -3 706 805 1867 1 -3 1174 1164 1898 1 -3 1349 1348 1868 1 -3 199 1239 1869 1 -3 1181 1559 1870 1 -3 1234 1355 1871 1 -3 8 9 1872 1 -3 1188 1187 1873 1 -3 1782 1131 1874 1 -3 799 844 1875 1 -3 107 108 1876 1 -3 1193 1189 1877 1 -3 1299 1146 1881 1 -3 1147 1414 1878 1 -3 147 148 1879 1 -3 1145 1332 1880 1 -3 149 150 1882 1 -3 145 146 1883 1 -3 143 144 1886 1 -3 1148 1149 1884 1 -3 151 152 1885 1 -3 1294 1297 1887 1 -3 1225 182 1890 1 -3 153 154 1888 1 -3 1151 1152 1889 1 -3 1312 1311 1893 1 -3 159 160 1891 1 -3 1182 1173 1892 1 -3 857 809 1894 1 -3 857 1894 1895 1 -3 1752 857 1895 1 -3 1303 1812 1919 1 -3 1854 1833 1919 1 -3 1255 192 1896 1 -3 1839 193 1924 1 -3 1392 738 1917 1 -3 17 18 1899 1 -3 236 141 1904 1 -3 200 1851 1929 1 -3 238 59 1900 1 -3 235 86 1901 1 -3 237 168 1902 1 -3 1848 226 1927 1 -3 102 103 1903 1 -3 1028 1564 1905 1 -3 201 1846 1926 1 -3 947 1828 1918 1 -3 805 1907 1916 1 -3 1232 1233 1920 1 -3 1173 1906 1912 1 -3 1908 1182 1913 1 -3 1909 1312 1914 1 -3 1173 1142 1906 1 -3 1907 1611 1908 1 -3 805 1611 1907 1 -3 1611 1182 1908 1 -3 220 1312 1909 1 -3 812 1829 1920 1 -3 1311 194 1906 1 -3 1315 1279 1907 1 -3 1315 1907 1908 1 -3 204 1315 1908 1 -3 1155 1175 1909 1 -3 1282 1283 1917 1 -3 1906 194 1912 1 -3 204 1908 1913 1 -3 1155 1909 1914 1 -3 1907 1279 1916 1 -3 1175 1153 1910 1 -3 194 163 1912 1 -3 1142 1676 1911 1 -3 165 204 1913 1 -3 1596 1155 1914 1 -3 1228 1227 1915 1 -3 1279 1280 1916 1 -3 1311 1906 1911 1 -3 1817 1260 1923 1 -3 1256 1255 1918 1 -3 1906 1142 1911 1 -3 234 1814 1921 1 -3 1812 216 1919 1 -3 1814 1196 1921 1 -3 1260 1457 1923 1 -3 1163 1367 1926 1 -3 1350 1161 1927 1 -3 1157 1392 1928 1 -3 1357 1170 1929 1 -3 21 200 1930 1 -3 200 1820 1930 1 -3 236 1815 1898 1 -3 1833 1303 1919 1 -3 1917 1283 1928 1 -3 1330 1849 1922 1 -3 1815 236 1904 1 -3 142 1815 1904 1 -3 1196 1827 1921 1 -3 1850 234 1921 1 -3 1392 1917 1928 1 -3 1842 1285 1925 1 -3 1840 195 1897 1 -3 216 1854 1919 1 -3 1829 1232 1920 1 -3 1185 1839 1924 1 -3 1828 1256 1918 1 -3 1283 1840 1928 1 -3 1822 1185 1924 1 -3 1867 805 1916 1 -3 1846 1163 1926 1 -3 1851 1357 1929 1 -3 1161 1848 1927 1 -3 1890 182 1910 1 -3 1892 1173 1912 1 -3 1893 1311 1911 1 -3 1182 1892 1913 1 -3 1312 1893 1914 1 -3 1151 1889 1915 1 \ No newline at end of file +2 +1895 3620 1 +0.0 0.0 +0.05 0.0 +0.05 0.025 +0.0 0.025 +0.0008928571428555298 0.0 +0.001785714285710985 0.0 +0.00267857142856618 0.0 +0.003571428571421811 0.0 +0.004464285714277792 0.0 +0.005357142857133653 0.0 +0.006249999999989272 0.0 +0.007142857142844019 0.0 +0.008035714285698598 0.0 +0.008928571428553174 0.0 +0.009821428571407075 0.0 +0.01071428571426165 0.0 +0.01160714285711623 0.0 +0.01249999999997081 0.0 +0.01339285714282538 0.0 +0.01428571428567996 0.0 +0.01517857142853454 0.0 +0.01607142857138912 0.0 +0.0169642857142437 0.0 +0.01785714285709827 0.0 +0.01874999999995217 0.0 +0.01964285714280608 0.0 +0.02053571428566065 0.0 +0.02142857142851523 0.0 +0.02232142857136981 0.0 +0.02321428571422439 0.0 +0.02410714285707896 0.0 +0.02499999999993422 0.0 +0.02589285714279296 0.0 +0.02678571428565267 0.0 +0.0276785714285119 0.0 +0.0285714285713718 0.0 +0.02946428571423103 0.0 +0.03035714285709093 0.0 +0.03124999999995015 0.0 +0.03214285714281025 0.0 +0.0330357142856689 0.0 +0.03392857142852908 0.0 +0.03482142857138832 0.0 +0.03571428571424793 0.0 +0.03660714285710773 0.0 +0.03749999999996677 0.0 +0.03839285714282581 0.0 +0.03928571428568561 0.0 +0.04017857142854522 0.0 +0.04107142857140445 0.0 +0.04196428571426464 0.0 +0.04285714285712328 0.0 +0.04374999999998407 0.0 +0.04464285714284213 0.0 +0.0455357142857029 0.0 +0.04642857142856116 0.0 +0.04732142857142174 0.0 +0.04821428571428057 0.0 +0.04910714285714057 0.0 +0.05 0.0008928571428554925 +0.05 0.001785714285710905 +0.05 0.002678571428566826 +0.05 0.003571428571422009 +0.05 0.004464285714276587 +0.05 0.005357142857130826 +0.05 0.006249999999985404 +0.05 0.007142857142839982 +0.05 0.008035714285694561 +0.05 0.008928571428549137 +0.05 0.009821428571403038 +0.05 0.01071428571425762 +0.05 0.01160714285711219 +0.05 0.01249999999996711 +0.05 0.01339285714282634 +0.05 0.0142857142856859 +0.05 0.01517857142854546 +0.05 0.01607142857140513 +0.05 0.01696428571426454 +0.05 0.01785714285712397 +0.05 0.01874999999998338 +0.05 0.01964285714284281 +0.05 0.02053571428570223 +0.05 0.02142857142856164 +0.05 0.02232142857142106 +0.05 0.02321428571428058 +0.05 0.02410714285714029 +0.04910714285714533 0.025 +0.04821428571429066 0.025 +0.04732142857143598 0.025 +0.0464285714285813 0.025 +0.04553571428572605 0.025 +0.04464285714286925 0.025 +0.04375000000001458 0.025 +0.0428571428571599 0.025 +0.04196428571430523 0.025 +0.04107142857145055 0.025 +0.04017857142859588 0.025 +0.03928571428574121 0.025 +0.03839285714288653 0.025 +0.03750000000003322 0.025 +0.0366071428571799 0.025 +0.03571428571432522 0.025 +0.03482142857147055 0.025 +0.03392857142861588 0.025 +0.0330357142857612 0.025 +0.03214285714290652 0.025 +0.03125000000005185 0.025 +0.03035714285719718 0.025 +0.02946428571434251 0.025 +0.02857142857148783 0.025 +0.02767857142863316 0.025 +0.02678571428577849 0.025 +0.02589285714292381 0.025 +0.02500000000006846 0.025 +0.02410714285720962 0.025 +0.02321428571434982 0.025 +0.02232142857149049 0.025 +0.0214285714286305 0.025 +0.02053571428577117 0.025 +0.01964285714291118 0.025 +0.01875000000005186 0.025 +0.01785714285719253 0.025 +0.01696428571433253 0.025 +0.01607142857147321 0.025 +0.01517857142861355 0.025 +0.01428571428575374 0.025 +0.01339285714289423 0.025 +0.01250000000003457 0.025 +0.01160714285717491 0.025 +0.01071428571431539 0.025 +0.009821428571455588 0.025 +0.00892857142859626 0.025 +0.008035714285736456 0.025 +0.007142857142876946 0.025 +0.006250000000017287 0.025 +0.005357142857157632 0.025 +0.00446428571429805 0.025 +0.003571428571438435 0.025 +0.002678571428578897 0.025 +0.001785714285719248 0.025 +0.0008928571428596377 0.025 +0.0 0.02410714285714533 +0.0 0.02321428571429065 +0.0 0.02232142857143463 +0.0 0.02142857142857995 +0.0 0.02053571428572528 +0.0 0.0196428571428706 +0.0 0.01875000000001661 +0.0 0.01785714285716261 +0.0 0.01696428571430794 +0.0 0.01607142857145326 +0.0 0.01517857142859859 +0.0 0.01428571428574392 +0.0 0.01339285714288924 +0.0 0.01250000000003423 +0.0 0.01160714285717491 +0.0 0.01071428571431525 +0.0 0.009821428571455588 +0.0 0.008928571428596266 +0.0 0.008035714285736606 +0.0 0.007142857142876872 +0.0 0.006250000000017287 +0.0 0.005357142857157696 +0.0 0.00446428571429813 +0.0 0.003571428571438473 +0.0 0.002678571428578816 +0.0 0.001785714285719217 +0.0 0.0008928571428596238 +0.0370689318578639 0.02412806191455077 +0.01830357142852494 0.0007732369676626342 +0.03258650695410954 0.02417932180047407 +0.01383928571424763 0.0007732369676602715 +0.02276785714279786 0.000773236967662862 +0.02812500000002834 0.0241449224651162 +0.02008928571431557 0.02411226159991751 +0.03526785714281493 0.0007732369676672268 +0.03080357142851934 0.0007732369676655927 +0.015623730940599 0.02414442606695786 +0.0008017397771972694 0.01289712759030341 +0.0491516233450916 0.01219117835774973 +0.01115944522630154 0.02414442606695673 +0.03973214285709605 0.000773236967672363 +0.009374999999969269 0.0007732369676582041 +0.0008526876128085243 0.009322585649827261 +0.049176303643053 0.01556640574358007 +0.02366071428575251 0.02411226159990698 +0.02723214285708186 0.0007732369676657152 +0.04062500000002321 0.02422676303233746 +0.0006847818786387323 0.01654286721895617 +0.04939299250549172 0.008509816711251506 +0.007589285714306698 0.02422676303233327 +0.04330357142854033 0.0007732369676760921 +0.04922676303233335 0.01919642857141308 +0.0007732369676667838 0.005803571428587491 +0.005803571428561463 0.00077323696766298 +0.04420792221426317 0.02413133423422874 +0.0007732369676622453 0.02008928571429794 +0.04929114334728927 0.00578323045537912 +0.004910714285727836 0.02422676303233321 +0.04598214285711591 0.0007732369676777714 +0.04915071596788145 0.0217699250814438 +0.0007732369676665806 0.003125000000008503 +0.0492061338881512 0.00311330219990481 +0.003113302199890193 0.0007938661118307851 +0.04690498561889542 0.0241404630759016 +0.0254464285713636 0.0007732369676645529 +0.02547847048529296 0.02412286224960309 +0.03258928571423944 0.000773236967666115 +0.0007732369676667102 0.01116071428574508 +0.03527124008767879 0.02417667081118918 +0.04919055300900371 0.01387313415871078 +0.0290178571428005 0.0007732369676661748 +0.03705357142852621 0.0007732369676691098 +0.02187500000003429 0.02411226159991823 +0.04151785714283453 0.0007732369676662279 +0.009375000000025915 0.02422676303233343 +0.01383928571428731 0.02411226159992021 +0.01830357142858425 0.02411226159992226 +0.007589285714267751 0.0007564836971837995 +0.01116071428567708 0.0007732369676600322 +0.01651785714281605 0.0007732369676620875 +0.003128382944803209 0.02417667081118881 +0.0007721406834161392 0.0218404260635372 +0.0008628792195006343 0.007697423147069707 +0.04930679596529199 0.01740352378215083 +0.0388522453193077 0.02419022499486971 +0.02008928571423408 0.0007732369676638155 +0.02991545040847089 0.0241143150474721 +0.04919877984838082 0.01031173256853062 +0.0008132237172853989 0.01839292245339945 +0.0007112526934547714 0.01478435311922574 +0.04241409723051498 0.02417667081119255 +0.0477605598056739 0.0007690238481059534 +0.0007533002718011114 0.001373817084464125 +0.04922676303233318 0.02366071428571036 +0.001364199244544823 0.02417625853670821 +0.04919134174333688 0.001421272874164007 +0.02633928571422342 0.0007732369676656514 +0.02678571428565189 0.001546473935330497 +0.02767857142850983 0.001546473935331242 +0.0272321428570803 0.00231971090299582 +0.02812499999993755 0.002319710902996828 +0.027678571428508 0.003092947870661022 +0.02678571428565098 0.003092947870660048 +0.02723214285707851 0.003866184838325051 +0.02812499999993555 0.003866184838326172 +0.02767857142850601 0.004639421805990095 +0.02857142857136303 0.0046394218059913 +0.02812499999993358 0.005412658773655239 +0.02901785714279051 0.005412658773656408 +0.02857142857136107 0.006185895741320214 +0.02946428571421703 0.006185895741321978 +0.02767857142850408 0.006185895741319023 +0.02901785714278854 0.006959132708985333 +0.0299107142856439 0.006959132708987292 +0.02946428571421577 0.007732369676650324 +0.03035714285707203 0.007732369676651729 +0.02991071428564324 0.008505606644315078 +0.03080357142849981 0.008505606644316243 +0.03035714285707063 0.009278843611979792 +0.03124999999992715 0.009278843611980926 +0.02946428571421369 0.00927884361197833 +0.03080357142849796 0.01005208057964444 +0.03169642857135437 0.0100520805796456 +0.03124999999992524 0.01082531754730904 +0.03214285714278154 0.0108253175473102 +0.03169642857135244 0.01159855451497358 +0.03258928571420869 0.01159855451497471 +0.0330357142856376 0.01082531754731149 +0.03348214285706493 0.01159855451497591 +0.03392857142849388 0.01082531754731261 +0.03437499999992126 0.01159855451497706 +0.03482142857135037 0.0108253175473137 +0.03526785714277785 0.0115985545149783 +0.03571428571420697 0.0108253175473148 +0.03616071428563452 0.01159855451497953 +0.03660714285706385 0.01082531754731581 +0.03705357142849131 0.0115985545149807 +0.03749999999992062 0.01082531754731694 +0.037946428571348 0.01159855451498177 +0.03392857142849184 0.01237179148264067 +0.03749999999991874 0.01237179148264554 +0.03839285714277534 0.01237179148264658 +0.03839285714277733 0.01082531754731803 +0.03794642857134616 0.01314502845031025 +0.03883928571420269 0.01314502845031131 +0.03839285714277353 0.0139182654179749 +0.03928571428562999 0.01391826541797598 +0.03883928571420075 0.01469150238563944 +0.03973214285705715 0.01469150238564057 +0.04017857142848645 0.01391826541797711 +0.03794642857134994 0.01005208057965323 +0.03883928571420665 0.01005208057965437 +0.04062499999991368 0.01469150238564176 +0.03124999999992803 0.007732369676652992 +0.03080357142849614 0.01159855451497243 +0.0263392857142217 0.003866184838323845 +0.0312499999999233 0.01237179148263696 +0.03035714285706706 0.01237179148263582 +0.0308035714284942 0.01314502845030033 +0.02991071428563792 0.01314502845029916 +0.0303571428570651 0.01391826541796372 +0.02946428571420873 0.01391826541796254 +0.02991071428563596 0.01469150238562714 +0.02901785714277959 0.01469150238562603 +0.02857142857135229 0.01391826541796138 +0.02812499999992315 0.01469150238562495 +0.02767857142849581 0.01391826541796028 +0.02723214285706663 0.01469150238562388 +0.0267857142856393 0.01391826541795926 +0.02633928571421121 0.01469150238562214 +0.02589285714278292 0.01391826541795806 +0.02544642857135487 0.01469150238562095 +0.02499999999992641 0.01391826541795739 +0.02455357142849849 0.01469150238561984 +0.02410714285706964 0.01391826541795624 +0.02366071428564184 0.01469150238561876 +0.02321428571421311 0.01391826541795525 +0.0227678571427851 0.01469150238561774 +0.02232142857135635 0.01391826541795358 +0.0218749999999283 0.0146915023856166 +0.02142857142849952 0.01391826541795236 +0.02098214285707015 0.01469150238561481 +0.0205357142856424 0.01391826541795112 +0.02008928571421298 0.0146915023856136 +0.01964285714278537 0.01391826541794997 +0.01919642857135596 0.01469150238561262 +0.01874999999992841 0.01391826541794889 +0.01830357142849896 0.01469150238561243 +0.01785714285707141 0.01391826541794795 +0.01741071428564195 0.01469150238561068 +0.01696428571421437 0.01391826541794676 +0.01651785714278492 0.01469150238560955 +0.01607142857135733 0.01391826541794563 +0.01562499999992787 0.01469150238560927 +0.0151785714285002 0.01391826541794464 +0.01473214285707071 0.01469150238560757 +0.01428571428564303 0.01391826541794345 +0.01383928571421352 0.0146915023856068 +0.01339285714278587 0.01391826541794241 +0.01294642857135632 0.01469150238560577 +0.01249999999992869 0.01391826541794135 +0.01919642857135734 0.01314502845028548 +0.01562499999992924 0.01314502845028093 +0.01205357142849961 0.01469150238560507 +0.01160714285707153 0.01391826541794049 +0.01205357142850101 0.01314502845027638 +0.0111607142856437 0.01469150238560388 +0.01116071428564398 0.01314502845027538 +0.01160714285707335 0.0123717914826114 +0.01071428571421646 0.01237179148261038 +0.01116071428564573 0.0115985545149465 +0.01026785714278896 0.01159855451494546 +0.02276785714278407 0.01314502845028925 +0.01071428571421818 0.01082531754728164 +0.009821428571361927 0.01082531754728089 +0.01026785714279081 0.01005208057961698 +0.01116071428564725 0.01005208057961796 +0.009374999999933561 0.01159855451494583 +0.00937499999993509 0.01005208057961591 +0.0124999999999303 0.01546473935326885 +0.01696428571421742 0.01546473935327217 +0.02678571428563984 0.01546473935328612 +0.02946428571420685 0.01546473935329058 +0.03035714285706311 0.01546473935329165 +0.02321428571422159 0.01546473935328138 +0.01964285714278902 0.0154647393532749 +0.04017857142848403 0.01546473935330528 +0.03839285714277933 0.009278843611989563 +0.03928571428563607 0.009278843611990642 +0.04107142857134292 0.01391826541797824 +0.04107142857134088 0.01546473935330644 +0.01071428571421991 0.009278843611953332 +0.01160714285707564 0.00927884361195404 +0.02991071428563405 0.01623797632095503 +0.03080357142849022 0.01623797632095612 +0.04062499999991132 0.01623797632097003 +0.04151785714276818 0.01623797632097112 +0.03883928571420865 0.008505606644325757 +0.03973214285706549 0.008505606644326832 +0.01116071428564893 0.008505606644289914 +0.01205357142850442 0.008505606644290275 +0.03794642857134448 0.01469150238563837 +0.02544642857135211 0.01314502845029327 +0.03035714285706125 0.01701121328861933 +0.03124999999991725 0.01701121328862043 +0.0410714285713377 0.01701121328863549 +0.04196428571419528 0.01701121328863589 +0.04241071428562478 0.01623797632097222 +0.039285714285638 0.007732369676661827 +0.04017857142849488 0.007732369676663015 +0.04062499999992229 0.008505606644327948 +0.04107142857135165 0.007732369676664304 +0.04151785714277891 0.008505606644329151 +0.03839285714278104 0.007732369676660723 +0.04196428571420827 0.007732369676665591 +0.04241071428563541 0.00850560664433029 +0.04017857142847803 0.01701121328863388 +0.01160714285707783 0.007732369676626633 +0.01249999999993377 0.007732369676627309 +0.01071428571422185 0.007732369676625602 +0.04285714285705209 0.01701121328863683 +0.04285714285706478 0.007732369676666705 +0.03080357142848839 0.01778445025628352 +0.03169642857134423 0.01778445025628455 +0.0299107142856363 0.01778445025628449 +0.04151785714276237 0.01778445025630034 +0.04330357142848158 0.01623797632097321 +0.043303571428492 0.008505606644331011 +0.03883928571421055 0.006959132708996615 +0.03794642857135312 0.006959132708995561 +0.0424107142856376 0.006959132709002183 +0.01205357142850681 0.006959132708963593 +0.01294642857136271 0.006959132708964592 +0.01339285714278976 0.007732369676628345 +0.01383928571421854 0.006959132708965596 +0.01428571428564556 0.007732369676629283 +0.01473214285707428 0.006959132708966568 +0.01517857142850129 0.007732369676630301 +0.0156249999999315 0.006959132708967545 +0.01607142857135705 0.007732369676631365 +0.01651785714278819 0.00695913270896895 +0.01696428571421265 0.007732369676632387 +0.01741071428564214 0.006959132708969833 +0.01785714285706845 0.00773236967663335 +0.01830357142849712 0.006959132708970476 +0.01874999999992404 0.007732369676634264 +0.0191964285713527 0.006959132708971326 +0.01964285714277974 0.007732369676635251 +0.02008928571420845 0.006959132708972209 +0.02053571428563557 0.007732369676636226 +0.04330357142849407 0.006959132709003388 +0.02098214285706432 0.006959132708973104 +0.02142857142849149 0.007732369676637208 +0.02991071428564443 0.005412658773659061 +0.03214285714277312 0.01701121328862158 +0.03258928571420004 0.01778445025628563 +0.03124999999991558 0.01855768722394742 +0.04374999999990906 0.01701121328863808 +0.03839285714278295 0.006185895741331189 +0.03749999999992526 0.006185895741330156 +0.01517857142850295 0.006185895741303716 +0.01249999999993568 0.006185895741300735 +0.04285714285706715 0.006185895741338918 +0.04374999999992342 0.006185895741339997 +0.0218749999999203 0.00695913270897399 +0.0223214285713475 0.007732369676638158 +0.02142857142849381 0.0061858957413103 +0.01785714285707283 0.006185895741305418 +0.03303571428562885 0.0170112132886227 +0.03348214285705573 0.0177844502562867 +0.03437499999992179 0.01005208057964935 +0.04419642857133842 0.01623797632097391 +0.04285714285706269 0.009278843611994696 +0.04374999999991897 0.009278843611995513 +0.01741071428563889 0.00850560664429641 +0.0209821428570624 0.008505606644300473 +0.04330357142848987 0.01005208057965891 +0.04419642857134592 0.01005208057965999 +0.0437499999999169 0.01082531754732315 +0.04464285714276611 0.01701121328863937 +0.04419642857133659 0.0177844502563033 +0.04464285714277528 0.009278843611996077 +0.04464285714277291 0.01082531754732425 +0.02276785714277635 0.006959132708974866 +0.0232142857142036 0.007732369676639119 +0.01473214285707094 0.008505606644293319 +0.03794642857135512 0.005412658773665631 +0.03705357142849745 0.005412658773664536 +0.03883928571421282 0.005412658773666742 +0.03660714285706754 0.006185895741329132 +0.03616071428563981 0.00541265877366348 +0.03571428571421 0.006185895741328076 +0.03526785714278212 0.005412658773662459 +0.04330357142849645 0.005412658773675433 +0.04419642857135273 0.005412658773676665 +0.03392857142848459 0.0170112132886238 +0.0343749999999115 0.01778445025628777 +0.03392857142848266 0.0185576872239506 +0.03482142857133833 0.01855768722395169 +0.03437499999990964 0.01933092419161438 +0.03526785714276515 0.0193309241916155 +0.03571428571419379 0.01855768722395285 +0.0361607142856206 0.01933092419161665 +0.04419642857134391 0.01159855451498737 +0.04464285714277975 0.006185895741341236 +0.04508928571420918 0.005412658773677918 +0.04508928571419377 0.01778445025630468 +0.04464285714276421 0.01855768722396877 +0.04508928571419999 0.01159855451498847 +0.04508928571419503 0.01623797632097479 +0.02366071428563485 0.006959132708974018 +0.0241071428570602 0.007732369676639793 +0.02366071428563084 0.008505606644303491 +0.02455357142848722 0.00850560664430444 +0.02410714285705812 0.009278843611967966 +0.02499999999991499 0.00927884361196896 +0.04464285714278205 0.004639421806013307 +0.03839285714278484 0.004639421806001009 +0.03928571428564268 0.004639421806002133 +0.04553571428563606 0.006185895741342405 +0.03482142857133652 0.02010416115927806 +0.03392857142848122 0.02010416115927702 +0.04553571428563858 0.004639421806014579 +0.03660714285704927 0.01855768722395398 +0.03705357142847596 0.01933092419161774 +0.04285714285706042 0.0108253175473228 +0.04464285714277087 0.01237179148265177 +0.04553571428562712 0.01237179148265273 +0.03348214285705766 0.01623797632095973 +0.03437499999991348 0.01623797632096084 +0.03705357142848913 0.0131450284503093 +0.01249999999993 0.01237179148261256 +0.01160714285708 0.006185895741299692 +0.01205357142850871 0.005412658773636954 +0.0111607142856533 0.005412658773635877 +0.04062499999991569 0.01314502845031364 +0.02098214285707121 0.01314502845028776 +0.02812499999992502 0.0131450284502968 +0.02857142857135924 0.007732369676649114 +0.03660714285704734 0.02010416115928032 +0.03749999999990254 0.02010416115928142 +0.0174107142856434 0.01314502845028326 +0.02321428571420762 0.006185895741309448 +0.01964285714278205 0.006185895741308693 +0.03660714285706941 0.004639421805998989 +0.01428571428564515 0.01546473935326967 +0.02901785714279256 0.003866184838327338 +0.01026785714278846 0.01314502845027415 +0.02499999999993576 0.01546473935328446 +0.0214285714285062 0.01546473935327856 +0.03616071428563579 0.0100520805796515 +0.01919642857135051 0.008505606644298419 +0.03482142857135251 0.00618589574132708 +0.03437499999992456 0.00541265877366147 +0.03482142857135422 0.004639421805996765 +0.03392857142849638 0.004639421805995704 +0.01160714285708193 0.004639421805973269 +0.01071428571422666 0.004639421805972187 +0.01249999999993719 0.004639421805974348 +0.010267857142798 0.005412658773634707 +0.009821428571371246 0.004639421805971025 +0.009374999999942549 0.00541265877363367 +0.00892857142851574 0.004639421805969838 +0.008482142857086943 0.005412658773632407 +0.008035714285660096 0.004639421805968652 +0.007589285714231187 0.005412658773631424 +0.007142857142804207 0.00463942180596738 +0.00669642857137515 0.00541265877363071 +0.006249999999947945 0.004644650765786864 +0.005803571428518674 0.005413530266933081 +0.006249999999946071 0.006186040990178309 +0.005371258748052977 0.004639543771879633 +0.005357142857089298 0.006186065198324554 +0.005803571428516878 0.006959146362380228 +0.004910714285659866 0.006959163227366096 +0.005357142857087461 0.007732377038594201 +0.00446428571423069 0.007732375990018263 +0.0049107142856581 0.008505607237588371 +0.006696428571372825 0.006959159192676281 +0.004458234843546508 0.006265856927301749 +0.005803571428514707 0.008505607970165965 +0.005357142857085652 0.009278843931814882 +0.004464285714229153 0.009278843764145003 +0.004910714285656679 0.01005208065829175 +0.005803571428513151 0.01005208064603961 +0.005357142857084164 0.01082531755357519 +0.004464285714227734 0.01082531756144119 +0.004910714285655185 0.01159855451835319 +0.005803571428511569 0.01159855451656198 +0.005357142857082661 0.01237179148344588 +0.006249999999938994 0.01237179148301811 +0.005803571428510127 0.01314502845048019 +0.004910714285653502 0.01314502845044638 +0.005357142857081236 0.01391826541795244 +0.006249999999937483 0.01391826541797403 +0.005803571428508178 0.01469150238560933 +0.006696428571364765 0.01469150238560869 +0.006249999999935564 0.01546473935326667 +0.007142857142792556 0.01546473935326669 +0.006696428571363332 0.01623797632092935 +0.005803571428505857 0.01623797632092932 +0.006249999999933798 0.0170112132885933 +0.007142857142791053 0.01701121328859376 +0.00669642857136139 0.01778445025625811 +0.007589285714218916 0.0177844502562587 +0.007142857142789344 0.01855768722392309 +0.008035714285646695 0.0185576872239241 +0.006249999999931877 0.01855768722392235 +0.006696428571359784 0.01933092419158734 +0.005803571428502554 0.01933092419158641 +0.006249999999930293 0.02010416115925154 +0.005357142857073104 0.02010416115925041 +0.004910714285645545 0.01933092419158544 +0.008482142857076434 0.01778445025625935 +0.008928571428504273 0.01855768722392493 +0.004464285714216208 0.02010416115924915 +0.0084821428570746 0.01933092419158963 +0.009374999999932253 0.01933092419159058 +0.009821428571361906 0.01855768722392578 +0.01026785714279001 0.01933092419159147 +0.008928571428502587 0.02010416115925536 +0.004910714285650836 0.01469150238560511 +0.01071428571421961 0.01855768722392665 +0.01116071428564789 0.01933092419159236 +0.01071428571421818 0.02010416115925734 +0.01160714285707623 0.0201041611592582 +0.01205357142850583 0.01933092419159313 +0.01249999999993435 0.020104161159259 +0.01294642857136398 0.01933092419159384 +0.01339285714279252 0.02010416115925968 +0.01383928571422231 0.01933092419159459 +0.01428571428565075 0.02010416115926043 +0.01473214285708054 0.01933092419159534 +0.01517857142850898 0.0201041611592611 +0.01562499999993891 0.01933092419159598 +0.01607142857136721 0.02010416115926195 +0.01651785714279723 0.01933092419159669 +0.01696428571422546 0.02010416115926256 +0.01741071428565531 0.01933092419159752 +0.01785714285708391 0.02010416115926339 +0.01830357142851344 0.01933092419159838 +0.0187499999999421 0.02010416115926414 +0.0191964285713715 0.01933092419159914 +0.01964285714280018 0.02010416115926482 +0.02008928571422949 0.01933092419159995 +0.02053571428565811 0.02010416115926549 +0.02098214285708736 0.01933092419160075 +0.02142857142851582 0.02010416115926617 +0.02187499999994501 0.01933092419160165 +0.02232142857137336 0.02010416115926681 +0.0227678571428024 0.01933092419160246 +0.02321428571423054 0.02010416115926748 +0.02366071428565956 0.01933092419160329 +0.02410714285708757 0.0201041611592681 +0.02455357142851653 0.01933092419160419 +0.02499999999994425 0.02010416115926879 +0.0254464285713732 0.01933092419160504 +0.02589285714280078 0.02010416115926943 +0.0263392857142296 0.01933092419160582 +0.02678571428565709 0.0201041611592702 +0.04553571428562884 0.0108253175473252 +0.04553571428562146 0.01855768722396996 +0.04508928571419177 0.01933092419163402 +0.04419642857133481 0.01933092419163286 +0.0446428571427623 0.02010416115929803 +0.04374999999990323 0.02010416115929684 +0.04553571428561921 0.02010416115929917 +0.03437499999990797 0.02087739812694049 +0.03348214285705289 0.02087739812693955 +0.01294642857136313 0.02087739812692478 +0.01741071428565556 0.02087739812692831 +0.005803571428500715 0.02087739812691576 +0.01473214285708 0.02087739812692611 +0.02633928571422836 0.02087739812693366 +0.02723214285708452 0.02087739812693432 +0.01919642857137261 0.02087739812692985 +0.02455357142851625 0.0208773981269322 +0.0227678571428021 0.02087739812693228 +0.02098214285708774 0.02087739812693135 +0.0450892857141897 0.02087739812696311 +0.004017857142798795 0.01159855451787144 +0.004017857142788814 0.0193309241915844 +0.04598214285704651 0.02087739812696431 +0.04598214285705116 0.01778445025630571 +0.0370535714284739 0.0208773981269439 +0.03794890478580058 0.02087596848385333 +0.03839326984516967 0.02010392288543405 +0.03883976720033146 0.02087712014078963 +0.01116071428564649 0.02087739812692337 +0.04508928571421147 0.003866184838350011 +0.04419642857135476 0.003866184838348524 +0.04598214285706785 0.003866184838351381 +0.03883928571421462 0.003866184838336214 +0.03973214285707269 0.003866184838337344 +0.02455357142849685 0.006959132708974922 +0.0343749999999263 0.003866184838330869 +0.03348214285706821 0.003866184838329809 +0.02455357142848553 0.01005208057963252 +0.02544642857134663 0.01005208057963365 +0.02366071428562897 0.01005208057963149 +0.02544642857134959 0.00850560664430603 +0.03928575307971602 0.02010413876149809 +0.03973222957041456 0.02087734806295725 +0.01785714285708513 0.01855768722393248 +0.01517857142851068 0.01855768722393 +0.04374999999991093 0.01546473935330918 +0.03973214285706335 0.01005208057965554 +0.03124999999992132 0.01391826541796479 +0.03526785714278026 0.006959132708992539 +0.03348214285706677 0.005412658773660423 +0.007142857142793977 0.01391826541794448 +0.01026785714279148 0.01778445025626102 +0.03437499999992295 0.00695913270899155 +0.0133928571427936 0.01855768722392879 +0.02589285714280215 0.01855768722394134 +0.02767857142851312 0.020104161159271 +0.02812499999993713 0.02087739812693631 +0.02410714285708857 0.01855768722393899 +0.02232142857137402 0.01855768722393666 +0.02053571428565884 0.01855768722393493 +0.01205357142851051 0.003866184838310822 +0.01294642857136559 0.003866184838311848 +0.01026785714279993 0.00386618483830839 +0.008482142857089075 0.003866184838305939 +0.02678571428565855 0.01855768722394218 +0.006693386330682356 0.003918339423609479 +0.003571428571371331 0.01082531755012688 +0.0267857142856559 0.02165063509459775 +0.03392857142847959 0.02165063509460284 +0.03303571428562452 0.02165063509460189 +0.04553571428561701 0.02165063509462808 +0.04464285714275534 0.02164888311054153 +0.03749999999990478 0.01855768722395508 +0.03705357142847804 0.01778445025629119 +0.04374999999991459 0.01237179148265137 +0.03392857142848659 0.01546473935329676 +0.03482142857134324 0.01546473935329824 +0.04196428571421141 0.006185895741337281 +0.04642857142849485 0.004639421806015813 +0.003571428571359688 0.02010416115924785 +0.004017857142786759 0.02087739812691258 +0.04642857142847619 0.02010416115930042 +0.0464285714284739 0.02165063509462936 +0.004464285714218023 0.01855768722392087 +0.00357142857136171 0.0185576872239198 +0.004017857142790592 0.01778445025625657 +0.04508928571419789 0.01314502845031626 +0.04598214285705418 0.01314502845031714 +0.04642857142848329 0.01237179148265377 +0.02589285714279441 0.003092947870659208 +0.02544642857136534 0.003866184838322728 +0.02499999999993813 0.003092947870658365 +0.02455357142850925 0.003866184838321658 +0.02410714285708215 0.003092947870657529 +0.02589285714279242 0.004639421805987306 +0.03482142857133451 0.02165063509460381 +0.03839285714277169 0.0154647393533029 +0.01205357142850224 0.01005208057961801 +0.03258928571419779 0.02087739812693852 +0.03214285714276935 0.02165063509460094 +0.02901785714278089 0.01623797632095427 +0.04017859234638129 0.02010414908232243 +0.04062501793844296 0.02087738777012351 +0.02991071428563982 0.01159855451497135 +0.03169642857134267 0.02087739812693756 +0.03124999999991416 0.0216506350946 +0.03214285714278341 0.009278843611982245 +0.03749999999992318 0.007732369676659891 +0.006696428571358277 0.02087739812691699 +0.006249999999928502 0.02165063509458161 +0.007142857142786372 0.02165063509458285 +0.008928571428513188 0.006185895741295976 +0.03749999999991544 0.0154647393533018 +0.02366071428565229 0.003866184838319971 +0.02321428571422624 0.003092947870656658 +0.02276785714279645 0.003866184838318833 +0.02232142857137068 0.003092947870655731 +0.02187499999994147 0.003866184838318071 +0.02142857142851538 0.003092947870654909 +0.02098214285708628 0.003866184838317114 +0.02053571428566014 0.003092947870654083 +0.02008928571423178 0.003866184838315785 +0.01964285714280517 0.003092947870653152 +0.01919642857137689 0.003866184838314742 +0.01874999999995023 0.003092947870652232 +0.018303571428522 0.003866184838313747 +0.01785714285709535 0.003092947870651296 +0.01741071428566712 0.003866184838312798 +0.01696428571424044 0.003092947870650314 +0.01651785714281221 0.003866184838312621 +0.01607142857138551 0.00309294787064947 +0.01562499999995728 0.003866184838311866 +0.01517857142852432 0.003092947870649054 +0.02857142857136522 0.02010416115927345 +0.01116071428564912 0.01778445025626185 +0.006696428571367914 0.01159855451528314 +0.04107143025709969 0.02010416018600317 +0.04151786041347119 0.02087739623859896 +0.02410714285705635 0.01082531754729611 +0.02321428571419986 0.01082531754729451 +0.03392857142849828 0.003092947870666069 +0.03303571428564011 0.00309294787066449 +0.03258928571421009 0.003866184838328921 +0.03482142857135612 0.003092947870667634 +0.03214285714278191 0.003092947870664252 +0.04464285714278468 0.003092947870685264 +0.04374999999992783 0.003092947870683526 +0.01249999999993873 0.00309294787064836 +0.00312499999994256 0.01159855451590495 +0.003132056377440761 0.0177885242577083 +0.003572604634281062 0.01701189228883461 +0.03844294318345932 0.0216742584243334 +0.04018958199763809 0.02159965907685819 +0.003124999999930301 0.02087739812691148 +0.003571428571357521 0.02165063509457624 +0.04687499999992404 0.003866184838352862 +0.04687499999991041 0.01314502845031804 +0.04642857142848146 0.01391826541798172 +0.03928571428564467 0.003092947870671243 +0.04017857142850283 0.003092947870672436 +0.04062499999993073 0.003866184838338492 +0.03839285714278635 0.003092947870670118 +0.04107142857136085 0.003092947870674875 +0.04642857142849722 0.003092947870688205 +0.03794642857133372 0.01778445025629238 +0.04330357142847539 0.01933092419163029 +0.04151785714277212 0.01314502845031476 +0.04107142857134488 0.01237179148265023 +0.04508928571420665 0.00695913270900562 +0.04598214285706259 0.006959132709006881 +0.01339285714279672 0.004639421805976054 +0.03973215280904414 0.01933091844583025 +0.03437499999991562 0.0146915023856337 +0.03526785714277239 0.01469150238563517 +0.03303571428563096 0.01546473935329549 +0.04196428571419936 0.01391826541797933 +0.02276785714277247 0.01005208057963037 +0.02232142857134338 0.01082531754729336 +0.03526785714277002 0.01623797632096301 +0.04151785714278813 0.003866184838340215 +0.03973214285707052 0.005412658773667949 +0.0348214285713507 0.007732369676656863 +0.03392857142849345 0.007732369676655787 +0.01071428571422097 0.01701121328859637 +0.03169642857135201 0.003866184838328053 +0.03124999999992409 0.003092947870663335 +0.02633928571423107 0.01778445025627897 +0.02723214285708747 0.01778445025628008 +0.03080357142848743 0.02087739812693654 +0.0303571428570589 0.02165063509459905 +0.04732142857135069 0.004639421806017252 +0.002678571428514881 0.01082531754791294 +0.002678571428505693 0.01855768722391869 +0.03168861379765543 0.02245772836666268 +0.0343749999999063 0.022423872062266 +0.03527448771460059 0.02245841206590031 +0.006732001288000031 0.02245024696973066 +0.007599431645014897 0.02242050652870538 +0.005809500214605905 0.02242826788016009 +0.04598214285704445 0.02242387206229307 +0.04688163057173909 0.02245841206592666 +0.04732253366663728 0.02165639176190242 +0.04732142857133795 0.01391826541798248 +0.04687499999990907 0.01468609056654614 +0.04732142857135346 0.003092947870689825 +0.002699170254613507 0.01700905288759787 +0.00312862914810689 0.01623772942080321 +0.002678571428500825 0.02165063509457512 +0.04732142857133916 0.01237179148265471 +0.03883928571421652 0.002319710903004892 +0.01339285714279395 0.003092947870649461 +0.03437499999993678 0.002319710903001761 +0.01294642857136707 0.002319710902986071 +0.01607142857138395 0.004639421805975181 +0.02410714285707587 0.004639421805982436 +0.02366071428565402 0.002319710902992289 +0.02098214285708867 0.002319710902991646 +0.01919642857137839 0.002319710902989759 +0.04687499999992156 0.005412658773680149 +0.004018658011306716 0.01623804833761553 +0.003572166907479314 0.01546471020602533 +0.002679299342556738 0.01546469334537031 +0.003125244374965215 0.01469148985974506 +0.04553571428563344 0.007732369676669741 +0.04642857142848907 0.007732369676671091 +0.04687499999991832 0.006959132709008041 +0.04732142857134473 0.007732369676672223 +0.04687499999991564 0.008505606644334831 +0.03571428571420794 0.00773236967665791 +0.03214285714277069 0.02010416115927511 +0.002670734674491521 0.02009963660720844 +0.04687499999991213 0.01159855451499031 +0.03571428571420455 0.01237179148264327 +0.03214285714278004 0.004639421805993723 +0.01383928571421479 0.01314502845027856 +0.003571428571370024 0.01237179148325523 +0.002678571428513986 0.01237179148287427 +0.04598214285705236 0.01469060041579559 +0.04107142857134959 0.009278843611992806 +0.009821428571363422 0.01701121328859554 +0.01562499999995781 0.002319710902986378 +0.01160714285708335 0.003092947870646939 +0.04196428571420126 0.01237179148265129 +0.04151785714277411 0.01159855451498668 +0.04062499999991773 0.0115985545149856 +0.03348214285706569 0.006959132708990554 +0.02767857142851497 0.01855768722394298 +0.0370535714284872 0.01469150238563723 +0.02589285714279971 0.02165063509459714 +0.02635272023295321 0.02241611563925832 +0.02549352633720467 0.02244274157689151 +0.02723438194353591 0.02242257932509557 +0.02187499999991604 0.01005208057962944 +0.02142857142848695 0.01082531754729235 +0.02098214285705962 0.01005208057962843 +0.02053571428563054 0.01082531754729133 +0.02008928571420323 0.01005208057962744 +0.01964285714277418 0.01082531754729036 +0.01919642857134691 0.01005208057962642 +0.01874999999991784 0.01082531754728935 +0.01741071428566903 0.002319710902987814 +0.007142857142795207 0.0123717914827342 +0.02544642857137464 0.01778445025627699 +0.04062499999992483 0.006959132708999258 +0.03482142857134467 0.01391826541797052 +0.03392857142848901 0.01391826541796917 +0.04107142857135875 0.004639421806004337 +0.01830357142849058 0.01005208057962544 +0.01785714285706152 0.0108253175472884 +0.01741071428563437 0.01005208057962445 +0.01696428571420522 0.01082531754728741 +0.01651785714277792 0.01005208057962339 +0.01607142857134887 0.01082531754728646 +0.0312499999999192 0.01546473935329284 +0.01026785714278818 0.02087739812692245 +0.01071428571421664 0.02165063509458866 +0.009821428571358506 0.02165063509458762 +0.01023643298218315 0.02245179073705959 +0.01115547692554472 0.02242852517472255 +0.03749999999992218 0.009278843611988722 +0.04642857142847891 0.01855768722397126 +0.04685845321628083 0.01777489696632492 +0.04725683930674682 0.0185085074952839 +0.04642112685838755 0.0170123269831947 +0.04727929636490125 0.01700250352686993 +0.003124999999943697 0.01005208058019446 +0.01562499999992179 0.01005208057962253 +0.01517857142849255 0.0108253175472855 +0.01473214285706548 0.01005208057962155 +0.01428571428563677 0.0108253175472846 +0.008037405274110395 0.02163478757428376 +0.009309945929587888 0.02242475062013915 +0.03526785714277871 0.008505606644321963 +0.01473214285709416 0.00231971090298658 +0.04330357142849924 0.003866184838346834 +0.04196428571421812 0.003092947870680167 +0.01473214285706619 0.01159855451494936 +0.007589285714223884 0.01159855451502346 +0.00714285714279681 0.0108253175473509 +0.00803571428565098 0.01237179148264378 +0.0116071428570779 0.0170112132885975 +0.01651785714277988 0.01159855451495132 +0.0330357142856374 0.007732369676655276 +0.0325892857142093 0.006959132708989961 +0.01830357142849297 0.01159855451495336 +0.01517857142852775 0.004639421805974604 +0.01383928571420963 0.01005208057962007 +0.01026785714279232 0.01623797632093139 +0.009374999999935532 0.01623797632093025 +0.01339285714278298 0.01082531754728317 +0.02008928571420603 0.01159855451495538 +0.03794642857135803 0.002319710903005144 +0.03749999999992789 0.003092947870669247 +0.03705357142849942 0.00231971090300439 +0.03660714285706994 0.003092947870668534 +0.02187499999991913 0.01159855451495744 +0.02366071428562859 0.01159855451495828 +0.02455357142848397 0.01159855451496052 +0.03348214285706522 0.008505606644320403 +0.03616071428564491 0.002319710903005315 +0.02053571428565385 0.004639421805980014 +0.02232142857136326 0.004639421805982378 +0.01874999999994219 0.004639421805977696 +0.009821428571364494 0.01546473935326602 +0.008928571428507757 0.01546473935326519 +0.009374999999935485 0.01469150238560072 +0.03080357142849639 0.003866184838329043 +0.03035714285707044 0.003092947870665487 +0.04687499999992671 0.002319710903025376 +0.04598214285707542 0.00231971090302678 +0.02589285714280363 0.01701121328861308 +0.02499999999994722 0.0170112132886129 +0.04419642857136678 0.002319710903016456 +0.04330357142850773 0.002319710903021898 +0.03169642857136126 0.002319710902999507 +0.04062499999994003 0.002319710903008394 +0.02812499999994381 0.01778445025627944 +0.02857142857137119 0.01855768722394372 +0.02767857142851006 0.01701121328861688 +0.04776785714277419 0.006959132709008758 +0.003131630571766014 0.02245841206588109 +0.0040316088778155 0.02250419195864136 +0.006292489633695147 0.02322861239162856 +0.02680176107191047 0.02318784441356059 +0.04776850393836984 0.02245692801353379 +0.002204441499807699 0.02246275211416775 +0.04776785714278304 0.002319710903027155 +0.04776785714276573 0.01468518859669702 +0.04775200291106188 0.01159998590534493 +0.04731878619938973 0.0108255561123858 +0.002254784019463523 0.01003900869862279 +0.002682344955578778 0.009276664965213859 +0.04196428654026455 0.02010416068234958 +0.04241071496840947 0.02087739773273918 +0.04196428637309783 0.02165063471418719 +0.04285714308065351 0.02165063496551051 +0.04241734500453293 0.02245841198098877 +0.04332205600932806 0.02246462150151081 +0.04152995549957453 0.02242328176705158 +0.0383928571427913 0.00154647393534285 +0.00312499999994093 0.01314502845042405 +0.002255303645079304 0.01315840033752503 +0.03660714285705817 0.01546473935330094 +0.03571428571420042 0.01391826541797138 +0.02410714285705976 0.01237179148262517 +0.02544642857136617 0.002319710902994409 +0.004910714285647251 0.017784450256257 +0.00848214285707817 0.01623797632092961 +0.03616071428563607 0.008505606644323151 +0.03571386667779803 0.02165551180403099 +0.03617944235829577 0.02246163811488844 +0.04107142857134718 0.01082531754732167 +0.04464285714277758 0.007732369676668521 +0.0464285714284802 0.01546473935331031 +0.01205357142850667 0.01778445025626264 +0.01249999999993541 0.01701121328859827 +0.008482142857079464 0.0146915023856006 +0.008928571428507514 0.01391826541793669 +0.01607142857135106 0.00927884361195898 +0.02232142857134538 0.009278843611965917 +0.03928571428563196 0.0123717914826477 +0.0374999999999069 0.01701121328862832 +0.03839285714276272 0.01701121328862956 +0.03883928571418938 0.01778445025629362 +0.03660714285705119 0.01701121328862781 +0.008035714285644806 0.02010416115925428 +0.01517857142853126 0.001546473935323795 +0.00803571428565299 0.01082531754728859 +0.00758928571422438 0.01005208057962782 +0.04196428571421484 0.004639421806007349 +0.04151785756139616 0.0193309239499216 +0.02991071428563216 0.02087739812693544 +0.03035714285706067 0.02010416115927277 +0.02946428571420362 0.02165063509459804 +0.02991071428563042 0.02242387206226161 +0.02901785714277989 0.02242908789811829 +0.04775183107811028 0.005403406120931788 +0.04820228903964303 0.004632390804019692 +0.002259015013049437 0.01467607154205412 +0.04774090482594179 0.008521167571712587 +0.04731693651853741 0.009281437099895104 +0.04642782275301933 0.00927927585997996 +0.001892287631849503 0.0153872141675088 +0.04817938820260831 0.009300384458729912 +0.001664808031753509 0.01241597828354204 +0.04833637790582 0.01079012308589383 +0.02768161907397371 0.02322966138478069 +0.005357142857067995 0.02319710902991167 +0.02946507506803496 0.0232325103556276 +0.03036351013983062 0.02323451656205934 +0.03083348062400533 0.02404796452821083 +0.03482445316728751 0.02322432628205674 +0.03392907552780406 0.02320164523861611 +0.002679530039080997 0.02321823672370506 +0.00177103890312161 0.02325578707060471 +0.0419680451560905 0.02322429042321522 +0.04092377446624568 0.02322645114300727 +0.01067653979028738 0.02326479102305475 +0.01159728011005327 0.02324242112122096 +0.01205105474398372 0.02243219959621694 +0.01249544940488374 0.02321561320516569 +0.01294642857136299 0.02242387206225634 +0.01339209871029473 0.02322916700174766 +0.01383915930880554 0.02242921505756136 +0.01428556681269363 0.02323231646705529 +0.01473209721068509 0.02243063046766394 +0.01517832773207831 0.02323843802413018 +0.0156249517761353 0.02243188662886055 +0.01606868105164743 0.02323858919709141 +0.01651739118554415 0.02243212118455415 +0.01696126277827298 0.02321496148253592 +0.0174104176110649 0.02242609158393565 +0.0160713428745251 0.02165334570940897 +0.01785658958867343 0.02322942830159173 +0.01830342977134855 0.02242962852781769 +0.01874988417904459 0.02323242892874087 +0.01919638565836356 0.02243071812299004 +0.01964283068718375 0.02323311063246055 +0.02008927415279543 0.02243101333947277 +0.02053570794951829 0.0232332734524948 +0.02098213987416214 0.02243108967889279 +0.02142856987537435 0.02323331331240417 +0.02187499924393803 0.02243110904544813 +0.02232142818655216 0.02323332318348217 +0.0227678569526688 0.02243111391838756 +0.02321428561844244 0.02323332564081671 +0.02366071423800897 0.02243111514009783 +0.0241385669938699 0.02326124492877344 +0.04643506799495659 0.0232321342938785 +0.04554213929476615 0.02319986222558192 +0.04820363137882133 0.01234335925058325 +0.001660216576203111 0.01078174919139129 +0.0482142857141884 0.0216506350946315 +0.04776804132531176 0.0208783575715114 +0.04864252291202636 0.02091489715388677 +0.0481937490965802 0.02013312187899566 +0.001732171530301868 0.02172187031604473 +0.001806062974609842 0.009270520315780875 +0.002236163226423769 0.008527853938546888 +0.003126298982678123 0.008508951418872708 +0.002668975603005001 0.007838711491180473 +0.001348064342396711 0.008517787037802736 +0.0482286162597963 0.01390969124327941 +0.0486636268430499 0.01470521699211592 +0.04820653459765838 0.0154837425492268 +0.04859209874128891 0.0163035663722993 +0.04823675737959619 0.00309634025889353 +0.04866971249867892 0.002288207171415759 +0.03437615193998454 0.02409549805490872 +0.03574195679071281 0.02334524873847627 +0.03663002939392525 0.02327826713735275 +0.03708783408499812 0.02242578441427123 +0.03755856886246562 0.02318050712508595 +0.03796474806179496 0.02408311822538977 +0.03848921811697979 0.02332777020545143 +0.03937112441833794 0.02345630530533324 +0.03907344167415516 0.02254817580066926 +0.03998058049091461 0.02284007001157141 +0.02723532526242516 0.02408879571017425 +0.01740763089518355 0.02409207579241078 +0.04598929405618533 0.0240904675988303 +0.0473748199767637 0.02326035494805299 +0.04838980290042716 0.02318997876984923 +0.04797995291081425 0.02406385448063122 +0.01294305637702393 0.02409214086287459 +0.02458357273985521 0.02410314852131025 +0.02503686203998266 0.02325073997179061 +0.01024076667298171 0.02411976891943988 +0.00963288360773535 0.02336462107875265 +0.008734970504072894 0.02309932908216724 +0.01473186615233759 0.02412124035967726 +0.02276785706277028 0.02411519533735402 +0.02098214154227403 0.02411518499412245 +0.01919640485868186 0.02411501046017353 +0.02901877805562012 0.02412002531887847 +0.002233878536049367 0.02408997423052037 +0.003590035774236108 0.02335296276911369 +0.005810653034170155 0.02410380507524214 +0.04150590886741873 0.02405810955407709 +0.04288485572787552 0.02334549937137882 +0.043764957430425 0.02328885129979538 +0.0007803055125252577 0.02349861812847251 +0.04865604449898507 0.003894932925720758 +0.006727738992733809 0.0241004011152626 +0.00735629344264568 0.02335535847481134 +0.04509608611179013 0.02406298778484713 +0.02635498550209876 0.02405701229279246 +0.03348200919985952 0.02407171482358846 +0.03303069145837107 0.02325926627510988 +0.03210307371179946 0.02340434905188888 +0.01205039566257866 0.02411576687603633 +0.01651616999191811 0.02411500875649932 +0.04913461252094017 0.02011867787493386 +0.04772874714459419 0.01623921850758004 +0.04865781062849933 0.0130901057515244 +0.02857222155672771 0.02326334658079827 +0.03617226445028097 0.02415470810026149 +0.004027538235339166 0.02419894083257576 +0.04331316257670885 0.02415705928609924 +0.047320212348514 0.001545771748758512 +0.01383928571422985 0.002319710902986635 +0.01428571428565612 0.003092947870649575 +0.03928571428565036 0.001546473935342431 +0.03660714285708461 0.001546473935337881 +0.0437530808006414 0.02165538266487869 +0.01562499999994988 0.005412658773638057 +0.01651785714280479 0.005412658773638996 +0.01339285714279566 0.001546473935323993 +0.01249999999995044 0.001546473935321917 +0.04241071449306942 0.01933092407185446 +0.0249999999999194 0.01237179148262742 +0.0254464285713462 0.01159855451496272 +0.0147321428570913 0.003866184838310931 +0.01428571428566047 0.004639421805974133 +0.02544642857137134 0.01623797632094863 +0.03928571428562005 0.01701121328863164 +0.02321428567460177 0.02165304925025746 +0.0397321428570456 0.01778445025629668 +0.04062499999990296 0.01778445025629849 +0.004464542248325964 0.01546474649817365 +0.02142857080536298 0.02165304419456707 +0.002686950981676321 0.01391792017093678 +0.00182538390176993 0.01390265223271253 +0.003572865892732949 0.01391820578915265 +0.0285714285713691 0.001546473935331716 +0.02901785714279415 0.002319710902998014 +0.0468736861498765 0.01005262462981836 +0.02455357142850665 0.0007732369676632925 +0.02499999999993427 0.00154647393532748 +0.0142857142856379 0.009278843611957013 +0.01339285714278412 0.009278843611955134 +0.0450892857142647 0.0007732369676747816 +0.04241071428563081 0.011598554514987 +0.0007877431628055479 0.01028777022001399 +0.0459817991028072 0.01005224329601748 +0.01964284806372834 0.02165296631758622 +0.03973214285705303 0.01623797632096897 +0.03616071428562938 0.01469150238563632 +0.04419642857140055 0.0007732369676732092 +0.04464285714280822 0.001546473935353325 +0.0007747456305129707 0.01204778726325364 +0.005357142857076828 0.01701121328859268 +0.04776785714276969 0.01005208057966541 +0.008035714285650877 0.01391826541793837 +0.02410714285708045 0.001546473935327087 +0.04241071428568736 0.0007732369676736236 +0.04196428571425032 0.00154647393534259 +0.04107142857138262 0.001546473935341315 +0.01785706980179234 0.02165196442580012 +0.004018303237229593 0.0146914866927731 +0.03660714285705909 0.01391826541797278 +0.04731875756057001 0.006184353632552963 +0.04815167162123302 0.006198502296057813 +0.04859972037159185 0.00692085077237507 +0.04819468506779551 0.007723886428634377 +0.01874999999991959 0.009278843611962037 +0.04508928571420443 0.008505606644332527 +0.03526785714277453 0.01314502845030698 +0.02991071428566069 0.0007732369676660938 +0.03035714285708289 0.001546473935332246 +0.02946428571422559 0.001546473935332041 +0.03660714285706543 0.007732369676658959 +0.04922676303233359 0.02276785714285057 +0.02589285714279242 0.001546473935328892 +0.04509569879711315 0.02241920259843647 +0.04642785476577847 0.01082547510258776 +0.0464281262600291 0.006185638723211568 +0.0007699141850222389 0.002237898085511619 +0.001545920138225327 0.002679530633305835 +0.001546381635815035 0.003571588438892055 +0.002319603220227717 0.003125186512038196 +0.002319677572617513 0.004017914872780325 +0.003092924368472139 0.003571469278427541 +0.003092938398569024 0.004464302120445613 +0.003092926006503456 0.00267860929841581 +0.003866184838329231 0.003125000000007702 +0.003866184838328932 0.002232142857150419 +0.004639421805993372 0.002678571428578838 +0.002319703769253234 0.004910726641735077 +0.003084237101169443 0.005342064949200634 +0.002318257919126254 0.005801060503258768 +0.003066697735551377 0.006162622821621556 +0.004633932912777727 0.001795039949522013 +0.00540249130536975 0.002249723199120793 +0.005435399988761213 0.003206416171197724 +0.006226253907170631 0.002656036174593808 +0.003887187635464186 0.004902373986523329 +0.00229535867953989 0.006623879832618502 +0.006226839703070634 0.001652253225853511 +0.006890557778290188 0.002249153202905685 +0.003096336614841311 0.001763248931992403 +0.001546230582396891 0.005356726428935926 +0.001542505056063112 0.001792588586263995 +0.001454263901292799 0.0008224870076375975 +0.002319710902998046 0.001339285714291595 +0.003895189336477142 0.001343511384449992 +0.004751454327875373 0.0008595193385744929 +0.002319500323143161 0.002229741612717972 +0.0007732215844136446 0.004017883787443267 +0.04285714285705806 0.01237179148265145 +0.002221912938848289 0.02088851657181561 +0.001746854587396448 0.02009703063501698 +0.001307608469000766 0.02093654535964418 +0.001302297986659305 0.01927001166657588 +0.002185122333005607 0.01930377687935235 +0.001781399344653011 0.01850087804853182 +0.001433511445340652 0.01768354019283967 +0.0007881773429724992 0.006714451476906684 +0.001574642002492467 0.007081797853225883 +0.02053571428563244 0.009278843611963976 +0.0441964285713483 0.00850560664433182 +0.003855628568114145 0.004016476611855686 +0.04598206866232155 0.005412615937323739 +0.03348214285709751 0.0007732369676656613 +0.03303571428566507 0.001546473935333003 +0.03214285714280996 0.00154647393533225 +0.03437499999995653 0.0007732369676657653 +0.03482142857137428 0.001546473935336249 +0.004018096696357797 0.01314501851230371 +0.03615912031452168 0.02087733095400094 +0.04285714300299205 0.02010416107503176 +0.04285714289162254 0.01855768720400319 +0.04375000000566884 0.01855768722063995 +0.044196942038119 0.02087789739132309 +0.04924010185449337 0.01830237301129631 +0.04851244420735121 0.01778218996335899 +0.04854087426999895 0.01873460460962625 +0.04017857142849064 0.01082531754732045 +0.00848214285716611 0.02425022409573386 +0.0406249999999613 0.0007732369676713477 +0.02767894460958342 0.02165041963840582 +0.03124999999992475 0.004639421805994456 +0.03169642857135162 0.005412658773659143 +0.03258928571420844 0.005412658773659571 +0.03214285714277788 0.006185895741323931 +0.03124999999992292 0.006185895741323618 +0.04508922842182694 0.01005210769905316 +0.03571402005234237 0.02010414996378881 +0.03660714285706158 0.01237179148264449 +0.02276785714279882 0.00231971090299164 +0.02187499999994418 0.00231971090299223 +0.02142857142851682 0.001546473935328378 +0.02053571428566188 0.001546473935328337 +0.02098214285708935 0.0007732369676649862 +0.01964285714280647 0.001546473935326206 +0.02232142857137216 0.001546473935328953 +0.04776882467680875 0.003870369750615654 +0.04916082257516761 0.004784071529084467 +0.03616071428563133 0.0131450284503084 +0.03258051554221187 0.02247441432418822 +0.04017857142849285 0.009278843611991694 +0.04062499999992007 0.01005208057965662 +0.04151785714277684 0.01005208057965757 +0.04196428571420389 0.01082531754732226 +0.003115857120252172 0.01932564554753859 +0.02678571428564912 0.004639421805988747 +0.0263392857142196 0.005412658773652175 +0.02544642857136323 0.005412658773649917 +0.0258928571427901 0.006185895741315295 +0.0249999999999323 0.006185895741310917 +0.0254464285713567 0.00695913270897763 +0.02633928571421641 0.006959132708979941 +0.02410714285706851 0.006185895741309487 +0.02366071428564252 0.005412658773646319 +0.02589285714278773 0.007732369676643516 +0.02678571428564408 0.007732369676644856 +0.02633928571421408 0.008505606644308205 +0.02723214285707123 0.008505606644309641 +0.02678571428564198 0.009278843611973136 +0.02767857142849846 0.009278843611974449 +0.02723214285706813 0.01005208057963736 +0.02812499999992643 0.01005208057963971 +0.02767857142849676 0.01082531754730301 +0.02678571428563868 0.01082531754730083 +0.02723214285706745 0.01159855451496644 +0.02812499999992524 0.01159855451496825 +0.0263392857142091 0.01159855451496471 +0.02678571428563885 0.01237179148263023 +0.02589285714277666 0.01082531754729869 +0.0258928571427783 0.009278843611970348 +0.02857142857135598 0.009278843611976341 +0.02767857142850108 0.007732369676646506 +0.04598202341327164 0.0115985807741997 +0.0245535714285092 0.00231971090299286 +0.0343749999999217 0.008505606644320905 +0.03392857142849375 0.00927884361198497 +0.03348214285705417 0.01933092419161335 +0.01607142857138738 0.001546473935324244 +0.01651785714281398 0.002319710902987134 +0.02812499999994181 0.01933092419160789 +0.02901785714279582 0.01933092419160959 +0.02008928571423345 0.00231971090299053 +0.01874999999995156 0.001546473935326554 +0.03214285714277135 0.01855768722394851 +0.0316964285713434 0.01933092419161132 +0.002286724877826675 0.01620579003392159 +0.01294642857135792 0.01314502845027739 +0.01339285714278593 0.01237179148261328 +0.01874999999994306 0.01855768722393332 +0.01830357142851488 0.01778445025626756 +0.01741071428565701 0.01778445025626665 +0.01785714285708669 0.01701121328860192 +0.01919642857137269 0.01778445025626837 +0.01696428571422781 0.01701121328860163 +0.01651785714279904 0.01778445025626575 +0.01607142857136987 0.01701121328860074 +0.01741071428565194 0.01623797632093697 +0.01830357142851006 0.01623797632093725 +0.01562499999994105 0.01778445025626486 +0.01517857142851328 0.01701121328859906 +0.01562499999993613 0.01623797632093447 +0.01473214285707791 0.01623797632093402 +0.01428571428565185 0.01701121328859918 +0.01964285714280097 0.01855768722393408 +0.02008928571423054 0.01778445025626926 +0.0209821428570882 0.01778445025627011 +0.02053571428566007 0.01701121328860612 +0.02142857142851749 0.01701121328860724 +0.02187499999994567 0.01778445025627122 +0.02232142857137479 0.01701121328860818 +0.02187499999994231 0.01623797632094539 +0.02276785714280297 0.01778445025627218 +0.02321428571423193 0.01701121328860903 +0.02366071428566036 0.01778445025627365 +0.0241071428570901 0.01701121328861162 +0.0236607142856575 0.01623797632094807 +0.01964285714280106 0.0170112132886046 +0.02008928571422436 0.01623797632094144 +0.02142857142851651 0.01855768722393589 +0.009374999999933926 0.01778445025626019 +0.01473214285707188 0.01314502845027977 +0.01517857142850213 0.01237179148261567 +0.03303571428563832 0.004639421805994691 +0.01428571428565243 0.0185576872239293 +0.01383928571422332 0.01778445025626374 +0.04151785714278616 0.00541265877367024 +0.04062499999992827 0.005412658773669218 +0.04017857142850061 0.004639421806003245 +0.04196428571420623 0.009278843611993728 +0.04108627683087092 0.02163569171990987 +0.01830357142850024 0.01314502845028444 +0.01874999999993034 0.01237179148262039 +0.0187499999999419 0.01701121328860363 +0.009374999999944547 0.003866184838307264 +0.008928571428517908 0.003092947870643549 +0.008056496832549581 0.003106091791974639 +0.00850638916179502 0.002333900365576275 +0.009379041050732105 0.002322075813415109 +0.008933285987780756 0.001549232997491322 +0.00982210207983734 0.003093342022383683 +0.01026864290267797 0.002320170746678816 +0.01071434902414861 0.003092984920981951 +0.01116085579729097 0.002319793718656379 +0.01071444025949185 0.001546564378550519 +0.0120535950137877 0.002319724705597602 +0.0111607142856477 0.01623797632093264 +0.009821428571363665 0.009278843611952263 +0.008928571428507559 0.009278843611950817 +0.009374999999936436 0.008505606644287532 +0.008482142857079954 0.008505606644286274 +0.008928571428509434 0.007732369676623024 +0.008035714285652718 0.007732369676621639 +0.007589285714223862 0.008505606644285211 +0.009821428571365958 0.007732369676624442 +0.03928571428561076 0.02165063509461014 +0.01294642857136449 0.01778445025626328 +0.01339285714279321 0.01701121328859899 +0.0129464285713609 0.01623797632093408 +0.00446432563981966 0.01237178982761264 +0.007592242431932 0.003878213035037201 +0.0316964285713786 0.0007732369676654108 +0.02008928571421413 0.01314502845028667 +0.0205357142856442 0.01237179148262263 +0.00624999999994377 0.007732375489121498 +0.01696428571420693 0.009278843611960052 +0.01830357142852369 0.002319710902988655 +0.01205357142850144 0.01159855451494728 +0.03973214285705921 0.01314502845031246 +0.03080214597814292 0.02243506566909031 +0.01517854150066895 0.0216535490257296 +0.002232142857086435 0.01159855451494164 +0.04776794911337421 0.01313408450917942 +0.01116071428565094 0.006959132708962588 +0.01428571428565232 0.006185895741301327 +0.0133928571427923 0.006185895741301528 +0.01383928571422864 0.005412658773637094 +0.02723214285707645 0.005412658773653675 +0.03928571428563402 0.01082531754731925 +0.0316964285713504 0.01314502845030143 +0.03214285714277737 0.01391826541796595 +0.03258928571420645 0.01314502845030265 +0.03169642857134828 0.01469150238562943 +0.03258928571420423 0.01469150238563077 +0.03705357142849413 0.008505606644323978 +0.008035714285649776 0.0154647393532656 +0.0111607248373085 0.003866191013365592 +0.03303571428562717 0.01855768722394953 +0.0491135754646491 0.009349222177084912 +0.03571428571420653 0.009278843611987166 +0.03928571428564057 0.00618589574133217 +0.01026785714279279 0.008505606644288847 +0.04553571428562375 0.01546458902500179 +0.04508928571419608 0.01469132700261861 +0.004582833473567175 0.003582901318233842 +0.04241071428562859 0.01314502845031573 +0.04285714285705575 0.01391826541798049 +0.04241071428562655 0.01469150238564398 +0.0433035714284851 0.01314502845031672 +0.04374999999991222 0.0139182654179811 +0.04419642857134153 0.01314502845031586 +0.01339283607522277 0.02165152559380829 +0.02053571428563811 0.00618589574130964 +0.02008928571420992 0.005412658773645275 +0.01874999999992694 0.006185895741307759 +0.01830357142850814 0.005412658773640477 +0.0165178571427862 0.01314502845028213 +0.01696428571421631 0.01237179148261806 +0.02633928571422269 0.002319710902994813 +0.03035714285706437 0.01855768722394894 +0.01607142857136902 0.01855768722393077 +0.03303571428563573 0.01237179148263921 +0.01741071428567071 0.0007732369676622634 +0.03705357142849535 0.006959132708994551 +0.01071428571421594 0.0139182654179387 +0.03883928571420467 0.01159855451498296 +0.02946428571421023 0.01701121328862053 +0.02187499999992785 0.01314502845028888 +0.022321428571351 0.01237179148262247 +0.006249999999941571 0.009278843897311777 +0.0272321428570681 0.01314502845029567 +0.02321428571423131 0.01855768722393787 +0.02633928571420839 0.01005208057963567 +0.00669256852192956 0.0007713213671945537 +0.03526747736454017 0.02087819785044051 +0.0441964285713505 0.006959132709004339 +0.03169642857134612 0.01623797632095736 +0.005357185612762301 0.0154647405440857 +0.02991071428564143 0.01005208057964338 +0.02901785714278424 0.01005208057964174 +0.03080357142849216 0.01469150238562826 +0.008928571428506081 0.01701121328859476 +0.008035714285648409 0.01701121328859433 +0.02321428571420174 0.009278843611966937 +0.0285714285713521 0.01546473935328893 +0.02767857142849578 0.01546473935328755 +0.02723214285707572 0.01623797632095097 +0.02232142857134911 0.006185895741310687 +0.02187499999992736 0.005412658773647142 +0.0147321428570821 0.01778445025626435 +0.01160714285707369 0.01082531754728205 +0.01696428571424282 0.001546473935324621 +0.02812499999994069 0.0007732369676658032 +0.03348214285706233 0.01314502845030429 +0.03303571428563722 0.006185895741325135 +0.0290178571427815 0.01314502845029795 +0.02857142857135402 0.01237179148263343 +0.02499999999991588 0.01082531754729737 +0.04922676303233765 0.01116071428568502 +0.008482142857082807 0.006959132708958631 +0.03571428571419956 0.01546473935329997 +0.03749999999991718 0.01391826541797384 +0.009821428571361143 0.01237179148261004 +0.01383928571422543 0.003866184838312223 +0.03526785714276704 0.01778445025628897 +0.03214285714277951 0.01237179148263809 +0.01919642857137922 0.0007732369676632015 +0.03348214285705144 0.02242387206226509 +0.03973214285706798 0.00695913270899758 +0.03482142857134034 0.017011213288625 +0.01294642857136654 0.005412658773637785 +0.02946428571421217 0.0108253175473069 +0.03258928571421001 0.01005208057964721 +0.00535714285707483 0.01855768722392168 +0.005803571428504328 0.01778445025625752 +0.02366071428565225 0.0007732369676627375 +0.02499999999991864 0.007732369676641029 +0.03839285714276019 0.01855768722395632 +0.02723214285708572 0.01933092419160674 +0.04553571428562506 0.01391808585916824 +0.04598201807781557 0.008505678685664018 +0.04017857142848848 0.01237179148264901 +0.03616071428563775 0.006959132708993528 +0.02499999999993558 0.004639421805984792 +0.02187499999991842 0.008505606644301543 +0.01026785714279547 0.006959132708961408 +0.02857142857135504 0.01082531754730522 +0.01071428571422464 0.006185895741298472 +0.04017857142849782 0.006185895741333824 +0.03392857142849495 0.006185895741326034 +0.02544642857137211 0.02087739812693298 +0.006696428571366279 0.01314502845040414 +0.01160714285707735 0.01855768722392743 +0.03035714285706892 0.01082531754730791 +0.00491071428564352 0.02087739812691417 +0.005358130988089041 0.02165136773089876 +0.0379464973550666 0.01933088447931084 +0.03169642857135582 0.008505606644317702 +0.007142857142801899 0.006185924363394853 +0.006249999999940517 0.01082531755973802 +0.04151785714277013 0.01469150238564288 +0.02499999999994554 0.0185576872239404 +0.04285714285705409 0.01546473935330855 +0.03705357142849304 0.01005208057965242 +0.04330357142848744 0.01159855451498719 +0.04196428571419741 0.01546473935330756 +0.01696428571423608 0.004639421805974125 +0.04241071428563332 0.01005208057965833 +0.03794642857135642 0.003866184838335174 +0.0116058505163049 0.02165279853566097 +0.004464615202791643 0.01701133845808108 +0.01696428571422712 0.01855768722393164 +0.02946428571421932 0.004639421805992866 +0.0009023104536534205 0.01386956285747393 +0.0006799594649247784 0.015653798046144 +0.02276785714277458 0.008505606644302527 +0.007589285714217086 0.01933092419158843 +0.02857142857136388 0.003092947870662773 +0.03973214285706125 0.01159855451498416 +0.03258928571420195 0.01623797632095856 +0.009821428571360223 0.02010416115925647 +0.03616071428562251 0.01778445025629026 +0.02142857142848904 0.009278843611965099 +0.008035714285652031 0.009278843611951752 +0.02946428571421068 0.01237179148263468 +0.009374999999930637 0.02087739812692111 +0.02901785714278593 0.008505606644313376 +0.03571428571421181 0.004639421805997961 +0.03303571428562597 0.02010416115927599 +0.04062500549561922 0.019330921018667 +0.0437499999999212 0.007732369676667629 +0.01249999999993532 0.01855768722392818 +0.01205335603837639 0.02087775870043609 +0.04553447352394099 0.01701139890439936 +0.0446428571427688 0.01391820626100748 +0.02678571428564666 0.006185895741316944 +0.004044784512937446 0.007018812251404955 +0.03482142857134801 0.01237179148264215 +0.04151785714278141 0.006959132709000898 +0.03973214285707656 0.00231971090300793 +0.03794642857135142 0.008505606644324771 +0.03526785714278377 0.003866184838332565 +0.03928571428562638 0.01546473935330433 +0.02008928571420635 0.008505606644299474 +0.02812499999992817 0.008505606644311329 +0.04598214285704891 0.01933092419163514 +0.02455357142851773 0.01778445025627576 +0.0007731938449685146 0.004910649321786355 +0.0258928571427796 0.01237179148262888 +0.02812499999993163 0.006959132708983656 +0.04330357142848327 0.01469150238564469 +0.02723214285707399 0.006959132708981821 +0.004017857142800188 0.0100520806210249 +0.04553571428564217 0.003092947870687517 +0.01964285714277645 0.009278843611963244 +0.04374999999992602 0.004639421806012069 +0.02633928571421015 0.01314502845029423 +0.009821428571368983 0.0061858957412974 +0.02500784962758375 0.02165378001370109 +0.006696428571368819 0.01005208064033589 +0.03571428571419587 0.01701121328862686 +0.001546473935333769 0.004464285714295616 +0.03214285714277512 0.01546473935329407 +0.03749999999992713 0.004639421805999979 +0.007589285714220548 0.01623797632092988 +0.04553550186874146 0.009278959299507202 +0.004749492385960966 0.005369247297708921 +0.03883937408622867 0.01933087316999786 +0.007589285714221902 0.01469150238560407 +0.02767857142849645 0.0123717914826318 +0.03258928571419879 0.0193309241916123 +0.007142857142787559 0.02010416115925275 +0.02901785714278283 0.01159855451496997 +0.04241071429138223 0.01778445025297382 +0.01785714285709736 0.001546473935324861 +0.01830357142849479 0.008505606644297278 +0.04687521487954634 0.02087851747893493 +0.004464639542450985 0.01391825120803889 +0.04686423512247421 0.01932272757018831 +0.01249999999993324 0.02165063509459021 +0.001549317249032464 0.006230247920588875 +0.04330357143616188 0.01778445025186586 +0.0178571428570641 0.00927884361196145 +0.03348214285705987 0.01469150238563222 +0.0392857306729561 0.0185576777627225 +0.03124999999991542 0.02010416115927387 +0.04464285714276716 0.01546472522241988 +0.003572273989671972 0.009279037998956189 +0.03705357142849879 0.003866184838334152 +0.004910952560128218 0.01623801057457966 +0.03303571428563321 0.01391826541796751 +0.03080357142849039 0.01933092419161174 +0.02366071427905485 0.02087780048620871 +0.04597600852893444 0.01624087372752648 +0.0361607142856411 0.003866184838333423 +0.01651785714278291 0.008505606644295189 +0.01562499999996093 0.000773236967661842 +0.01383928220295999 0.02087754654346188 +0.004466742358555699 0.02166414385003116 +0.007589285714223138 0.01314502845032298 +0.004018214542973678 0.008506197681033487 +0.007589567545626711 0.02087475687353493 +0.0343749999999183 0.01314502845030591 +0.01428567652590372 0.02165331080252519 +0.008482142857078656 0.01314502845028771 +0.009374999999939786 0.006959132708960161 +0.01562499999992701 0.0085056066442943 +0.02187499999994354 0.0007732369676641964 +0.003574593225962009 0.007777185013800685 +0.01517857142849567 0.009278843611958838 +0.03660714285706462 0.009278843611987823 +0.0084824716603861 0.0208743166646392 +0.02232142830321981 0.02165385211042056 +0.01562498072915765 0.02087833555125239 +0.04107142857135498 0.006185895741335119 +0.03526785714277876 0.01005208057965067 +0.04419642857133974 0.01469146094049682 +0.01473214285710642 0.0007732369676612358 +0.004920584569610916 0.02248038813874365 +0.03482142857135043 0.009278843611985638 +0.02187499985139363 0.02087833581289737 +0.01651783964819298 0.02087800613345144 +0.01383928571421586 0.008505606644291647 +0.03348214285706577 0.01005208057964844 +0.0169641292344625 0.02165315452734644 +0.04731880081343755 0.02010610358232533 +0.008035714285657327 0.006185900511645273 +0.0089180657154075 0.021632340092427 +0.01294642857135948 0.008505606644290996 +0.02053571024456108 0.02165381829739666 +0.01830355925263182 0.0208776196821303 +0.02008928352753467 0.02087831719789573 +0.01874995351987287 0.02165338253387571 +0.01294642857135748 0.0115985545149496 +0.03705357142848073 0.01623797632096595 +0.01428571428566749 0.001546473935323751 +0.03571428571421376 0.003092947870669378 +0.03794642857133709 0.01623797632096688 +0.0424107142856413 0.005412658773674521 +0.01428571428564187 0.01237179148261541 +0.04687358107329776 0.0007724177499841054 +0.03883928571419297 0.0162379763209683 +0.01562499999992214 0.01159855451494959 +0.03080357142849838 0.006959132708988435 +0.01607142857135655 0.01237179148261817 +0.007589285714227752 0.006959142688319764 +0.02321428571422572 0.001546473935326335 +0.0428571428570704 0.004639421806010378 +0.01741071428563517 0.01159855451495152 +0.008482142857079926 0.01005208057961632 +0.01785714285707054 0.01237179148262069 +0.04781036828461307 0.01922868243663873 +0.04822110230029517 0.001515324132619194 +0.04642813223693353 0.001546220367974516 +0.008928571428507297 0.01082531754728149 +0.01919642857134808 0.01159855451495347 +0.008482142857078975 0.01159855451496549 +0.04017857413553338 0.01855768566103661 +0.007142857142796764 0.009278843669633021 +0.0316964285713535 0.006959132708989086 +0.01964285714278428 0.01237179148262306 +0.03303571428563791 0.009278843611984233 +0.03616071428562592 0.01623797632096409 +0.02098214285706105 0.01159855451495543 +0.02455357142849604 0.01314502845029324 +0.007142857142798474 0.007732376722551679 +0.04241071428564377 0.003866184838344108 +0.02142857142849737 0.01237179148262464 +0.0236607142856393 0.01314502845029101 +0.03258928571421042 0.008505606644319236 +0.0227678571427747 0.01159855451495744 +0.01071428571421834 0.01546473935326701 +0.04285714285707483 0.003092947870683514 +0.008928571428506263 0.01237179148262125 +0.04508928571422477 0.002319710903023982 +0.006696428571369911 0.00850560727455064 +0.03214285714278241 0.007732369676654041 +0.01249999999992995 0.009278843611953996 +0.01383928571421147 0.01159855451494847 +0.01160714285707347 0.0154647393532683 +0.04374999999994656 0.001546473935353093 +0.01294642857135609 0.01005208057961818 +0.024553571428503 0.00541265877364731 +0.01205357142850428 0.01623797632093327 +0.01964285714279945 0.004639421805977382 +0.02098214285707015 0.005412658773648263 +0.009374999999933983 0.0131450284502776 +0.01919642857135924 0.005412658773645812 +0.01249999999992729 0.01082531754728092 +0.02142857142850706 0.004639421805982162 +0.01785714285708837 0.004639421805975259 +0.02276785714278463 0.005412658773645915 +0.00982142857136183 0.01391826541793744 +0.02410807732539317 0.02165220706029555 +0.01696428571421989 0.006185895741306474 +0.01339285714278746 0.01546473935327027 +0.02457426609367385 0.02244863811525834 +0.01026785714278996 0.01469150238560229 +0.04107143000823262 0.0185576863943649 +0.01607142857136785 0.00618589574130472 +0.01383928571421941 0.01623797632093437 +0.04196428606474421 0.01855768702156971 +0.03035714285707009 0.006185895741324663 +0.03080357142849814 0.005412658773660101 +0.03035714285707105 0.004639421805996151 +0.04151785714280071 0.002319710903011982 +0.03883928571423235 0.0007732369676752092 +0.04330417064845311 0.02087827249813001 +0.04017857142851781 0.00154647393534063 +0.01517857142850221 0.01546473935327045 +0.02991071428564621 0.002319710902998002 +0.02812499999992921 0.01623797632095358 +0.01607142857136043 0.01546473935327254 +0.03392857142851672 0.001546473935334801 +0.02991071428564326 0.003866184838332189 +0.01651785714279393 0.01623797632093642 +0.0267857142856581 0.01701121328861903 +0.02589285714278892 0.01546473935328441 +0.02321428571421916 0.004639421805982641 +0.01785714285707447 0.0154647393532733 +0.03348214285707019 0.002319710903006363 +0.03526785714279256 0.00231971090300431 +0.02946428571421758 0.003092947870664909 +0.01874999999993242 0.01546473935327543 +0.03080357142850455 0.002319710902997848 +0.03258928571421675 0.002319710903002738 +0.03124999999994248 0.001546473935328508 +0.03749999999993958 0.001546473935340247 +0.01473214285709241 0.005412658773636257 +0.01919642857136647 0.01623797632093954 +0.03616071428567116 0.0007732369676664 +0.0205357142856487 0.01546473935327876 +0.02098214285708318 0.01623797632094292 +0.02232142857136458 0.01546473935328182 +0.01294642857139534 0.0007732369676552971 +0.02276785714280027 0.01623797632094724 +0.0241071428570795 0.01546473935328465 +0.02455357142851356 0.01623797632094839 +0.01205357142853519 0.0007732369676576468 +0.02321428571420624 0.01237179148262394 +0.01160719613078887 0.001546505112240683 +0.02812607548299307 0.02244095498696687 +0.02857167001538058 0.02165431564532753 +0.0102678829003653 0.0007732520415323817 +0.02901789738345559 0.02087801155205801 +0.02946429242099206 0.02010426339679423 +0.00982304885016954 0.001547422157554392 +0.0424107142856581 0.002319710903017863 +0.02991071540343644 0.01933094123119822 +0.008482928616991157 0.0007709045996094566 +0.01741071428565501 0.005412658773640125 +0.02946428590051537 0.01855769006387868 +0.0290178571738396 0.01778445072960496 +0.02857142857653563 0.01701121336750494 +0.008035714285677398 0.001546473935323415 +0.02633928571422223 0.01623797632094861 +0.0357142857142304 0.00154647393533623 +0.03794642857138034 0.0007732369676712358 +0.04285714285709839 0.001546473935347526 +0.04553564108707042 0.001546431674121859 +0.004493238044003309 0.0234084784893893 +0.007057809261709192 0.00308027705361617 +0.03124729827703582 0.02327067926289033 +0.03170001179611789 0.02420153598082227 +0.04420535587888118 0.02243423910638554 +0.03661811535846955 0.0216566201083654 +0.03754121362852994 0.02166168810221117 +0.03973952757251177 0.02424512234102068 +0.04920749364579028 0.007629190204802416 +0.005854507150262322 0.00396300168431973 +0.04730893161273111 0.01546886522527304 +0.04685210094122354 0.01624598530328531 +0.03803220325843132 0.02246969734533708 +0.04465202662120646 0.02325607954154586 +0.002266928581006896 0.01776786699032666 +0.04863350574511168 0.0007326592199933988 +0.001257905663692988 0.02260018815763054 +0.04060721585398616 0.02233419157273085 +0.004577305341309638 0.004441452949319998 +0.001891684688844238 0.0169753374744834 +0.008449705576294687 0.02236137022608712 +0.02591972094490712 0.0232462193573161 +0.003079814567401314 0.007016419303586126 +0.00715551697823091 0.001475961918276926 +0.0006716813298921563 0.01741071428573526 +0.003813936827198645 0.005713075218706266 +0.04012800138960664 0.02359894236665401 +0.04856654861648117 0.005474594025044724 +0.005360466876730936 0.001451009670597642 +0.04854951278275438 0.01161220883667297 +0.001424853181755994 0.01160272417903187 +0.04766857644099861 0.01772713051641669 +0.04809771773915734 0.01699595859658819 +0.0485525828494923 0.02236144234854297 +0.04934442248924606 0.0165232025726773 +0.001423746409818588 0.01614591294182492 +0.007688757057828812 0.002367479290170732 +0.001785714285659939 0.007876355385100904 +0.04937899687818922 0.00669642857141281 +0.04851919571284558 0.009960708573980934 +0.00147229886917811 0.009940326815127241 +0.001486578099121026 0.01324203440690008 +0.0487220616391786 0.02433018255178402 +0.04939143836643945 0.01294642857139684 +0.0493929640499823 0.02096755832028185 +0.00057059722401583 0.02096610857035691 +0.0494134376260334 0.002257413591952462 +0.002232142857147199 0.0005981008759687569 +0.04940414528948751 0.0147321428571158 +0.0005999424365421449 0.008486899586820768 +0.008025906816235997 0.02301300373389399 +0.001499546360955099 0.01459897585807087 +0.04849900038465019 0.008598972208597327 +0.0005753326671276944 0.01920491118909991 +0.04941172324262454 0.003999375089878882 +0.003959132029988462 0.000599379366971054 +0.04855550177099974 0.01946623003833522 +0.0006536167924748725 0.02434638320752644 +0.0006536167924736154 0.0006536167924747124 +0.04934638320752872 0.0006536167924703368 +0.04935222440591067 0.02435222440590943 +0.006231746555780824 0.003362401989975422 +0.008112490225243624 0.02366074409999438 +0.0005462893081593339 0.02271580870301297 +0.03975691482794127 0.02216615056028967 +0.005164260940390665 0.003966663178990185 +0.008928571428596018 0.02373818749563778 +0.04794813260108016 0.01835380444824283 +0.001201546621270981 0.01701877823218299 +0.003739043662866458 0.006365046436828996 +0.002280901027619722 0.007287432773142377 +0.04882856555432814 0.006286619609318196 +0.0487706958284671 0.01700168825741492 +0.04858524210417257 0.02379618756417342 +0.001241358512200548 0.01531405082655487 +3 1216 1829 1873 1 +3 1092 180 1156 1 +3 1829 190 1873 1 +3 169 1112 1114 1 +3 10 195 1258 1 +3 65 198 1309 1 +3 1156 180 1864 1 +3 89 205 1125 1 +3 984 838 1146 1 +3 1248 1627 1846 1 +3 139 140 1137 1 +3 135 136 1139 1 +3 135 1139 1145 1 +3 134 135 1145 1 +3 228 1050 1051 1 +3 112 113 1148 1 +3 111 112 1120 1 +3 1120 112 1148 1 +3 104 105 1149 1 +3 1110 104 1149 1 +3 103 104 1110 1 +3 181 1059 1060 1 +3 217 1064 1066 1 +3 178 1068 1070 1 +3 218 1075 1077 1 +3 186 1087 1089 1 +3 175 1079 1081 1 +3 214 1083 1085 1 +3 95 96 1140 1 +3 91 92 1147 1 +3 1122 91 1147 1 +3 90 91 1122 1 +3 1098 987 1837 1 +3 1046 179 1202 1 +3 1047 229 1519 1 +3 1093 209 1195 1 +3 1128 1089 1757 1 +3 919 1059 1130 1 +3 169 1114 1115 1 +3 196 1142 1834 1 +3 99 100 1115 1 +3 1250 195 1494 1 +3 174 1048 1157 1 +3 983 1679 1821 1 +3 1148 207 1842 1 +3 1126 128 1152 1 +3 1121 123 1153 1 +3 793 1118 1833 1 +3 1112 169 1158 1 +3 1142 196 1160 1 +3 128 129 1152 1 +3 123 124 1153 1 +3 201 1094 1096 1 +3 1098 223 1264 1 +3 1118 793 1426 1 +3 207 1128 1842 1 +3 1138 983 1821 1 +3 114 115 1127 1 +3 130 131 1129 1 +3 125 126 1132 1 +3 120 121 1135 1 +3 118 119 1134 1 +3 116 117 1133 1 +3 109 110 1136 1 +3 127 128 1126 1 +3 122 123 1121 1 +3 223 1098 1837 1 +3 237 1109 1713 1 +3 1119 1058 1847 1 +3 1627 1248 1839 1 +3 107 108 1052 1 +3 1151 835 1311 1 +3 982 983 1138 1 +3 837 1012 1111 1 +3 998 999 1141 1 +3 842 986 1123 1 +3 1265 230 1267 1 +3 210 1053 1111 1 +3 222 1055 1138 1 +3 232 1057 1141 1 +3 205 1090 1123 1 +3 228 1051 1052 1 +3 1150 171 1151 1 +3 1058 1119 1838 1 +3 88 89 1125 1 +3 892 1128 1757 1 +3 933 919 1130 1 +3 838 839 1146 1 +3 1147 196 1834 1 +3 1105 185 1106 1 +3 1250 1494 1844 1 +3 179 1046 1862 1 +3 205 1123 1125 1 +3 1075 218 1121 1 +3 1064 217 1126 1 +3 1050 228 1136 1 +3 1059 181 1129 1 +3 1087 186 1133 1 +3 1068 178 1132 1 +3 1083 214 1134 1 +3 1079 175 1135 1 +3 217 1066 1132 1 +3 214 1085 1133 1 +3 218 1077 1135 1 +3 175 1081 1134 1 +3 186 1089 1127 1 +3 1823 1151 1824 1 +3 1052 1823 1824 1 +3 1056 236 1143 1 +3 235 1124 1224 1 +3 229 1047 1860 1 +3 1093 1195 1861 1 +3 142 143 1143 1 +3 210 103 1110 1 +3 1053 210 1110 1 +3 174 111 1120 1 +3 1048 174 1120 1 +3 232 95 1140 1 +3 1057 232 1140 1 +3 222 139 1137 1 +3 1055 222 1137 1 +3 191 134 1145 1 +3 205 90 1122 1 +3 1090 205 1122 1 +3 236 1056 1137 1 +3 140 236 1137 1 +3 199 1049 1139 1 +3 136 199 1139 1 +3 113 207 1148 1 +3 1149 171 1150 1 +3 105 171 1149 1 +3 188 1058 1140 1 +3 96 188 1140 1 +3 92 196 1147 1 +3 64 65 1309 1 +3 9 10 1258 1 +3 181 1060 1152 1 +3 178 1070 1153 1 +3 1111 1112 1158 1 +3 1141 1142 1160 1 +3 1258 195 1849 1 +3 1309 198 1848 1 +3 1058 188 1847 1 +3 100 169 1115 1 +3 226 99 1115 1 +3 201 1096 1865 1 +3 1264 223 1866 1 +3 108 228 1052 1 +3 1150 1151 1311 1 +3 1055 982 1138 1 +3 1053 837 1111 1 +3 1057 998 1141 1 +3 1090 842 1123 1 +3 1145 984 1146 1 +3 1049 199 1821 1 +3 5 6 1255 1 +3 230 1265 1874 1 +3 1627 561 1846 1 +3 1103 224 1858 1 +3 1099 184 1103 1 +3 1844 1815 1857 1 +3 1127 1089 1128 1 +3 1059 1129 1130 1 +3 1111 1012 1112 1 +3 1123 986 1124 1 +3 1141 999 1142 1 +3 1136 174 1157 1 +3 207 114 1127 1 +3 115 186 1127 1 +3 217 127 1126 1 +3 218 122 1121 1 +3 131 216 1129 1 +3 181 130 1129 1 +3 126 217 1132 1 +3 178 125 1132 1 +3 175 120 1135 1 +3 121 218 1135 1 +3 214 118 1134 1 +3 119 175 1134 1 +3 186 116 1133 1 +3 117 214 1133 1 +3 228 109 1136 1 +3 110 174 1136 1 +3 1109 237 1867 1 +3 1104 211 1105 1 +3 226 1116 1117 1 +3 129 181 1152 1 +3 124 178 1153 1 +3 142 1143 1878 1 +3 1113 1827 1833 1 +3 1679 1049 1821 1 +3 1124 235 1894 1 +3 226 1115 1116 1 +3 203 1108 1109 1 +3 204 1252 1256 1 +3 81 82 1154 1 +3 1459 1045 1873 1 +3 1106 185 1107 1 +3 987 1056 1837 1 +3 197 1263 1264 1 +3 5 1255 1879 1 +3 107 1052 1824 1 +3 835 1151 1823 1 +3 1574 1184 1872 1 +3 1251 1844 1857 1 +3 1263 197 1265 1 +3 195 1250 1849 1 +3 185 1105 1869 1 +3 1247 1251 1822 1 +3 1108 203 1144 1 +3 1252 204 1257 1 +3 224 1103 1870 1 +3 1216 1215 1829 1 +3 193 81 1154 1 +3 1114 1113 1833 1 +3 211 1104 1156 1 +3 237 1713 1836 1 +3 1047 1519 1850 1 +3 209 1093 1851 1 +3 1267 230 1268 1 +3 933 1130 1131 1 +3 190 1459 1873 1 +3 224 1270 1858 1 +3 180 1092 1850 1 +3 1046 1202 1851 1 +3 1118 1116 1833 1 +3 1224 1124 1854 1 +3 1247 1822 1882 1 +3 231 1574 1872 1 +3 872 1266 1316 1 +3 1827 793 1833 1 +3 1103 184 1870 1 +3 1151 171 1824 1 +3 1052 1051 1823 1 +3 553 1627 1839 1 +3 1184 1574 1862 1 +3 1251 1250 1844 1 +3 1045 1459 1860 1 +3 184 1099 1861 1 +3 1062 1126 1152 1 +3 1072 1121 1153 1 +3 834 1266 1267 1 +3 1112 1012 1113 1 +3 1123 1124 1125 1 +3 210 1111 1158 1 +3 222 1138 1159 1 +3 232 1141 1160 1 +3 1117 1116 1118 1 +3 1105 211 1869 1 +3 1015 1831 1832 1 +3 1094 201 1854 1 +3 834 1267 1835 1 +3 1072 1075 1121 1 +3 1062 1064 1126 1 +3 1085 1087 1133 1 +3 1081 1083 1134 1 +3 1077 1079 1135 1 +3 1066 1068 1132 1 +3 1108 1144 1308 1 +3 1144 1039 1308 1 +3 1244 1238 1257 1 +3 1238 1252 1257 1 +3 1037 1157 1802 1 +3 191 1145 1146 1 +3 872 1263 1266 1 +3 1266 834 1316 1 +3 1115 1114 1116 1 +3 101 102 1158 1 +3 93 94 1160 1 +3 137 138 1159 1 +3 1060 1062 1152 1 +3 1070 1072 1153 1 +3 207 1127 1128 1 +3 1129 216 1130 1 +3 1106 1107 1155 1 +3 1142 999 1825 1 +3 1263 1265 1266 1 +3 1154 82 1865 1 +3 926 1155 1853 1 +3 1155 1107 1853 1 +3 1128 892 1842 1 +3 1050 1136 1157 1 +3 1037 1050 1157 1 +3 1157 1048 1802 1 +3 1039 1144 1309 1 +3 1244 1257 1258 1 +3 226 1117 1828 1 +3 1826 666 1827 1 +3 169 101 1158 1 +3 102 210 1158 1 +3 94 232 1160 1 +3 196 93 1160 1 +3 138 222 1159 1 +3 199 137 1159 1 +3 1112 1113 1114 1 +3 1117 1118 1119 1 +3 1831 1155 1832 1 +3 1267 1268 1835 1 +3 203 1109 1867 1 +3 204 1256 1868 1 +3 1159 1138 1821 1 +3 199 1159 1821 1 +3 1288 1712 1888 1 +3 1156 1104 1443 1 +3 1092 1156 1443 1 +3 1113 1012 1826 1 +3 1266 1265 1267 1 +3 1712 924 1888 1 +3 1113 1826 1827 1 +3 1200 1201 1741 1 +3 1201 974 1741 1 +3 1193 200 1820 1 +3 1291 1209 1769 1 +3 48 182 1767 1 +3 1209 977 1769 1 +3 233 1161 1701 1 +3 1207 192 1819 1 +3 182 1164 1767 1 +3 1701 1161 1714 1 +3 1161 233 1713 1 +3 200 1701 1714 1 +3 1445 1447 1789 1 +3 192 1200 1741 1 +3 974 1201 1735 1 +3 1162 1169 1696 1 +3 1766 1208 1808 1 +3 1162 935 1163 1 +3 935 774 1163 1 +3 1169 172 1696 1 +3 935 1162 1696 1 +3 1175 812 1524 1 +3 1163 774 1174 1 +3 812 1175 1447 1 +3 1174 1175 1524 1 +3 1209 1208 1766 1 +3 1447 1175 1789 1 +3 492 524 1324 1 +3 176 1791 1817 1 +3 46 47 1818 1 +3 182 1291 1769 1 +3 1171 807 1282 1 +3 994 1171 1282 1 +3 384 1172 1609 1 +3 47 48 1767 1 +3 647 1285 1768 1 +3 680 1340 1518 1 +3 676 1321 1322 1 +3 977 1209 1766 1 +3 676 1322 1537 1 +3 200 1714 1820 1 +3 1172 1173 1609 1 +3 1322 1326 1537 1 +3 1173 1338 1609 1 +3 1324 524 1325 1 +3 1326 682 1537 1 +3 1163 1174 1524 1 +3 1795 1170 1799 1 +3 682 1326 1328 1 +3 1325 856 1743 1 +3 682 1328 1341 1 +3 442 1167 1760 1 +3 807 1171 1283 1 +3 1340 1173 1518 1 +3 1324 1325 1743 1 +3 1338 1173 1340 1 +3 1634 1283 1762 1 +3 676 492 1324 1 +3 1279 853 1774 1 +3 1340 680 1493 1 +3 1164 182 1769 1 +3 713 1166 1285 1 +3 387 407 1180 1 +3 774 773 1174 1 +3 1729 354 1800 1 +3 773 947 1174 1 +3 1777 972 1816 1 +3 192 1741 1819 1 +3 1415 220 1801 1 +3 442 1445 1789 1 +3 1476 964 1748 1 +3 1387 1797 1798 1 +3 420 442 1760 1 +3 995 994 1282 1 +3 213 1165 1791 1 +3 1774 853 1781 1 +3 1165 213 1788 1 +3 1277 976 1787 1 +3 1389 1792 1793 1 +3 449 1755 1811 1 +3 1414 1415 1801 1 +3 1792 531 1793 1 +3 1169 1170 1795 1 +3 1474 962 1746 1 +3 857 1301 1707 1 +3 1277 1276 1786 1 +3 220 1415 1804 1 +3 964 1745 1748 1 +3 1276 1781 1786 1 +3 1332 1335 1493 1 +3 1270 1269 1641 1 +3 1410 183 1807 1 +3 1249 1270 1641 1 +3 1328 1330 1341 1 +3 1006 1725 1729 1 +3 1006 1172 1725 1 +3 680 1341 1493 1 +3 1321 676 1324 1 +3 398 1177 1198 1 +3 957 1489 1728 1 +3 980 1507 1772 1 +3 1373 1374 1761 1 +3 1180 407 1759 1 +3 1187 1186 1222 1 +3 1177 398 1179 1 +3 1409 1410 1807 1 +3 1186 212 1222 1 +3 952 1434 1721 1 +3 1283 1171 1762 1 +3 1176 530 1778 1 +3 16 220 1804 1 +3 1307 1303 1668 1 +3 963 1509 1750 1 +3 1030 1620 1719 1 +3 1007 1190 1225 1 +3 1603 1198 1702 1 +3 1432 1277 1787 1 +3 946 1403 1711 1 +3 1724 957 1728 1 +3 1389 1388 1790 1 +3 718 815 1521 1 +3 857 1206 1345 1 +3 964 1476 1751 1 +3 1003 1002 1183 1 +3 1285 1166 1768 1 +3 1716 952 1721 1 +3 398 387 1180 1 +3 1003 1183 1184 1 +3 1341 1330 1493 1 +3 527 1373 1761 1 +3 943 1478 1705 1 +3 219 1810 1815 1 +3 1745 1474 1748 1 +3 680 497 1341 1 +3 1172 384 1725 1 +3 497 682 1341 1 +3 938 1393 1700 1 +3 1183 1002 1185 1 +3 1278 1279 1774 1 +3 1709 946 1711 1 +3 1174 947 1175 1 +3 962 1474 1745 1 +3 853 1279 1782 1 +3 603 1181 1211 1 +3 366 317 1797 1 +3 1368 1365 1776 1 +3 889 1004 1199 1 +3 531 321 1794 1 +3 1225 239 1479 1 +3 1206 1190 1345 1 +3 1374 1396 1428 1 +3 1206 857 1707 1 +3 1276 1774 1781 1 +3 1489 957 1731 1 +3 57 233 1701 1 +3 367 1389 1790 1 +3 1509 963 1752 1 +3 155 156 1202 1 +3 1434 1724 1728 1 +3 1507 1506 1772 1 +3 173 1307 1668 1 +3 1703 943 1705 1 +3 1339 1336 1630 1 +3 1190 1007 1345 1 +3 27 28 1305 1 +3 1434 952 1724 1 +3 179 155 1202 1 +3 1382 1794 1796 1 +3 530 313 1778 1 +3 1304 227 1305 1 +3 1178 659 1653 1 +3 227 27 1305 1 +3 889 1199 1212 1 +3 1403 1716 1721 1 +3 976 1785 1787 1 +3 755 856 1779 1 +3 1335 1340 1493 1 +3 227 1304 1306 1 +3 1387 366 1797 1 +3 212 1186 1513 1 +3 1330 1332 1493 1 +3 1491 1339 1630 1 +3 1403 946 1716 1 +3 1205 1018 1629 1 +3 1517 1337 1633 1 +3 1042 1045 1204 1 +3 1334 1333 1547 1 +3 659 1178 1673 1 +3 172 1169 1795 1 +3 1673 1182 1681 1 +3 1167 1168 1760 1 +3 1382 531 1794 1 +3 1478 1709 1711 1 +3 206 33 238 1 +3 1333 1342 1500 1 +3 1333 1500 1547 1 +3 1342 262 1500 1 +3 1325 1752 1779 1 +3 692 1205 1629 1 +3 1385 1386 1607 1 +3 1398 1397 1675 1 +3 1473 1474 1746 1 +3 362 1368 1776 1 +3 981 1213 1214 1 +3 1269 194 1641 1 +3 577 579 1498 1 +3 1478 943 1709 1 +3 1181 603 1498 1 +3 1584 1030 1719 1 +3 158 184 1195 1 +3 206 238 1225 1 +3 1475 1476 1748 1 +3 864 1185 1211 1 +3 981 1214 1215 1 +3 820 718 1521 1 +3 1354 170 1527 1 +3 856 1325 1779 1 +3 1188 991 1227 1 +3 574 575 1638 1 +3 1369 1368 1780 1 +3 864 1183 1185 1 +3 1261 716 1469 1 +3 1188 1042 1204 1 +3 1386 973 1607 1 +3 1306 1354 1527 1 +3 815 1199 1521 1 +3 659 1673 1681 1 +3 1261 1194 1565 1 +3 238 239 1225 1 +3 1498 582 1650 1 +3 981 867 1213 1 +3 976 1277 1786 1 +3 991 1188 1204 1 +3 1393 1392 1700 1 +3 1253 194 1608 1 +3 1393 1703 1705 1 +3 507 1194 1315 1 +3 1396 1374 1510 1 +3 642 1196 1227 1 +3 1198 1177 1702 1 +3 1007 1225 1479 1 +3 156 209 1202 1 +3 1182 660 1681 1 +3 1429 1017 1744 1 +3 945 1296 1515 1 +3 859 1306 1353 1 +3 1395 1396 1510 1 +3 1456 1009 1625 1 +3 1194 507 1565 1 +3 1460 1010 1671 1 +3 1203 1008 1571 1 +3 54 55 1193 1 +3 1690 1197 1692 1 +3 1296 1295 1515 1 +3 807 1283 1284 1 +3 1385 699 1492 1 +3 1369 1780 1784 1 +3 1337 1547 1633 1 +3 1227 873 1344 1 +3 1393 938 1703 1 +3 36 212 1513 1 +3 580 1456 1625 1 +3 716 1261 1565 1 +3 377 398 1198 1 +3 1437 902 1635 1 +3 1041 868 1216 1 +3 1773 362 1776 1 +3 368 377 1198 1 +3 657 1197 1693 1 +3 1507 980 1777 1 +3 1372 1373 1770 1 +3 699 1385 1607 1 +3 1179 398 1180 1 +3 1213 867 1228 1 +3 1784 367 1790 1 +3 52 53 192 1 +3 1029 1710 1715 1 +3 1489 1488 1728 1 +3 1280 877 1430 1 +3 1455 749 1601 1 +3 1350 1349 1512 1 +3 1298 463 1626 1 +3 1434 1433 1721 1 +3 660 1182 1690 1 +3 1190 206 1225 1 +3 1746 962 1750 1 +3 1196 642 1298 1 +3 1463 1015 1654 1 +3 1191 467 1670 1 +3 1403 1402 1711 1 +3 215 51 1207 1 +3 1199 1005 1212 1 +3 1306 1304 1353 1 +3 1478 1477 1705 1 +3 32 33 206 1 +3 1469 716 1471 1 +3 1219 874 1310 1 +3 1372 1770 1773 1 +3 1694 1438 1749 1 +3 1319 1321 1743 1 +3 1383 1385 1492 1 +3 1254 234 1255 1 +3 1752 963 1779 1 +3 759 963 1750 1 +3 1300 512 1310 1 +3 1315 1314 1568 1 +3 1212 1005 1310 1 +3 1509 1746 1750 1 +3 491 453 1647 1 +3 156 157 209 1 +3 215 1207 1208 1 +3 512 1212 1310 1 +3 1256 1252 1259 1 +3 34 187 238 1 +3 1306 859 1354 1 +3 991 873 1227 1 +3 1191 1192 1683 1 +3 1197 1078 1693 1 +3 1004 1695 1723 1 +3 1436 456 1643 1 +3 384 1609 1617 1 +3 33 34 238 1 +3 74 75 211 1 +3 700 1383 1492 1 +3 115 116 186 1 +3 583 585 1535 1 +3 361 1429 1744 1 +3 854 789 1416 1 +3 209 157 1195 1 +3 55 200 1193 1 +3 507 1315 1568 1 +3 1529 1461 1549 1 +3 1772 742 1814 1 +3 1301 1307 1707 1 +3 1791 1165 1817 1 +3 1700 1359 1739 1 +3 1295 691 1515 1 +3 1229 234 1254 1 +3 1337 1334 1547 1 +3 1347 1346 1680 1 +3 212 37 1220 1 +3 603 577 1498 1 +3 1303 1305 1668 1 +3 1397 719 1675 1 +3 463 455 1272 1 +3 1199 1004 1521 1 +3 574 1280 1430 1 +3 1336 1337 1630 1 +3 1609 1339 1617 1 +3 1218 463 1272 1 +3 1212 512 1522 1 +3 1181 862 1211 1 +3 754 738 1698 1 +3 1436 1020 1656 1 +3 1006 1729 1800 1 +3 212 1220 1222 1 +3 1236 1232 1259 1 +3 1470 1469 1471 1 +3 85 235 1224 1 +3 1223 749 1455 1 +3 1339 1491 1617 1 +3 455 409 1272 1 +3 883 1413 1414 1 +3 700 1380 1383 1 +3 1280 574 1638 1 +3 704 1413 1457 1 +3 32 206 1189 1 +3 281 1598 1663 1 +3 43 176 1278 1 +3 1683 1192 1689 1 +3 642 1227 1344 1 +3 1759 407 1762 1 +3 862 864 1211 1 +3 1289 688 1313 1 +3 889 1212 1522 1 +3 738 1603 1702 1 +3 1008 1203 1535 1 +3 1797 530 1798 1 +3 1349 221 1512 1 +3 652 1210 1685 1 +3 579 582 1498 1 +3 660 1690 1692 1 +3 1210 1073 1685 1 +3 686 1370 1481 1 +3 467 1667 1670 1 +3 1197 657 1692 1 +3 1004 754 1695 1 +3 167 234 1229 1 +3 1422 1520 1666 1 +3 520 1587 1605 1 +3 841 1091 1226 1 +3 616 686 1481 1 +3 1297 1296 1720 1 +3 1587 1342 1605 1 +3 463 1218 1626 1 +3 501 487 1274 1 +3 1521 1004 1723 1 +3 262 1342 1587 1 +3 238 187 239 1 +3 194 163 1608 1 +3 452 1347 1680 1 +3 227 1306 1527 1 +3 1254 1255 1256 1 +3 520 1343 1610 1 +3 872 1262 1263 1 +3 1002 877 1280 1 +3 1013 1313 1314 1 +3 1470 1471 1595 1 +3 921 1455 1601 1 +3 582 1203 1650 1 +3 1380 700 1390 1 +3 721 872 1316 1 +3 1695 754 1698 1 +3 1200 1193 1201 1 +3 170 1354 1635 1 +3 691 1295 1394 1 +3 1278 176 1279 1 +3 1337 1517 1630 1 +3 1217 533 1615 1 +3 192 53 1200 1 +3 1196 1298 1626 1 +3 117 118 214 1 +3 883 1414 1416 1 +3 407 1634 1762 1 +3 586 584 1503 1 +3 1413 883 1457 1 +3 1698 738 1702 1 +3 34 35 187 1 +3 595 586 1503 1 +3 868 981 1216 1 +3 1013 1314 1315 1 +3 491 1463 1654 1 +3 1228 501 1274 1 +3 686 1395 1510 1 +3 603 1211 1638 1 +3 1222 1221 1771 1 +3 1018 1456 1629 1 +3 50 51 215 1 +3 54 1193 1200 1 +3 409 403 1591 1 +3 1660 941 1665 1 +3 1220 1221 1222 1 +3 1756 527 1761 1 +3 874 1300 1310 1 +3 1013 1289 1313 1 +3 905 1529 1549 1 +3 1396 695 1427 1 +3 1232 1230 1259 1 +3 1272 409 1591 1 +3 1441 1067 1664 1 +3 1396 1427 1428 1 +3 1281 1011 1495 1 +3 1656 1020 1667 1 +3 902 1350 1512 1 +3 872 795 1262 1 +3 846 1108 1308 1 +3 1453 1454 1623 1 +3 874 1219 1598 1 +3 1189 206 1190 1 +3 930 1191 1670 1 +3 1356 1355 1631 1 +3 1351 979 1352 1 +3 1170 854 1416 1 +3 1185 1002 1280 1 +3 812 1447 1531 1 +3 1321 1324 1743 1 +3 1005 1219 1310 1 +3 585 589 1535 1 +3 532 1460 1671 1 +3 162 194 1269 1 +3 811 501 1228 1 +3 1262 1098 1264 1 +3 749 1223 1484 1 +3 1406 1409 1411 1 +3 1167 442 1789 1 +3 888 979 1351 1 +3 871 1356 1631 1 +3 1203 583 1535 1 +3 194 1253 1641 1 +3 85 86 235 1 +3 789 883 1416 1 +3 902 1512 1635 1 +3 1398 822 1399 1 +3 860 1213 1228 1 +3 456 1636 1643 1 +3 1317 247 1448 1 +3 37 38 1220 1 +3 1248 1235 1273 1 +3 701 1376 1377 1 +3 701 1375 1376 1 +3 1196 1188 1227 1 +3 654 1441 1664 1 +3 867 811 1228 1 +3 1472 1063 1640 1 +3 695 610 1592 1 +3 157 158 1195 1 +3 76 77 185 1 +3 215 1209 1291 1 +3 1608 1260 1622 1 +3 1318 1317 1448 1 +3 368 1198 1603 1 +3 1168 1755 1760 1 +3 1252 1236 1259 1 +3 575 603 1638 1 +3 140 141 236 1 +3 647 646 1285 1 +3 733 735 1345 1 +3 1343 520 1605 1 +3 1447 1446 1531 1 +3 1667 1020 1670 1 +3 240 187 1513 1 +3 41 42 1275 1 +3 860 1228 1274 1 +3 441 411 1484 1 +3 462 1284 1642 1 +3 1354 1437 1635 1 +3 1620 1490 1719 1 +3 802 908 1399 1 +3 712 841 1226 1 +3 487 504 1274 1 +3 911 1436 1643 1 +3 1463 491 1647 1 +3 1411 1409 1412 1 +3 1271 457 1583 1 +3 1502 595 1503 1 +3 1370 686 1510 1 +3 202 1229 1230 1 +3 618 616 1481 1 +3 1009 1503 1625 1 +3 981 1215 1216 1 +3 202 1231 1260 1 +3 158 159 184 1 +3 1454 816 1623 1 +3 735 857 1345 1 +3 1354 859 1437 1 +3 1361 1363 1404 1 +3 663 721 1316 1 +3 1230 1254 1259 1 +3 1210 652 1691 1 +3 502 482 1299 1 +3 489 645 1284 1 +3 1230 1229 1254 1 +3 39 40 1432 1 +3 467 1191 1683 1 +3 1194 885 1315 1 +3 160 161 224 1 +3 216 132 1290 1 +3 509 490 1344 1 +3 167 168 234 1 +3 456 1436 1656 1 +3 490 642 1344 1 +3 760 858 1302 1 +3 657 625 1692 1 +3 80 193 1286 1 +3 645 807 1284 1 +3 1302 1303 1307 1 +3 1610 1343 1612 1 +3 119 120 175 1 +3 893 709 1292 1 +3 50 215 1291 1 +3 548 707 1431 1 +3 1263 1262 1264 1 +3 701 626 1375 1 +3 660 629 1681 1 +3 1237 1236 1238 1 +3 201 84 1224 1 +3 539 704 1457 1 +3 1253 1608 1622 1 +3 1636 1217 1643 1 +3 224 1269 1270 1 +3 1448 253 1596 1 +3 1284 1283 1642 1 +3 849 987 1098 1 +3 874 276 1300 1 +3 1305 28 1668 1 +3 51 52 1207 1 +3 1205 1660 1665 1 +3 36 37 212 1 +3 652 621 1691 1 +3 849 1098 1262 1 +3 1181 1498 1650 1 +3 202 166 1229 1 +3 1405 1406 1411 1 +3 224 161 1269 1 +3 885 1013 1315 1 +3 1234 1236 1237 1 +3 571 574 1430 1 +3 795 849 1262 1 +3 704 1411 1413 1 +3 1186 240 1513 1 +3 701 1377 1390 1 +3 1299 1281 1495 1 +3 42 43 1278 1 +3 1461 822 1549 1 +3 464 459 1298 1 +3 1391 595 1502 1 +3 731 1007 1479 1 +3 688 1289 1449 1 +3 1304 858 1353 1 +3 1785 1221 1787 1 +3 691 535 1550 1 +3 1239 1238 1244 1 +3 1302 858 1303 1 +3 1237 1238 1239 1 +3 1427 695 1592 1 +3 822 1398 1549 1 +3 1520 753 1666 1 +3 1150 1311 1528 1 +3 1189 1190 1206 1 +3 1377 1380 1390 1 +3 688 1312 1313 1 +3 1239 1246 1465 1 +3 1456 580 1629 1 +3 651 1472 1640 1 +3 888 1351 1539 1 +3 908 1398 1399 1 +3 841 1090 1091 1 +3 1420 1425 1462 1 +3 688 370 1312 1 +3 1452 1514 1651 1 +3 1205 692 1660 1 +3 1234 1232 1236 1 +3 902 770 1350 1 +3 900 1217 1615 1 +3 98 99 226 1 +3 1029 1030 1710 1 +3 1363 1369 1404 1 +3 459 463 1298 1 +3 414 443 1446 1 +3 630 628 1390 1 +3 1237 1239 1465 1 +3 1293 875 1294 1 +3 244 731 1479 1 +3 642 464 1298 1 +3 1231 1230 1232 1 +3 1074 1441 1674 1 +3 775 1351 1352 1 +3 876 1358 1359 1 +3 1282 647 1768 1 +3 57 58 233 1 +3 687 1611 1677 1 +3 253 1610 1612 1 +3 1239 1244 1245 1 +3 533 1604 1615 1 +3 1286 193 1288 1 +3 537 691 1394 1 +3 225 1286 1287 1 +3 704 1405 1411 1 +3 1374 1428 1761 1 +3 132 133 1290 1 +3 451 479 1458 1 +3 1682 652 1685 1 +3 1091 1090 1122 1 +3 397 454 1400 1 +3 626 624 1375 1 +3 23 24 1483 1 +3 244 297 731 1 +3 620 618 1572 1 +3 411 749 1484 1 +3 1425 401 1462 1 +3 1220 177 1221 1 +3 254 520 1610 1 +3 1247 1245 1250 1 +3 1254 1256 1259 1 +3 1211 1185 1638 1 +3 678 537 1394 1 +3 960 824 1346 1 +3 841 842 1090 1 +3 704 542 1405 1 +3 985 893 1048 1 +3 1311 711 1528 1 +3 758 760 1302 1 +3 713 712 1226 1 +3 1301 758 1302 1 +3 482 484 1299 1 +3 1418 1420 1462 1 +3 661 712 713 1 +3 78 79 225 1 +3 347 513 1358 1 +3 859 766 1437 1 +3 826 875 1293 1 +3 165 202 1260 1 +3 594 597 663 1 +3 794 744 1401 1 +3 394 397 1400 1 +3 700 630 1390 1 +3 533 1217 1636 1 +3 1213 1038 1214 1 +3 215 1208 1209 1 +3 960 1346 1347 1 +3 136 137 199 1 +3 138 139 222 1 +3 432 445 1496 1 +3 646 661 1285 1 +3 793 669 1426 1 +3 56 57 1701 1 +3 721 795 872 1 +3 452 271 1684 1 +3 596 595 1391 1 +3 896 1271 1583 1 +3 663 597 721 1 +3 1247 1250 1251 1 +3 716 508 1471 1 +3 225 79 1286 1 +3 675 802 1399 1 +3 1314 1400 1568 1 +3 797 846 1308 1 +3 344 1392 1393 1 +3 166 167 1229 1 +3 591 593 594 1 +3 202 1230 1231 1 +3 1486 1449 1579 1 +3 787 974 1735 1 +3 1091 1122 1147 1 +3 1364 1361 1404 1 +3 1104 844 1443 1 +3 245 247 1317 1 +3 1596 253 1612 1 +3 1446 443 1531 1 +3 1471 728 1595 1 +3 276 278 1300 1 +3 985 1048 1120 1 +3 244 245 297 1 +3 1515 691 1550 1 +3 846 988 1108 1 +3 1395 695 1396 1 +3 462 489 1284 1 +3 569 571 1430 1 +3 706 888 1539 1 +3 24 170 1483 1 +3 1038 832 1039 1 +3 1087 1086 1088 1 +3 860 832 1038 1 +3 756 758 1301 1 +3 182 49 1291 1 +3 850 730 873 1 +3 508 728 1471 1 +3 1085 1084 1086 1 +3 1409 1408 1410 1 +3 730 509 1344 1 +3 728 1540 1595 1 +3 1598 1219 1663 1 +3 52 192 1207 1 +3 1233 1232 1234 1 +3 659 633 1653 1 +3 38 177 1220 1 +3 720 797 832 1 +3 555 560 1435 1 +3 342 347 1358 1 +3 165 166 202 1 +3 83 84 201 1 +3 600 596 1391 1 +3 1085 1086 1087 1 +3 764 859 1353 1 +3 1604 1271 1615 1 +3 471 441 1484 1 +3 502 1299 1495 1 +3 1087 1088 1089 1 +3 1083 1082 1084 1 +3 102 103 210 1 +3 725 663 726 1 +3 858 762 1353 1 +3 731 297 732 1 +3 848 847 1357 1 +3 1406 1408 1409 1 +3 344 336 1392 1 +3 1358 513 1359 1 +3 891 893 985 1 +3 747 835 1440 1 +3 1449 1289 1579 1 +3 594 593 597 1 +3 1083 1084 1085 1 +3 612 695 1395 1 +3 489 644 645 1 +3 1377 1376 1378 1 +3 1007 733 1345 1 +3 1453 915 1501 1 +3 645 646 647 1 +3 177 39 1432 1 +3 514 413 1444 1 +3 1360 685 1361 1 +3 915 1453 1623 1 +3 1347 452 1684 1 +3 1203 1571 1650 1 +3 1303 858 1304 1 +3 11 12 1494 1 +3 908 821 1031 1 +3 84 85 1224 1 +3 10 11 195 1 +3 850 873 990 1 +3 370 380 1312 1 +3 504 673 720 1 +3 532 275 1676 1 +3 1388 1364 1404 1 +3 810 501 811 1 +3 1405 705 1406 1 +3 618 1481 1572 1 +3 479 1348 1458 1 +3 518 1433 1434 1 +3 1000 998 1057 1 +3 791 726 834 1 +3 12 219 1494 1 +3 1295 875 1394 1 +3 35 36 1513 1 +3 1238 1236 1252 1 +3 968 826 1293 1 +3 1241 1235 1248 1 +3 1246 1245 1247 1 +3 661 713 1285 1 +3 733 734 735 1 +3 770 772 1350 1 +3 1438 352 1511 1 +3 622 685 1360 1 +3 720 832 860 1 +3 857 756 1301 1 +3 1235 1234 1273 1 +3 538 539 1457 1 +3 866 867 868 1 +3 486 487 501 1 +3 1000 1057 1058 1 +3 731 732 733 1 +3 330 523 1402 1 +3 1301 1302 1307 1 +3 1081 1080 1082 1 +3 518 324 1433 1 +3 1473 525 1474 1 +3 825 949 1417 1 +3 891 709 893 1 +3 865 811 866 1 +3 645 644 646 1 +3 1466 1261 1469 1 +3 437 451 1458 1 +3 1058 1057 1140 1 +3 403 432 1591 1 +3 1029 1715 1717 1 +3 836 837 1053 1 +3 453 687 1647 1 +3 521 522 666 1 +3 807 647 1282 1 +3 413 399 1444 1 +3 635 636 637 1 +3 712 724 841 1 +3 727 726 791 1 +3 164 165 1260 1 +3 802 821 908 1 +3 544 705 1405 1 +3 628 701 1390 1 +3 290 368 1603 1 +3 913 1020 1436 1 +3 826 784 875 1 +3 1081 1082 1083 1 +3 43 44 176 1 +3 187 35 1513 1 +3 55 56 200 1 +3 1475 449 1476 1 +3 1093 833 1442 1 +3 239 241 1479 1 +3 836 737 837 1 +3 751 840 1556 1 +3 445 476 486 1 +3 744 779 1401 1 +3 990 991 1047 1 +3 162 163 194 1 +3 735 755 756 1 +3 208 1277 1432 1 +3 249 253 1448 1 +3 866 811 867 1 +3 735 756 857 1 +3 728 729 1540 1 +3 440 470 1461 1 +3 594 663 725 1 +3 784 678 1394 1 +3 669 684 1426 1 +3 133 191 1290 1 +3 377 387 398 1 +3 831 747 1440 1 +3 1084 1082 1182 1 +3 633 634 635 1 +3 684 794 1426 1 +3 996 998 1000 1 +3 481 503 1348 1 +3 1231 1232 1233 1 +3 504 720 1274 1 +3 274 874 1598 1 +3 430 525 1473 1 +3 350 352 1438 1 +3 908 1031 1397 1 +3 790 662 877 1 +3 827 826 968 1 +3 161 162 1269 1 +3 878 1002 1003 1 +3 542 544 1405 1 +3 637 638 639 1 +3 709 656 1292 1 +3 631 632 633 1 +3 426 449 1475 1 +3 1646 1034 1652 1 +3 1080 1078 1197 1 +3 824 823 1346 1 +3 124 125 178 1 +3 1376 1364 1388 1 +3 949 881 950 1 +3 868 867 981 1 +3 990 873 991 1 +3 798 730 850 1 +3 1009 950 1502 1 +3 1011 737 1495 1 +3 1108 988 1109 1 +3 496 681 1504 1 +3 802 804 821 1 +3 1234 1237 1273 1 +3 790 877 878 1 +3 1508 448 1509 1 +3 760 762 858 1 +3 764 766 859 1 +3 416 414 1446 1 +3 523 1477 1478 1 +3 792 791 847 1 +3 26 27 227 1 +3 1355 437 1458 1 +3 1406 1407 1408 1 +3 762 764 1353 1 +3 817 808 1466 1 +3 481 482 502 1 +3 639 640 641 1 +3 825 881 949 1 +3 410 440 1461 1 +3 1047 991 1204 1 +3 655 641 656 1 +3 635 634 636 1 +3 869 868 1041 1 +3 725 726 727 1 +3 405 437 1355 1 +3 241 243 244 1 +3 470 822 1461 1 +3 68 69 190 1 +3 756 757 758 1 +3 133 134 191 1 +3 521 666 1281 1 +3 1294 1296 1297 1 +3 631 630 632 1 +3 737 649 1495 1 +3 80 81 193 1 +3 1420 1422 1425 1 +3 1233 1234 1235 1 +3 589 591 1534 1 +3 629 628 630 1 +3 629 630 631 1 +3 699 634 1492 1 +3 656 697 698 1 +3 710 737 836 1 +3 594 725 1534 1 +3 825 693 881 1 +3 559 562 563 1 +3 1377 1378 1379 1 +3 1022 283 1486 1 +3 48 49 182 1 +3 397 396 403 1 +3 486 476 487 1 +3 1360 1361 1364 1 +3 950 881 1502 1 +3 1303 1304 1305 1 +3 1040 863 1044 1 +3 720 673 797 1 +3 949 950 965 1 +3 539 542 704 1 +3 633 632 634 1 +3 733 732 734 1 +3 529 349 1485 1 +3 568 569 662 1 +3 860 1038 1213 1 +3 446 448 1508 1 +3 645 647 807 1 +3 484 506 521 1 +3 559 557 562 1 +3 1287 1286 1288 1 +3 358 357 373 1 +3 457 1545 1583 1 +3 810 811 865 1 +3 758 759 760 1 +3 385 406 1487 1 +3 443 514 515 1 +3 729 799 1540 1 +3 1294 1295 1296 1 +3 624 622 1360 1 +3 965 950 966 1 +3 634 632 1492 1 +3 837 1011 1012 1 +3 459 455 463 1 +3 1074 1674 1682 1 +3 880 394 1400 1 +3 534 473 690 1 +3 397 403 409 1 +3 637 636 638 1 +3 394 396 397 1 +3 1260 1231 1622 1 +3 18 1795 1799 1 +3 375 385 1487 1 +3 490 464 642 1 +3 382 381 399 1 +3 486 501 810 1 +3 1444 1546 1548 1 +3 627 626 628 1 +3 1397 1031 1699 1 +3 523 332 1477 1 +3 557 555 1435 1 +3 888 978 979 1 +3 515 516 538 1 +3 394 393 396 1 +3 667 669 793 1 +3 512 285 1522 1 +3 374 373 381 1 +3 565 563 566 1 +3 589 1534 1535 1 +3 400 399 413 1 +3 414 413 443 1 +3 878 877 1002 1 +3 882 1028 1349 1 +3 355 357 358 1 +3 627 628 629 1 +3 656 698 1292 1 +3 457 1271 1604 1 +3 694 690 823 1 +3 760 761 762 1 +3 996 997 998 1 +3 355 358 1511 1 +3 534 690 694 1 +3 1275 42 1278 1 +3 283 280 1486 1 +3 735 734 755 1 +3 1294 875 1295 1 +3 404 405 438 1 +3 967 966 1018 1 +3 675 801 802 1 +3 1076 1073 1210 1 +3 1088 1086 1178 1 +3 766 768 1437 1 +3 656 641 697 1 +3 358 739 1511 1 +3 540 538 702 1 +3 404 386 405 1 +3 741 711 1311 1 +3 1019 1018 1205 1 +3 944 824 960 1 +3 1414 1412 1415 1 +3 1050 1036 1051 1 +3 823 870 934 1 +3 1445 1446 1447 1 +3 479 480 481 1 +3 503 502 649 1 +3 470 500 822 1 +3 481 480 482 1 +3 823 934 1346 1 +3 1361 1362 1363 1 +3 49 50 1291 1 +3 392 393 394 1 +3 302 689 1501 1 +3 565 566 567 1 +3 662 569 1430 1 +3 622 620 685 1 +3 706 829 888 1 +3 762 763 764 1 +3 146 147 197 1 +3 247 249 1448 1 +3 445 486 1496 1 +3 347 349 350 1 +3 525 428 1475 1 +3 385 386 404 1 +3 1363 1365 1368 1 +3 282 285 512 1 +3 438 405 1355 1 +3 1385 1384 1386 1 +3 624 1360 1375 1 +3 694 823 824 1 +3 1071 1069 1074 1 +3 1418 1419 1420 1 +3 1313 880 1314 1 +3 965 966 967 1 +3 448 433 1473 1 +3 776 693 825 1 +3 1069 1067 1441 1 +3 355 356 357 1 +3 564 563 565 1 +3 616 614 686 1 +3 326 328 343 1 +3 625 624 626 1 +3 454 409 455 1 +3 1483 170 1635 1 +3 471 1484 1543 1 +3 513 350 1438 1 +3 399 401 1444 1 +3 827 968 969 1 +3 544 546 705 1 +3 725 1008 1534 1 +3 942 825 1417 1 +3 1079 1078 1080 1 +3 338 340 876 1 +3 1089 1088 1757 1 +3 571 573 574 1 +3 589 590 591 1 +3 1532 1499 1554 1 +3 610 608 1592 1 +3 768 902 1437 1 +3 1452 1482 1514 1 +3 16 17 220 1 +3 336 338 1392 1 +3 392 394 880 1 +3 426 424 449 1 +3 438 1355 1356 1 +3 568 567 569 1 +3 612 610 695 1 +3 913 928 1020 1 +3 443 413 514 1 +3 340 342 1358 1 +3 1445 416 1446 1 +3 1363 1368 1369 1 +3 789 702 883 1 +3 710 649 737 1 +3 385 376 386 1 +3 515 514 516 1 +3 287 289 383 1 +3 358 373 374 1 +3 1383 1381 1384 1 +3 875 784 1394 1 +3 343 1402 1403 1 +3 375 376 385 1 +3 244 243 245 1 +3 862 848 863 1 +3 866 868 869 1 +3 808 884 1466 1 +3 911 913 1436 1 +3 79 80 1286 1 +3 639 638 640 1 +3 538 516 539 1 +3 285 286 287 1 +3 768 770 902 1 +3 756 755 757 1 +3 129 130 181 1 +3 249 251 253 1 +3 374 381 382 1 +3 1367 1371 1372 1 +3 934 1010 1460 1 +3 354 1488 1489 1 +3 1009 1502 1503 1 +3 1380 1379 1381 1 +3 614 612 1395 1 +3 293 370 688 1 +3 887 824 944 1 +3 405 436 437 1 +3 786 784 826 1 +3 1169 854 1170 1 +3 876 340 1358 1 +3 689 1453 1501 1 +3 1482 281 1514 1 +3 324 326 1433 1 +3 382 399 400 1 +3 1484 1223 1543 1 +3 481 502 503 1 +3 625 626 627 1 +3 930 948 1191 1 +3 821 804 937 1 +3 967 1018 1019 1 +3 727 791 792 1 +3 338 876 1392 1 +3 764 765 766 1 +3 1273 1237 1465 1 +3 221 23 1483 1 +3 835 741 1311 1 +3 286 1022 1439 1 +3 400 413 414 1 +3 489 643 644 1 +3 628 626 701 1 +3 1361 685 1362 1 +3 703 702 789 1 +3 1314 880 1400 1 +3 352 353 355 1 +3 401 1425 1546 1 +3 418 416 1445 1 +3 521 506 522 1 +3 655 656 709 1 +3 334 344 1477 1 +3 420 418 442 1 +3 731 733 1007 1 +3 1363 1362 1365 1 +3 494 496 1504 1 +3 549 547 1559 1 +3 879 1463 1464 1 +3 1074 1069 1441 1 +3 458 455 459 1 +3 639 641 655 1 +3 900 909 1217 1 +3 326 343 1433 1 +3 873 730 1344 1 +3 864 863 1040 1 +3 282 283 285 1 +3 915 365 1501 1 +3 1079 1080 1081 1 +3 888 829 978 1 +3 287 288 289 1 +3 473 471 1543 1 +3 1381 1379 1382 1 +3 267 268 1526 1 +3 484 521 1299 1 +3 562 557 1435 1 +3 558 557 559 1 +3 686 614 1395 1 +3 347 350 513 1 +3 604 600 693 1 +3 623 622 624 1 +3 278 282 1300 1 +3 1077 1076 1078 1 +3 195 11 1494 1 +3 354 320 1488 1 +3 404 438 1480 1 +3 907 1644 1651 1 +3 896 898 1271 1 +3 302 300 689 1 +3 350 351 352 1 +3 925 665 1594 1 +3 698 697 775 1 +3 22 23 221 1 +3 363 1506 1507 1 +3 729 509 730 1 +3 474 473 534 1 +3 373 1418 1462 1 +3 515 538 540 1 +3 818 894 1021 1 +3 346 348 1485 1 +3 346 345 348 1 +3 772 774 882 1 +3 1375 1364 1376 1 +3 330 332 523 1 +3 1383 1384 1385 1 +3 1428 1017 1429 1 +3 380 391 392 1 +3 852 789 854 1 +3 1037 1036 1050 1 +3 126 127 217 1 +3 270 281 1482 1 +3 304 302 1501 1 +3 817 1466 1467 1 +3 548 550 707 1 +3 569 570 571 1 +3 792 847 848 1 +3 422 420 1760 1 +3 208 1276 1277 1 +3 280 279 284 1 +3 1239 1245 1246 1 +3 681 818 1504 1 +3 1411 1412 1413 1 +3 1378 1388 1389 1 +3 1545 1021 1583 1 +3 850 990 1092 1 +3 1372 1371 1373 1 +3 666 522 667 1 +3 479 481 1348 1 +3 433 430 1473 1 +3 1042 1041 1045 1 +3 399 381 401 1 +3 836 1054 1528 1 +3 347 346 349 1 +3 363 309 1506 1 +3 934 870 1010 1 +3 863 848 1357 1 +3 375 365 376 1 +3 254 255 256 1 +3 726 663 1316 1 +3 1377 1379 1380 1 +3 1380 1381 1383 1 +3 878 1003 1046 1 +3 693 600 1391 1 +3 1010 1455 1671 1 +3 1065 1063 1472 1 +3 697 641 1539 1 +3 25 26 1527 1 +3 383 738 754 1 +3 265 266 267 1 +3 320 322 1488 1 +3 1075 1073 1076 1 +3 451 478 479 1 +3 1191 948 1192 1 +3 256 257 258 1 +3 349 346 1485 1 +3 650 649 710 1 +3 383 289 738 1 +3 546 548 1431 1 +3 392 391 393 1 +3 332 334 1477 1 +3 758 757 759 1 +3 377 378 387 1 +3 684 744 794 1 +3 779 995 996 1 +3 263 264 265 1 +3 364 304 365 1 +3 342 346 347 1 +3 241 244 1479 1 +3 293 688 1449 1 +3 565 567 568 1 +3 256 255 257 1 +3 365 304 1501 1 +3 371 291 517 1 +3 376 915 1497 1 +3 703 789 852 1 +3 1183 1040 1184 1 +3 823 690 870 1 +3 334 336 344 1 +3 40 208 1432 1 +3 328 330 1402 1 +3 889 754 1004 1 +3 278 280 282 1 +3 322 324 518 1 +3 522 506 1557 1 +3 635 637 658 1 +3 772 882 1350 1 +3 882 935 1028 1 +3 265 264 266 1 +3 343 328 1402 1 +3 397 409 454 1 +3 1420 1421 1422 1 +3 1351 697 1539 1 +3 280 284 1486 1 +3 428 426 1475 1 +3 569 567 570 1 +3 1355 1458 1631 1 +3 1018 966 1456 1 +3 646 648 661 1 +3 342 345 346 1 +3 884 1194 1261 1 +3 251 252 254 1 +3 260 263 1499 1 +3 779 996 1401 1 +3 254 252 255 1 +3 537 535 691 1 +3 446 433 448 1 +3 1036 831 1440 1 +3 632 630 700 1 +3 1035 831 1036 1 +3 760 759 761 1 +3 454 455 458 1 +3 574 573 575 1 +3 430 428 525 1 +3 62 63 203 1 +3 287 383 1522 1 +3 417 416 418 1 +3 708 662 790 1 +3 1386 1384 1387 1 +3 783 678 784 1 +3 460 459 464 1 +3 1312 880 1313 1 +3 623 624 625 1 +3 267 266 268 1 +3 453 408 687 1 +3 747 741 835 1 +3 802 801 804 1 +3 1054 1053 1110 1 +3 884 885 1194 1 +3 1242 1241 1243 1 +3 364 365 375 1 +3 368 372 377 1 +3 661 664 712 1 +3 274 276 874 1 +3 300 298 1450 1 +3 540 702 703 1 +3 442 418 1445 1 +3 131 132 216 1 +3 263 261 264 1 +3 419 418 420 1 +3 1450 298 1526 1 +3 387 388 407 1 +3 383 889 1522 1 +3 380 392 1312 1 +3 571 572 573 1 +3 1467 1466 1469 1 +3 1710 360 1715 1 +3 415 414 416 1 +3 1044 863 1357 1 +3 254 256 520 1 +3 1318 1448 1596 1 +3 322 518 1488 1 +3 405 386 436 1 +3 1360 1364 1375 1 +3 462 488 489 1 +3 260 261 263 1 +3 996 1000 1401 1 +3 818 819 894 1 +3 352 355 1511 1 +3 966 1009 1456 1 +3 38 39 177 1 +3 297 245 1317 1 +3 1378 1376 1388 1 +3 1413 1412 1414 1 +3 736 1318 1319 1 +3 582 583 1203 1 +3 632 700 1492 1 +3 1581 916 1586 1 +3 998 997 999 1 +3 1072 1071 1073 1 +3 1504 1021 1576 1 +3 877 662 1430 1 +3 621 620 622 1 +3 1162 854 1169 1 +3 762 761 763 1 +3 966 950 1009 1 +3 1514 907 1651 1 +3 1173 959 1518 1 +3 515 540 1531 1 +3 1418 360 1419 1 +3 1453 1451 1454 1 +3 245 246 247 1 +3 342 341 345 1 +3 745 1532 1554 1 +3 955 954 956 1 +3 540 812 1531 1 +3 258 259 260 1 +3 1406 705 1407 1 +3 822 500 1399 1 +3 836 1053 1054 1 +3 766 767 768 1 +3 555 552 560 1 +3 896 897 898 1 +3 421 420 422 1 +3 674 499 1569 1 +3 371 517 808 1 +3 882 1349 1350 1 +3 604 693 776 1 +3 1070 1069 1071 1 +3 465 446 1508 1 +3 524 465 1508 1 +3 284 293 1449 1 +3 894 895 896 1 +3 619 618 620 1 +3 385 404 406 1 +3 881 693 1391 1 +3 472 471 473 1 +3 866 869 1541 1 +3 764 763 765 1 +3 487 498 504 1 +3 278 279 280 1 +3 742 375 1487 1 +3 591 592 593 1 +3 258 257 259 1 +3 307 1505 1506 1 +3 350 349 351 1 +3 898 899 900 1 +3 908 1397 1398 1 +3 786 826 827 1 +3 247 248 249 1 +3 308 310 1491 1 +3 359 353 1523 1 +3 121 122 218 1 +3 1054 1150 1528 1 +3 479 478 480 1 +3 268 1482 1526 1 +3 736 1319 1544 1 +3 882 774 935 1 +3 702 538 1457 1 +3 585 587 589 1 +3 852 854 1162 1 +3 900 901 909 1 +3 303 306 1516 1 +3 776 825 942 1 +3 668 522 1557 1 +3 639 655 1551 1 +3 406 404 1480 1 +3 1051 1036 1440 1 +3 640 696 706 1 +3 862 863 864 1 +3 1348 503 1589 1 +3 437 450 451 1 +3 887 944 945 1 +3 294 291 371 1 +3 909 910 911 1 +3 249 250 251 1 +3 808 809 884 1 +3 834 726 1316 1 +3 270 272 281 1 +3 615 614 616 1 +3 636 634 699 1 +3 649 502 1495 1 +3 706 828 829 1 +3 732 297 736 1 +3 617 616 618 1 +3 818 1021 1504 1 +3 602 1581 1586 1 +3 837 737 1011 1 +3 1482 1452 1526 1 +3 1068 1067 1069 1 +3 503 649 650 1 +3 241 242 243 1 +3 841 724 842 1 +3 340 341 342 1 +3 423 422 424 1 +3 1062 1061 1063 1 +3 884 809 885 1 +3 306 308 519 1 +3 260 259 261 1 +3 373 357 1418 1 +3 330 331 332 1 +3 338 339 340 1 +3 392 880 1312 1 +3 301 300 302 1 +3 689 300 1450 1 +3 351 349 529 1 +3 1064 1063 1065 1 +3 278 277 279 1 +3 376 365 915 1 +3 552 549 1559 1 +3 482 483 484 1 +3 288 286 1439 1 +3 1319 1320 1321 1 +3 685 620 1572 1 +3 689 1451 1453 1 +3 1365 1366 1367 1 +3 285 287 1522 1 +3 305 304 364 1 +3 689 1450 1451 1 +3 1010 1223 1455 1 +3 303 302 304 1 +3 613 612 614 1 +3 911 912 913 1 +3 31 32 1189 1 +3 492 465 524 1 +3 364 375 742 1 +3 282 280 283 1 +3 268 270 1482 1 +3 881 1391 1502 1 +3 65 66 198 1 +3 575 577 603 1 +3 352 351 353 1 +3 285 283 286 1 +3 1066 1065 1067 1 +3 1444 401 1546 1 +3 808 517 809 1 +3 1035 1036 1037 1 +3 571 570 572 1 +3 251 250 252 1 +3 328 329 330 1 +3 355 353 356 1 +3 299 298 300 1 +3 1439 1022 1542 1 +3 1172 959 1173 1 +3 318 320 354 1 +3 458 459 460 1 +3 681 781 818 1 +3 928 929 930 1 +3 306 307 308 1 +3 870 690 1543 1 +3 383 754 889 1 +3 1332 1334 1335 1 +3 308 309 310 1 +3 1367 1370 1371 1 +3 170 25 1527 1 +3 284 292 293 1 +3 239 187 240 1 +3 296 267 298 1 +3 287 286 288 1 +3 832 797 1308 1 +3 298 267 1526 1 +3 1338 1336 1339 1 +3 451 477 478 1 +3 1336 1334 1337 1 +3 96 97 188 1 +3 658 637 1551 1 +3 326 327 328 1 +3 687 408 1563 1 +3 1335 1338 1340 1 +3 621 622 623 1 +3 996 995 997 1 +3 869 1041 1042 1 +3 636 699 1562 1 +3 282 512 1300 1 +3 357 360 1418 1 +3 425 424 426 1 +3 721 722 795 1 +3 930 931 948 1 +3 1332 1333 1334 1 +3 511 820 1530 1 +3 913 914 928 1 +3 591 594 1534 1 +3 293 369 370 1 +3 403 412 432 1 +3 445 475 476 1 +3 291 288 1439 1 +3 312 314 384 1 +3 484 505 506 1 +3 1223 870 1543 1 +3 1022 1486 1579 1 +3 309 307 1506 1 +3 1427 1017 1428 1 +3 437 436 450 1 +3 559 563 564 1 +3 768 769 770 1 +3 611 610 612 1 +3 265 267 296 1 +3 351 529 1523 1 +3 953 803 954 1 +3 70 71 229 1 +3 284 1449 1486 1 +3 357 356 360 1 +3 26 227 1527 1 +3 1335 1334 1336 1 +3 306 519 1516 1 +3 818 781 819 1 +3 474 534 535 1 +3 869 1043 1541 1 +3 1420 1419 1421 1 +3 1077 1078 1079 1 +3 1658 654 1664 1 +3 803 674 1569 1 +3 710 836 1528 1 +3 310 311 312 1 +3 864 1040 1183 1 +3 1014 865 1218 1 +3 469 441 471 1 +3 511 718 820 1 +3 1335 1336 1338 1 +3 504 671 673 1 +3 631 633 659 1 +3 650 710 711 1 +3 884 1261 1466 1 +3 1516 519 1517 1 +3 358 374 739 1 +3 258 260 262 1 +3 324 325 326 1 +3 1016 942 1017 1 +3 694 824 887 1 +3 239 240 241 1 +3 883 702 1457 1 +3 356 353 359 1 +3 896 895 897 1 +3 432 444 445 1 +3 609 608 610 1 +3 262 260 1499 1 +3 485 464 490 1 +3 878 1046 1442 1 +3 766 765 767 1 +3 1006 959 1172 1 +3 989 844 1104 1 +3 809 517 1542 1 +3 262 1499 1500 1 +3 519 308 1491 1 +3 417 418 419 1 +3 500 675 1399 1 +3 1240 1235 1241 1 +3 1452 1450 1526 1 +3 1503 584 1625 1 +3 1330 1331 1332 1 +3 336 337 338 1 +3 894 819 895 1 +3 1242 1243 1249 1 +3 415 416 417 1 +3 890 709 891 1 +3 1075 1076 1077 1 +3 332 333 334 1 +3 563 562 1490 1 +3 312 313 314 1 +3 1021 1545 1576 1 +3 316 317 318 1 +3 53 54 1200 1 +3 221 1483 1512 1 +3 1218 865 1541 1 +3 1328 1329 1330 1 +3 740 711 741 1 +3 1332 1331 1333 1 +3 249 248 250 1 +3 400 414 415 1 +3 898 897 899 1 +3 1060 920 1061 1 +3 1373 1371 1374 1 +3 419 420 421 1 +3 320 321 322 1 +3 322 323 324 1 +3 289 288 290 1 +3 879 1464 1540 1 +3 679 680 1518 1 +3 290 294 368 1 +3 472 473 474 1 +3 604 776 1553 1 +3 314 315 316 1 +3 370 379 380 1 +3 958 780 959 1 +3 301 303 1516 1 +3 917 670 1570 1 +3 1072 1073 1075 1 +3 770 771 772 1 +3 900 899 901 1 +3 711 710 1528 1 +3 746 741 747 1 +3 958 959 1006 1 +3 411 395 749 1 +3 12 13 219 1 +3 307 305 1505 1 +3 1070 1071 1072 1 +3 1499 263 1554 1 +3 183 1410 1810 1 +3 530 1176 1798 1 +3 640 706 1539 1 +3 861 848 862 1 +3 1326 1327 1328 1 +3 284 279 292 1 +3 381 373 1462 1 +3 1333 1331 1342 1 +3 294 371 1561 1 +3 286 283 1022 1 +3 797 805 846 1 +3 318 319 320 1 +3 290 288 291 1 +3 729 730 798 1 +3 790 878 1442 1 +3 679 497 680 1 +3 579 581 582 1 +3 1319 1318 1320 1 +3 247 246 248 1 +3 923 665 925 1 +3 959 780 1518 1 +3 852 1162 1163 1 +3 795 796 849 1 +3 815 1005 1199 1 +3 245 243 246 1 +3 443 515 1531 1 +3 772 773 774 1 +3 1330 1329 1331 1 +3 1365 1362 1366 1 +3 439 461 462 1 +3 720 860 1274 1 +3 607 605 608 1 +3 380 390 391 1 +3 598 1027 1577 1 +3 421 422 423 1 +3 706 696 828 1 +3 655 890 1551 1 +3 1451 1450 1452 1 +3 894 896 1583 1 +3 799 879 1540 1 +3 371 808 817 1 +3 535 534 1550 1 +3 783 784 786 1 +3 1025 1177 1179 1 +3 776 1016 1553 1 +3 1068 1069 1070 1 +3 955 956 961 1 +3 276 277 278 1 +3 640 638 696 1 +3 1500 1499 1532 1 +3 1516 1517 1585 1 +3 521 1281 1299 1 +3 810 865 1014 1 +3 992 833 1093 1 +3 1422 1421 1423 1 +3 496 679 681 1 +3 619 620 621 1 +3 340 339 341 1 +3 423 424 425 1 +3 617 618 619 1 +3 163 164 1608 1 +3 909 901 910 1 +3 885 809 886 1 +3 372 294 1561 1 +3 1348 1589 1631 1 +3 1010 870 1223 1 +3 427 426 428 1 +3 1321 1320 1322 1 +3 308 307 309 1 +3 1534 1008 1535 1 +3 865 866 1541 1 +3 667 668 669 1 +3 482 480 483 1 +3 517 291 1439 1 +3 615 616 617 1 +3 906 814 907 1 +3 613 614 615 1 +3 601 600 604 1 +3 885 886 1013 1 +3 1467 1469 1470 1 +3 1328 1327 1329 1 +3 268 269 270 1 +3 377 372 378 1 +3 978 829 980 1 +3 265 296 1554 1 +3 993 1100 1101 1 +3 749 395 1601 1 +3 852 1163 1524 1 +3 1356 871 1646 1 +3 1322 1323 1326 1 +3 768 767 769 1 +3 306 305 307 1 +3 486 810 1496 1 +3 332 331 333 1 +3 1054 1110 1149 1 +3 1329 1327 1343 1 +3 911 910 912 1 +3 681 679 780 1 +3 830 747 831 1 +3 930 929 931 1 +3 14 15 183 1 +3 780 679 1518 1 +3 338 337 339 1 +3 353 351 1523 1 +3 451 450 477 1 +3 154 155 179 1 +3 637 639 1551 1 +3 1013 886 1289 1 +3 334 335 336 1 +3 566 563 1490 1 +3 972 973 1176 1 +3 514 1444 1548 1 +3 368 294 372 1 +3 311 309 363 1 +3 330 329 331 1 +3 540 703 812 1 +3 496 497 679 1 +3 681 780 781 1 +3 1066 1067 1068 1 +3 1422 1423 1520 1 +3 310 309 311 1 +3 913 912 914 1 +3 588 586 595 1 +3 948 931 951 1 +3 208 1275 1276 1 +3 497 495 682 1 +3 703 852 1524 1 +3 1023 715 1026 1 +3 1039 832 1308 1 +3 928 914 929 1 +3 372 1561 1566 1 +3 425 426 427 1 +3 717 510 816 1 +3 296 298 299 1 +3 806 1024 1025 1 +3 575 573 576 1 +3 817 1467 1468 1 +3 1062 1063 1064 1 +3 470 499 500 1 +3 781 780 958 1 +3 403 396 412 1 +3 611 612 613 1 +3 1014 1272 1591 1 +3 268 266 269 1 +3 690 473 1543 1 +3 1367 1366 1370 1 +3 1514 281 1663 1 +3 920 917 1570 1 +3 460 464 485 1 +3 1468 1563 1566 1 +3 72 73 180 1 +3 386 376 1497 1 +3 627 629 660 1 +3 985 1120 1148 1 +3 434 433 446 1 +3 328 327 329 1 +3 264 261 748 1 +3 846 970 988 1 +3 447 446 465 1 +3 1400 454 1568 1 +3 495 493 1537 1 +3 493 676 1537 1 +3 263 265 1554 1 +3 775 697 1351 1 +3 387 378 388 1 +3 110 111 174 1 +3 1326 1323 1327 1 +3 520 256 1587 1 +3 575 576 577 1 +3 641 640 1539 1 +3 849 982 987 1 +3 190 69 1459 1 +3 105 106 171 1 +3 299 300 301 1 +3 326 325 327 1 +3 1016 1017 1427 1 +3 1064 1065 1066 1 +3 589 587 590 1 +3 938 1700 1739 1 +3 755 734 856 1 +3 839 752 932 1 +3 478 477 1530 1 +3 770 769 771 1 +3 431 430 433 1 +3 669 683 684 1 +3 572 777 903 1 +3 599 596 600 1 +3 108 109 228 1 +3 646 644 648 1 +3 393 391 905 1 +3 567 566 1560 1 +3 609 610 611 1 +3 517 1439 1542 1 +3 1547 1532 1633 1 +3 886 809 1542 1 +3 432 1496 1591 1 +3 539 541 542 1 +3 19 20 172 1 +3 496 495 497 1 +3 315 313 530 1 +3 458 460 507 1 +3 903 939 941 1 +3 345 341 361 1 +3 1356 1646 1652 1 +3 598 602 1027 1 +3 895 819 957 1 +3 305 364 1505 1 +3 493 492 676 1 +3 494 495 496 1 +3 29 30 173 1 +3 429 428 430 1 +3 1371 1370 1510 1 +3 251 254 1610 1 +3 898 900 1615 1 +3 506 505 714 1 +3 466 493 494 1 +3 312 311 313 1 +3 466 465 492 1 +3 740 741 746 1 +3 484 483 505 1 +3 434 446 447 1 +3 487 476 498 1 +3 431 433 434 1 +3 1033 831 1035 1 +3 1322 1320 1323 1 +3 1060 1061 1062 1 +3 576 573 1552 1 +3 1563 389 1566 1 +3 623 625 657 1 +3 494 493 495 1 +3 24 25 170 1 +3 772 771 773 1 +3 324 323 325 1 +3 953 954 955 1 +3 573 572 1552 1 +3 447 465 466 1 +3 339 337 527 1 +3 572 570 777 1 +3 477 511 1530 1 +3 1026 715 1582 1 +3 270 271 272 1 +3 1167 855 1168 1 +3 303 305 306 1 +3 542 543 544 1 +3 1491 310 1617 1 +3 1549 1398 1675 1 +3 776 942 1016 1 +3 290 291 294 1 +3 718 814 815 1 +3 314 313 315 1 +3 477 510 511 1 +3 511 510 717 1 +3 511 717 718 1 +3 466 492 493 1 +3 401 381 1462 1 +3 480 478 1525 1 +3 828 904 972 1 +3 536 535 537 1 +3 939 940 1029 1 +3 318 317 319 1 +3 436 386 1497 1 +3 560 552 1559 1 +3 806 1025 1538 1 +3 246 243 1578 1 +3 607 608 609 1 +3 736 1317 1318 1 +3 899 897 952 1 +3 274 275 276 1 +3 258 262 1587 1 +3 759 757 963 1 +3 100 101 169 1 +3 1014 1218 1272 1 +3 718 717 814 1 +3 972 904 973 1 +3 316 315 317 1 +3 655 709 890 1 +3 272 273 274 1 +3 322 321 323 1 +3 923 925 926 1 +3 469 471 472 1 +3 684 743 744 1 +3 578 576 692 1 +3 489 488 643 1 +3 916 917 918 1 +3 675 800 801 1 +3 903 777 939 1 +3 301 302 303 1 +3 319 317 366 1 +3 334 333 335 1 +3 564 565 1613 1 +3 650 711 740 1 +3 277 275 532 1 +3 431 434 457 1 +3 45 46 213 1 +3 939 777 940 1 +3 440 468 470 1 +3 792 848 861 1 +3 320 319 321 1 +3 364 742 1505 1 +3 815 906 1005 1 +3 1189 1206 1536 1 +3 427 428 429 1 +3 1029 940 1030 1 +3 296 299 745 1 +3 508 490 509 1 +3 608 605 1553 1 +3 429 430 431 1 +3 568 662 708 1 +3 500 674 675 1 +3 954 803 1569 1 +3 815 814 906 1 +3 221 1349 1657 1 +3 887 945 1515 1 +3 296 745 1554 1 +3 462 461 488 1 +3 705 546 1431 1 +3 1025 1024 1177 1 +3 477 450 510 1 +3 336 335 337 1 +3 1500 1532 1547 1 +3 682 495 1537 1 +3 539 516 541 1 +3 606 670 916 1 +3 485 490 508 1 +3 746 747 830 1 +3 828 696 904 1 +3 918 919 933 1 +3 293 292 369 1 +3 887 1515 1550 1 +3 850 1092 1443 1 +3 763 761 962 1 +3 667 522 668 1 +3 725 727 1008 1 +3 303 304 305 1 +3 259 257 295 1 +3 692 576 1552 1 +3 323 321 531 1 +3 94 95 232 1 +3 389 378 1566 1 +3 1366 1362 1572 1 +3 740 746 871 1 +3 485 508 716 1 +3 601 604 605 1 +3 812 703 1524 1 +3 241 240 242 1 +3 556 555 557 1 +3 830 831 1033 1 +3 833 790 1442 1 +3 1061 920 1570 1 +3 577 576 578 1 +3 861 862 1181 1 +3 410 1461 1529 1 +3 879 1015 1463 1 +3 388 378 389 1 +3 773 855 947 1 +3 292 279 1564 1 +3 1005 906 1219 1 +3 1525 478 1530 1 +3 830 1033 1034 1 +3 276 275 277 1 +3 773 771 855 1 +3 279 277 1564 1 +3 447 466 1576 1 +3 506 714 1557 1 +3 417 419 467 1 +3 599 600 601 1 +3 1374 1371 1510 1 +3 806 715 1023 1 +3 270 269 271 1 +3 516 514 1548 1 +3 751 838 840 1 +3 423 425 456 1 +3 1362 685 1572 1 +3 714 806 1538 1 +3 1054 1149 1150 1 +3 371 817 1561 1 +3 252 250 435 1 +3 806 1023 1024 1 +3 483 480 1525 1 +3 1101 1100 1102 1 +3 661 648 664 1 +3 779 994 995 1 +3 1542 1022 1579 1 +3 1233 1235 1240 1 +3 261 259 1558 1 +3 544 545 546 1 +3 910 901 946 1 +3 274 273 275 1 +3 588 595 596 1 +3 744 778 779 1 +3 31 1189 1536 1 +3 931 929 938 1 +3 669 668 683 1 +3 466 494 1576 1 +3 947 855 1167 1 +3 1589 871 1631 1 +3 921 292 1564 1 +3 582 581 583 1 +3 677 537 678 1 +3 799 845 879 1 +3 721 597 722 1 +3 714 715 806 1 +3 556 557 558 1 +3 370 369 379 1 +3 619 621 652 1 +3 1240 1241 1242 1 +3 734 732 1544 1 +3 1370 1366 1481 1 +3 613 615 654 1 +3 572 903 1552 1 +3 408 389 1563 1 +3 1423 1421 1424 1 +3 388 389 402 1 +3 728 509 729 1 +3 266 264 1533 1 +3 914 912 943 1 +3 369 292 921 1 +3 461 453 491 1 +3 840 984 1049 1 +3 732 736 1544 1 +3 272 271 273 1 +3 869 1042 1043 1 +3 987 1055 1056 1 +3 402 389 408 1 +3 797 673 805 1 +3 434 447 1545 1 +3 767 765 964 1 +3 150 151 189 1 +3 273 271 452 1 +3 450 436 1580 1 +3 546 547 548 1 +3 289 290 1603 1 +3 736 297 1317 1 +3 427 429 533 1 +3 1043 1042 1188 1 +3 714 505 715 1 +3 333 331 362 1 +3 494 1504 1576 1 +3 327 325 367 1 +3 410 395 411 1 +3 248 246 528 1 +3 301 1516 1585 1 +3 1644 1454 1651 1 +3 609 611 651 1 +3 470 468 499 1 +3 605 604 1553 1 +3 886 1542 1579 1 +3 264 748 1533 1 +3 591 590 592 1 +3 810 1014 1496 1 +3 439 408 453 1 +3 1063 1061 1640 1 +3 390 379 395 1 +3 570 567 1560 1 +3 788 672 936 1 +3 1289 886 1579 1 +3 890 891 892 1 +3 1561 1468 1566 1 +3 474 535 536 1 +3 606 605 607 1 +3 1021 894 1583 1 +3 684 683 743 1 +3 528 246 1578 1 +3 1496 1014 1591 1 +3 391 390 1529 1 +3 1349 1028 1657 1 +3 708 790 833 1 +3 782 678 783 1 +3 916 670 917 1 +3 554 552 555 1 +3 577 578 579 1 +3 771 769 1567 1 +3 312 384 1617 1 +3 468 441 469 1 +3 1490 562 1736 1 +3 653 751 1556 1 +3 1168 855 1567 1 +3 432 412 444 1 +3 548 549 550 1 +3 1460 532 1676 1 +3 588 596 598 1 +3 816 510 1580 1 +3 919 917 920 1 +3 510 450 1580 1 +3 712 664 724 1 +3 1481 1366 1572 1 +3 256 258 1587 1 +3 601 605 606 1 +3 1059 920 1060 1 +3 851 1001 1164 1 +3 1548 1546 1618 1 +3 743 683 813 1 +3 440 411 441 1 +3 918 917 919 1 +3 243 242 1578 1 +3 1562 699 1607 1 +3 378 372 1566 1 +3 445 444 475 1 +3 1545 447 1576 1 +3 638 636 1562 1 +3 816 1454 1644 1 +3 851 953 1001 1 +3 1096 1095 1097 1 +3 817 1468 1561 1 +3 151 152 1575 1 +3 277 532 1564 1 +3 1025 1179 1645 1 +3 856 734 1544 1 +3 799 798 844 1 +3 457 434 1545 1 +3 748 261 1558 1 +3 436 1497 1580 1 +3 777 570 1560 1 +3 598 596 599 1 +3 1329 1343 1605 1 +3 299 301 1585 1 +3 30 31 1536 1 +3 485 716 1565 1 +3 508 509 728 1 +3 1043 1188 1196 1 +3 804 801 977 1 +3 390 395 410 1 +3 542 541 543 1 +3 648 644 1606 1 +3 994 778 1032 1 +3 955 961 1165 1 +3 606 607 670 1 +3 909 911 1643 1 +3 940 777 1560 1 +3 851 803 953 1 +3 606 916 1581 1 +3 469 472 526 1 +3 380 379 390 1 +3 1342 1331 1605 1 +3 744 743 778 1 +3 714 1538 1557 1 +3 1517 519 1630 1 +3 999 997 1166 1 +3 855 771 1567 1 +3 919 920 1059 1 +3 439 462 1642 1 +3 152 153 231 1 +3 786 827 976 1 +3 579 578 580 1 +3 587 586 588 1 +3 598 599 602 1 +3 242 1186 1187 1 +3 504 498 671 1 +3 269 266 1533 1 +3 1560 566 1620 1 +3 1555 653 1556 1 +3 779 778 994 1 +3 412 396 1599 1 +3 396 393 1599 1 +3 507 460 1565 1 +3 554 555 556 1 +3 1530 820 1621 1 +3 440 441 468 1 +3 500 499 674 1 +3 585 584 586 1 +3 272 274 1598 1 +3 250 248 1573 1 +3 410 411 440 1 +3 536 537 677 1 +3 544 543 545 1 +3 677 782 785 1 +3 393 905 1599 1 +3 694 887 1550 1 +3 402 408 439 1 +3 541 516 1548 1 +3 153 154 1574 1 +3 593 592 653 1 +3 687 1563 1611 1 +3 745 299 1585 1 +3 583 584 585 1 +3 1540 1464 1595 1 +3 534 694 1550 1 +3 994 1032 1171 1 +3 1421 1419 1584 1 +3 1407 705 1431 1 +3 677 678 782 1 +3 916 918 1586 1 +3 905 391 1529 1 +3 579 580 581 1 +3 585 586 587 1 +3 583 581 584 1 +3 729 798 799 1 +3 643 665 922 1 +3 460 485 1565 1 +3 846 805 970 1 +3 1320 1318 1596 1 +3 164 1260 1608 1 +3 503 650 1589 1 +3 439 453 461 1 +3 696 638 1562 1 +3 40 41 208 1 +3 554 556 561 1 +3 545 543 753 1 +3 1343 1327 1612 1 +3 588 598 1577 1 +3 454 458 1568 1 +3 390 410 1529 1 +3 242 1187 1578 1 +3 458 507 1568 1 +3 922 665 923 1 +3 1480 438 1652 1 +3 607 609 1593 1 +3 904 696 1562 1 +3 431 457 1604 1 +3 71 72 1519 1 +3 838 752 839 1 +3 727 792 1571 1 +3 675 674 800 1 +3 1425 1422 1666 1 +3 715 505 1582 1 +3 546 545 547 1 +3 1497 915 1623 1 +3 208 41 1275 1 +3 173 30 1536 1 +3 800 674 803 1 +3 1541 1043 1626 1 +3 548 547 549 1 +3 785 782 853 1 +3 92 93 196 1 +3 1323 1320 1596 1 +3 259 295 1558 1 +3 738 289 1603 1 +3 1634 402 1642 1 +3 956 954 1649 1 +3 498 476 1616 1 +3 1551 890 1619 1 +3 429 431 1604 1 +3 940 1560 1620 1 +3 22 221 1657 1 +3 800 803 851 1 +3 1074 1682 1685 1 +3 798 850 1443 1 +3 1580 1497 1623 1 +3 1424 1421 1584 1 +3 643 488 665 1 +3 444 412 719 1 +3 565 568 1613 1 +3 599 601 1581 1 +3 799 844 845 1 +3 505 483 1582 1 +3 1139 984 1145 1 +3 1283 1634 1642 1 +3 670 607 1593 1 +3 248 528 1573 1 +3 281 272 1598 1 +3 816 1580 1623 1 +3 751 750 752 1 +3 879 845 1015 1 +3 650 740 1589 1 +3 1049 984 1139 1 +3 1026 1582 1621 1 +3 483 1525 1582 1 +3 1338 1339 1609 1 +3 922 923 924 1 +3 840 838 984 1 +3 1331 1329 1605 1 +3 593 653 1555 1 +3 551 554 1627 1 +3 533 429 1604 1 +3 609 651 1593 1 +3 253 251 1610 1 +3 989 1104 1105 1 +3 551 549 552 1 +3 751 752 838 1 +3 904 1562 1607 1 +3 740 871 1589 1 +3 144 145 223 1 +3 719 412 1599 1 +3 590 587 1577 1 +3 644 643 1606 1 +3 1043 1196 1626 1 +3 587 588 1577 1 +3 653 750 751 1 +3 7 8 204 1 +3 154 179 1574 1 +3 553 551 1627 1 +3 1008 727 1571 1 +3 1570 670 1593 1 +3 242 240 1186 1 +3 69 70 1459 1 +3 792 861 1571 1 +3 787 788 974 1 +3 435 250 1573 1 +3 602 599 1581 1 +3 597 593 1555 1 +3 668 1557 1628 1 +3 550 551 553 1 +3 1016 1427 1592 1 +3 973 904 1607 1 +3 1699 1031 1708 1 +3 1096 1097 1154 1 +3 907 814 1644 1 +3 601 606 1581 1 +3 608 1553 1592 1 +3 551 552 554 1 +3 566 1490 1620 1 +3 1553 1016 1592 1 +3 310 312 1617 1 +3 890 892 1619 1 +3 1271 898 1615 1 +3 550 549 551 1 +3 993 1099 1100 1 +3 842 843 986 1 +3 1323 1596 1612 1 +3 974 788 975 1 +3 658 1551 1619 1 +3 1327 1323 1612 1 +3 801 800 1600 1 +3 558 1661 1669 1 +3 1468 1467 1611 1 +3 229 71 1519 1 +3 844 798 1443 1 +3 189 151 1575 1 +3 671 672 787 1 +3 1240 1242 1253 1 +3 743 813 1590 1 +3 787 672 788 1 +3 653 592 750 1 +3 113 114 207 1 +3 1458 1348 1631 1 +3 1451 1452 1651 1 +3 927 992 993 1 +3 472 474 1588 1 +3 1467 1470 1611 1 +3 72 180 1519 1 +3 673 671 1614 1 +3 723 648 1606 1 +3 395 379 1601 1 +3 1569 499 1624 1 +3 927 833 992 1 +3 708 833 927 1 +3 1032 778 1590 1 +3 1231 1233 1622 1 +3 795 722 796 1 +3 148 149 230 1 +3 1585 1517 1633 1 +3 584 581 1625 1 +3 805 673 1614 1 +3 558 559 1661 1 +3 1218 1541 1626 1 +3 1100 1099 1103 1 +3 499 468 1624 1 +3 526 472 1588 1 +3 993 992 1099 1 +3 778 743 1590 1 +3 977 801 1600 1 +3 556 558 1597 1 +3 469 526 1624 1 +3 456 425 1636 1 +3 152 231 1575 1 +3 633 635 1653 1 +3 1557 1538 1628 1 +3 664 648 723 1 +3 830 1034 1646 1 +3 1185 1280 1638 1 +3 568 708 1613 1 +3 476 475 1616 1 +3 580 578 1629 1 +3 1094 843 1095 1 +3 1563 1468 1611 1 +3 70 229 1459 1 +3 683 668 1628 1 +3 369 921 1601 1 +3 536 677 1602 1 +3 1628 1538 1645 1 +3 519 1491 1630 1 +3 849 796 982 1 +3 1233 1240 1622 1 +3 1472 1658 1664 1 +3 672 498 1616 1 +3 427 533 1636 1 +3 993 1101 1648 1 +3 468 469 1624 1 +3 671 498 672 1 +3 665 488 1594 1 +3 1525 1530 1621 1 +3 1030 940 1620 1 +3 845 844 989 1 +3 581 580 1625 1 +3 1582 1525 1621 1 +3 851 1164 1600 1 +3 951 1694 1749 1 +3 578 692 1629 1 +3 60 61 237 1 +3 970 805 971 1 +3 987 982 1055 1 +3 1441 654 1674 1 +3 1532 745 1633 1 +3 474 536 1588 1 +3 1624 526 1649 1 +3 677 785 1602 1 +3 231 153 1574 1 +3 1067 1065 1664 1 +3 1577 1027 1632 1 +3 1704 1297 1720 1 +3 564 1613 1648 1 +3 1755 1168 1811 1 +3 1084 1182 1673 1 +3 561 556 1597 1 +3 1094 1095 1096 1 +3 1611 1470 1677 1 +3 723 1606 1639 1 +3 1346 934 1680 1 +3 388 402 1634 1 +3 717 816 1644 1 +3 753 543 1618 1 +3 1593 651 1640 1 +3 871 746 1646 1 +3 379 369 1601 1 +3 425 427 1636 1 +3 903 941 1660 1 +3 813 683 1628 1 +3 800 851 1600 1 +3 1470 1595 1677 1 +3 936 672 1616 1 +3 89 90 205 1 +3 813 1628 1645 1 +3 1588 536 1602 1 +3 1472 651 1658 1 +3 907 1514 1663 1 +3 671 787 1614 1 +3 1030 1584 1710 1 +3 988 970 1161 1 +3 643 922 1606 1 +3 842 724 843 1 +3 1178 1086 1673 1 +3 407 388 1634 1 +3 708 927 1613 1 +3 541 1548 1618 1 +3 543 541 1618 1 +3 1512 1483 1635 1 +3 590 1577 1632 1 +3 554 561 1627 1 +3 1242 1249 1641 1 +3 461 491 1594 1 +3 722 597 1555 1 +3 745 1585 1633 1 +3 423 456 1656 1 +3 840 1049 1679 1 +3 592 590 1632 1 +3 989 1105 1106 1 +3 928 930 1670 1 +3 1606 922 1639 1 +3 971 805 1614 1 +3 1657 1028 1678 1 +3 1240 1253 1622 1 +3 1570 1593 1640 1 +3 488 461 1594 1 +3 613 654 1658 1 +3 1307 173 1707 1 +3 982 796 983 1 +3 28 29 1668 1 +3 986 843 1094 1 +3 1217 909 1643 1 +3 1392 876 1700 1 +3 1056 1055 1137 1 +3 932 752 1662 1 +3 750 592 1632 1 +3 1691 657 1693 1 +3 651 611 1658 1 +3 1569 1624 1649 1 +3 1659 1556 1679 1 +3 956 1649 1655 1 +3 1595 1464 1677 1 +3 366 1387 1796 1 +3 1720 945 1737 1 +3 753 1618 1666 1 +3 1618 1546 1666 1 +3 531 1382 1793 1 +3 1182 1082 1690 1 +3 1088 1178 1754 1 +3 1253 1242 1641 1 +3 906 907 1663 1 +3 1455 921 1671 1 +3 936 1708 1727 1 +3 746 830 1646 1 +3 1073 1071 1685 1 +3 1078 1076 1693 1 +3 983 1659 1679 1 +3 467 419 1667 1 +3 1080 1197 1690 1 +3 1794 366 1796 1 +3 1732 965 1758 1 +3 814 717 1644 1 +3 724 664 1637 1 +3 1454 1451 1651 1 +3 629 631 1681 1 +3 925 1594 1654 1 +3 1095 843 1637 1 +3 692 1552 1660 1 +3 1061 1570 1640 1 +3 1538 1025 1645 1 +3 1613 927 1648 1 +3 1571 861 1650 1 +3 1464 1463 1647 1 +3 922 924 1639 1 +3 1648 1101 1661 1 +3 438 1356 1652 1 +3 402 439 1642 1 +3 635 658 1653 1 +3 172 20 1678 1 +3 1210 1691 1693 1 +3 1632 1027 1662 1 +3 861 1181 1650 1 +3 664 723 1637 1 +3 654 615 1674 1 +3 421 423 1656 1 +3 275 273 1676 1 +3 1507 1777 1816 1 +3 21 22 1657 1 +3 750 1632 1662 1 +3 921 1564 1671 1 +3 1647 687 1677 1 +3 1359 513 1694 1 +3 611 613 1658 1 +3 1559 1687 1706 1 +3 927 993 1648 1 +3 843 724 1637 1 +3 271 269 1684 1 +3 382 400 1689 1 +3 918 933 1688 1 +3 359 1523 1734 1 +3 954 1569 1649 1 +3 619 652 1682 1 +3 417 467 1683 1 +3 621 623 1691 1 +3 1734 1523 1747 1 +3 1097 1095 1686 1 +3 625 627 1692 1 +3 1402 523 1711 1 +3 1672 1586 1688 1 +3 1552 903 1660 1 +3 564 1648 1661 1 +3 559 564 1661 1 +3 172 1678 1696 1 +3 1594 491 1654 1 +3 1019 1205 1665 1 +3 1477 344 1705 1 +3 1661 1101 1669 1 +3 1429 361 1756 1 +3 1555 1556 1659 1 +3 382 1689 1738 1 +3 1676 452 1680 1 +3 1065 1472 1664 1 +3 932 1662 1672 1 +3 1715 359 1717 1 +3 753 1520 1687 1 +3 1597 558 1669 1 +3 421 1656 1667 1 +3 419 421 1667 1 +3 47 1767 1818 1 +3 1219 906 1663 1 +3 1599 905 1675 1 +3 1559 547 1687 1 +3 752 750 1662 1 +3 905 1549 1675 1 +3 545 753 1687 1 +3 526 1588 1655 1 +3 21 1657 1678 1 +3 1325 524 1752 1 +3 602 1586 1672 1 +3 1460 1676 1680 1 +3 1546 1425 1666 1 +3 983 796 1659 1 +3 1649 526 1655 1 +3 29 173 1668 1 +3 1588 1602 1655 1 +3 1429 1756 1761 1 +3 932 1672 1688 1 +3 719 1397 1699 1 +3 961 956 1697 1 +3 1020 928 1670 1 +3 1389 367 1792 1 +3 1433 343 1721 1 +3 1086 1084 1673 1 +3 796 722 1659 1 +3 722 1555 1659 1 +3 1564 532 1671 1 +3 1810 1410 1815 1 +3 1027 602 1672 1 +3 295 257 1704 1 +3 821 937 1727 1 +3 914 943 1703 1 +3 1101 1102 1669 1 +3 1556 840 1679 1 +3 615 617 1674 1 +3 938 929 1703 1 +3 1662 1027 1672 1 +3 273 452 1676 1 +3 1488 518 1728 1 +3 1372 1773 1776 1 +3 910 946 1709 1 +3 1368 362 1780 1 +3 1187 1771 1783 1 +3 20 21 1678 1 +3 360 356 1715 1 +3 1708 1031 1727 1 +3 444 719 1699 1 +3 1417 949 1732 1 +3 1687 1520 1706 1 +3 934 1460 1680 1 +3 939 1029 1717 1 +3 943 912 1709 1 +3 1584 1419 1710 1 +3 899 952 1716 1 +3 318 354 1729 1 +3 384 314 1725 1 +3 617 619 1682 1 +3 631 659 1681 1 +3 946 901 1716 1 +3 1674 617 1682 1 +3 1088 1754 1757 1 +3 719 1599 1675 1 +3 1740 361 1744 1 +3 895 957 1724 1 +3 415 417 1683 1 +3 1296 945 1720 1 +3 960 1347 1722 1 +3 952 897 1724 1 +3 1373 527 1770 1 +3 1071 1074 1685 1 +3 1179 1180 1718 1 +3 781 958 1731 1 +3 957 819 1731 1 +3 269 1533 1684 1 +3 1678 1028 1696 1 +3 1645 1179 1718 1 +3 415 1683 1689 1 +3 400 415 1689 1 +3 1369 1784 1790 1 +3 944 960 1730 1 +3 1637 723 1686 1 +3 1082 1080 1690 1 +3 1438 1511 1749 1 +3 956 1655 1697 1 +3 1655 1602 1697 1 +3 1095 1637 1686 1 +3 1464 1647 1677 1 +3 623 657 1691 1 +3 739 374 1738 1 +3 876 1359 1700 1 +3 547 545 1687 1 +3 448 1473 1746 1 +3 1076 1210 1693 1 +3 525 1475 1748 1 +3 513 1438 1694 1 +3 627 660 1692 1 +3 1161 970 1714 1 +3 988 1161 1713 1 +3 945 944 1737 1 +3 1586 918 1688 1 +3 723 1639 1686 1 +3 1689 1192 1738 1 +3 960 1722 1730 1 +3 948 951 1742 1 +3 1097 1686 1712 1 +3 1590 813 1718 1 +3 951 931 1739 1 +3 1508 1509 1752 1 +3 1028 935 1696 1 +3 1023 1026 1695 1 +3 1417 1740 1744 1 +3 1017 942 1744 1 +3 1023 1695 1698 1 +3 820 1521 1723 1 +3 173 1536 1707 1 +3 1621 820 1723 1 +3 1742 951 1749 1 +3 944 1730 1737 1 +3 739 1738 1742 1 +3 1024 1023 1698 1 +3 761 759 1750 1 +3 424 422 1755 1 +3 200 56 1701 1 +3 1359 1694 1739 1 +3 1386 1387 1798 1 +3 763 962 1745 1 +3 348 345 1740 1 +3 936 1616 1708 1 +3 964 765 1745 1 +3 1602 785 1697 1 +3 475 444 1699 1 +3 1544 1319 1743 1 +3 1719 1490 1736 1 +3 348 1732 1758 1 +3 1177 1024 1702 1 +3 1590 1718 1759 1 +3 295 1720 1737 1 +3 767 964 1751 1 +3 257 255 1704 1 +3 1567 769 1751 1 +3 1024 1698 1702 1 +3 339 527 1756 1 +3 929 914 1703 1 +3 1523 529 1747 1 +3 344 1393 1705 1 +3 969 968 1775 1 +3 361 341 1756 1 +3 1653 658 1754 1 +3 1695 1026 1723 1 +3 968 1293 1765 1 +3 1109 988 1713 1 +3 475 1699 1708 1 +3 1614 787 1735 1 +3 523 1478 1711 1 +3 1520 1423 1706 1 +3 912 910 1709 1 +3 1435 560 1726 1 +3 560 1559 1706 1 +3 1684 1533 1722 1 +3 1763 435 1764 1 +3 1419 360 1710 1 +3 967 1019 1753 1 +3 788 936 1733 1 +3 356 359 1715 1 +3 1347 1684 1722 1 +3 967 1753 1758 1 +3 1686 1639 1712 1 +3 1616 475 1708 1 +3 562 1435 1736 1 +3 970 971 1714 1 +3 1201 1193 1820 1 +3 1536 1206 1707 1 +3 901 899 1716 1 +3 975 788 1733 1 +3 1178 1653 1754 1 +3 941 939 1717 1 +3 343 1403 1721 1 +3 1706 1423 1726 1 +3 1694 951 1739 1 +3 295 1704 1720 1 +3 1424 1584 1719 1 +3 560 1706 1726 1 +3 1731 958 1800 1 +3 1533 748 1722 1 +3 314 316 1725 1 +3 1717 359 1734 1 +3 965 967 1758 1 +3 1725 316 1729 1 +3 518 1434 1728 1 +3 897 895 1724 1 +3 813 1645 1718 1 +3 969 1775 1783 1 +3 1423 1424 1726 1 +3 1031 821 1727 1 +3 316 318 1729 1 +3 1639 924 1712 1 +3 1026 1621 1723 1 +3 177 1432 1787 1 +3 1435 1726 1736 1 +3 1293 1294 1764 1 +3 1722 748 1730 1 +3 354 1489 1800 1 +3 968 1765 1775 1 +3 252 435 1763 1 +3 819 781 1731 1 +3 995 1282 1768 1 +3 1727 937 1733 1 +3 748 1558 1730 1 +3 220 1799 1801 1 +3 1665 1734 1747 1 +3 949 965 1732 1 +3 1726 1424 1736 1 +3 345 361 1740 1 +3 1718 1180 1759 1 +3 1802 1292 1803 1 +3 1799 1170 1801 1 +3 1388 1404 1790 1 +3 1730 1558 1737 1 +3 804 977 1766 1 +3 1365 1367 1776 1 +3 997 995 1768 1 +3 527 337 1770 1 +3 1506 1505 1772 1 +3 980 829 1777 1 +3 1771 1221 1785 1 +3 374 382 1738 1 +3 333 362 1773 1 +3 1558 295 1737 1 +3 828 972 1777 1 +3 757 755 1779 1 +3 971 1614 1735 1 +3 1417 1732 1740 1 +3 183 1804 1807 1 +3 313 311 1778 1 +3 974 975 1741 1 +3 931 938 1739 1 +3 362 331 1780 1 +3 176 44 1791 1 +3 1192 948 1742 1 +3 1275 1278 1774 1 +3 1732 348 1740 1 +3 327 367 1784 1 +3 1382 1379 1793 1 +3 955 1165 1788 1 +3 1738 1192 1742 1 +3 1665 941 1734 1 +3 853 782 1781 1 +3 45 213 1791 1 +3 786 976 1786 1 +3 785 853 1782 1 +3 1378 1389 1793 1 +3 1804 1415 1807 1 +3 739 1742 1749 1 +3 1001 953 1788 1 +3 1600 1164 1769 1 +3 1387 1384 1796 1 +3 1416 1414 1801 1 +3 1474 525 1748 1 +3 1511 739 1749 1 +3 856 1544 1743 1 +3 942 1417 1744 1 +3 765 763 1745 1 +3 1509 448 1746 1 +3 936 1727 1733 1 +3 1381 1382 1796 1 +3 1578 1187 1783 1 +3 323 531 1792 1 +3 980 1772 1814 1 +3 962 761 1750 1 +3 1704 255 1763 1 +3 367 325 1792 1 +3 19 172 1795 1 +3 769 767 1751 1 +3 529 1485 1753 1 +3 321 319 1794 1 +3 1476 449 1811 1 +3 1293 1764 1765 1 +3 893 1292 1802 1 +3 317 315 1797 1 +3 524 1508 1752 1 +3 1567 1751 1811 1 +3 1753 1485 1758 1 +3 17 18 1799 1 +3 1297 1704 1763 1 +3 1489 1731 1800 1 +3 449 424 1755 1 +3 1485 348 1758 1 +3 1208 1207 1819 1 +3 658 1619 1754 1 +3 341 339 1756 1 +3 1755 422 1760 1 +3 1019 1665 1747 1 +3 1619 892 1757 1 +3 1032 1759 1762 1 +3 1187 1222 1771 1 +3 941 1717 1734 1 +3 1428 1429 1761 1 +3 1032 1590 1759 1 +3 1424 1719 1736 1 +3 976 827 1785 1 +3 15 16 1804 1 +3 1171 1032 1762 1 +3 1771 969 1783 1 +3 1754 1619 1757 1 +3 1412 1409 1807 1 +3 775 1352 1806 1 +3 1176 973 1798 1 +3 1297 1763 1764 1 +3 1480 1652 1809 1 +3 698 775 1805 1 +3 14 183 1810 1 +3 406 1812 1813 1 +3 1019 1747 1753 1 +3 1292 698 1803 1 +3 219 13 1810 1 +3 255 252 1763 1 +3 1747 529 1753 1 +3 1805 775 1806 1 +3 1803 698 1805 1 +3 1480 1809 1812 1 +3 406 1480 1812 1 +3 1294 1297 1764 1 +3 1001 1788 1818 1 +3 961 1697 1782 1 +3 1751 1476 1811 1 +3 937 804 1766 1 +3 827 969 1785 1 +3 1487 406 1813 1 +3 435 1573 1765 1 +3 1164 1001 1767 1 +3 1487 1813 1814 1 +3 742 1487 1814 1 +3 1166 997 1768 1 +3 337 335 1770 1 +3 977 1600 1769 1 +3 947 1167 1789 1 +3 335 333 1773 1 +3 1770 335 1773 1 +3 1276 1275 1774 1 +3 1505 742 1772 1 +3 1765 1573 1775 1 +3 1367 1372 1776 1 +3 1806 1352 1809 1 +3 937 1766 1808 1 +3 1573 528 1775 1 +3 1175 947 1789 1 +3 829 828 1777 1 +3 1764 435 1765 1 +3 311 363 1778 1 +3 963 757 1779 1 +3 972 1176 1816 1 +3 331 329 1780 1 +3 782 783 1781 1 +3 213 46 1818 1 +3 329 327 1784 1 +3 1780 329 1784 1 +3 1775 528 1783 1 +3 783 786 1786 1 +3 528 1578 1783 1 +3 1221 177 1787 1 +3 1781 783 1786 1 +3 953 955 1788 1 +3 1404 1369 1790 1 +3 44 45 1791 1 +3 973 1386 1798 1 +3 1379 1378 1793 1 +3 325 323 1792 1 +3 1279 176 1817 1 +3 319 366 1794 1 +3 18 19 1795 1 +3 1384 1381 1796 1 +3 315 530 1797 1 +3 1697 785 1782 1 +3 220 17 1799 1 +3 1037 1802 1803 1 +3 958 1006 1800 1 +3 961 1782 1817 1 +3 1170 1416 1801 1 +3 1048 893 1802 1 +3 1778 363 1816 1 +3 1176 1778 1816 1 +3 969 1771 1785 1 +3 1788 213 1818 1 +3 1035 1037 1803 1 +3 183 15 1804 1 +3 1035 1803 1805 1 +3 1033 1035 1805 1 +3 1034 1033 1806 1 +3 1033 1805 1806 1 +3 1415 1412 1807 1 +3 1782 1279 1817 1 +3 13 14 1810 1 +3 1809 1352 1812 1 +3 1034 1806 1809 1 +3 1652 1034 1809 1 +3 1808 1208 1819 1 +3 1812 979 1813 1 +3 975 1733 1808 1 +3 1168 1567 1811 1 +3 1352 979 1812 1 +3 979 978 1813 1 +3 1813 978 1814 1 +3 1410 1408 1815 1 +3 978 980 1814 1 +3 363 1507 1816 1 +3 1733 937 1808 1 +3 971 1735 1820 1 +3 1735 1201 1820 1 +3 975 1808 1819 1 +3 1165 961 1817 1 +3 1767 1001 1818 1 +3 1741 975 1819 1 +3 1714 971 1820 1 +3 1407 1431 1822 1 +3 1440 835 1823 1 +3 106 107 1824 1 +3 713 1226 1825 1 +3 999 1166 1825 1 +3 1281 666 1826 1 +3 1012 1011 1826 1 +3 1214 1848 1892 1 +3 197 1264 1866 1 +3 1431 707 1822 1 +3 1051 1440 1823 1 +3 171 106 1824 1 +3 666 667 1827 1 +3 847 1835 1840 1 +3 1856 1575 1895 1 +3 1166 713 1825 1 +3 1011 1281 1826 1 +3 188 97 1828 1 +3 98 226 1828 1 +3 1825 1226 1834 1 +3 67 68 1829 1 +3 1155 926 1832 1 +3 1106 1155 1831 1 +3 707 550 1830 1 +3 1654 1015 1832 1 +3 926 925 1832 1 +3 1015 845 1831 1 +3 989 1106 1831 1 +3 667 793 1827 1 +3 1142 1825 1834 1 +3 1091 1147 1834 1 +3 1044 1856 1895 1 +3 225 1287 1893 1 +3 847 791 1835 1 +3 1713 233 1836 1 +3 58 59 1836 1 +3 97 98 1828 1 +3 794 1838 1885 1 +3 68 190 1829 1 +3 1124 986 1854 1 +3 933 1131 1841 1 +3 1107 185 1855 1 +3 1268 230 1845 1 +3 1848 198 1892 1 +3 1116 1114 1833 1 +3 1249 1843 1891 1 +3 1287 1853 1893 1 +3 550 553 1830 1 +3 1143 236 1878 1 +3 845 989 1831 1 +3 925 1654 1832 1 +3 1835 1268 1840 1 +3 794 1401 1838 1 +3 1000 1058 1838 1 +3 1273 1465 1839 1 +3 1226 1091 1834 1 +3 1056 1143 1837 1 +3 1574 179 1862 1 +3 1688 933 1841 1 +3 839 932 1841 1 +3 985 1148 1842 1 +3 892 891 1842 1 +3 1597 1669 1843 1 +3 219 1815 1844 1 +3 150 189 1845 1 +3 230 149 1845 1 +3 67 1829 1859 1 +3 1243 1241 1846 1 +3 1265 197 1874 1 +3 1214 1038 1848 1 +3 1250 1245 1849 1 +3 924 923 1852 1 +3 1459 229 1860 1 +3 1195 184 1861 1 +3 791 834 1835 1 +3 233 58 1836 1 +3 1096 1154 1865 1 +3 185 77 1855 1 +3 78 225 1855 1 +3 1407 1822 1857 1 +3 1249 1243 1843 1 +3 1838 1119 1885 1 +3 1843 1102 1891 1 +3 1244 1258 1849 1 +3 1039 1309 1848 1 +3 1102 1100 1858 1 +3 1815 1408 1857 1 +3 1822 1251 1857 1 +3 1829 1215 1859 1 +3 198 66 1859 1 +3 1047 1204 1860 1 +3 992 1093 1861 1 +3 1046 1003 1862 1 +3 211 1156 1864 1 +3 1822 707 1882 1 +3 74 211 1864 1 +3 180 73 1864 1 +3 83 201 1865 1 +3 146 197 1866 1 +3 223 145 1866 1 +3 62 203 1867 1 +3 237 61 1867 1 +3 7 204 1868 1 +3 211 75 1869 1 +3 76 185 1869 1 +3 184 159 1870 1 +3 160 224 1870 1 +3 1040 1044 1872 1 +3 1041 1216 1873 1 +3 1883 1131 1887 1 +3 197 147 1874 1 +3 148 230 1874 1 +3 1144 203 1875 1 +3 1257 204 1876 1 +3 141 4 1878 1 +3 4 142 1878 1 +3 168 1 1879 1 +3 1 5 1879 1 +3 1255 234 1879 1 +3 59 2 1880 1 +3 2 60 1880 1 +3 189 1575 1856 1 +3 1093 1442 1851 1 +3 990 1047 1850 1 +3 144 223 1884 1 +3 1401 1000 1838 1 +3 88 1125 1863 1 +3 86 3 1881 1 +3 3 87 1881 1 +3 1248 1273 1839 1 +3 1357 847 1840 1 +3 1597 1843 1890 1 +3 203 63 1875 1 +3 204 8 1876 1 +3 1092 990 1850 1 +3 1442 1046 1851 1 +3 1465 1246 1886 1 +3 932 1688 1841 1 +3 891 985 1842 1 +3 1146 839 1871 1 +3 1118 1426 1885 1 +3 201 1224 1854 1 +3 1669 1102 1843 1 +3 1494 219 1844 1 +3 188 1828 1847 1 +3 149 150 1845 1 +3 193 1154 1877 1 +3 1117 1119 1847 1 +3 1287 1852 1853 1 +3 1241 1248 1846 1 +3 223 1837 1884 1 +3 1246 1830 1886 1 +3 1357 1840 1856 1 +3 1038 1039 1848 1 +3 1245 1244 1849 1 +3 1519 180 1850 1 +3 1202 209 1851 1 +3 1852 926 1853 1 +3 923 926 1852 1 +3 1856 1840 1889 1 +3 839 1841 1871 1 +3 1828 1117 1847 1 +3 1154 1097 1877 1 +3 986 1094 1854 1 +3 77 78 1855 1 +3 1871 1131 1883 1 +3 1255 6 1868 1 +3 1246 1247 1882 1 +3 1843 1243 1890 1 +3 1044 1357 1856 1 +3 1408 1407 1857 1 +3 1100 1103 1858 1 +3 1712 1288 1877 1 +3 66 67 1859 1 +3 1097 1712 1877 1 +3 1204 1045 1860 1 +3 1099 992 1861 1 +3 1131 1130 1887 1 +3 1003 1184 1862 1 +3 64 1309 1875 1 +3 9 1258 1876 1 +3 1830 1246 1882 1 +3 87 88 1863 1 +3 73 74 1864 1 +3 1143 143 1884 1 +3 82 83 1865 1 +3 145 146 1866 1 +3 61 62 1867 1 +3 6 7 1868 1 +3 1256 1255 1868 1 +3 1863 235 1881 1 +3 75 76 1869 1 +3 159 160 1870 1 +3 1130 216 1887 1 +3 8 9 1876 1 +3 63 64 1875 1 +3 1184 1040 1872 1 +3 191 1146 1883 1 +3 1045 1041 1873 1 +3 235 1863 1894 1 +3 1309 1144 1875 1 +3 1258 1257 1876 1 +3 1119 1118 1885 1 +3 1841 1131 1871 1 +3 147 148 1874 1 +3 1288 193 1877 1 +3 1836 59 1880 1 +3 189 1856 1889 1 +3 1839 1465 1886 1 +3 1872 1044 1895 1 +3 561 1597 1890 1 +3 235 86 1881 1 +3 236 141 1878 1 +3 234 168 1879 1 +3 60 237 1880 1 +3 1125 1124 1894 1 +3 1102 1858 1891 1 +3 198 1859 1892 1 +3 1855 225 1893 1 +3 707 1830 1882 1 +3 924 1852 1888 1 +3 1290 191 1883 1 +3 1287 1288 1888 1 +3 1845 189 1889 1 +3 1243 1846 1890 1 +3 143 144 1884 1 +3 1426 794 1885 1 +3 1290 1883 1887 1 +3 216 1290 1887 1 +3 1215 1214 1892 1 +3 1270 1249 1891 1 +3 1575 231 1895 1 +3 237 1836 1880 1 +3 1837 1143 1884 1 +3 1830 553 1886 1 +3 553 1839 1886 1 +3 1846 561 1890 1 +3 1853 1107 1893 1 +3 1840 1268 1889 1 +3 1146 1871 1883 1 +3 1268 1845 1889 1 +3 1852 1287 1888 1 +3 87 1863 1881 1 +3 1107 1855 1893 1 +3 1858 1270 1891 1 +3 1863 1125 1894 1 +3 1859 1215 1892 1 +3 231 1872 1895 1 diff --git a/tests/mito.lib/io/vtk_mesh_writer_2D.py b/tests/mito.lib/io/vtk_mesh_writer_2D.py index b42e61d3..346938cd 100644 --- a/tests/mito.lib/io/vtk_mesh_writer_2D.py +++ b/tests/mito.lib/io/vtk_mesh_writer_2D.py @@ -16,13 +16,13 @@ def test_SummitMeshToVtk(): # check the number of cells (tetrahedra) num_cells = mesh.GetNumberOfCells() print("Number of cells:", num_cells) - assert num_cells == 3690 + assert num_cells == 3620 # check points of the mesh points = mesh.GetPoints() num_points = points.GetNumberOfPoints() print("Number of points:", num_points) - assert num_points == 1930 + assert num_points == 1895 # remove file cleanup(filename) \ No newline at end of file From 7243d1f50397e0fd13f8b09fb1cac9b2c3499312 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 16:50:19 +0200 Subject: [PATCH 19/52] tests/mesh: move tests on volume calculation in Euclidean space to {mesh} directory --- .cmake/mito_tests_mito_lib.cmake | 4 +- .../mito.lib/manifolds/tetra_rectangle_2D.cc | 36 ---------------- .../{manifolds => mesh}/tetra_cube_3D.cc | 20 +++++---- tests/mito.lib/mesh/tetra_rectangle_2D.cc | 42 +++++++++++++++++++ 4 files changed, 56 insertions(+), 46 deletions(-) delete mode 100644 tests/mito.lib/manifolds/tetra_rectangle_2D.cc rename tests/mito.lib/{manifolds => mesh}/tetra_cube_3D.cc (64%) create mode 100644 tests/mito.lib/mesh/tetra_rectangle_2D.cc diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index e06394b9..59678063 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -107,8 +107,6 @@ mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/segment_2D.cc) mito_test_driver(tests/mito.lib/manifolds/triangle_3D.cc) -mito_test_driver(tests/mito.lib/manifolds/tetra_rectangle_2D.cc) -mito_test_driver(tests/mito.lib/manifolds/tetra_cube_3D.cc) mito_test_driver(tests/mito.lib/manifolds/volume_half_ball.cc) mito_test_driver(tests/mito.lib/manifolds/volume_disk_polar_cartesian.cc) mito_test_driver(tests/mito.lib/manifolds/volume_disk_change_coordinates.cc) @@ -133,6 +131,8 @@ mito_test_driver(tests/mito.lib/mesh/tetra_triangle_3D.cc) mito_test_driver(tests/mito.lib/mesh/tetra_tetrahedron_3D.cc) mito_test_driver(tests/mito.lib/mesh/tetra_zero_subdivisions.cc) mito_test_driver(tests/mito.lib/mesh/tetra_multiple_subdivisions.cc) +mito_test_driver(tests/mito.lib/mesh/tetra_rectangle_2D.cc) +mito_test_driver(tests/mito.lib/mesh/tetra_cube_3D.cc) mito_test_driver(tests/mito.lib/mesh/erase_element.cc) mito_test_driver(tests/mito.lib/mesh/sphere.cc) mito_test_driver(tests/mito.lib/mesh/summit_read_write.cc) diff --git a/tests/mito.lib/manifolds/tetra_rectangle_2D.cc b/tests/mito.lib/manifolds/tetra_rectangle_2D.cc deleted file mode 100644 index 69d75f87..00000000 --- a/tests/mito.lib/manifolds/tetra_rectangle_2D.cc +++ /dev/null @@ -1,36 +0,0 @@ -// -*- c++ -*- -// -// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved -// - -#include -#include -#include -#include - - -// cartesian coordinates in 2D -using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; - - -TEST(Tetra, Rectangle) -{ - // the coordinate system - auto coord_system = mito::geometry::coordinate_system(); - - // load a mesh of triangles - std::ifstream fileStream("rectangle.summit"); - auto mesh = mito::io::summit::reader>(fileStream, coord_system); - - // do tetra mesh refinements - auto tetra_mesh = mito::mesh::tetra(mesh, coord_system, 1); - - // compute the volume of the original mesh - auto volume_mesh = mito::manifolds::manifold(mesh, coord_system).volume(); - - // compute the volume of the refined mesh - auto volume_tetra_mesh = mito::manifolds::manifold(tetra_mesh, coord_system).volume(); - - // assert that the two volumes coincide - EXPECT_NEAR(volume_mesh, volume_tetra_mesh, 1.e-15); -} diff --git a/tests/mito.lib/manifolds/tetra_cube_3D.cc b/tests/mito.lib/mesh/tetra_cube_3D.cc similarity index 64% rename from tests/mito.lib/manifolds/tetra_cube_3D.cc rename to tests/mito.lib/mesh/tetra_cube_3D.cc index 2c71b904..50efc071 100644 --- a/tests/mito.lib/manifolds/tetra_cube_3D.cc +++ b/tests/mito.lib/mesh/tetra_cube_3D.cc @@ -12,6 +12,9 @@ // cartesian coordinates in 3D using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::CARTESIAN>; +// the metric space type +using metric_space_t = mito::geometry::metric_space; + TEST(Tetra, Cube) { @@ -26,15 +29,16 @@ TEST(Tetra, Cube) // do tetra mesh refinement const auto subdivisions = 2; auto tetra_mesh = mito::mesh::tetra(mesh, coord_system, subdivisions); - // assert that the refined mesh has 8 times more elements than the original one - EXPECT_EQ(tetra_mesh.nCells(), std::pow(8, subdivisions) * mesh.nCells()); - // compute the volume of the original mesh - auto volume_mesh = mito::manifolds::manifold(mesh, coord_system).volume(); + // check that the refined mesh has 8 times more elements than the original one + EXPECT_EQ(tetra_mesh.nCells(), std::pow(8, subdivisions) * mesh.nCells()); - // compute the volume of the refined mesh - auto volume_tetra_mesh = mito::manifolds::manifold(tetra_mesh, coord_system).volume(); + // loop over the mesh cells + auto volume = 0.0; + for (const auto & cell : tetra_mesh.cells()) { + volume += mito::geometry::volume(cell, coord_system, metric_space_t::w); + } - // assert that the two volumes coincide - EXPECT_NEAR(volume_mesh, volume_tetra_mesh, 1.e-13); + // check that the result of the calculation is correct + EXPECT_NEAR(volume, 1.0, 1e-13); } diff --git a/tests/mito.lib/mesh/tetra_rectangle_2D.cc b/tests/mito.lib/mesh/tetra_rectangle_2D.cc new file mode 100644 index 00000000..75b3bfaa --- /dev/null +++ b/tests/mito.lib/mesh/tetra_rectangle_2D.cc @@ -0,0 +1,42 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +#include +#include +#include + + +// cartesian coordinates in 2D +using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; + +// the metric space type +using metric_space_t = mito::geometry::metric_space; + + +TEST(Tetra, Rectangle) +{ + // the coordinate system + auto coord_system = mito::geometry::coordinate_system(); + + // load a mesh of triangles + std::ifstream fileStream("rectangle.summit"); + auto mesh = mito::io::summit::reader>(fileStream, coord_system); + + // do tetra mesh refinements + const auto subdivisions = 1; + auto tetra_mesh = mito::mesh::tetra(mesh, coord_system, subdivisions); + + // check that the refined mesh has 4 times more elements than the original one + EXPECT_EQ(tetra_mesh.nCells(), std::pow(4, subdivisions) * mesh.nCells()); + + // loop over the mesh cells + auto volume = 0.0; + for (const auto & cell : tetra_mesh.cells()) { + volume += mito::geometry::volume(cell, coord_system, metric_space_t::w); + } + + // check that the result of the calculation is correct + EXPECT_DOUBLE_EQ(volume, 0.00125); +} From 7adb4bddcece72b6f8cbc8bae1fa676a1c44b9aa Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 17:23:58 +0200 Subject: [PATCH 20/52] tests/mesh: move tests on volume of single-element submanifolds out to {geometry} directory --- .cmake/mito_tests_mito_lib.cmake | 4 +- tests/mito.lib/geometry/segment_2D.cc | 54 +++++++++++++++++++ .../{manifolds => geometry}/triangle_3D.cc | 39 ++++++++------ .../{manifolds => geometry}/triangle_3D.nb | 0 tests/mito.lib/manifolds/segment_2D.cc | 43 --------------- 5 files changed, 78 insertions(+), 62 deletions(-) create mode 100644 tests/mito.lib/geometry/segment_2D.cc rename tests/mito.lib/{manifolds => geometry}/triangle_3D.cc (63%) rename tests/mito.lib/{manifolds => geometry}/triangle_3D.nb (100%) delete mode 100644 tests/mito.lib/manifolds/segment_2D.cc diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 59678063..1f003bd4 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -26,6 +26,8 @@ mito_test_driver(tests/mito.lib/geometry/barycenter_segment_3D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_triangle_2D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_triangle_3D.cc) mito_test_driver(tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc) +mito_test_driver(tests/mito.lib/geometry/segment_2D.cc) +mito_test_driver(tests/mito.lib/geometry/triangle_3D.cc) mito_test_driver(tests/mito.lib/geometry/triangle_2D.cc) mito_test_driver(tests/mito.lib/geometry/tetrahedron_3D.cc) mito_test_driver(tests/mito.lib/geometry/cell_directors.cc) @@ -105,8 +107,6 @@ mito_test_driver(tests/mito.lib/fields/spherical_metric_field.cc) mito_test_driver(tests/mito.lib/manifolds/euclidean_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) -mito_test_driver(tests/mito.lib/manifolds/segment_2D.cc) -mito_test_driver(tests/mito.lib/manifolds/triangle_3D.cc) mito_test_driver(tests/mito.lib/manifolds/volume_half_ball.cc) mito_test_driver(tests/mito.lib/manifolds/volume_disk_polar_cartesian.cc) mito_test_driver(tests/mito.lib/manifolds/volume_disk_change_coordinates.cc) diff --git a/tests/mito.lib/geometry/segment_2D.cc b/tests/mito.lib/geometry/segment_2D.cc new file mode 100644 index 00000000..bb363d20 --- /dev/null +++ b/tests/mito.lib/geometry/segment_2D.cc @@ -0,0 +1,54 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +#include +#include + + +// cartesian coordinates in 2D +using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; + +// the metric space type +using metric_space_t = mito::geometry::metric_space; + + +TEST(Geometry, Segment2D) +{ + // the coordinate system + auto coord_system = mito::geometry::coordinate_system(); + + // construct a segment + auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); + auto node_1 = mito::geometry::node(coord_system, { 0.5, 0.5 }); + + // build segment from the nodes + auto segment = mito::geometry::segment<2>({ node_0, node_1 }); + + // the normal vector to the segment + constexpr auto v = mito::tensor::vector_t<2>{ 0.5, -0.5 }; + constexpr auto normal_vector = v / mito::tensor::norm(v); + + // get the metric volume form + constexpr auto w = metric_space_t::w; + + // get the director edges of this segment and the point where they stem from + auto [point, directors] = mito::geometry::directors(segment, coord_system); + + // strip namespace from the placeholder for forms contractions + using mito::tensor::_; + + // the 1D restriction of the 2D metric volume form to the segment at the origin of the segment + constexpr auto wS = w(point)(normal_vector, _); + + // compute the length of the segment as the contraction of the restricted volume form with the + // cell directors + auto length = wS(directors); + + // check that the length of the segment is correct + EXPECT_DOUBLE_EQ(0.5 * std::sqrt(2.0), length); +} + + +// end of file diff --git a/tests/mito.lib/manifolds/triangle_3D.cc b/tests/mito.lib/geometry/triangle_3D.cc similarity index 63% rename from tests/mito.lib/manifolds/triangle_3D.cc rename to tests/mito.lib/geometry/triangle_3D.cc index 71f3701a..b9ef7e48 100644 --- a/tests/mito.lib/manifolds/triangle_3D.cc +++ b/tests/mito.lib/geometry/triangle_3D.cc @@ -4,34 +4,26 @@ // #include -#include +#include // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::CARTESIAN>; +// the metric space type +using metric_space_t = mito::geometry::metric_space; -TEST(Manifolds, Triangle3D) + +TEST(Geometry, Triangle3D) { // the coordinate system auto coord_system = mito::geometry::coordinate_system(); - // an empty mesh of triangles - auto mesh = mito::mesh::mesh>(); - // build nodes constexpr auto x_0 = mito::geometry::cartesian::coordinates({ 0.0, 0.0, 0.0 }); constexpr auto x_1 = mito::geometry::cartesian::coordinates({ 1.0, 0.0, 1.0 }); constexpr auto x_2 = mito::geometry::cartesian::coordinates({ 1.0, 1.0, 1.0 }); - // the normal vector to the submanifold - constexpr auto cross = mito::tensor::cross(x_1 - x_0, x_2 - x_0); - constexpr auto normal_vector = cross / mito::tensor::norm(cross); - constexpr auto normal_field = mito::functions::constant(normal_vector); - - // create a submanifold on {mesh} with the appropriate normal field - auto manifold = mito::manifolds::submanifold(mesh, coord_system, normal_field); - // build nodes of a triangle (counterclockwise order) auto node_0 = mito::geometry::node(coord_system, x_0); auto node_1 = mito::geometry::node(coord_system, x_1); @@ -40,11 +32,24 @@ TEST(Manifolds, Triangle3D) // build triangle with a positive volume (reference triangle) auto triangle = mito::geometry::triangle<3>({ node_0, node_1, node_2 }); - // insert triangle in the mesh - mesh.insert(triangle); + // the normal vector to the submanifold + constexpr auto cross = mito::tensor::cross(x_1 - x_0, x_2 - x_0); + constexpr auto normal_vector = cross / mito::tensor::norm(cross); + + // get the metric volume form + constexpr auto w = metric_space_t::w; + + // get the director edges of this triangle and the point where they stem from + auto [point, directors] = mito::geometry::directors(triangle, coord_system); + + // strip namespace from the placeholder for forms contractions + using mito::tensor::_; + + // the 1D restriction of the 2D metric volume form to the segment at the origin of the segment + constexpr auto wS = w(point)(normal_vector, _, _); - // compute the area of the manifold - mito::tensor::scalar_t area = manifold.volume(); + // compute the area of the triangle + auto area = 1.0 / mito::tensor::factorial<2>() * wS(directors); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(0.5 * std::sqrt(2.0), area); diff --git a/tests/mito.lib/manifolds/triangle_3D.nb b/tests/mito.lib/geometry/triangle_3D.nb similarity index 100% rename from tests/mito.lib/manifolds/triangle_3D.nb rename to tests/mito.lib/geometry/triangle_3D.nb diff --git a/tests/mito.lib/manifolds/segment_2D.cc b/tests/mito.lib/manifolds/segment_2D.cc deleted file mode 100644 index 98993bf0..00000000 --- a/tests/mito.lib/manifolds/segment_2D.cc +++ /dev/null @@ -1,43 +0,0 @@ -// -*- c++ -*- -// -// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved -// - -#include -#include - - -// cartesian coordinates in 2D -using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; - - -TEST(Manifolds, Segment2D) -{ - // the coordinate system - auto coord_system = mito::geometry::coordinate_system(); - - // an empty mesh of segments - auto mesh = mito::mesh::mesh>(); - - // construct a segment - auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); - auto node_1 = mito::geometry::node(coord_system, { 0.5, 0.5 }); - mesh.insert({ node_0, node_1 }); - - // the normal vector to the segment - constexpr auto v = mito::tensor::vector_t<2>{ 0.5, -0.5 }; - constexpr auto normal_vector = v / mito::tensor::norm(v); - constexpr auto normal_field = mito::functions::constant(normal_vector); - - // create a submanifold on {mesh} with the appropriate normal field - auto manifold = mito::manifolds::submanifold(mesh, coord_system, normal_field); - - // compute the length of the segment submanifold - auto length = manifold.volume(); - - // check that the length of the segment is correct - EXPECT_DOUBLE_EQ(0.5 * std::sqrt(2.0), length); -} - - -// end of file From 5f3267ca78aad65cd3984bd7dcd7e7f134d453e7 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 19:06:54 +0200 Subject: [PATCH 21/52] tests/mesh: move tests on volume of meshes to {mesh} directory --- .cmake/mito_tests_mito_lib.cmake | 6 ++-- .../disk_change_coordinates.cc} | 15 ++++++---- .../disk_polar_cartesian.cc} | 15 ++++++---- .../volume_half_ball.cc => mesh/half_ball.cc} | 28 +++++++++++-------- 4 files changed, 38 insertions(+), 26 deletions(-) rename tests/mito.lib/{manifolds/volume_disk_change_coordinates.cc => mesh/disk_change_coordinates.cc} (85%) rename tests/mito.lib/{manifolds/volume_disk_polar_cartesian.cc => mesh/disk_polar_cartesian.cc} (82%) rename tests/mito.lib/{manifolds/volume_half_ball.cc => mesh/half_ball.cc} (62%) diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 1f003bd4..e668c56e 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -107,9 +107,6 @@ mito_test_driver(tests/mito.lib/fields/spherical_metric_field.cc) mito_test_driver(tests/mito.lib/manifolds/euclidean_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) -mito_test_driver(tests/mito.lib/manifolds/volume_half_ball.cc) -mito_test_driver(tests/mito.lib/manifolds/volume_disk_polar_cartesian.cc) -mito_test_driver(tests/mito.lib/manifolds/volume_disk_change_coordinates.cc) mito_test_driver(tests/mito.lib/manifolds/surface_half_sphere_cartesian.cc) mito_test_driver(tests/mito.lib/manifolds/surface_half_sphere_spherical.cc) @@ -135,6 +132,9 @@ mito_test_driver(tests/mito.lib/mesh/tetra_rectangle_2D.cc) mito_test_driver(tests/mito.lib/mesh/tetra_cube_3D.cc) mito_test_driver(tests/mito.lib/mesh/erase_element.cc) mito_test_driver(tests/mito.lib/mesh/sphere.cc) +mito_test_driver(tests/mito.lib/mesh/half_ball.cc) +mito_test_driver(tests/mito.lib/mesh/disk_polar_cartesian.cc) +mito_test_driver(tests/mito.lib/mesh/disk_change_coordinates.cc) mito_test_driver(tests/mito.lib/mesh/summit_read_write.cc) if(WITH_METIS) diff --git a/tests/mito.lib/manifolds/volume_disk_change_coordinates.cc b/tests/mito.lib/mesh/disk_change_coordinates.cc similarity index 85% rename from tests/mito.lib/manifolds/volume_disk_change_coordinates.cc rename to tests/mito.lib/mesh/disk_change_coordinates.cc index 89ad2b47..5538a9c7 100644 --- a/tests/mito.lib/manifolds/volume_disk_change_coordinates.cc +++ b/tests/mito.lib/mesh/disk_change_coordinates.cc @@ -5,7 +5,7 @@ #include #include -#include +#include // cartesian coordinates in 2D @@ -28,18 +28,21 @@ area_change_coordinates(std::string mesh_file_name) -> mito::tensor::scalar_t // perform change of coordinates from {coordT1} to {coordT2} auto coord_system_changed = mito::geometry::coordinate_system(coord_system); - // create a manifold on {mesh} with the coordinate system {coordT2} - auto manifold = mito::manifolds::manifold(mesh, coord_system_changed); + // the metric space + using metric_space_t = mito::geometry::metric_space; - // compute the area of the manifold - auto area = manifold.volume(); + // loop over the mesh cells + auto area = 0.0; + for (const auto & cell : mesh.cells()) { + area += mito::geometry::volume(cell, coord_system_changed, metric_space_t::w); + } // all done return area; } -TEST(Manifolds, Disk) +TEST(Mesh, Disk) { // compute the area in polar coordinates on a cartesian mesh auto area_polar = area_change_coordinates( diff --git a/tests/mito.lib/manifolds/volume_disk_polar_cartesian.cc b/tests/mito.lib/mesh/disk_polar_cartesian.cc similarity index 82% rename from tests/mito.lib/manifolds/volume_disk_polar_cartesian.cc rename to tests/mito.lib/mesh/disk_polar_cartesian.cc index d06dfac8..3634cf16 100644 --- a/tests/mito.lib/manifolds/volume_disk_polar_cartesian.cc +++ b/tests/mito.lib/mesh/disk_polar_cartesian.cc @@ -5,7 +5,7 @@ #include #include -#include +#include // cartesian coordinates in 2D @@ -25,18 +25,21 @@ area(std::string mesh_file_name) -> mito::tensor::scalar_t auto filestream = std::ifstream(mesh_file_name); auto mesh = mito::io::summit::reader>(filestream, coord_system); - // create a manifold on {mesh} - auto manifold = mito::manifolds::manifold(mesh, coord_system); + // the metric space + using metric_space_t = mito::geometry::metric_space; - // compute the area of the manifold - auto area = manifold.volume(); + // loop over the mesh cells + auto area = 0.0; + for (const auto & cell : mesh.cells()) { + area += mito::geometry::volume(cell, coord_system, metric_space_t::w); + } // all done return area; } -TEST(Manifolds, Disk) +TEST(Mesh, Disk) { // compute the area of the disk parametrized in polar coordinates auto area_polar = area("disk_polar.summit"); diff --git a/tests/mito.lib/manifolds/volume_half_ball.cc b/tests/mito.lib/mesh/half_ball.cc similarity index 62% rename from tests/mito.lib/manifolds/volume_half_ball.cc rename to tests/mito.lib/mesh/half_ball.cc index 45725649..11cd49aa 100644 --- a/tests/mito.lib/manifolds/volume_half_ball.cc +++ b/tests/mito.lib/mesh/half_ball.cc @@ -5,7 +5,7 @@ #include #include -#include +#include // cartesian coordinates in 3D @@ -14,7 +14,7 @@ using cartesian_coordinates_t = mito::geometry::coordinates_t<3, mito::geometry: using spherical_coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::SPHERICAL>; -TEST(Manifolds, Ball) +TEST(Mesh, HalfBall) { // the coordinate system auto coord_system = mito::geometry::coordinate_system(); @@ -24,22 +24,28 @@ TEST(Manifolds, Ball) auto mesh = mito::io::summit::reader>(fileStream, coord_system); - // create a manifold on {mesh} - auto manifold_cartesian = mito::manifolds::manifold(mesh, coord_system); + // the metric space + using cartesian_metric_space_t = mito::geometry::metric_space; - // compute the area of the manifold - auto volume_cartesian = manifold_cartesian.volume(); + // loop over the mesh cells + auto volume_cartesian = 0.0; + for (const auto & cell : mesh.cells()) { + volume_cartesian += mito::geometry::volume(cell, coord_system, cartesian_metric_space_t::w); + } // perform change of coordinates from cartesian to spherical auto spherical_coord_system = mito::geometry::coordinate_system(coord_system); - // create a manifold on {mesh} - auto manifold_spherical = mito::manifolds::manifold(mesh, spherical_coord_system); - - // compute the area of the manifold - auto volume_spherical = manifold_spherical.volume(); + // the metric space + using spherical_metric_space_t = mito::geometry::metric_space; + // loop over the mesh cells + auto volume_spherical = 0.0; + for (const auto & cell : mesh.cells()) { + volume_spherical += + mito::geometry::volume(cell, spherical_coord_system, spherical_metric_space_t::w); + } // expect the same result in cartesian and spherical coordinates EXPECT_DOUBLE_EQ(volume_cartesian, volume_spherical); From 6afd02eb955ea4cb13dd0204d05996df5728d022 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 4 May 2026 19:47:18 +0200 Subject: [PATCH 22/52] tests/manifolds: temporarily remove tests of half sphere These tests will be re-enabled once higher order parametrizations are implemented. --- .cmake/mito_tests_mito_lib.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index e668c56e..6e89fb09 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -107,8 +107,8 @@ mito_test_driver(tests/mito.lib/fields/spherical_metric_field.cc) mito_test_driver(tests/mito.lib/manifolds/euclidean_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) -mito_test_driver(tests/mito.lib/manifolds/surface_half_sphere_cartesian.cc) -mito_test_driver(tests/mito.lib/manifolds/surface_half_sphere_spherical.cc) +# mito_test_driver(tests/mito.lib/manifolds/surface_half_sphere_cartesian.cc) +# mito_test_driver(tests/mito.lib/manifolds/surface_half_sphere_spherical.cc) # materials mito_test_driver(tests/mito.lib/materials/gent.cc) From e735d16746cfd96b2a93d9def87280b3ecba8c0e Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Tue, 5 May 2026 06:37:01 +0200 Subject: [PATCH 23/52] geometry: improve comment in {GeometricSimplex} --- lib/mito/geometry/GeometricSimplex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mito/geometry/GeometricSimplex.h b/lib/mito/geometry/GeometricSimplex.h index e5bd3aa8..942b19ae 100644 --- a/lib/mito/geometry/GeometricSimplex.h +++ b/lib/mito/geometry/GeometricSimplex.h @@ -160,7 +160,7 @@ namespace mito::geometry { private: // the simplex nodes nodes_type _nodes; - // the shared pointer to the footprint + // the underlying oriented simplex footprint simplex_type _simplex; }; From cf059bda5a3dee0c59fe16950e795492f91cf097 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Sat, 30 May 2026 11:25:29 +0200 Subject: [PATCH 24/52] fem: redesign blocks and weakform integration The weakform stores a single left hand side block and a single right hand side block, as opposed to a collection of them. This requires implementing an algebra of blocks, so we can mix and match them before handing them ot the weakform. Also, this means that blocks do not need to derive from a common parent class any more. --- benchmarks/mito.lib/pdes/poisson.cc | 4 +- lib/mito/fem/DiscreteSystem.h | 4 +- lib/mito/fem/Weakform.h | 79 +++++++-------------------- lib/mito/fem/api.h | 17 +++--- lib/mito/fem/blocks/AssemblyBlock.h | 50 ----------------- lib/mito/fem/blocks/GradGradBlock.h | 4 +- lib/mito/fem/blocks/L2NormBlock.h | 4 +- lib/mito/fem/blocks/MassBlock.h | 4 +- lib/mito/fem/blocks/SourceTermBlock.h | 4 +- lib/mito/fem/blocks/api.h | 4 -- lib/mito/fem/blocks/forward.h | 4 -- lib/mito/fem/blocks/public.h | 1 - lib/mito/fem/factories.h | 9 +-- lib/mito/fem/forward.h | 9 ++- 14 files changed, 53 insertions(+), 144 deletions(-) delete mode 100644 lib/mito/fem/blocks/AssemblyBlock.h diff --git a/benchmarks/mito.lib/pdes/poisson.cc b/benchmarks/mito.lib/pdes/poisson.cc index 69845671..465549c3 100644 --- a/benchmarks/mito.lib/pdes/poisson.cc +++ b/benchmarks/mito.lib/pdes/poisson.cc @@ -84,9 +84,7 @@ main() mito::fem::blocks::source_term_block(f); // create the weak form and populate it with the blocks - auto weakform = mito::fem::weakform(); - weakform.add_block(fem_lhs_block); - weakform.add_block(fem_rhs_block); + auto weakform = mito::fem::weakform(fem_lhs_block, fem_rhs_block); // the discrete system auto discrete_system = diff --git a/lib/mito/fem/DiscreteSystem.h b/lib/mito/fem/DiscreteSystem.h index 57709a9a..852671c6 100644 --- a/lib/mito/fem/DiscreteSystem.h +++ b/lib/mito/fem/DiscreteSystem.h @@ -13,7 +13,7 @@ namespace mito::fem { // extend the design to the case that there are multiple finite element discretizations that // end up on the same linear system. - template + template class DiscreteSystem { private: @@ -22,7 +22,7 @@ namespace mito::fem { // the element type using element_type = typename function_space_type::element_type; // the weakform type - using weakform_type = weakform_t; + using weakform_type = weakformT; // the linear system type using linear_system_type = linearSystemT; // the label type diff --git a/lib/mito/fem/Weakform.h b/lib/mito/fem/Weakform.h index f599b817..d29bc5c3 100644 --- a/lib/mito/fem/Weakform.h +++ b/lib/mito/fem/Weakform.h @@ -9,33 +9,30 @@ namespace mito::fem { - // TODO: concept for element type - template + template + requires compatible_assembly_blocks_c class Weakform { private: + // the type of the left hand side assembly block + using lhs_block_type = lhsBlockT; + // the type of the right hand side assembly block + using rhs_block_type = rhsBlockT; // the element type - using element_type = elementT; + using element_type = typename lhsBlockT::element_type; // the number of nodes per element static constexpr int n_element_nodes = element_type::n_nodes; // the elementary matrix type using elementary_matrix_type = tensor::matrix_t; // the elementary vector type using elementary_vector_type = tensor::vector_t; - // the type of the lhs assembly block - using lhs_assembly_block_type = - blocks::assembly_block_t; - // a collection of lhs assembly blocks - using lhs_assembly_blocks_type = std::vector; - // the type of the rhs assembly block - using rhs_assembly_block_type = - blocks::assembly_block_t; - // a collection of rhs assembly blocks - using rhs_assembly_blocks_type = std::vector; public: - // default constructor - constexpr Weakform() = default; + // constructor + constexpr Weakform(const lhsBlockT & lhs_block, const rhsBlockT & rhs_block) : + _lhs_block(lhs_block), + _rhs_block(rhs_block) + {} // destructor constexpr ~Weakform() = default; @@ -53,60 +50,26 @@ namespace mito::fem { constexpr Weakform & operator=(Weakform &&) noexcept = delete; public: - // add a left hand side assembly block - constexpr auto add_block(const lhs_assembly_block_type & block) -> void - { - // add the block to the collection - _lhs_assembly_blocks.push_back(&block); - - // all done - return; - } - - // add a right hand side assembly block - constexpr auto add_block(const rhs_assembly_block_type & block) -> void - { - // add the block to the collection - _rhs_assembly_blocks.push_back(&block); - - // all done - return; - } - // compute the elementary contributions to matrix and right-hand side from the weakform constexpr auto compute_blocks(const element_type & element) const -> std::pair { - // instantiate the elementary matrix - auto elementary_matrix = elementary_matrix_type(); - // loop on the left hand side assembly blocks - for (const auto & block : _lhs_assembly_blocks) { - // compute the elementary contribution of the block - auto matrix_block = block->compute(element); - // add the elementary contribution to the elementary matrix - elementary_matrix += matrix_block; - } - - // instantiate the elementary vector - auto elementary_vector = elementary_vector_type(); - // loop on the right hand side assembly blocks - for (const auto & block : _rhs_assembly_blocks) { - // compute the elementary contribution of the block - auto vector_block = block->compute(element); - // add the elementary contribution to the elementary vector - elementary_vector += vector_block; - } + // the elementary matrix + auto elementary_matrix = _lhs_block.compute(element); + + // the elementary vector + auto elementary_vector = _rhs_block.compute(element); // return the elementary matrix and vector return { elementary_matrix, elementary_vector }; } private: - // the collection of left hand side assembly blocks - lhs_assembly_blocks_type _lhs_assembly_blocks; + // the left hand side assembly block + lhs_block_type _lhs_block; - // the collection of right hand side assembly blocks - rhs_assembly_blocks_type _rhs_assembly_blocks; + // the right hand side assembly block + rhs_block_type _rhs_block; }; } // namespace mito diff --git a/lib/mito/fem/api.h b/lib/mito/fem/api.h index 0d5e17a8..f07e255d 100644 --- a/lib/mito/fem/api.h +++ b/lib/mito/fem/api.h @@ -25,21 +25,22 @@ namespace mito::fem { constexpr auto function_space(const manifoldT & manifold, const constraintsT & constraints); // weakform alias - template - using weakform_t = Weakform; + template + using weakform_t = Weakform; // weakform factory - template - constexpr auto weakform(); + template + constexpr auto weakform(const lhsBlockT & lhs_block, const rhsBlockT & rhs_block); // discrete system alias - template - using discrete_system_t = DiscreteSystem; + template + using discrete_system_t = DiscreteSystem; // discrete system factory - template + template constexpr auto discrete_system( - const functionSpaceT & function_space, const std::string & label); + const functionSpaceT & function_space, const weakformT & weakform, + const std::string & label); } diff --git a/lib/mito/fem/blocks/AssemblyBlock.h b/lib/mito/fem/blocks/AssemblyBlock.h deleted file mode 100644 index 358d12d4..00000000 --- a/lib/mito/fem/blocks/AssemblyBlock.h +++ /dev/null @@ -1,50 +0,0 @@ -// -*- c++ -*- -// -// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved -// - -// code guard -#pragma once - - -namespace mito::fem::blocks { - - // TODO: implement sum and subtraction operators for the blocks (only for blocks that result in - // the same elementary type) - - template - class AssemblyBlock { - - public: - // my template parameters - using element_type = elementT; - using elementary_block_type = blockT; - - public: - // the constructor - constexpr AssemblyBlock() = default; - - // destructor - constexpr ~AssemblyBlock() = default; - - // delete move constructor - constexpr AssemblyBlock(AssemblyBlock &&) noexcept = delete; - - // delete copy constructor - constexpr AssemblyBlock(const AssemblyBlock &) = delete; - - // delete assignment operator - constexpr AssemblyBlock & operator=(const AssemblyBlock &) = delete; - - // delete move assignment operator - constexpr AssemblyBlock & operator=(AssemblyBlock &&) noexcept = delete; - - public: - // compute the elementary contribution of this block - virtual auto compute(const element_type & element) const -> elementary_block_type = 0; - }; - -} // namespace mito - - -// end of file diff --git a/lib/mito/fem/blocks/GradGradBlock.h b/lib/mito/fem/blocks/GradGradBlock.h index 65d8eb2d..7f34d007 100644 --- a/lib/mito/fem/blocks/GradGradBlock.h +++ b/lib/mito/fem/blocks/GradGradBlock.h @@ -10,7 +10,7 @@ namespace mito::fem::blocks { template - class GradGradBlock : public AssemblyBlock> { + class GradGradBlock { public: // my template parameters @@ -24,7 +24,7 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type override + auto compute(const element_type & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 0d0a00f4..0a9f2faa 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -13,7 +13,7 @@ namespace mito::fem::blocks { // require that {functionT} is a function in barycentric coordinates requires(std::is_same_v< typename functionT::input_type, typename quadratureRuleT::quadrature_point_type>) - class L2NormBlock : public AssemblyBlock { + class L2NormBlock { public: // my template parameters @@ -34,7 +34,7 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type override + auto compute(const element_type & element) const -> elementary_block_type { // the number of quadrature points per element constexpr int n_quads = quadrature_rule_type::npoints; diff --git a/lib/mito/fem/blocks/MassBlock.h b/lib/mito/fem/blocks/MassBlock.h index d8300760..1c11a05e 100644 --- a/lib/mito/fem/blocks/MassBlock.h +++ b/lib/mito/fem/blocks/MassBlock.h @@ -10,7 +10,7 @@ namespace mito::fem::blocks { template - class MassBlock : public AssemblyBlock> { + class MassBlock { public: // my template parameters @@ -24,7 +24,7 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type override + auto compute(const element_type & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; diff --git a/lib/mito/fem/blocks/SourceTermBlock.h b/lib/mito/fem/blocks/SourceTermBlock.h index ed9ecb8e..fe7df0f0 100644 --- a/lib/mito/fem/blocks/SourceTermBlock.h +++ b/lib/mito/fem/blocks/SourceTermBlock.h @@ -12,7 +12,7 @@ namespace mito::fem::blocks { // TOFIX: the source does not need to be necessarily a scalar field, it can be some other field // see if we can use {field_c} instead of {scalar_field_c} template - class SourceTermBlock : public AssemblyBlock> { + class SourceTermBlock { public: // my template parameters @@ -33,7 +33,7 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type override + auto compute(const element_type & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; diff --git a/lib/mito/fem/blocks/api.h b/lib/mito/fem/blocks/api.h index 67393844..80aa5d1f 100644 --- a/lib/mito/fem/blocks/api.h +++ b/lib/mito/fem/blocks/api.h @@ -9,10 +9,6 @@ namespace mito::fem::blocks { - // assembly block - template - using assembly_block_t = AssemblyBlock; - // grad grad block template using grad_grad_block_t = GradGradBlock; diff --git a/lib/mito/fem/blocks/forward.h b/lib/mito/fem/blocks/forward.h index 39be2440..e0cae9d2 100644 --- a/lib/mito/fem/blocks/forward.h +++ b/lib/mito/fem/blocks/forward.h @@ -9,10 +9,6 @@ namespace mito::fem::blocks { - // assembly block - template - class AssemblyBlock; - // grad grad block template class GradGradBlock; diff --git a/lib/mito/fem/blocks/public.h b/lib/mito/fem/blocks/public.h index 20b5b6e9..0795215b 100644 --- a/lib/mito/fem/blocks/public.h +++ b/lib/mito/fem/blocks/public.h @@ -17,7 +17,6 @@ #include "api.h" // classes implementation -#include "AssemblyBlock.h" #include "GradGradBlock.h" #include "MassBlock.h" #include "SourceTermBlock.h" diff --git a/lib/mito/fem/factories.h b/lib/mito/fem/factories.h index edaf89b6..ff9e64b4 100644 --- a/lib/mito/fem/factories.h +++ b/lib/mito/fem/factories.h @@ -25,10 +25,10 @@ namespace mito::fem { } // weakform factory - template - constexpr auto weakform() + template + constexpr auto weakform(const lhsBlockT & lhs_block, const rhsBlockT & rhs_block) { - return weakform_t(); + return weakform_t(lhs_block, rhs_block); } // discrete system factory @@ -37,7 +37,8 @@ namespace mito::fem { const std::string & label, const functionSpaceT & function_space, const weakformT & weakform) { - return discrete_system_t(label, function_space, weakform); + return discrete_system_t( + label, function_space, weakform); } } diff --git a/lib/mito/fem/forward.h b/lib/mito/fem/forward.h index 9f312bf6..d80d11eb 100644 --- a/lib/mito/fem/forward.h +++ b/lib/mito/fem/forward.h @@ -22,12 +22,17 @@ namespace mito::fem { }(c); }; + template + concept compatible_assembly_blocks_c = + std::is_same_v; + // weakform alias - template + template + requires compatible_assembly_blocks_c class Weakform; // class discrete system - template + template class DiscreteSystem; // class domain field From 9534f28e77741e3787596ff2f34cd0eb255f043e Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Tue, 5 May 2026 10:44:56 +0200 Subject: [PATCH 25/52] manifolds: major redesign of class {Manifold} A manifold is now equipped with an {Atlas}, which provides the parametrization of elements in the manifold. The {parametrization} method has hence been removed from {GeometricSimplex}. Also, now manifolds are able to expose fully-fledged parametrized elements with attached their own metric volume form. The {Integrator} class is now fully integrated with the differential geometry layer, so it does no longer feel that things are done twice (e.g. element parametrization). The Poisson benchmark has been temporarily commented out as the function space and blocks still need to adjust to the new design. --- .cmake/mito_benchmarks_mito_lib.cmake | 2 +- .cmake/mito_tests_mito_lib.cmake | 1 + lib/mito/fem/elements/IsoparametricTriangle.h | 3 - lib/mito/geometry/GeometricSimplex.h | 24 +----- lib/mito/manifolds/Atlas.h | 83 +++++++++++++++++++ lib/mito/manifolds/Manifold.h | 67 ++++++--------- lib/mito/manifolds/ManifoldElementsView.h | 73 ++++++++++++++++ lib/mito/manifolds/ParametrizedElement.h | 77 +++++++++++++++++ lib/mito/manifolds/api.h | 22 +++++ lib/mito/manifolds/factories.h | 19 +++++ lib/mito/manifolds/forward.h | 13 +++ lib/mito/manifolds/public.h | 3 + lib/mito/quadrature/Integrator.h | 54 +++++------- .../manifolds/manifold_elements_view.cc | 62 ++++++++++++++ 14 files changed, 406 insertions(+), 97 deletions(-) create mode 100644 lib/mito/manifolds/Atlas.h create mode 100644 lib/mito/manifolds/ManifoldElementsView.h create mode 100644 lib/mito/manifolds/ParametrizedElement.h create mode 100644 tests/mito.lib/manifolds/manifold_elements_view.cc diff --git a/.cmake/mito_benchmarks_mito_lib.cmake b/.cmake/mito_benchmarks_mito_lib.cmake index 19c3b988..1b826ab4 100644 --- a/.cmake/mito_benchmarks_mito_lib.cmake +++ b/.cmake/mito_benchmarks_mito_lib.cmake @@ -22,7 +22,7 @@ mito_benchmark_driver(benchmarks/mito.lib/operators/laplacian.cc) if(WITH_PETSC) # poisson boundary value problem - mito_benchmark_driver(benchmarks/mito.lib/pdes/poisson.cc) + # mito_benchmark_driver(benchmarks/mito.lib/pdes/poisson.cc) endif() # end of file diff --git a/.cmake/mito_tests_mito_lib.cmake b/.cmake/mito_tests_mito_lib.cmake index 6e89fb09..0c813032 100644 --- a/.cmake/mito_tests_mito_lib.cmake +++ b/.cmake/mito_tests_mito_lib.cmake @@ -104,6 +104,7 @@ mito_test_driver(tests/mito.lib/fields/polar_metric_field.cc) mito_test_driver(tests/mito.lib/fields/spherical_metric_field.cc) # manifolds +mito_test_driver(tests/mito.lib/manifolds/manifold_elements_view.cc) mito_test_driver(tests/mito.lib/manifolds/euclidean_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/polar_gradient.cc) mito_test_driver(tests/mito.lib/manifolds/spherical_gradient.cc) diff --git a/lib/mito/fem/elements/IsoparametricTriangle.h b/lib/mito/fem/elements/IsoparametricTriangle.h index 5426f2ad..fe1652a9 100644 --- a/lib/mito/fem/elements/IsoparametricTriangle.h +++ b/lib/mito/fem/elements/IsoparametricTriangle.h @@ -60,9 +60,6 @@ namespace mito::fem { // get the geometric simplex constexpr auto cell() const noexcept -> const cell_type & { return _cell; } - // get the mapping from parametric coordinates to physical coordinates - constexpr auto parametrization() const { return _cell.parametrization(_coord_system); } - protected: // a const reference to the geometric simplex const cell_type & _cell; diff --git a/lib/mito/geometry/GeometricSimplex.h b/lib/mito/geometry/GeometricSimplex.h index 942b19ae..18aecd4a 100644 --- a/lib/mito/geometry/GeometricSimplex.h +++ b/lib/mito/geometry/GeometricSimplex.h @@ -134,27 +134,11 @@ namespace mito::geometry { // return the composition of this simplex in terms of its vertices constexpr auto nodes() const -> const nodes_type & { return _nodes; } - // get the parametrization of the geometric simplex in physical space - template - constexpr auto parametrization(const coordinateSystemT & coordinate_system) const -> auto + // the I-th parametric coordinate + template + constexpr auto xi() const -> auto { - // helper to assemble the parametrization on this simplex - constexpr auto _assemble = []( - const auto & nodes, const auto & coordinate_system, - tensor::integer_sequence) { - // get the origin of the coordinate system - constexpr auto origin = coordinate_system.origin(); - - // assemble the parametrization as x0 * xi<0> + ... - // where {xi} are the barycentric coordinates on the reference simplex and the - // {xa} are the position vectors of the nodes - return ( - ((reference_simplex_type::template xi - * (coordinate_system.coordinates(nodes[a]->point()) - origin))) - + ...); - }; - return _assemble( - _nodes, coordinate_system, tensor::make_integer_sequence{}); + return reference_simplex_type::template xi; } private: diff --git a/lib/mito/manifolds/Atlas.h b/lib/mito/manifolds/Atlas.h new file mode 100644 index 00000000..3c008d0b --- /dev/null +++ b/lib/mito/manifolds/Atlas.h @@ -0,0 +1,83 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::manifolds { + + template + // compatible dimension of physical embedding of cell and type of coordinates + requires(cellT::dim == coordsT::dim) + class Atlas { + public: + // the cell type + using cell_type = cellT; + // typedef for a set of coordinates + using coordinates_type = coordsT; + // typedef for a coordinates system + using coordinate_system_type = geometry::coordinate_system_t; + + public: + // the constructor + constexpr Atlas(const coordinate_system_type & coord_system) : _coord_system(coord_system) + {} + + // destructor + constexpr ~Atlas() = default; + + // delete default constructor + constexpr Atlas() noexcept = delete; + + // default move constructor + constexpr Atlas(Atlas &&) noexcept = default; + + // delete copy constructor + constexpr Atlas(const Atlas &) = delete; + + // delete assignment operator + constexpr Atlas & operator=(const Atlas &) = delete; + + // default move assignment operator + constexpr Atlas & operator=(Atlas &&) noexcept = default; + + public: + // accessor to the coordinate system + constexpr auto coordinate_system() const -> const coordinate_system_type & + { + return _coord_system; + } + + // return the parametrization of a cell in physical space + constexpr auto parametrization(const cell_type & cell) const -> auto + { + // helper to assemble the parametrization on this cell + constexpr auto _assemble = []( + const auto & cell, const auto & coord_system, + tensor::integer_sequence) { + // get the origin of the coordinate system + auto origin = coord_system.origin(); + // assemble the parametrization as x0 * xi<0> + ... + // where {xi} are the barycentric coordinates on the reference simplex and the + // {xa} are the position vectors of the nodes + return ( + ((cell.template xi() + * (coord_system.coordinates(cell.nodes()[a]->point()) - origin))) + + ...); + }; + return _assemble( + cell, _coord_system, tensor::make_integer_sequence{}); + } + + private: + // a const reference to the coordinate system + const coordinate_system_type & _coord_system; + }; + +} // namespace mito + + +// end of file diff --git a/lib/mito/manifolds/Manifold.h b/lib/mito/manifolds/Manifold.h index 3fb1b0ae..3d032bc5 100644 --- a/lib/mito/manifolds/Manifold.h +++ b/lib/mito/manifolds/Manifold.h @@ -24,23 +24,29 @@ namespace mito::manifolds { static constexpr int N = cellT::order; public: + // my type + using manifold_type = Manifold; + // my element view type + using manifold_elements_view_type = manifold_elements_view_t; // typedef for cell type using cell_type = cellT; + // typedef for a set of coordinates + using coordinates_type = coordsT; // typedef for mesh type using mesh_type = mesh::mesh_t; // typedef for the cell type using cells_type = mesh_type::cells_type; - // typedef for a set of coordinates - using coordinates_type = coordsT; + // typedef for the atlas + using atlas_type = atlas_t; // typedef for a coordinates system - using coordinate_system_type = geometry::coordinate_system_t; + using coordinate_system_type = atlas_type::coordinate_system_type; public: constexpr Manifold( const mesh_type & mesh, const coordinate_system_type & coordinate_system, volume_form_type volume_form) : _mesh(mesh), - _coordinate_system(coordinate_system), + _atlas(coordinate_system), _volume_form(volume_form) {} @@ -67,13 +73,8 @@ namespace mito::manifolds { // accessor for the mesh constexpr auto mesh() const noexcept -> const mesh_type & { return _mesh; } - // accessor for the coordinate system - constexpr auto coordinate_system() const noexcept -> const coordinate_system_type & - { - return _coordinate_system; - } - - constexpr auto elements() const noexcept -> const cells_type & { return _mesh.cells(); } + // return an iterable view of the manifold elements + constexpr auto elements() const noexcept { return manifold_elements_view_type{ *this }; } constexpr auto nElements() const noexcept -> int { return std::size(_mesh.cells()); } @@ -99,46 +100,28 @@ namespace mito::manifolds { } } - constexpr auto volume() const -> tensor::scalar_t - { - tensor::scalar_t result = 0.0; - for (const auto & cell : _mesh.cells()) { - result += volume(cell); - } - // all done - return result; - } - - // computes the volume of {cell} - constexpr auto volume(const cell_type & cell) const -> tensor::scalar_t - { - // all done - return _volume(cell, tensor::make_integer_sequence{}); - } - private: - // computes the volume of a cell - template - constexpr auto _volume(const cell_type & cell, tensor::integer_sequence) const - -> tensor::scalar_t - requires(sizeof...(J) == N) + // return the manifold element associated to a cell + constexpr auto element(const cell_type & cell) const { - // get the director edges of this cell and the point where they stem from - auto [point, directors] = mito::geometry::directors(cell, _coordinate_system); - // compute the volume of a N-order simplicial cell as (1/N!) times the volume form - // contracted with the cell directors - auto volume = 1.0 / mito::tensor::factorial() * _volume_form(point)(directors[J]...); - // all done - return volume; + // get the parametrization of this cell + auto phi = _atlas.parametrization(cell); + // get the metric volume form of this cell + auto w = _volume_form; + // assemble and return the manifold element + return parametrized_element(cell, phi, w); } private: // the underlying mesh const mesh_type & _mesh; - // the coordinate system - const coordinate_system_type & _coordinate_system; + // the atlas + atlas_type _atlas; // the volume form volume_form_type _volume_form; + + // frienship with the manifold elements view + friend manifold_elements_view_type; }; } // namespace mito diff --git a/lib/mito/manifolds/ManifoldElementsView.h b/lib/mito/manifolds/ManifoldElementsView.h new file mode 100644 index 00000000..8b0a0335 --- /dev/null +++ b/lib/mito/manifolds/ManifoldElementsView.h @@ -0,0 +1,73 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::manifolds { + + template + class ManifoldElementsView { + + private: + // my template parameter + using manifold_type = manifoldT; + // the type of the cells of the underlying mesh + using mesh_cells_type = typename manifold_type::mesh_type::cells_type; + // the type of the iterator over the cells of the underlying mesh + using mesh_cells_iterator_type = decltype(std::begin(std::declval())); + + public: + // constructor from a manifold + constexpr ManifoldElementsView(const manifoldT & manifold) : _manifold(manifold) {} + + // iterator class for the manifold elements view + class iterator { + public: + constexpr iterator(const manifold_type & manifold, mesh_cells_iterator_type cell_iter) : + _manifold(manifold), + _cell_iterator(cell_iter) + {} + + constexpr auto operator*() const { return _manifold.element(*_cell_iterator); } + + constexpr iterator & operator++() + { + ++_cell_iterator; + return *this; + } + + constexpr bool operator==(const iterator & other) const + { + return _cell_iterator == other._cell_iterator; + } + + constexpr bool operator!=(const iterator & other) const { return !(*this == other); } + + private: + const manifold_type & _manifold; + mesh_cells_iterator_type _cell_iterator; + }; + + constexpr auto begin() const + { + return iterator{ _manifold, std::begin(_manifold.mesh().cells()) }; + } + + constexpr auto end() const + { + return iterator{ _manifold, std::end(_manifold.mesh().cells()) }; + } + + private: + // the manifold whose elements I am viewing + const manifold_type & _manifold; + }; + +} // namespace mito + + +// end of file diff --git a/lib/mito/manifolds/ParametrizedElement.h b/lib/mito/manifolds/ParametrizedElement.h new file mode 100644 index 00000000..6fe2df83 --- /dev/null +++ b/lib/mito/manifolds/ParametrizedElement.h @@ -0,0 +1,77 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::manifolds { + + // Class {ParametrizedElement} represents a cell equipped with a parametrization in physical + // space and a metric volume form. + template + class ParametrizedElement { + public: + // the cell type + using cell_type = cellT; + // the parametrization type + using parametrization_type = parametrizationT; + // the metric volume form type + using metric_volume_form_type = metricVolumeFormT; + + public: + // the constructor + constexpr ParametrizedElement( + const cell_type & cell, const parametrization_type & parametrization, + const metric_volume_form_type & metric_volume_form) : + _cell(cell), + _parametrization(parametrization), + _metric_volume_form(metric_volume_form) + {} + + // destructor + constexpr ~ParametrizedElement() = default; + + // delete default constructor + constexpr ParametrizedElement() noexcept = delete; + + // default move constructor + constexpr ParametrizedElement(ParametrizedElement &&) noexcept = default; + + // delete copy constructor + constexpr ParametrizedElement(const ParametrizedElement &) = delete; + + // delete assignment operator + constexpr ParametrizedElement & operator=(const ParametrizedElement &) = delete; + + // default move assignment operator + constexpr ParametrizedElement & operator=(ParametrizedElement &&) noexcept = default; + + public: + // return the underlying cell + constexpr auto cell() const -> cell_type { return _cell; } + + // return the parametrization of this element in physical space + constexpr auto parametrization() const -> parametrization_type { return _parametrization; } + + // return the metric volume form of this element + constexpr auto metric_volume_form() const -> metric_volume_form_type + { + return _metric_volume_form; + } + + private: + // the underlying cell + cell_type _cell; + // the parametrization of the manifold element + parametrization_type _parametrization; + // the metric volume form of the manifold element + metric_volume_form_type _metric_volume_form; + }; + +} // namespace mito + + +// end of file diff --git a/lib/mito/manifolds/api.h b/lib/mito/manifolds/api.h index a899f221..012ec7a9 100644 --- a/lib/mito/manifolds/api.h +++ b/lib/mito/manifolds/api.h @@ -9,6 +9,28 @@ namespace mito::manifolds { + // atlas alias + template + using atlas_t = Atlas; + + // factory of atlases from a coordinate system + template + constexpr auto atlas(const geometry::coordinate_system_t &); + + // manifold element alias + template + using parametrized_element_t = ParametrizedElement; + + // factory of parametrized elements from a cell, a parametrization, and a metric volume form + template + constexpr auto parametrized_element( + const cellT & cell, const parametrizationT & parametrization, + const metricVolumeFormT & metric_volume_form); + + // manifold elements view alias + template + using manifold_elements_view_t = ManifoldElementsView; + // manifold alias template using manifold_t = Manifold; diff --git a/lib/mito/manifolds/factories.h b/lib/mito/manifolds/factories.h index efbd08f4..f89106a8 100644 --- a/lib/mito/manifolds/factories.h +++ b/lib/mito/manifolds/factories.h @@ -9,6 +9,25 @@ namespace mito::manifolds { + // factory of atlases from a coordinate system + template + // compatible dimension of physical embedding of cell and type of coordinates + requires(cellT::dim == coordsT::dim) + constexpr auto atlas(const geometry::coordinate_system_t & coordinate_system) + { + return atlas_t(coordinate_system); + } + + // factory of manifold elements from a cell, a parametrization, and a metric volume form + template + constexpr auto parametrized_element( + const cellT & cell, const parametrizationT & parametrization, + const metricVolumeFormT & metric_volume_form) + { + return parametrized_element_t( + cell, parametrization, metric_volume_form); + } + // factory manifold template constexpr auto manifold( diff --git a/lib/mito/manifolds/forward.h b/lib/mito/manifolds/forward.h index e2811808..382d5d5f 100644 --- a/lib/mito/manifolds/forward.h +++ b/lib/mito/manifolds/forward.h @@ -9,6 +9,19 @@ namespace mito::manifolds { + // class atlas + template + requires(cellT::dim == coordsT::dim) + class Atlas; + + // class parametrized element + template + class ParametrizedElement; + + // class manifold elements view + template + class ManifoldElementsView; + // class manifold template requires(cellT::dim == coordsT::dim) diff --git a/lib/mito/manifolds/public.h b/lib/mito/manifolds/public.h index 3604ef15..78fa171a 100644 --- a/lib/mito/manifolds/public.h +++ b/lib/mito/manifolds/public.h @@ -17,6 +17,9 @@ #include "api.h" // classes implementation +#include "Atlas.h" +#include "ParametrizedElement.h" +#include "ManifoldElementsView.h" #include "Manifold.h" // factories implementation diff --git a/lib/mito/quadrature/Integrator.h b/lib/mito/quadrature/Integrator.h index 89124595..fec2db65 100644 --- a/lib/mito/quadrature/Integrator.h +++ b/lib/mito/quadrature/Integrator.h @@ -17,7 +17,7 @@ namespace mito::quadrature { public: // publish my template parameters using manifold_type = manifoldT; - using cell_type = typename manifold_type::cell_type::simplex_type; + using cell_type = typename manifold_type::cell_type; using reference_cell_type = typename manifold_type::cell_type::reference_simplex_type; using coordinates_type = typename manifold_type::coordinates_type; @@ -28,54 +28,46 @@ namespace mito::quadrature { static constexpr auto _quadratureRule = quadrature_rule_type(); // the number of quadrature points static constexpr int Q = quadrature_rule_type::npoints; - // the quadrature field type to store the coordinates of the quadrature points - using quadrature_field_type = discrete::quadrature_field_t; - - private: - template - auto _computeQuadPointCoordinates(tensor::integer_sequence) -> void - { - // loop on elements - for (const auto & element : _manifold.elements()) { - // get element parametrization under the manifold's coordinate system - const auto parametrization = element.parametrization(_manifold.coordinate_system()); - // populate the field with the coordinates of the quadrature points in physical - // space - _coordinates.insert( - element.simplex(), { parametrization(_quadratureRule.point(q))... }); - } - - // all done - return; - } public: - Integrator(const manifold_type & manifold) : - _manifold(manifold), - _coordinates("coordinates") - { - _computeQuadPointCoordinates(tensor::make_integer_sequence{}); - } + // the constructor + Integrator(const manifold_type & manifold) : _manifold(manifold) {} + // integrate field {f} auto integrate(const fields::scalar_field_c auto & f) const -> tensor::scalar_t { + // initialize the result auto result = tensor::scalar_t{ 0.0 }; // assemble elementary contributions for (const auto & cell : _manifold.elements()) { + // get cell parametrization under the manifold's coordinate system + const auto phi = cell.parametrization(); + // compute the derivative of the cell parametrization + const auto J = functions::derivative(phi); + // get the manifold's metric volume form + const auto w = cell.metric_volume_form(); + // loop on quadrature points for (auto q = 0; q < Q; ++q) { - auto point = _coordinates(cell.simplex())[q]; - result += f(point) * _quadratureRule.weight(q) * _manifold.volume(cell); + // get the quadrature point coordinates in physical space + const auto x_q = _quadratureRule.point(q); + // get the quadrature weight and scale it by the reference simplex area + const auto w_q = + _quadratureRule.weight(q) * cell_type::reference_simplex_type::area; + // construct the metric volume element at {x} by contracting the metric volume + // form with the tangent vectors at {x} + const auto dV = w(phi(x_q))(tensor::columns(J(x_q))); + // assemble the elementary contribution + result += f(phi(x_q)) * w_q * dV; } } + // all done return result; } private: // the domain of integration const manifold_type & _manifold; - // the coordinates of the quadrature points in the domain of integration - quadrature_field_type _coordinates; }; } // namespace mito diff --git a/tests/mito.lib/manifolds/manifold_elements_view.cc b/tests/mito.lib/manifolds/manifold_elements_view.cc new file mode 100644 index 00000000..6b43c1f9 --- /dev/null +++ b/tests/mito.lib/manifolds/manifold_elements_view.cc @@ -0,0 +1,62 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +#include +#include +#include + + +// the type of coordinates +using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; + +// the metric space type +using metric_space_t = mito::geometry::metric_space; + + +TEST(Manifolds, ElementView) +{ + // the coordinate system + auto coord_system = mito::geometry::coordinate_system(); + + // an empty mesh of simplicial topology in 2D + auto mesh = mito::mesh::mesh>(); + + // build nodes + auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); + auto node_1 = mito::geometry::node(coord_system, { 1.0, 0.0 }); + auto node_2 = mito::geometry::node(coord_system, { 1.0, 1.0 }); + auto node_3 = mito::geometry::node(coord_system, { 0.5, 0.5 }); + auto node_4 = mito::geometry::node(coord_system, { 0.0, 1.0 }); + + // insert triangles in mesh + mesh.insert({ node_0, node_1, node_3 }); + mesh.insert({ node_1, node_2, node_3 }); + mesh.insert({ node_2, node_4, node_3 }); + mesh.insert({ node_4, node_0, node_3 }); + + // create a manifold on {mesh} with the appropriate metric volume form + auto manifold = mito::manifolds::manifold(mesh, coord_system, metric_space_t::w); + + // compute the volume of the manifold + auto area = 0.0; + for (const auto & e : manifold.elements()) { + // get the parametrization of this element + auto phi = e.parametrization(); + // compute the derivative of the cell parametrization + const auto J = mito::functions::derivative(phi); + // get the metric volume form of this element + auto w = e.metric_volume_form(); + // get the director edges of this cell and the point where they stem from + auto [point, directors] = mito::geometry::directors(e.cell(), coord_system); + // compute the area of the cell + area += 1.0 / 2 * w(point)(directors); + } + + // check that the result of the calculation is correct + EXPECT_DOUBLE_EQ(area, 1.0); +} + + +// end of file From 9a2e96f9adeff57cbe1f33f668f92278404629b5 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Tue, 2 Jun 2026 09:26:23 +0200 Subject: [PATCH 26/52] fem/elements: consistency edits across isoparametric elements, mostly in comments --- .../elements/tri1/IsoparametricTriangleP1.h | 18 ++++++++--------- .../elements/tri2/IsoparametricTriangleP2.h | 20 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h index 6364a68e..50295193 100644 --- a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h +++ b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h @@ -8,8 +8,8 @@ // DESIGN NOTES -// Class {IsoparametricTriangleP1} represents a second order simplex living in 2D cartesian space, -// equipped with linear shape functions defined in the parametric space. +// Class {IsoparametricTriangleP1} represents a second order simplex (triangle) living in 2D +// cartesian space, equipped with linear shape functions defined in the parametric space. namespace mito::fem { @@ -28,7 +28,7 @@ namespace mito::fem { typename canonical_element_type::parametric_coordinates_type; // the linear shape functions static constexpr auto shape_functions = shape_functions_type(); - // the number of discretization discretization nodes + // the number of discretization nodes static constexpr int n_nodes = shape_functions_type::N; // a collection of discretization discretization nodes using connectivity_type = std::array; @@ -73,10 +73,10 @@ namespace mito::fem { return shape_functions.shape(); } - // get the jacobian of the isoparametric mapping from barycentric to actual coordinates + // get the jacobian of the isoparametric mapping from parametric to actual coordinates constexpr auto jacobian() const { - // assemble the jacobian as a function of barycentric coordinates + // assemble the jacobian as a function of parametric coordinates auto jacobian_function = functions::function( [&](const parametric_coordinates_type & xi) -> tensor::matrix_t<2> { // get the shape functions derivatives @@ -84,7 +84,7 @@ namespace mito::fem { constexpr auto dphi_1 = shape_functions.dshape<1>(); constexpr auto dphi_2 = shape_functions.dshape<2>(); - // compute the gradient of the isoparametric mapping + // compute the jacobian of the isoparametric mapping return ( tensor::dyadic(_x0, dphi_0(xi)) + tensor::dyadic(_x1, dphi_1(xi)) + tensor::dyadic(_x2, dphi_2(xi))); @@ -94,18 +94,18 @@ namespace mito::fem { return jacobian_function; } - // get the gradient of the a-th shape function as a function of barycentric coordinates + // get the gradient of the a-th shape function as a function of parametric coordinates template requires(a >= 0 && a < n_nodes) constexpr auto gradient() const { - // assemble the gradient as a function of barycentric coordinates + // assemble the gradient as a function of parametric coordinates auto gradient_function = functions::function( [&](const parametric_coordinates_type & xi) -> tensor::vector_t<2> { // the jacobian of the mapping from the reference element to the physical // element evaluated at {xi} auto J = jacobian()(xi); - // the derivative of the coordinates with respect to the barycentric coordinates + // the derivative of the coordinates with respect to the parametric coordinates auto J_inv = tensor::inverse(J); // return the spatial gradients of the shape functions evaluated at {xi} return shape_functions.dshape()(xi) * J_inv; diff --git a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h index 6a13b1fc..11f0b842 100644 --- a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h +++ b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h @@ -8,8 +8,8 @@ // DESIGN NOTES -// Class {IsoparametricTriangleP2} represents a second order simplex living in 2D cartesian space -// equipped with quadratic shape functions defined in the parametric space. +// Class {IsoparametricTriangleP2} represents a second order simplex (triangle) living in 2D +// cartesian space, equipped with quadratic shape functions defined in the parametric space. namespace mito::fem { @@ -23,7 +23,7 @@ namespace mito::fem { using shape_functions_type = ShapeTriangleP2; // the canonical element type using canonical_element_type = typename shape_functions_type::reference_element_type; - // type of a point in parametric coordinates + // the parametric coordinates type using parametric_coordinates_type = typename canonical_element_type::parametric_coordinates_type; // the linear shape functions @@ -43,7 +43,7 @@ namespace mito::fem { {} // destructor - ~IsoparametricTriangleP2() = default; + inline ~IsoparametricTriangleP2() = default; // delete move constructor constexpr IsoparametricTriangleP2(IsoparametricTriangleP2 &&) noexcept = delete; @@ -73,10 +73,10 @@ namespace mito::fem { return shape_functions.shape(); } - // get the jacobian of the isoparametric mapping from barycentric to actual coordinates + // get the jacobian of the isoparametric mapping from parametric to actual coordinates constexpr auto jacobian() const { - // assemble the jacobian as a function of barycentric coordinates + // assemble the jacobian as a function of parametric coordinates auto jacobian_function = functions::function( [&](const parametric_coordinates_type & xi) -> tensor::matrix_t<2> { auto x3 = 0.5 * (_x0 + _x1); @@ -91,7 +91,7 @@ namespace mito::fem { constexpr auto dphi_4 = shape_functions.dshape<4>(); constexpr auto dphi_5 = shape_functions.dshape<5>(); - // compute the gradient of the isoparametric mapping + // compute the jacobian of the isoparametric mapping return ( tensor::dyadic(_x0, dphi_0(xi)) + tensor::dyadic(_x1, dphi_1(xi)) + tensor::dyadic(_x2, dphi_2(xi)) + tensor::dyadic(x3, dphi_3(xi)) @@ -102,18 +102,18 @@ namespace mito::fem { return jacobian_function; } - // get the gradient of the a-th shape function as a function of barycentric coordinates + // get the gradient of the a-th shape function as a function of parametric coordinates template requires(a >= 0 && a < n_nodes) constexpr auto gradient() const { - // assemble the gradient as a function of barycentric coordinates + // assemble the gradient as a function of parametric coordinates auto gradient_function = functions::function( [&](const parametric_coordinates_type & xi) -> tensor::vector_t<2> { // the jacobian of the mapping from the reference element to the physical // element evaluated at {xi} auto J = jacobian()(xi); - // the derivative of the coordinates with respect to the barycentric coordinates + // the derivative of the coordinates with respect to the parametric coordinates auto J_inv = tensor::inverse(J); // return the spatial gradients of the shape functions evaluated at {xi} return shape_functions.dshape()(xi) * J_inv; From 982400af380c4e090a72558a6011a0265636bd31 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 14:08:48 +0200 Subject: [PATCH 27/52] fem/elements: major redesign of the finite elements implementation Finite elements are now templated with respect to the parametrized element, which provides the geometric context. Finite elements have now access to their own parametrization, which can be used to compute the compute the coordinates of the nodes without resorting to the coordinate system. The function space class does not store the finite elements any more, but it builds them on the fly upon request by endowing mesh cells with local element geometry information (manifold element) and shape functions. --- .cmake/mito_benchmarks_mito_lib.cmake | 2 +- benchmarks/mito.lib/pdes/poisson.cc | 2 +- lib/mito/fem/DiscreteSystem.h | 2 +- lib/mito/fem/FemField.h | 21 ++--- lib/mito/fem/FunctionSpace.h | 91 +++++++++++++------ lib/mito/fem/FunctionSpaceElementsView.h | 77 ++++++++++++++++ lib/mito/fem/Weakform.h | 11 +-- lib/mito/fem/api.h | 15 ++- lib/mito/fem/blocks/GradGradBlock.h | 6 +- lib/mito/fem/blocks/L2NormBlock.h | 6 +- lib/mito/fem/blocks/MassBlock.h | 6 +- lib/mito/fem/blocks/SourceTermBlock.h | 6 +- lib/mito/fem/elements/Discretizer.h | 10 +- lib/mito/fem/elements/IsoparametricSegment.h | 75 --------------- lib/mito/fem/elements/IsoparametricTriangle.h | 79 ---------------- lib/mito/fem/elements/api.h | 16 +++- lib/mito/fem/elements/elements_library.h | 7 ++ lib/mito/fem/elements/public.h | 2 - lib/mito/fem/elements/seg1/DiscretizerCG.h | 30 +++--- .../elements/seg1/IsoparametricSegmentP1.h | 49 +++++++--- lib/mito/fem/elements/seg1/api.h | 23 ++++- lib/mito/fem/elements/seg1/forward.h | 19 ++++ lib/mito/fem/elements/seg1/public.h | 9 +- lib/mito/fem/elements/tri1/DiscretizerCG.h | 29 +++--- .../elements/tri1/IsoparametricTriangleP1.h | 53 ++++++++--- lib/mito/fem/elements/tri1/api.h | 22 ++++- lib/mito/fem/elements/tri1/forward.h | 19 ++++ lib/mito/fem/elements/tri1/public.h | 9 +- lib/mito/fem/elements/tri2/DiscretizerCG.h | 34 +++---- .../elements/tri2/IsoparametricTriangleP2.h | 57 +++++++++--- lib/mito/fem/elements/tri2/api.h | 22 ++++- lib/mito/fem/elements/tri2/forward.h | 19 ++++ lib/mito/fem/elements/tri2/public.h | 9 +- lib/mito/fem/factories.h | 5 +- lib/mito/fem/forward.h | 24 ++--- lib/mito/fem/norms.h | 6 -- lib/mito/fem/public.h | 7 +- lib/mito/io/vtk/NodeVTKWriter.h | 3 +- lib/mito/manifolds/Manifold.h | 2 +- lib/mito/manifolds/ParametrizedElement.h | 4 +- tests/mito.lib/fem/block_grad_grad.cc | 47 ++++++---- tests/mito.lib/fem/block_grad_grad_segment.cc | 28 ++++-- tests/mito.lib/fem/block_mass.cc | 47 ++++++---- tests/mito.lib/fem/block_mass_segment.cc | 29 ++++-- tests/mito.lib/fem/fem_field.cc | 6 +- tests/mito.lib/fem/isoparametric_segment.cc | 29 ++++-- tests/mito.lib/fem/isoparametric_triangle.cc | 47 ++++++---- 47 files changed, 678 insertions(+), 443 deletions(-) create mode 100644 lib/mito/fem/FunctionSpaceElementsView.h delete mode 100644 lib/mito/fem/elements/IsoparametricSegment.h delete mode 100644 lib/mito/fem/elements/IsoparametricTriangle.h create mode 100644 lib/mito/fem/elements/seg1/forward.h create mode 100644 lib/mito/fem/elements/tri1/forward.h create mode 100644 lib/mito/fem/elements/tri2/forward.h diff --git a/.cmake/mito_benchmarks_mito_lib.cmake b/.cmake/mito_benchmarks_mito_lib.cmake index 1b826ab4..19c3b988 100644 --- a/.cmake/mito_benchmarks_mito_lib.cmake +++ b/.cmake/mito_benchmarks_mito_lib.cmake @@ -22,7 +22,7 @@ mito_benchmark_driver(benchmarks/mito.lib/operators/laplacian.cc) if(WITH_PETSC) # poisson boundary value problem - # mito_benchmark_driver(benchmarks/mito.lib/pdes/poisson.cc) + mito_benchmark_driver(benchmarks/mito.lib/pdes/poisson.cc) endif() # end of file diff --git a/benchmarks/mito.lib/pdes/poisson.cc b/benchmarks/mito.lib/pdes/poisson.cc index 465549c3..181feaa3 100644 --- a/benchmarks/mito.lib/pdes/poisson.cc +++ b/benchmarks/mito.lib/pdes/poisson.cc @@ -14,7 +14,7 @@ using cell_t = mito::geometry::triangle_t<2>; // second degree finite elements constexpr int degree = 2; // assemble the finite element type -using finite_element_t = mito::fem::isoparametric_simplex_t; +using finite_element_t = mito::fem::finite_element_family; // the reference simplex using reference_simplex_t = mito::geometry::reference_triangle_t; diff --git a/lib/mito/fem/DiscreteSystem.h b/lib/mito/fem/DiscreteSystem.h index 852671c6..6053fd04 100644 --- a/lib/mito/fem/DiscreteSystem.h +++ b/lib/mito/fem/DiscreteSystem.h @@ -37,7 +37,7 @@ namespace mito::fem { // the solution field type using solution_field_type = tensor::scalar_t; // the fem field type - using fem_field_type = fem_field_t; + using fem_field_type = fem_field_t; // the number of nodes per element static constexpr int n_element_nodes = element_type::n_nodes; diff --git a/lib/mito/fem/FemField.h b/lib/mito/fem/FemField.h index fe2d2909..7b567c62 100644 --- a/lib/mito/fem/FemField.h +++ b/lib/mito/fem/FemField.h @@ -17,7 +17,7 @@ namespace mito::fem { // TODO: implement higher-dimensional fields (e.g. vector fields, tensor fields, ...) - template + template class FemField { private: @@ -27,8 +27,6 @@ namespace mito::fem { using nodal_field_type = discrete::nodal_field_t; // the node type using node_type = typename nodal_field_type::input_type; - // the element type - using element_type = typename functionSpaceT::element_type; public: // constructor from temporary nodal field @@ -63,18 +61,19 @@ namespace mito::fem { auto nodal_values() const -> const nodal_field_type & { return _nodal_field; } // localize the field on {element} - auto localize(const element_type & element) const -> auto + // TODO: concept {finite_element_c} + template + auto localize(const elementT & element) const -> auto { + // get the connectivity table of the element + auto connectivity = element.connectivity(); + // helper lambda to assemble the field localization on {element} - constexpr auto _assemble = []( - const element_type & element, - const nodal_field_type & field, - tensor::integer_sequence) { + auto _assemble = [&](tensor::integer_sequence) { // assemble the field localization from the shape functions - return ((element.template shape() * field(element.connectivity()[a])) + ...); + return ((element.template shape() * _nodal_field(connectivity[a])) + ...); }; - return _assemble( - element, _nodal_field, tensor::make_integer_sequence{}); + return _assemble(tensor::make_integer_sequence{}); } // iterators on the nodal field diff --git a/lib/mito/fem/FunctionSpace.h b/lib/mito/fem/FunctionSpace.h index 87028808..19a4e890 100644 --- a/lib/mito/fem/FunctionSpace.h +++ b/lib/mito/fem/FunctionSpace.h @@ -12,51 +12,64 @@ namespace mito::fem { // Class {FunctionSpace} represents a collection of finite elements of order {p} defined on a // manifold and subjected to a set of constraints. // TOFIX: add concept for element type - template + template class FunctionSpace { public: - // the function space type - using function_space_type = FunctionSpace; + // my template parameter, the finite element type + using element_type = finiteElementT; + using finite_element_type = finiteElementT; + // the manifold type + using manifold_type = manifoldT; // the constraints type using constraints_type = constraintsT; - // my template parameter, the finite element type - using element_type = elementT; - // typedef for a collection of finite elements - using elements_type = utilities::segmented_vector_t; - // the degree of the finite element - static constexpr int degree = element_type::degree; + // the function space type + using function_space_type = + FunctionSpace; + + // my element view type + using finite_elements_view_type = function_space_elements_view_t; + // the dimension of the physical space - static constexpr int dim = element_type::dim; + static constexpr int dim = finite_element_type::dim; + // the mesh cell type + using mesh_cell_type = typename finite_element_type::mesh_cell_type; // assemble the mesh node type - using mesh_node_type = geometry::node_t; + using mesh_node_type = typename manifold_type::mesh_type::node_type; + // the discretization node type - using discretization_node_type = typename element_type::discretization_node_type; + using discretization_node_type = typename finite_element_type::discretization_node_type; // the constrained nodes type using constrained_nodes_type = std::set; // the type of a map between the mesh nodes and discretization nodes using map_type = std::unordered_map< mesh_node_type, discretization_node_type, utilities::hash_function>; + + // id type of a mesh cell + using cell_id_type = utilities::index_t; + // a collection of discretization discretization nodes + using connectivity_type = typename finite_element_type::connectivity_type; + // connectivity table type + using connectivity_table_type = std::unordered_map; + // a finite element field type template - using fem_field_type = fem_field_t; + using fem_field_type = fem_field_t; public: // the constructor - template < - manifolds::manifold_c manifoldT, - discretization_t discretizationT = discretization_t::CG> - // require compatibility between the manifold cell and the finite element cell - requires(std::is_same_v< - typename manifoldT::mesh_type::cell_type, typename element_type::cell_type>) - constexpr FunctionSpace(const manifoldT & manifold, const constraints_type & constraints) : - _elements(manifold.nElements()), + template + constexpr FunctionSpace( + const manifold_type & manifold, const constraints_type & constraints) : + _manifold(manifold), _constraints(constraints), + _connectivity_table(), _node_map() { + // TODO: merge the discretization type with the finite element type // discretize the manifold subject to the constraints - discretize( - manifold, constraints, _elements, _node_map, _constrained_nodes); + discretize( + manifold, constraints, _connectivity_table, _node_map, _constrained_nodes); } // destructor @@ -74,6 +87,23 @@ namespace mito::fem { // delete move assignment operator constexpr FunctionSpace & operator=(FunctionSpace &&) noexcept = delete; + public: + // accessor to the underlying manifold + constexpr auto manifold() const noexcept -> const manifold_type & { return _manifold; } + + // return an iterable view of the finite elements + constexpr auto elements() const noexcept { return finite_elements_view_type{ *this }; } + + private: + // return the finite element associated to a mesh cell + constexpr auto element(const mesh_cell_type & cell) const + { + // assemble and return the finite element from the manifold element and the localization + // of the connectivity table to this cell + return finite_element( + _manifold.element(cell), _connectivity_table.at(cell.simplex().id())); + } + public: // TOFIX: not sure this should be constexpr // accessor for the constraints @@ -82,9 +112,6 @@ namespace mito::fem { return _constraints; } - // get the finite elements - auto elements() const noexcept -> const elements_type & { return _elements; } - // get the constrained nodes constexpr auto constrained_nodes() const noexcept -> const constrained_nodes_type & { @@ -106,13 +133,11 @@ namespace mito::fem { get_discretization_nodes(*this, nodes); // build a nodal field on the discretization nodes collected from the function space - return fem_field_t( - discrete::nodal_field_t(nodes, name)); + return fem_field_type(discrete::nodal_field_t(nodes, name)); } private: - // a collection of finite elements - elements_type _elements; + const manifold_type & _manifold; // TOFIX: this should be a collection of constraints. Also, constraints may involve // different degrees of freedom (e.g. periodic boundary conditions to impose relations @@ -127,12 +152,18 @@ namespace mito::fem { // the constrained nodes constrained_nodes_type _constrained_nodes; + // the connectivity table of the finite elements + connectivity_table_type _connectivity_table; + // QUESTION: the reason why we need this map is to write the solution in the vtk writer file // (we need to know how the solution maps to the mesh nodes). I am not sure this is a good // reason to build and store this map, though. Also, if we plan to keep this map, we should // come up with a better name // a map between the mesh nodes and discretization nodes map_type _node_map; + + // frienship with the manifold elements view + friend finite_elements_view_type; }; } // namespace mito diff --git a/lib/mito/fem/FunctionSpaceElementsView.h b/lib/mito/fem/FunctionSpaceElementsView.h new file mode 100644 index 00000000..8ad7ab0b --- /dev/null +++ b/lib/mito/fem/FunctionSpaceElementsView.h @@ -0,0 +1,77 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::fem { + + template + class FunctionSpaceElementsView { + + private: + // my template parameter + using function_space_type = functionSpaceT; + // the type of the cells of the underlying mesh + using mesh_cells_type = typename function_space_type::manifold_type::mesh_type::cells_type; + // the type of the iterator over the cells of the underlying mesh + using mesh_cells_iterator_type = decltype(std::begin(std::declval())); + + public: + // constructor from a manifold + constexpr FunctionSpaceElementsView(const function_space_type & function_space) : + _function_space(function_space) + {} + + // iterator class for the manifold elements view + class iterator { + public: + constexpr iterator( + const function_space_type & function_space, mesh_cells_iterator_type cell_iter) : + _function_space(function_space), + _cell_iterator(cell_iter) + {} + + constexpr auto operator*() const { return _function_space.element(*_cell_iterator); } + + constexpr iterator & operator++() + { + ++_cell_iterator; + return *this; + } + + constexpr bool operator==(const iterator & other) const + { + return _cell_iterator == other._cell_iterator; + } + + constexpr bool operator!=(const iterator & other) const { return !(*this == other); } + + private: + const function_space_type & _function_space; + mesh_cells_iterator_type _cell_iterator; + }; + + constexpr auto begin() const + { + return iterator{ _function_space, + std::begin(_function_space.manifold().mesh().cells()) }; + } + + constexpr auto end() const + { + return iterator{ _function_space, std::end(_function_space.manifold().mesh().cells()) }; + } + + private: + // the function space whose elements I am viewing + const function_space_type & _function_space; + }; + +} // namespace mito + + +// end of file diff --git a/lib/mito/fem/Weakform.h b/lib/mito/fem/Weakform.h index d29bc5c3..a63a6b61 100644 --- a/lib/mito/fem/Weakform.h +++ b/lib/mito/fem/Weakform.h @@ -18,14 +18,10 @@ namespace mito::fem { using lhs_block_type = lhsBlockT; // the type of the right hand side assembly block using rhs_block_type = rhsBlockT; - // the element type - using element_type = typename lhsBlockT::element_type; - // the number of nodes per element - static constexpr int n_element_nodes = element_type::n_nodes; // the elementary matrix type - using elementary_matrix_type = tensor::matrix_t; + using elementary_matrix_type = typename lhs_block_type::elementary_block_type; // the elementary vector type - using elementary_vector_type = tensor::vector_t; + using elementary_vector_type = typename rhs_block_type::elementary_block_type; public: // constructor @@ -51,7 +47,8 @@ namespace mito::fem { public: // compute the elementary contributions to matrix and right-hand side from the weakform - constexpr auto compute_blocks(const element_type & element) const + template + constexpr auto compute_blocks(const elementType & element) const -> std::pair { // the elementary matrix diff --git a/lib/mito/fem/api.h b/lib/mito/fem/api.h index f07e255d..85d2e19c 100644 --- a/lib/mito/fem/api.h +++ b/lib/mito/fem/api.h @@ -10,20 +10,25 @@ namespace mito::fem { // finite element field alias - template - using fem_field_t = FemField; + template + using fem_field_t = FemField; // the possible discretization types: continuous Galerking (CG) vs. discontinuous Galerkin (DG) enum class discretization_t { CG, DG }; // function space alias - template - using function_space_t = FunctionSpace; + template + using function_space_t = FunctionSpace; // function space factory - template + template < + class elementT, manifolds::manifold_c manifoldT, constraints::constraint_c constraintsT> constexpr auto function_space(const manifoldT & manifold, const constraintsT & constraints); + // function space elements view alias + template + using function_space_elements_view_t = FunctionSpaceElementsView; + // weakform alias template using weakform_t = Weakform; diff --git a/lib/mito/fem/blocks/GradGradBlock.h b/lib/mito/fem/blocks/GradGradBlock.h index 7f34d007..43503713 100644 --- a/lib/mito/fem/blocks/GradGradBlock.h +++ b/lib/mito/fem/blocks/GradGradBlock.h @@ -24,7 +24,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type + template + requires(std::is_same_v) + auto compute(const elementType & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; @@ -42,7 +44,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - element_type::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::area * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 0a9f2faa..0e077d94 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -34,7 +34,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type + template + requires(std::is_same_v) + auto compute(const elementType & element) const -> elementary_block_type { // the number of quadrature points per element constexpr int n_quads = quadrature_rule_type::npoints; @@ -49,7 +51,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - element_type::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::area * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/MassBlock.h b/lib/mito/fem/blocks/MassBlock.h index 1c11a05e..094ae934 100644 --- a/lib/mito/fem/blocks/MassBlock.h +++ b/lib/mito/fem/blocks/MassBlock.h @@ -24,7 +24,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type + template + requires(std::is_same_v) + auto compute(const elementType & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; @@ -42,7 +44,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - element_type::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::area * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/SourceTermBlock.h b/lib/mito/fem/blocks/SourceTermBlock.h index fe7df0f0..c10b4624 100644 --- a/lib/mito/fem/blocks/SourceTermBlock.h +++ b/lib/mito/fem/blocks/SourceTermBlock.h @@ -33,7 +33,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - auto compute(const element_type & element) const -> elementary_block_type + template + requires(std::is_same_v) + auto compute(const elementType & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; @@ -54,7 +56,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - element_type::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::area * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/elements/Discretizer.h b/lib/mito/fem/elements/Discretizer.h index 29147573..c5c98011 100644 --- a/lib/mito/fem/elements/Discretizer.h +++ b/lib/mito/fem/elements/Discretizer.h @@ -12,20 +12,20 @@ namespace mito::fem { template struct Discretizer { template < - typename manifoldT, typename constraintsT, typename elements_type, typename map_type, - typename constrained_nodes_type> + typename manifoldT, typename constraintsT, typename connectivity_table_type, + typename map_type, typename constrained_nodes_type> static void apply( - const manifoldT &, const constraintsT &, elements_type &, map_type &, + const manifoldT &, const constraintsT &, connectivity_table_type &, map_type &, constrained_nodes_type &); }; template auto discretize( - const auto & manifold, const auto & constraints, auto & elements, auto & node_map, + const auto & manifold, const auto & constraints, auto & connectivity, auto & node_map, auto & constrained_nodes) { Discretizer::apply( - manifold, constraints, elements, node_map, constrained_nodes); + manifold, constraints, connectivity, node_map, constrained_nodes); } } diff --git a/lib/mito/fem/elements/IsoparametricSegment.h b/lib/mito/fem/elements/IsoparametricSegment.h deleted file mode 100644 index cc3b384b..00000000 --- a/lib/mito/fem/elements/IsoparametricSegment.h +++ /dev/null @@ -1,75 +0,0 @@ -// -*- c++ -*- -// -// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved -// - -// code guard -#pragma once - - -// DESIGN NOTES -// Class {IsoparametricSegment} represents a first order simplex (segment) equipped with parametric -// coordinates. - - -namespace mito::fem { - - class IsoparametricSegment : public utilities::Invalidatable { - public: - // the dimension of the physical space - static constexpr int dim = 1; - // the discretization node type - using discretization_node_type = discrete::discretization_node_t; - // the underlying cell type - using cell_type = geometry::segment_t; - - protected: - // cartesian coordinates in 1D - using coordinates_type = geometry::coordinates_t<1, geometry::CARTESIAN>; - // the coordinate system type - using coordinate_system_type = geometry::coordinate_system_t; - // the vector type - using vector_type = tensor::vector_t<1>; - - public: - // the default constructor - constexpr IsoparametricSegment( - const cell_type & cell, const coordinate_system_type & coord_system) : - _cell(cell), - _x0{ coord_system.coordinates(cell.nodes()[0]->point()) - coordinates_type{} }, - _x1{ coord_system.coordinates(cell.nodes()[1]->point()) - coordinates_type{} } - {} - - // destructor - constexpr ~IsoparametricSegment() = default; - - // delete move constructor - constexpr IsoparametricSegment(IsoparametricSegment &&) noexcept = delete; - - // delete copy constructor - constexpr IsoparametricSegment(const IsoparametricSegment &) = delete; - - // delete assignment operator - constexpr IsoparametricSegment & operator=(const IsoparametricSegment &) = delete; - - // delete move assignment operator - constexpr IsoparametricSegment & operator=(IsoparametricSegment &&) noexcept = delete; - - public: - // get the geometric simplex - constexpr auto cell() const noexcept -> const cell_type & { return _cell; } - - protected: - // QUESTION: do we need to maintain a reference to the geometric simplex? - // a const reference to the geometric simplex - const cell_type & _cell; - - // the coordinates of the discretization nodes of the segment - const vector_type _x0; - const vector_type _x1; - }; - -} // namespace mito - - -// end of file diff --git a/lib/mito/fem/elements/IsoparametricTriangle.h b/lib/mito/fem/elements/IsoparametricTriangle.h deleted file mode 100644 index fe1652a9..00000000 --- a/lib/mito/fem/elements/IsoparametricTriangle.h +++ /dev/null @@ -1,79 +0,0 @@ -// -*- c++ -*- -// -// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved -// - -// code guard -#pragma once - - -// DESIGN NOTES -// Class {IsoparametricTriangle} represents a second order simplex equipped barycentric coordinates. - - -namespace mito::fem { - - class IsoparametricTriangle : public utilities::Invalidatable { - public: - // the dimension of the physical space - static constexpr int dim = 2; - // the discretization node type - using discretization_node_type = discrete::discretization_node_t; - // the underlying cell type - using cell_type = geometry::triangle_t; - - protected: - // cartesian coordinates in 2D - using coordinates_type = geometry::coordinates_t<2, geometry::CARTESIAN>; - // the coordinate system type - using coordinate_system_type = geometry::coordinate_system_t; - // the vector type - using vector_type = tensor::vector_t<2>; - - public: - // the default constructor - constexpr IsoparametricTriangle( - const cell_type & cell, const coordinate_system_type & coord_system) : - _cell(cell), - _coord_system(coord_system), - _x0{ coord_system.coordinates(cell.nodes()[0]->point()) - coordinates_type{} }, - _x1{ coord_system.coordinates(cell.nodes()[1]->point()) - coordinates_type{} }, - _x2{ coord_system.coordinates(cell.nodes()[2]->point()) - coordinates_type{} } - {} - - // destructor - constexpr ~IsoparametricTriangle() = default; - - // delete move constructor - constexpr IsoparametricTriangle(IsoparametricTriangle &&) noexcept = delete; - - // delete copy constructor - constexpr IsoparametricTriangle(const IsoparametricTriangle &) = delete; - - // delete assignment operator - constexpr IsoparametricTriangle & operator=(const IsoparametricTriangle &) = delete; - - // delete move assignment operator - constexpr IsoparametricTriangle & operator=(IsoparametricTriangle &&) noexcept = delete; - - public: - // get the geometric simplex - constexpr auto cell() const noexcept -> const cell_type & { return _cell; } - - protected: - // a const reference to the geometric simplex - const cell_type & _cell; - - // a const reference to the coordinate system - const coordinate_system_type & _coord_system; - - // the coordinates of the discretization nodes of the triangle - const vector_type _x0; - const vector_type _x1; - const vector_type _x2; - }; - -} // namespace mito - - -// end of file diff --git a/lib/mito/fem/elements/api.h b/lib/mito/fem/elements/api.h index 89cc64b5..1890c6b4 100644 --- a/lib/mito/fem/elements/api.h +++ b/lib/mito/fem/elements/api.h @@ -9,9 +9,19 @@ namespace mito::fem { - // type alias for convenient access to the isoparametric simplex type - template - using isoparametric_simplex_t = typename isoparametric_simplex::type; + // factory of finite element from a parametrized element + template + constexpr auto finite_element( + const parametrizedElementT & element, + const typename finiteElementTraits::connectivity_type & connectivity) + { + // get the type of the finite element from the traits + using finite_element_type = + typename finiteElementTraits::template type; + + // assemble the finite element from the parametrized element and the connectivity + return finite_element_type(element, connectivity); + } } diff --git a/lib/mito/fem/elements/elements_library.h b/lib/mito/fem/elements/elements_library.h index 60e59338..22703f17 100644 --- a/lib/mito/fem/elements/elements_library.h +++ b/lib/mito/fem/elements/elements_library.h @@ -7,6 +7,13 @@ #pragma once +namespace mito::fem { + + template + struct finite_element_family; + +} + #include "seg1/public.h" #include "tri1/public.h" #include "tri2/public.h" diff --git a/lib/mito/fem/elements/public.h b/lib/mito/fem/elements/public.h index 7ed2002a..33eeb6f6 100644 --- a/lib/mito/fem/elements/public.h +++ b/lib/mito/fem/elements/public.h @@ -17,8 +17,6 @@ #include "api.h" // classes implementation -#include "IsoparametricSegment.h" -#include "IsoparametricTriangle.h" #include "Discretizer.h" // library of finite elements diff --git a/lib/mito/fem/elements/seg1/DiscretizerCG.h b/lib/mito/fem/elements/seg1/DiscretizerCG.h index 0043129d..c77b391f 100644 --- a/lib/mito/fem/elements/seg1/DiscretizerCG.h +++ b/lib/mito/fem/elements/seg1/DiscretizerCG.h @@ -9,29 +9,31 @@ namespace mito::fem { - // discretizer specialization for {IsoparametricSegmentP1} with continuous Galerkin + // discretizer specialization for a segment in 1D with order 1 continuous Galerkin template <> - struct Discretizer { + struct Discretizer, 1>, discretization_t::CG> { template < - typename manifoldT, typename constraintsT, typename elements_type, typename map_type, - typename constrained_nodes_type> + typename manifoldT, typename constraintsT, typename connectivity_table_type, + typename map_type, typename constrained_nodes_type> static void apply( - const manifoldT & manifold, const constraintsT & constraints, elements_type & elements, - map_type & node_map, constrained_nodes_type & constrained_nodes) + const manifoldT & manifold, const constraintsT & constraints, + connectivity_table_type & connectivity, map_type & node_map, + constrained_nodes_type & constrained_nodes) { + // the finite element type + using finite_element_type = finite_element_family, 1>; // the discretization node type - using discretization_node_type = - typename IsoparametricSegmentP1::discretization_node_type; + using discretization_node_type = typename finite_element_type::discretization_node_type; // the connectivity type - using connectivity_type = typename IsoparametricSegmentP1::connectivity_type; + using connectivity_type = typename finite_element_type::connectivity_type; - // get the coordinate system of the manifold - const auto & coord_system = manifold.coordinate_system(); + // loop on the elements of the manifold + for (const auto & element : manifold.elements()) { - // loop on the cells of the mesh - for (const auto & cell : manifold.elements()) { + // access the underlying cell of the element + const auto & cell = element.cell(); // get the nodes of the cell const auto & nodes = cell.nodes(); @@ -44,7 +46,7 @@ namespace mito::fem { node_map.insert({ nodes[1], discretization_node_type() }).first->second; // create a finite element for each cell and add it to the pile - elements.emplace(cell, coord_system, connectivity_type{ node_0, node_1 }); + connectivity.emplace(cell.simplex().id(), connectivity_type{ node_0, node_1 }); } // populate the constrained nodes diff --git a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h index 9893b7fc..a8c22d5d 100644 --- a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h +++ b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h @@ -14,11 +14,22 @@ namespace mito::fem { - class IsoparametricSegmentP1 : public IsoparametricSegment { + template + class IsoparametricSegmentP1 : public utilities::Invalidatable { public: + // the underlying type of parametrized element + using element_type = parametrizedElementT; + // the underlying mesh cell type + using mesh_cell_type = typename element_type::cell_type; + // the degree of the finite element static constexpr int degree = 1; + // the traits of this element + using traits = finite_element_family; + // the connectivity type of the element + using connectivity_type = traits::connectivity_type; + // the type of shape functions using shape_functions_type = ShapeSegmentP1; // the canonical element type @@ -30,23 +41,23 @@ namespace mito::fem { static constexpr auto shape_functions = shape_functions_type(); // the number of discretization nodes static constexpr int n_nodes = shape_functions_type::N; - // a collection of discretization nodes - using connectivity_type = std::array; public: // the default constructor inline IsoparametricSegmentP1( - const cell_type & geometric_simplex, const coordinate_system_type & coord_system, - const connectivity_type & connectivity) : - IsoparametricSegment(geometric_simplex, coord_system), + const element_type & element, const connectivity_type & connectivity) : + _element(element), _connectivity(connectivity) - {} + { + // check consistency between the number of nodes and the number of shape functions + static_assert(n_nodes == traits::n_nodes); + } // destructor inline ~IsoparametricSegmentP1() = default; - // delete move constructor - constexpr IsoparametricSegmentP1(IsoparametricSegmentP1 &&) noexcept = delete; + // default move constructor + constexpr IsoparametricSegmentP1(IsoparametricSegmentP1 &&) noexcept = default; // delete copy constructor constexpr IsoparametricSegmentP1(const IsoparametricSegmentP1 &) = delete; @@ -64,6 +75,16 @@ namespace mito::fem { return _connectivity; } + // get the element parmetrization + constexpr auto parametrization() const noexcept + { + // delegate to the underlying element + return _element.parametrization(); + } + + // get the mesh cell + constexpr auto cell() const noexcept -> mesh_cell_type { return _element.cell(); } + // get the shape function associated with local node {a} template requires(a >= 0 && a < n_nodes) @@ -83,8 +104,12 @@ namespace mito::fem { constexpr auto dphi_0 = shape_functions.dshape<0>(); constexpr auto dphi_1 = shape_functions.dshape<1>(); + // store the coordinates of the vertices of the triangle in physical space + auto x0 = _element.parametrization()({ 0.0 }); + auto x1 = _element.parametrization()({ 1.0 }); + // compute the jacobian of the isoparametric mapping: dx/dxi - auto dx_dxi = _x0 * dphi_0(xi) + _x1 * dphi_1(xi); + auto dx_dxi = x0 * dphi_0(xi) + x1 * dphi_1(xi); // wrap the result in a 1x1 matrix return tensor::matrix_t<1>{ dx_dxi }; }); @@ -114,7 +139,9 @@ namespace mito::fem { } private: - // the discretization nodes of the simplex + // the parametrized element (geometric information) + const element_type _element; + // the finite element connectivity const connectivity_type _connectivity; }; diff --git a/lib/mito/fem/elements/seg1/api.h b/lib/mito/fem/elements/seg1/api.h index cbdd9a0e..b61c5c27 100644 --- a/lib/mito/fem/elements/seg1/api.h +++ b/lib/mito/fem/elements/seg1/api.h @@ -9,10 +9,27 @@ namespace mito::fem { - // specialization for linear shape functions on segments in 1D + // specialization of {finite_element_family} for first order segments template <> - struct isoparametric_simplex<1, geometry::segment_t<1>> { - using type = IsoparametricSegmentP1; + struct finite_element_family, 1> { + + // the dimension of the physical space + static constexpr int dim = 1; + // the underlying mesh cell type + using mesh_cell_type = geometry::segment_t; + // the degree of the finite element + static constexpr int degree = 1; + // the number of nodes per element + static constexpr int n_nodes = 2; + + // the discretization node type + using discretization_node_type = discrete::discretization_node_t; + // the connectivity type of the element + using connectivity_type = std::array; + + // the type of instances of this finite element + template + using type = IsoparametricSegmentP1; }; } diff --git a/lib/mito/fem/elements/seg1/forward.h b/lib/mito/fem/elements/seg1/forward.h new file mode 100644 index 00000000..8d151773 --- /dev/null +++ b/lib/mito/fem/elements/seg1/forward.h @@ -0,0 +1,19 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::fem { + + // forward declaration of the class {IsoparametricSegmentP1} + template + class IsoparametricSegmentP1; + +} + + +// end of file diff --git a/lib/mito/fem/elements/seg1/public.h b/lib/mito/fem/elements/seg1/public.h index 9849d6ed..9cc73241 100644 --- a/lib/mito/fem/elements/seg1/public.h +++ b/lib/mito/fem/elements/seg1/public.h @@ -7,13 +7,16 @@ #pragma once +// forward declarations +#include "forward.h" + +// published types and factories +#include "api.h" + // classes implementation #include "ShapeSegmentP1.h" #include "IsoparametricSegmentP1.h" #include "DiscretizerCG.h" -// published types and factories -#include "api.h" - // end of file diff --git a/lib/mito/fem/elements/tri1/DiscretizerCG.h b/lib/mito/fem/elements/tri1/DiscretizerCG.h index 2c4f2bc0..92782591 100644 --- a/lib/mito/fem/elements/tri1/DiscretizerCG.h +++ b/lib/mito/fem/elements/tri1/DiscretizerCG.h @@ -11,27 +11,29 @@ namespace mito::fem { // discretizer specialization for {IsoparametricTriangleP1} with continuous Galerkin template <> - struct Discretizer { + struct Discretizer, 1>, discretization_t::CG> { template < - typename manifoldT, typename constraintsT, typename elements_type, typename map_type, - typename constrained_nodes_type> + typename manifoldT, typename constraintsT, typename connectivity_table_type, + typename map_type, typename constrained_nodes_type> static void apply( - const manifoldT & manifold, const constraintsT & constraints, elements_type & elements, - map_type & node_map, constrained_nodes_type & constrained_nodes) + const manifoldT & manifold, const constraintsT & constraints, + connectivity_table_type & connectivity, map_type & node_map, + constrained_nodes_type & constrained_nodes) { + // the finite element type + using finite_element_type = finite_element_family, 1>; // the discretization node type - using discretization_node_type = - typename IsoparametricTriangleP1::discretization_node_type; + using discretization_node_type = typename finite_element_type::discretization_node_type; // the connectivity type - using connectivity_type = typename IsoparametricTriangleP1::connectivity_type; + using connectivity_type = typename finite_element_type::connectivity_type; - // get the coordinate system of the manifold - const auto & coord_system = manifold.coordinate_system(); + // loop on the elements of the manifold + for (const auto & element : manifold.elements()) { - // loop on the cells of the mesh - for (const auto & cell : manifold.elements()) { + // access the underlying cell of the element + const auto & cell = element.cell(); // get the nodes of the cell const auto & nodes = cell.nodes(); @@ -46,7 +48,8 @@ namespace mito::fem { node_map.insert({ nodes[2], discretization_node_type() }).first->second; // create a finite element for each cell and add it to the pile - elements.emplace(cell, coord_system, connectivity_type{ node_0, node_1, node_2 }); + connectivity.emplace( + cell.simplex().id(), connectivity_type{ node_0, node_1, node_2 }); } // populate the constrained nodes diff --git a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h index 50295193..861b92a5 100644 --- a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h +++ b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h @@ -14,11 +14,22 @@ namespace mito::fem { - class IsoparametricTriangleP1 : public IsoparametricTriangle { + template + class IsoparametricTriangleP1 : public utilities::Invalidatable { public: + // the underlying type of parametrized element + using element_type = parametrizedElementT; + // the underlying mesh cell type + using mesh_cell_type = typename element_type::cell_type; + // the degree of the finite element static constexpr int degree = 1; + // the traits of this element + using traits = finite_element_family; + // the connectivity type of the element + using connectivity_type = traits::connectivity_type; + // the type of shape functions using shape_functions_type = ShapeTriangleP1; // the canonical element type @@ -30,23 +41,23 @@ namespace mito::fem { static constexpr auto shape_functions = shape_functions_type(); // the number of discretization nodes static constexpr int n_nodes = shape_functions_type::N; - // a collection of discretization discretization nodes - using connectivity_type = std::array; public: // the default constructor inline IsoparametricTriangleP1( - const cell_type & geometric_simplex, const coordinate_system_type & coord_system, - const connectivity_type & connectivity) : - IsoparametricTriangle(geometric_simplex, coord_system), + const element_type & element, const connectivity_type & connectivity) : + _element(element), _connectivity(connectivity) - {} + { + // check consistency between the number of nodes and the number of shape functions + static_assert(n_nodes == traits::n_nodes); + } // destructor inline ~IsoparametricTriangleP1() = default; - // delete move constructor - constexpr IsoparametricTriangleP1(IsoparametricTriangleP1 &&) noexcept = delete; + // default move constructor + constexpr IsoparametricTriangleP1(IsoparametricTriangleP1 &&) noexcept = default; // delete copy constructor constexpr IsoparametricTriangleP1(const IsoparametricTriangleP1 &) = delete; @@ -64,6 +75,16 @@ namespace mito::fem { return _connectivity; } + // get the element parmetrization + constexpr auto parametrization() const noexcept + { + // delegate to the underlying element + return _element.parametrization(); + } + + // get the mesh cell + constexpr auto cell() const noexcept -> mesh_cell_type { return _element.cell(); } + // get the shape function associated with local node {a} template requires(a >= 0 && a < n_nodes) @@ -84,10 +105,15 @@ namespace mito::fem { constexpr auto dphi_1 = shape_functions.dshape<1>(); constexpr auto dphi_2 = shape_functions.dshape<2>(); + // store the coordinates of the vertices of the triangle in physical space + auto x0 = _element.parametrization()({ 0.0, 0.0 }); + auto x1 = _element.parametrization()({ 1.0, 0.0 }); + auto x2 = _element.parametrization()({ 0.0, 1.0 }); + // compute the jacobian of the isoparametric mapping return ( - tensor::dyadic(_x0, dphi_0(xi)) + tensor::dyadic(_x1, dphi_1(xi)) - + tensor::dyadic(_x2, dphi_2(xi))); + tensor::dyadic(x0, dphi_0(xi)) + tensor::dyadic(x1, dphi_1(xi)) + + tensor::dyadic(x2, dphi_2(xi))); }); // and return it @@ -110,12 +136,15 @@ namespace mito::fem { // return the spatial gradients of the shape functions evaluated at {xi} return shape_functions.dshape()(xi) * J_inv; }); + // and return it return gradient_function; } private: - // the discretization nodes of the simplex + // the parametrized element (geometric information) + const element_type _element; + // the finite element connectivity const connectivity_type _connectivity; }; diff --git a/lib/mito/fem/elements/tri1/api.h b/lib/mito/fem/elements/tri1/api.h index 388c39f6..d2efc5f9 100644 --- a/lib/mito/fem/elements/tri1/api.h +++ b/lib/mito/fem/elements/tri1/api.h @@ -9,10 +9,26 @@ namespace mito::fem { - // specialization for linear shape functions on triangles in 2D template <> - struct isoparametric_simplex<1, geometry::triangle_t<2>> { - using type = IsoparametricTriangleP1; + struct finite_element_family, 1> { + + // the dimension of the physical space + static constexpr int dim = 2; + // the underlying mesh cell type + using mesh_cell_type = geometry::triangle_t; + // the degree of the finite element + static constexpr int degree = 1; + // the number of nodes per element + static constexpr int n_nodes = 3; + + // the discretization node type + using discretization_node_type = discrete::discretization_node_t; + // the connectivity type of the element + using connectivity_type = std::array; + + // the type of instances of this finite element + template + using type = IsoparametricTriangleP1; }; } diff --git a/lib/mito/fem/elements/tri1/forward.h b/lib/mito/fem/elements/tri1/forward.h new file mode 100644 index 00000000..becdaae0 --- /dev/null +++ b/lib/mito/fem/elements/tri1/forward.h @@ -0,0 +1,19 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::fem { + + // forward declaration of the class {IsoparametricTriangleP1} + template + class IsoparametricTriangleP1; + +} + + +// end of file diff --git a/lib/mito/fem/elements/tri1/public.h b/lib/mito/fem/elements/tri1/public.h index d5dc5c0d..3339641e 100644 --- a/lib/mito/fem/elements/tri1/public.h +++ b/lib/mito/fem/elements/tri1/public.h @@ -7,13 +7,16 @@ #pragma once +// forward declarations +#include "forward.h" + +// published types and factories +#include "api.h" + // classes implementation #include "ShapeTriangleP1.h" #include "IsoparametricTriangleP1.h" #include "DiscretizerCG.h" -// published types and factories -#include "api.h" - // end of file diff --git a/lib/mito/fem/elements/tri2/DiscretizerCG.h b/lib/mito/fem/elements/tri2/DiscretizerCG.h index 6ab25111..b6322be3 100644 --- a/lib/mito/fem/elements/tri2/DiscretizerCG.h +++ b/lib/mito/fem/elements/tri2/DiscretizerCG.h @@ -11,26 +11,26 @@ namespace mito::fem { // discretizer specialization for {IsoparametricTriangleP2} with continuous Galerkin template <> - struct Discretizer { + struct Discretizer, 2>, discretization_t::CG> { template < - typename manifoldT, typename constraintsT, typename elements_type, typename map_type, - typename constrained_nodes_type> + typename manifoldT, typename constraintsT, typename connectivity_table_type, + typename map_type, typename constrained_nodes_type> static void apply( - const manifoldT & manifold, const constraintsT & constraints, elements_type & elements, - map_type & node_map, constrained_nodes_type & constrained_nodes) + const manifoldT & manifold, const constraintsT & constraints, + connectivity_table_type & connectivity, map_type & node_map, + constrained_nodes_type & constrained_nodes) { - // the dimension of the physical space - constexpr int dim = IsoparametricTriangleP2::dim; + // the finite element type + using finite_element_type = finite_element_family, 2>; // assemble the mesh node type - using mesh_node_type = geometry::node_t; + using mesh_node_type = typename manifoldT::mesh_type::node_type; // the discretization node type - using discretization_node_type = - typename IsoparametricTriangleP2::discretization_node_type; + using discretization_node_type = typename finite_element_type::discretization_node_type; // the connectivity type - using connectivity_type = typename IsoparametricTriangleP2::connectivity_type; + using connectivity_type = typename finite_element_type::connectivity_type; // id type of mesh nodes using mesh_node_id_t = utilities::index_t; @@ -42,11 +42,11 @@ namespace mito::fem { // create a map to store the mid nodes auto mid_nodes_map = mid_nodes_map_type(); - // get the coordinate system of the manifold - const auto & coord_system = manifold.coordinate_system(); + // loop on the elements of the manifold + for (const auto & element : manifold.elements()) { - // loop on the cells of the mesh - for (const auto & cell : manifold.elements()) { + // access the underlying cell of the element + const auto & cell = element.cell(); // get the nodes of the cell const auto & nodes = cell.nodes(); @@ -77,8 +77,8 @@ namespace mito::fem { .first->second; // create a finite element for each cell and add it to the pile - elements.emplace( - cell, coord_system, + connectivity.emplace( + cell.simplex().id(), connectivity_type{ node_0, node_1, node_2, node_3, node_4, node_5 }); } diff --git a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h index 11f0b842..8deb2d44 100644 --- a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h +++ b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h @@ -14,11 +14,22 @@ namespace mito::fem { - class IsoparametricTriangleP2 : public IsoparametricTriangle { + template + class IsoparametricTriangleP2 : public utilities::Invalidatable { public: + // the underlying type of parametrized element + using element_type = parametrizedElementT; + // the underlying mesh cell type + using mesh_cell_type = typename element_type::cell_type; + // the degree of the finite element static constexpr int degree = 2; + // the traits of this element + using traits = finite_element_family; + // the connectivity type of the element + using connectivity_type = traits::connectivity_type; + // the type of shape functions using shape_functions_type = ShapeTriangleP2; // the canonical element type @@ -30,23 +41,23 @@ namespace mito::fem { static constexpr auto shape_functions = shape_functions_type(); // the number of discretization nodes static constexpr int n_nodes = shape_functions_type::N; - // a collection of discretization nodes - using connectivity_type = std::array; public: // the default constructor inline IsoparametricTriangleP2( - const cell_type & geometric_simplex, const coordinate_system_type & coord_system, - const connectivity_type & connectivity) : - IsoparametricTriangle(geometric_simplex, coord_system), + const element_type & element, const connectivity_type & connectivity) : + _element(element), _connectivity(connectivity) - {} + { + // check consistency between the number of nodes and the number of shape functions + static_assert(n_nodes == traits::n_nodes); + } // destructor inline ~IsoparametricTriangleP2() = default; - // delete move constructor - constexpr IsoparametricTriangleP2(IsoparametricTriangleP2 &&) noexcept = delete; + // default move constructor + constexpr IsoparametricTriangleP2(IsoparametricTriangleP2 &&) noexcept = default; // delete copy constructor constexpr IsoparametricTriangleP2(const IsoparametricTriangleP2 &) = delete; @@ -64,6 +75,16 @@ namespace mito::fem { return _connectivity; } + // get the element parmetrization + constexpr auto parametrization() const noexcept + { + // delegate to the underlying element + return _element.parametrization(); + } + + // get the mesh cell + constexpr auto cell() const noexcept -> mesh_cell_type { return _element.cell(); } + // get the shape function associated with local node {a} template requires(a >= 0 && a < n_nodes) @@ -79,9 +100,13 @@ namespace mito::fem { // assemble the jacobian as a function of parametric coordinates auto jacobian_function = functions::function( [&](const parametric_coordinates_type & xi) -> tensor::matrix_t<2> { - auto x3 = 0.5 * (_x0 + _x1); - auto x4 = 0.5 * (_x1 + _x2); - auto x5 = 0.5 * (_x2 + _x0); + // store the coordinates of the vertices of the triangle in physical space + auto x0 = _element.parametrization()({ 0.0, 0.0 }); + auto x1 = _element.parametrization()({ 1.0, 0.0 }); + auto x2 = _element.parametrization()({ 0.0, 1.0 }); + auto x3 = 0.5 * (x0 + x1); + auto x4 = 0.5 * (x1 + x2); + auto x5 = 0.5 * (x2 + x0); // get the shape functions derivatives constexpr auto dphi_0 = shape_functions.dshape<0>(); @@ -93,8 +118,8 @@ namespace mito::fem { // compute the jacobian of the isoparametric mapping return ( - tensor::dyadic(_x0, dphi_0(xi)) + tensor::dyadic(_x1, dphi_1(xi)) - + tensor::dyadic(_x2, dphi_2(xi)) + tensor::dyadic(x3, dphi_3(xi)) + tensor::dyadic(x0, dphi_0(xi)) + tensor::dyadic(x1, dphi_1(xi)) + + tensor::dyadic(x2, dphi_2(xi)) + tensor::dyadic(x3, dphi_3(xi)) + tensor::dyadic(x4, dphi_4(xi)) + tensor::dyadic(x5, dphi_5(xi))); }); @@ -123,7 +148,9 @@ namespace mito::fem { } private: - // the discretization nodes of the simplex + // the parametrized element (geometric information) + const element_type _element; + // the finite element connectivity const connectivity_type _connectivity; }; diff --git a/lib/mito/fem/elements/tri2/api.h b/lib/mito/fem/elements/tri2/api.h index b7045d0b..396b5a08 100644 --- a/lib/mito/fem/elements/tri2/api.h +++ b/lib/mito/fem/elements/tri2/api.h @@ -9,10 +9,26 @@ namespace mito::fem { - // specialization for quadratic shape functions on triangles in 2D template <> - struct isoparametric_simplex<2, geometry::triangle_t<2>> { - using type = IsoparametricTriangleP2; + struct finite_element_family, 2> { + + // the dimension of the physical space + static constexpr int dim = 2; + // the underlying mesh cell type + using mesh_cell_type = geometry::triangle_t; + // the degree of the finite element + static constexpr int degree = 2; + // the number of nodes per element + static constexpr int n_nodes = 6; + + // the discretization node type + using discretization_node_type = discrete::discretization_node_t; + // the connectivity type of the element + using connectivity_type = std::array; + + // the type of instances of this finite element + template + using type = IsoparametricTriangleP2; }; } diff --git a/lib/mito/fem/elements/tri2/forward.h b/lib/mito/fem/elements/tri2/forward.h new file mode 100644 index 00000000..f79d2bb2 --- /dev/null +++ b/lib/mito/fem/elements/tri2/forward.h @@ -0,0 +1,19 @@ +// -*- c++ -*- +// +// Copyright (c) 2020-2026, the MiTo Authors, all rights reserved +// + +// code guard +#pragma once + + +namespace mito::fem { + + // forward declaration of the class {IsoparametricTriangleP2} + template + class IsoparametricTriangleP2; + +} + + +// end of file diff --git a/lib/mito/fem/elements/tri2/public.h b/lib/mito/fem/elements/tri2/public.h index 93dfdc49..1f46cca9 100644 --- a/lib/mito/fem/elements/tri2/public.h +++ b/lib/mito/fem/elements/tri2/public.h @@ -7,13 +7,16 @@ #pragma once +// forward declarations +#include "forward.h" + +// published types and factories +#include "api.h" + // classes implementation #include "ShapeTriangleP2.h" #include "IsoparametricTriangleP2.h" #include "DiscretizerCG.h" -// published types and factories -#include "api.h" - // end of file diff --git a/lib/mito/fem/factories.h b/lib/mito/fem/factories.h index ff9e64b4..0ddf651a 100644 --- a/lib/mito/fem/factories.h +++ b/lib/mito/fem/factories.h @@ -17,11 +17,12 @@ namespace mito::fem { template < class elementT, manifolds::manifold_c manifoldT, constraints::constraint_c constraintsT> // require compatibility between the manifold cell and the finite element cell - requires(std::is_same_v) + requires( + std::is_same_v) constexpr auto function_space(const manifoldT & manifold, const constraintsT & constraints) { // build a function space on the manifold and return it - return function_space_t(manifold, constraints); + return function_space_t(manifold, constraints); } // weakform factory diff --git a/lib/mito/fem/forward.h b/lib/mito/fem/forward.h index d80d11eb..67a167f0 100644 --- a/lib/mito/fem/forward.h +++ b/lib/mito/fem/forward.h @@ -10,18 +10,26 @@ namespace mito::fem { // class function space - template + template class FunctionSpace; // concept of a function space template concept function_space_c = requires(F c) { // require that F only binds to {FunctionSpace} specializations - []( - const FunctionSpace &) { + []( + const FunctionSpace &) { }(c); }; + // class function space elements view + template + class FunctionSpaceElementsView; + + // class function space elements view + template + class FunctionSpaceElementsView; + template concept compatible_assembly_blocks_c = std::is_same_v; @@ -40,20 +48,14 @@ namespace mito::fem { class DomainField; // class finite element field - template + template class FemField; - // concept of a localizable field - template - concept localizable_field_c = requires(const F & f, const E & e) { - { localize(f, e) }; - }; - // concept of a fem field template concept fem_field_c = requires(F c) { // require that F only binds to {FemField} specializations - [](const FemField &) { + [](const FemField &) { }(c); }; } diff --git a/lib/mito/fem/norms.h b/lib/mito/fem/norms.h index 2d4ad2d1..0eff54b6 100644 --- a/lib/mito/fem/norms.h +++ b/lib/mito/fem/norms.h @@ -11,9 +11,6 @@ namespace mito::fem { // compute L2 norm on a given function space of the difference between two localizable fields template - requires( - localizable_field_c - && localizable_field_c) constexpr auto compute_l2_norm( const functionSpaceT & function_space, const F1 & u1, const F2 & u2) -> tensor::scalar_t { @@ -40,9 +37,6 @@ namespace mito::fem { // compute H1 norm on a given function space of the difference between two localizable fields template - requires( - localizable_field_c - && localizable_field_c) constexpr auto compute_h1_norm( const functionSpaceT & function_space, const F1 & u1, const F2 & u2) -> tensor::scalar_t { diff --git a/lib/mito/fem/public.h b/lib/mito/fem/public.h index 8e1a6216..eca0d96f 100644 --- a/lib/mito/fem/public.h +++ b/lib/mito/fem/public.h @@ -22,15 +22,16 @@ // utilities implementation #include "utilities.h" +// finite elements implementation +#include "elements.h" + // classes implementation +#include "FunctionSpaceElementsView.h" #include "FunctionSpace.h" #include "FemField.h" #include "DiscreteSystem.h" #include "Weakform.h" -// finite elements implementation -#include "elements.h" - // factories implementation #include "factories.h" diff --git a/lib/mito/io/vtk/NodeVTKWriter.h b/lib/mito/io/vtk/NodeVTKWriter.h index 5d856527..3d6cc7f1 100644 --- a/lib/mito/io/vtk/NodeVTKWriter.h +++ b/lib/mito/io/vtk/NodeVTKWriter.h @@ -73,7 +73,8 @@ namespace mito::io::vtk { const auto & cell = element.cell(); // create vtk cell - auto cellVtk = vtkCellPointer(); + auto cellVtk = + vtkCellPointer(); // local index for the points of the cell auto indexLocalPointVtk = 0; diff --git a/lib/mito/manifolds/Manifold.h b/lib/mito/manifolds/Manifold.h index 3d032bc5..c2c15413 100644 --- a/lib/mito/manifolds/Manifold.h +++ b/lib/mito/manifolds/Manifold.h @@ -100,7 +100,7 @@ namespace mito::manifolds { } } - private: + public: // return the manifold element associated to a cell constexpr auto element(const cell_type & cell) const { diff --git a/lib/mito/manifolds/ParametrizedElement.h b/lib/mito/manifolds/ParametrizedElement.h index 6fe2df83..cbebb343 100644 --- a/lib/mito/manifolds/ParametrizedElement.h +++ b/lib/mito/manifolds/ParametrizedElement.h @@ -40,8 +40,8 @@ namespace mito::manifolds { // default move constructor constexpr ParametrizedElement(ParametrizedElement &&) noexcept = default; - // delete copy constructor - constexpr ParametrizedElement(const ParametrizedElement &) = delete; + // default copy constructor + constexpr ParametrizedElement(const ParametrizedElement &) = default; // delete assignment operator constexpr ParametrizedElement & operator=(const ParametrizedElement &) = delete; diff --git a/tests/mito.lib/fem/block_grad_grad.cc b/tests/mito.lib/fem/block_grad_grad.cc index 1abeab8f..7b5f4c89 100644 --- a/tests/mito.lib/fem/block_grad_grad.cc +++ b/tests/mito.lib/fem/block_grad_grad.cc @@ -9,8 +9,8 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; +// the metric space type +using metric_space_t = mito::geometry::metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell @@ -28,7 +28,10 @@ constexpr auto quadrature_rule = quadrature_rule_t(); TEST(Fem, IsoparametricTriangle) { // the coordinate system - auto coord_system = coord_system_t(); + auto coord_system = mito::geometry::coordinate_system_t(); + + // an atlas under the coordinate system + auto atlas = mito::manifolds::atlas(coord_system); // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); @@ -36,25 +39,30 @@ TEST(Fem, IsoparametricTriangle) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // make a geometric simplex - auto geometric_simplex = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); - { - // first order isoparametric triangle - using element_p1_t = mito::fem::isoparametric_simplex_t<1, cell_t>; + // make a manifold element from the segment + auto element = mito::manifolds::parametrized_element( + triangle, atlas.parametrization(triangle), metric_space_t::w); + { // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); auto discretization_node_2 = discretization_node_t(); + // the degree of the finite element + constexpr int degree = 1; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + // a finite element - auto element_p1 = element_p1_t( - geometric_simplex, coord_system, - { discretization_node_0, discretization_node_1, discretization_node_2 }); + auto element_p1 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1, discretization_node_2 }); // a grad-grad matrix block auto grad_grad_block = - mito::fem::blocks::grad_grad_block(); + mito::fem::blocks::grad_grad_block(); // the analytical elementary stiffness matrix auto analytical_block = 1.0 / 2.0 * mito::tensor::matrix_t<3>{ 2.0, -1.0, -1.0, -1.0, 1.0, @@ -71,9 +79,6 @@ TEST(Fem, IsoparametricTriangle) } { - // second order isoparametric triangle - using element_p2_t = mito::fem::isoparametric_simplex_t<2, cell_t>; - // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); @@ -82,15 +87,19 @@ TEST(Fem, IsoparametricTriangle) auto discretization_node_4 = discretization_node_t(); auto discretization_node_5 = discretization_node_t(); + // the degree of the finite element + constexpr int degree = 2; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + // a finite element - auto element_p2 = element_p2_t( - geometric_simplex, coord_system, - { discretization_node_0, discretization_node_1, discretization_node_2, - discretization_node_3, discretization_node_4, discretization_node_5 }); + auto element_p2 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1, discretization_node_2, + discretization_node_3, discretization_node_4, discretization_node_5 }); // a grad-grad matrix block auto grad_grad_block = - mito::fem::blocks::grad_grad_block(); + mito::fem::blocks::grad_grad_block(); // the analytical elementary stiffness matrix auto analytical_block = mito::tensor::matrix_t<6>{ diff --git a/tests/mito.lib/fem/block_grad_grad_segment.cc b/tests/mito.lib/fem/block_grad_grad_segment.cc index 1d6a9553..09bc8e9a 100644 --- a/tests/mito.lib/fem/block_grad_grad_segment.cc +++ b/tests/mito.lib/fem/block_grad_grad_segment.cc @@ -9,8 +9,8 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; +// the metric space type +using metric_space_t = mito::geometry::metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell @@ -28,30 +28,38 @@ constexpr auto quadrature_rule = quadrature_rule_t(); TEST(Fem, BlockGradGradSegment) { // the coordinate system - auto coord_system = coord_system_t(); + auto coord_system = mito::geometry::coordinate_system_t(); + + // an atlas under the coordinate system + auto atlas = mito::manifolds::atlas(coord_system); // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0 }); auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // make a geometric simplex - auto geometric_simplex = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment<1>({ node_0, node_1 }); - { - // first order isoparametric segment - using element_p1_t = mito::fem::isoparametric_simplex_t<1, cell_t>; + // make a manifold element from the segment + auto element = mito::manifolds::parametrized_element( + segment, atlas.parametrization(segment), metric_space_t::w); + { // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); + // the degree of the finite element + constexpr int degree = 1; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; // a finite element - auto element_p1 = element_p1_t( - geometric_simplex, coord_system, { discretization_node_0, discretization_node_1 }); + auto element_p1 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1 }); // a grad-grad matrix block auto grad_grad_block = - mito::fem::blocks::grad_grad_block(); + mito::fem::blocks::grad_grad_block(); // the analytical elementary stiffness matrix auto analytical_block = mito::tensor::matrix_t<2>{ 1.0, -1.0, -1.0, 1.0 }; diff --git a/tests/mito.lib/fem/block_mass.cc b/tests/mito.lib/fem/block_mass.cc index 06d19987..18500af4 100644 --- a/tests/mito.lib/fem/block_mass.cc +++ b/tests/mito.lib/fem/block_mass.cc @@ -9,8 +9,8 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; +// the metric space type +using metric_space_t = mito::geometry::metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell @@ -28,7 +28,10 @@ constexpr auto quadrature_rule = quadrature_rule_t(); TEST(Fem, IsoparametricTriangle) { // the coordinate system - auto coord_system = coord_system_t(); + auto coord_system = mito::geometry::coordinate_system_t(); + + // an atlas under the coordinate system + auto atlas = mito::manifolds::atlas(coord_system); // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); @@ -36,24 +39,29 @@ TEST(Fem, IsoparametricTriangle) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // make a geometric simplex - auto geometric_simplex = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); - { - // first order isoparametric triangle - using element_p1_t = mito::fem::isoparametric_simplex_t<1, cell_t>; + // make a manifold element from the triangle + auto element = mito::manifolds::parametrized_element( + triangle, atlas.parametrization(triangle), metric_space_t::w); + { // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); auto discretization_node_2 = discretization_node_t(); + // the degree of the finite element + constexpr int degree = 1; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + // a finite element - auto element_p1 = element_p1_t( - geometric_simplex, coord_system, - { discretization_node_0, discretization_node_1, discretization_node_2 }); + auto element_p1 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1, discretization_node_2 }); // a mass matrix block - auto mass_block = mito::fem::blocks::mass_block(); + auto mass_block = mito::fem::blocks::mass_block(); // the analytical elementary mass matrix auto analytical_block = @@ -70,9 +78,6 @@ TEST(Fem, IsoparametricTriangle) } { - // second order isoparametric triangle - using element_p2_t = mito::fem::isoparametric_simplex_t<2, cell_t>; - // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); @@ -81,14 +86,18 @@ TEST(Fem, IsoparametricTriangle) auto discretization_node_4 = discretization_node_t(); auto discretization_node_5 = discretization_node_t(); + // the degree of the finite element + constexpr int degree = 2; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + // a finite element - auto element_p2 = element_p2_t( - geometric_simplex, coord_system, - { discretization_node_0, discretization_node_1, discretization_node_2, - discretization_node_3, discretization_node_4, discretization_node_5 }); + auto element_p2 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1, discretization_node_2, + discretization_node_3, discretization_node_4, discretization_node_5 }); // a mass matrix block - auto mass_block = mito::fem::blocks::mass_block(); + auto mass_block = mito::fem::blocks::mass_block(); // the analytical elementary mass matrix auto analytical_block = mito::tensor::matrix_t<6>{ diff --git a/tests/mito.lib/fem/block_mass_segment.cc b/tests/mito.lib/fem/block_mass_segment.cc index 64602992..2a74933d 100644 --- a/tests/mito.lib/fem/block_mass_segment.cc +++ b/tests/mito.lib/fem/block_mass_segment.cc @@ -9,8 +9,8 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; +// the metric space type +using metric_space_t = mito::geometry::metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell @@ -28,29 +28,38 @@ constexpr auto quadrature_rule = quadrature_rule_t(); TEST(Fem, BlockMassSegment) { // the coordinate system - auto coord_system = coord_system_t(); + auto coord_system = mito::geometry::coordinate_system_t(); + + // an atlas under the coordinate system + auto atlas = mito::manifolds::atlas(coord_system); // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0 }); auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // make a geometric simplex - auto geometric_simplex = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment<1>({ node_0, node_1 }); - { - // first order isoparametric segment - using element_p1_t = mito::fem::isoparametric_simplex_t<1, cell_t>; + // make a manifold element from the segment + auto element = mito::manifolds::parametrized_element( + segment, atlas.parametrization(segment), metric_space_t::w); + { // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); + // the degree of the finite element + constexpr int degree = 1; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + // a finite element - auto element_p1 = element_p1_t( - geometric_simplex, coord_system, { discretization_node_0, discretization_node_1 }); + auto element_p1 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1 }); // a mass matrix block - auto mass_block = mito::fem::blocks::mass_block(); + auto mass_block = mito::fem::blocks::mass_block(); // the analytical elementary mass matrix auto analytical_block = 1.0 / 6.0 * mito::tensor::matrix_t<2>{ 2.0, 1.0, 1.0, 2.0 }; diff --git a/tests/mito.lib/fem/fem_field.cc b/tests/mito.lib/fem/fem_field.cc index 99121425..2335269f 100644 --- a/tests/mito.lib/fem/fem_field.cc +++ b/tests/mito.lib/fem/fem_field.cc @@ -15,7 +15,7 @@ using cell_t = mito::geometry::triangle_t<2>; // first degree finite elements constexpr int degree = 1; // assemble the finite element type -using finite_element_t = mito::fem::isoparametric_simplex_t; +using finite_element_t = mito::fem::finite_element_family; // the x scalar field in 2D constexpr auto x = mito::functions::component; // the y scalar field in 2D @@ -59,8 +59,10 @@ TEST(Fem, FemField) // loop on all the elements of the functions space for (const auto & element : function_space.elements()) { + // get the mesh cell of the element + auto cell = element.cell(); // loop on all the nodes of the element - for (const auto & node : element.cell().nodes()) { + for (const auto & node : cell.nodes()) { // compute the coordinates of the node auto coords = coord_system.coordinates(node->point()); // set the field value at {node} diff --git a/tests/mito.lib/fem/isoparametric_segment.cc b/tests/mito.lib/fem/isoparametric_segment.cc index cdd98bbe..90e78953 100644 --- a/tests/mito.lib/fem/isoparametric_segment.cc +++ b/tests/mito.lib/fem/isoparametric_segment.cc @@ -9,8 +9,8 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; +// the metric space type +using metric_space_t = mito::geometry::metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell @@ -90,26 +90,35 @@ test_gradient_consistency(const auto & element) TEST(Fem, IsoparametricSegment) { // the coordinate system - auto coord_system = coord_system_t(); + auto coord_system = mito::geometry::coordinate_system_t(); + + // an atlas under the coordinate system + auto atlas = mito::manifolds::atlas(coord_system); // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0 }); auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // make a geometric simplex - auto geometric_simplex = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment<1>({ node_0, node_1 }); - { - // first order isoparametric segment - using element_p1_t = mito::fem::isoparametric_simplex_t<1, cell_t>; + // make a manifold element from the segment + auto element = mito::manifolds::parametrized_element( + segment, atlas.parametrization(segment), metric_space_t::w); + { // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); - // a finite element - auto element_p1 = element_p1_t( - geometric_simplex, coord_system, { discretization_node_0, discretization_node_1 }); + // the degree of the finite element + constexpr int degree = 1; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + + // first order isoparametric finite element + auto element_p1 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1 }); // check that first order shape functions are a partition of unity test_partition_of_unity(element_p1); diff --git a/tests/mito.lib/fem/isoparametric_triangle.cc b/tests/mito.lib/fem/isoparametric_triangle.cc index ce16d413..c317d7ea 100644 --- a/tests/mito.lib/fem/isoparametric_triangle.cc +++ b/tests/mito.lib/fem/isoparametric_triangle.cc @@ -9,8 +9,8 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; -// the type of coordinate system -using coord_system_t = mito::geometry::coordinate_system_t; +// the metric space type +using metric_space_t = mito::geometry::metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell @@ -91,7 +91,10 @@ test_gradient_consistency(const auto & element) TEST(Fem, IsoparametricTriangle) { // the coordinate system - auto coord_system = coord_system_t(); + auto coord_system = mito::geometry::coordinate_system_t(); + + // an atlas under the coordinate system + auto atlas = mito::manifolds::atlas(coord_system); // build nodes auto node_0 = mito::geometry::node(coord_system, { 0.0, 0.0 }); @@ -99,21 +102,26 @@ TEST(Fem, IsoparametricTriangle) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // make a geometric simplex - auto geometric_simplex = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); - { - // first order isoparametric triangle - using element_p1_t = mito::fem::isoparametric_simplex_t<1, cell_t>; + // make a manifold element from the triangle + auto element = mito::manifolds::parametrized_element( + triangle, atlas.parametrization(triangle), metric_space_t::w); + { // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); auto discretization_node_2 = discretization_node_t(); - // a finite element - auto element_p1 = element_p1_t( - geometric_simplex, coord_system, - { discretization_node_0, discretization_node_1, discretization_node_2 }); + // the degree of the finite element + constexpr int degree = 1; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + + // first order isoparametric finite element + auto element_p1 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1, discretization_node_2 }); // check that first order shape functions are a partition of unity test_partition_of_unity(element_p1); @@ -123,9 +131,6 @@ TEST(Fem, IsoparametricTriangle) } { - // second order isoparametric triangle - using element_p2_t = mito::fem::isoparametric_simplex_t<2, cell_t>; - // build the discretization nodes auto discretization_node_0 = discretization_node_t(); auto discretization_node_1 = discretization_node_t(); @@ -134,11 +139,15 @@ TEST(Fem, IsoparametricTriangle) auto discretization_node_4 = discretization_node_t(); auto discretization_node_5 = discretization_node_t(); - // a finite element - auto element_p2 = element_p2_t( - geometric_simplex, coord_system, - { discretization_node_0, discretization_node_1, discretization_node_2, - discretization_node_3, discretization_node_4, discretization_node_5 }); + // the degree of the finite element + constexpr int degree = 2; + // assemble the finite element type + using finite_element_t = mito::fem::finite_element_family; + + // second order isoparametric finite element + auto element_p2 = mito::fem::finite_element( + element, { discretization_node_0, discretization_node_1, discretization_node_2, + discretization_node_3, discretization_node_4, discretization_node_5 }); // check that second order shape functions are a partition of unity test_partition_of_unity(element_p2); From a5ad83336a7722be57c3deb1a3f8cd238f0a019a Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 14:23:30 +0200 Subject: [PATCH 28/52] =?UTF-8?q?tests:=20infer=20the=20reference=C2=A0sim?= =?UTF-8?q?plex=20type=20for=20the=20quadrature=20rule=20from=20the=20mesh?= =?UTF-8?q?=20cell=20when=20possible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- benchmarks/mito.lib/pdes/poisson.cc | 2 +- tests/mito.lib/fem/block_grad_grad.cc | 2 +- tests/mito.lib/fem/block_grad_grad_segment.cc | 2 +- tests/mito.lib/fem/block_mass.cc | 2 +- tests/mito.lib/fem/block_mass_segment.cc | 2 +- tests/mito.lib/fem/isoparametric_segment.cc | 2 +- tests/mito.lib/fem/isoparametric_triangle.cc | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/benchmarks/mito.lib/pdes/poisson.cc b/benchmarks/mito.lib/pdes/poisson.cc index 181feaa3..85040fdf 100644 --- a/benchmarks/mito.lib/pdes/poisson.cc +++ b/benchmarks/mito.lib/pdes/poisson.cc @@ -17,7 +17,7 @@ constexpr int degree = 2; using finite_element_t = mito::fem::finite_element_family; // the reference simplex -using reference_simplex_t = mito::geometry::reference_triangle_t; +using reference_simplex_t = cell_t::reference_simplex_type; // degree of exactness for the quadrature rule constexpr int doe = 2; // Gauss quadrature on triangles with degree of exactness 2 diff --git a/tests/mito.lib/fem/block_grad_grad.cc b/tests/mito.lib/fem/block_grad_grad.cc index 7b5f4c89..ca207d8c 100644 --- a/tests/mito.lib/fem/block_grad_grad.cc +++ b/tests/mito.lib/fem/block_grad_grad.cc @@ -16,7 +16,7 @@ using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell using cell_t = mito::geometry::triangle_t<2>; // the reference simplex -using reference_simplex_t = mito::geometry::reference_triangle_t; +using reference_simplex_t = cell_t::reference_simplex_type; // Gauss quadrature on triangles with degree of exactness 4 using quadrature_rule_t = mito::quadrature::quadrature_rule_t; diff --git a/tests/mito.lib/fem/block_grad_grad_segment.cc b/tests/mito.lib/fem/block_grad_grad_segment.cc index 09bc8e9a..cfe3d336 100644 --- a/tests/mito.lib/fem/block_grad_grad_segment.cc +++ b/tests/mito.lib/fem/block_grad_grad_segment.cc @@ -16,7 +16,7 @@ using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell using cell_t = mito::geometry::segment_t<1>; // the reference simplex -using reference_simplex_t = mito::geometry::reference_segment_t; +using reference_simplex_t = cell_t::reference_simplex_type; // Gauss quadrature on segments with degree of exactness 2 using quadrature_rule_t = mito::quadrature::quadrature_rule_t; diff --git a/tests/mito.lib/fem/block_mass.cc b/tests/mito.lib/fem/block_mass.cc index 18500af4..1c5177a7 100644 --- a/tests/mito.lib/fem/block_mass.cc +++ b/tests/mito.lib/fem/block_mass.cc @@ -16,7 +16,7 @@ using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell using cell_t = mito::geometry::triangle_t<2>; // the reference simplex -using reference_simplex_t = mito::geometry::reference_triangle_t; +using reference_simplex_t = cell_t::reference_simplex_type; // Gauss quadrature on triangles with degree of exactness 4 using quadrature_rule_t = mito::quadrature::quadrature_rule_t; diff --git a/tests/mito.lib/fem/block_mass_segment.cc b/tests/mito.lib/fem/block_mass_segment.cc index 2a74933d..e9112996 100644 --- a/tests/mito.lib/fem/block_mass_segment.cc +++ b/tests/mito.lib/fem/block_mass_segment.cc @@ -16,7 +16,7 @@ using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell using cell_t = mito::geometry::segment_t<1>; // the reference simplex -using reference_simplex_t = mito::geometry::reference_segment_t; +using reference_simplex_t = cell_t::reference_simplex_type; // Gauss quadrature on segments with degree of exactness 2 using quadrature_rule_t = mito::quadrature::quadrature_rule_t; diff --git a/tests/mito.lib/fem/isoparametric_segment.cc b/tests/mito.lib/fem/isoparametric_segment.cc index 90e78953..ddbb86ca 100644 --- a/tests/mito.lib/fem/isoparametric_segment.cc +++ b/tests/mito.lib/fem/isoparametric_segment.cc @@ -16,7 +16,7 @@ using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell using cell_t = mito::geometry::segment_t<1>; // the reference simplex -using reference_simplex_t = mito::geometry::reference_segment_t; +using reference_simplex_t = cell_t::reference_simplex_type; // Gauss quadrature on segments with degree of exactness 2 using quadrature_rule_t = mito::quadrature::quadrature_rule_t; diff --git a/tests/mito.lib/fem/isoparametric_triangle.cc b/tests/mito.lib/fem/isoparametric_triangle.cc index c317d7ea..991dac20 100644 --- a/tests/mito.lib/fem/isoparametric_triangle.cc +++ b/tests/mito.lib/fem/isoparametric_triangle.cc @@ -16,7 +16,7 @@ using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell using cell_t = mito::geometry::triangle_t<2>; // the reference simplex -using reference_simplex_t = mito::geometry::reference_triangle_t; +using reference_simplex_t = cell_t::reference_simplex_type; // Gauss quadrature on triangles with degree of exactness 4 using quadrature_rule_t = mito::quadrature::quadrature_rule_t; From 20ada6c2069f6f6621ca3c2a0ec80c2e27b61a2d Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 14:40:17 +0200 Subject: [PATCH 29/52] fem: in class {FunctionSpace} replace {element_type} with {finite_element_type} --- lib/mito/fem/DiscreteSystem.h | 6 +++--- lib/mito/fem/FunctionSpace.h | 11 ++++++++++- lib/mito/fem/norms.h | 10 +++++----- lib/mito/io/vtk/NodeVTKWriter.h | 5 ++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/mito/fem/DiscreteSystem.h b/lib/mito/fem/DiscreteSystem.h index 6053fd04..dd4d41ad 100644 --- a/lib/mito/fem/DiscreteSystem.h +++ b/lib/mito/fem/DiscreteSystem.h @@ -19,8 +19,6 @@ namespace mito::fem { private: // the function space type using function_space_type = functionSpaceT; - // the element type - using element_type = typename function_space_type::element_type; // the weakform type using weakform_type = weakformT; // the linear system type @@ -38,8 +36,10 @@ namespace mito::fem { using solution_field_type = tensor::scalar_t; // the fem field type using fem_field_type = fem_field_t; + // the element type + using finite_element_type = typename function_space_type::finite_element_type; // the number of nodes per element - static constexpr int n_element_nodes = element_type::n_nodes; + static constexpr int n_element_nodes = finite_element_type::n_nodes; public: // constructor diff --git a/lib/mito/fem/FunctionSpace.h b/lib/mito/fem/FunctionSpace.h index 19a4e890..5edf0dcf 100644 --- a/lib/mito/fem/FunctionSpace.h +++ b/lib/mito/fem/FunctionSpace.h @@ -17,7 +17,6 @@ namespace mito::fem { public: // my template parameter, the finite element type - using element_type = finiteElementT; using finite_element_type = finiteElementT; // the manifold type using manifold_type = manifoldT; @@ -100,6 +99,8 @@ namespace mito::fem { { // assemble and return the finite element from the manifold element and the localization // of the connectivity table to this cell + // QUESTION: manifold element is morally the local geometry of the cell. Shall we call + // it that way? return finite_element( _manifold.element(cell), _connectivity_table.at(cell.simplex().id())); } @@ -137,6 +138,12 @@ namespace mito::fem { } private: + // TOFIX: similarly to the manifold, which should not own (a reference to) the mesh, the + // function space should not own (a reference to) the manifold. + // the manifold should be able to endow the mesh elements with metric information, and the + // function space should be able to endow the mesh elements with shape functions + // Then we don't even need views! + // to the manifold on which the function space is defined const manifold_type & _manifold; // TOFIX: this should be a collection of constraints. Also, constraints may involve @@ -159,6 +166,8 @@ namespace mito::fem { // (we need to know how the solution maps to the mesh nodes). I am not sure this is a good // reason to build and store this map, though. Also, if we plan to keep this map, we should // come up with a better name + // TOFIX: discretization node should be a struct containing the mesh node and the local node + // index, so that we can get rid of this map // a map between the mesh nodes and discretization nodes map_type _node_map; diff --git a/lib/mito/fem/norms.h b/lib/mito/fem/norms.h index 0eff54b6..6aa8afc1 100644 --- a/lib/mito/fem/norms.h +++ b/lib/mito/fem/norms.h @@ -15,7 +15,7 @@ namespace mito::fem { const functionSpaceT & function_space, const F1 & u1, const F2 & u2) -> tensor::scalar_t { // get the element type - using element_type = typename functionSpaceT::element_type; + using finite_element_type = typename functionSpaceT::finite_element_type; // initialize the norm auto norm = tensor::scalar_t{ 0.0 }; @@ -27,7 +27,7 @@ namespace mito::fem { // localize {u2} on this element auto u2_local = localize(u2, element); // compute the elementary contribution to the norm - norm += blocks::l2_norm_block(u1_local - u2_local) + norm += blocks::l2_norm_block(u1_local - u2_local) .compute(element); } @@ -41,7 +41,7 @@ namespace mito::fem { const functionSpaceT & function_space, const F1 & u1, const F2 & u2) -> tensor::scalar_t { // get the element type - using element_type = typename functionSpaceT::element_type; + using finite_element_type = typename functionSpaceT::finite_element_type; // initialize the norm auto norm = tensor::scalar_t{ 0.0 }; @@ -57,9 +57,9 @@ namespace mito::fem { // localize the gradient of the exact solution on this element auto u2_local_gradient = operators::gradient(u2_local); // compute the elementary contributions to the H1 norm - norm += blocks::l2_norm_block(u1_local - u2_local) + norm += blocks::l2_norm_block(u1_local - u2_local) .compute(element) - + blocks::l2_norm_block( + + blocks::l2_norm_block( u1_local_gradient - u2_local_gradient) .compute(element); } diff --git a/lib/mito/io/vtk/NodeVTKWriter.h b/lib/mito/io/vtk/NodeVTKWriter.h index 3d6cc7f1..cd41b508 100644 --- a/lib/mito/io/vtk/NodeVTKWriter.h +++ b/lib/mito/io/vtk/NodeVTKWriter.h @@ -27,7 +27,7 @@ namespace mito::io::vtk { private: // the element type - using element_type = typename grid_type::element_type; + using element_type = typename grid_type::finite_element_type::mesh_cell_type::simplex_type; // the coordinate system type using coord_system_type = coordSystemT; // the dimension of the physical space @@ -73,8 +73,7 @@ namespace mito::io::vtk { const auto & cell = element.cell(); // create vtk cell - auto cellVtk = - vtkCellPointer(); + auto cellVtk = vtkCellPointer(); // local index for the points of the cell auto indexLocalPointVtk = 0; From aaf9d26e2c0145889748283188fb3f65e3669702 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 14:46:10 +0200 Subject: [PATCH 30/52] fem/elements: in isoparametric element classes replace {element_type} with {parametrized_element_type} --- lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h | 8 ++++---- lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h | 8 ++++---- lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h index a8c22d5d..6bae15a0 100644 --- a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h +++ b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h @@ -19,9 +19,9 @@ namespace mito::fem { public: // the underlying type of parametrized element - using element_type = parametrizedElementT; + using parametrized_element_type = parametrizedElementT; // the underlying mesh cell type - using mesh_cell_type = typename element_type::cell_type; + using mesh_cell_type = typename parametrized_element_type::cell_type; // the degree of the finite element static constexpr int degree = 1; @@ -45,7 +45,7 @@ namespace mito::fem { public: // the default constructor inline IsoparametricSegmentP1( - const element_type & element, const connectivity_type & connectivity) : + const parametrized_element_type & element, const connectivity_type & connectivity) : _element(element), _connectivity(connectivity) { @@ -140,7 +140,7 @@ namespace mito::fem { private: // the parametrized element (geometric information) - const element_type _element; + const parametrized_element_type _element; // the finite element connectivity const connectivity_type _connectivity; }; diff --git a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h index 861b92a5..86797d6e 100644 --- a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h +++ b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h @@ -19,9 +19,9 @@ namespace mito::fem { public: // the underlying type of parametrized element - using element_type = parametrizedElementT; + using parametrized_element_type = parametrizedElementT; // the underlying mesh cell type - using mesh_cell_type = typename element_type::cell_type; + using mesh_cell_type = typename parametrized_element_type::cell_type; // the degree of the finite element static constexpr int degree = 1; @@ -45,7 +45,7 @@ namespace mito::fem { public: // the default constructor inline IsoparametricTriangleP1( - const element_type & element, const connectivity_type & connectivity) : + const parametrized_element_type & element, const connectivity_type & connectivity) : _element(element), _connectivity(connectivity) { @@ -143,7 +143,7 @@ namespace mito::fem { private: // the parametrized element (geometric information) - const element_type _element; + const parametrized_element_type _element; // the finite element connectivity const connectivity_type _connectivity; }; diff --git a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h index 8deb2d44..2ef55175 100644 --- a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h +++ b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h @@ -19,9 +19,9 @@ namespace mito::fem { public: // the underlying type of parametrized element - using element_type = parametrizedElementT; + using parametrized_element_type = parametrizedElementT; // the underlying mesh cell type - using mesh_cell_type = typename element_type::cell_type; + using mesh_cell_type = typename parametrized_element_type::cell_type; // the degree of the finite element static constexpr int degree = 2; @@ -45,7 +45,7 @@ namespace mito::fem { public: // the default constructor inline IsoparametricTriangleP2( - const element_type & element, const connectivity_type & connectivity) : + const parametrized_element_type & element, const connectivity_type & connectivity) : _element(element), _connectivity(connectivity) { @@ -149,7 +149,7 @@ namespace mito::fem { private: // the parametrized element (geometric information) - const element_type _element; + const parametrized_element_type _element; // the finite element connectivity const connectivity_type _connectivity; }; From c633547fbd8e0af4e06666e6fa0f0325b71d7873 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 15:03:31 +0200 Subject: [PATCH 31/52] geometry: remove obsolete method to instantiate a {GeometricSimplex} --- lib/mito/geometry/GeometricSimplex.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/mito/geometry/GeometricSimplex.h b/lib/mito/geometry/GeometricSimplex.h index 18aecd4a..f1d8baf6 100644 --- a/lib/mito/geometry/GeometricSimplex.h +++ b/lib/mito/geometry/GeometricSimplex.h @@ -84,18 +84,6 @@ namespace mito::geometry { } public: - // constructor with an existing oriented simplex and a collection of nodes - constexpr GeometricSimplex(const simplex_type & simplex, const nodes_type & nodes) : - Invalidatable(), - _nodes(nodes), - _simplex(simplex) - { - // check that the vertices in {nodes} match the vertices of the {simplex} within a - // positive permutation - assert(_sanity_check()); - } - - // QUESTION: do we need this method? // constructor with an existing oriented simplex and a collection of nodes constexpr GeometricSimplex(const nodes_type & nodes) : Invalidatable(), From 8006c80f6dfd61dfc30cb9a2c64053bc3acd623e Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 15:07:40 +0200 Subject: [PATCH 32/52] geometry: rename {area} to dimension-angostic {measure} in {ReferenceSimplex} --- lib/mito/fem/blocks/GradGradBlock.h | 2 +- lib/mito/fem/blocks/L2NormBlock.h | 2 +- lib/mito/fem/blocks/MassBlock.h | 2 +- lib/mito/fem/blocks/SourceTermBlock.h | 2 +- lib/mito/geometry/ReferenceSimplex.h | 4 ++-- lib/mito/quadrature/Integrator.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/mito/fem/blocks/GradGradBlock.h b/lib/mito/fem/blocks/GradGradBlock.h index 43503713..2243f45f 100644 --- a/lib/mito/fem/blocks/GradGradBlock.h +++ b/lib/mito/fem/blocks/GradGradBlock.h @@ -44,7 +44,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - elementType::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 0e077d94..bb4256ac 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -51,7 +51,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - elementType::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/MassBlock.h b/lib/mito/fem/blocks/MassBlock.h index 094ae934..76fbe758 100644 --- a/lib/mito/fem/blocks/MassBlock.h +++ b/lib/mito/fem/blocks/MassBlock.h @@ -44,7 +44,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - elementType::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/SourceTermBlock.h b/lib/mito/fem/blocks/SourceTermBlock.h index c10b4624..252ec57c 100644 --- a/lib/mito/fem/blocks/SourceTermBlock.h +++ b/lib/mito/fem/blocks/SourceTermBlock.h @@ -56,7 +56,7 @@ namespace mito::fem::blocks { // the quadrature weight at this point scaled with the area of the canonical simplex constexpr auto w = - elementType::canonical_element_type::area * quadrature_rule.weight(q); + elementType::canonical_element_type::measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/geometry/ReferenceSimplex.h b/lib/mito/geometry/ReferenceSimplex.h index 690b699b..2f389821 100644 --- a/lib/mito/geometry/ReferenceSimplex.h +++ b/lib/mito/geometry/ReferenceSimplex.h @@ -15,8 +15,8 @@ namespace mito::geometry { // the order of the reference simplex constexpr static int order = N; - // the area of the reference simplex - constexpr static double area = 1.0 / mito::tensor::factorial(); + // the measure of the reference simplex + constexpr static double measure = 1.0 / mito::tensor::factorial(); private: // helper to compute 1 - xi0 - xi1 - ... - xi(N-1) diff --git a/lib/mito/quadrature/Integrator.h b/lib/mito/quadrature/Integrator.h index fec2db65..6be01718 100644 --- a/lib/mito/quadrature/Integrator.h +++ b/lib/mito/quadrature/Integrator.h @@ -52,7 +52,7 @@ namespace mito::quadrature { const auto x_q = _quadratureRule.point(q); // get the quadrature weight and scale it by the reference simplex area const auto w_q = - _quadratureRule.weight(q) * cell_type::reference_simplex_type::area; + _quadratureRule.weight(q) * cell_type::reference_simplex_type::measure; // construct the metric volume element at {x} by contracting the metric volume // form with the tangent vectors at {x} const auto dV = w(phi(x_q))(tensor::columns(J(x_q))); From 5883fdf510c701aa08a27d86570aa84dfc70222e Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 15:20:56 +0200 Subject: [PATCH 33/52] geometry: rename {metric_space} to {euclidean_metric_space} throughout Make explicit the assumption that the metric space to be built is Euclidean. --- .../geometry/{metric_space.h => euclidean_metric_space.h} | 8 ++++---- lib/mito/geometry/public.h | 2 +- lib/mito/manifolds/factories.h | 4 ++-- tests/mito.lib/fem/block_grad_grad.cc | 2 +- tests/mito.lib/fem/block_grad_grad_segment.cc | 2 +- tests/mito.lib/fem/block_mass.cc | 2 +- tests/mito.lib/fem/block_mass_segment.cc | 2 +- tests/mito.lib/fem/isoparametric_segment.cc | 2 +- tests/mito.lib/fem/isoparametric_triangle.cc | 2 +- tests/mito.lib/geometry/euclidean_metric_space.cc | 2 +- tests/mito.lib/geometry/polar_metric_space.cc | 2 +- tests/mito.lib/geometry/segment_2D.cc | 2 +- tests/mito.lib/geometry/spherical_metric_space.cc | 2 +- tests/mito.lib/geometry/tetrahedron_3D.cc | 2 +- tests/mito.lib/geometry/triangle_2D.cc | 2 +- tests/mito.lib/geometry/triangle_3D.cc | 2 +- tests/mito.lib/manifolds/euclidean_gradient.cc | 2 +- tests/mito.lib/manifolds/manifold_elements_view.cc | 2 +- tests/mito.lib/manifolds/polar_gradient.cc | 2 +- tests/mito.lib/manifolds/spherical_gradient.cc | 2 +- tests/mito.lib/mesh/disk_change_coordinates.cc | 2 +- tests/mito.lib/mesh/disk_polar_cartesian.cc | 2 +- tests/mito.lib/mesh/half_ball.cc | 6 ++++-- tests/mito.lib/mesh/tetra_cube_3D.cc | 2 +- tests/mito.lib/mesh/tetra_rectangle_2D.cc | 2 +- 25 files changed, 32 insertions(+), 30 deletions(-) rename lib/mito/geometry/{metric_space.h => euclidean_metric_space.h} (94%) diff --git a/lib/mito/geometry/metric_space.h b/lib/mito/geometry/euclidean_metric_space.h similarity index 94% rename from lib/mito/geometry/metric_space.h rename to lib/mito/geometry/euclidean_metric_space.h index 9a08ebfb..b9e424a3 100644 --- a/lib/mito/geometry/metric_space.h +++ b/lib/mito/geometry/euclidean_metric_space.h @@ -10,7 +10,7 @@ namespace mito::geometry { template - struct metric_space { + struct euclidean_metric_space { private: // the physical dimension of the manifold (that is that of the cell) @@ -67,7 +67,7 @@ namespace mito::geometry { template - constexpr auto metric_space::metric_equivalent( + constexpr auto euclidean_metric_space::metric_equivalent( const fields::one_form_field_c auto & one_form) { // return a vector field that, once evaluated at {x}... @@ -84,7 +84,7 @@ namespace mito::geometry { } template - constexpr auto metric_space::metric_equivalent( + constexpr auto euclidean_metric_space::metric_equivalent( const fields::vector_field_c auto & vector) { // return a one form field that, once evaluated at {x}... @@ -93,7 +93,7 @@ namespace mito::geometry { template template - constexpr auto metric_space::_one_form( + constexpr auto euclidean_metric_space::_one_form( const vectorFieldT & vector, const tensorFieldT & matrix) requires(fields::compatible_fields_c) { diff --git a/lib/mito/geometry/public.h b/lib/mito/geometry/public.h index 9d67301b..918d7735 100644 --- a/lib/mito/geometry/public.h +++ b/lib/mito/geometry/public.h @@ -19,7 +19,7 @@ // support #include "basis.h" #include "metric.h" -#include "metric_space.h" +#include "euclidean_metric_space.h" // algebra #include "algebra_coordinates.h" diff --git a/lib/mito/manifolds/factories.h b/lib/mito/manifolds/factories.h index f89106a8..4db45e42 100644 --- a/lib/mito/manifolds/factories.h +++ b/lib/mito/manifolds/factories.h @@ -51,7 +51,7 @@ namespace mito::manifolds { static_assert(mesh_type::dim == mesh_type::order); // the metric space type - using metric_space_type = geometry::metric_space; + using metric_space_type = geometry::euclidean_metric_space; // get the metric volume form constexpr auto volume_form = metric_space_type::w; @@ -75,7 +75,7 @@ namespace mito::manifolds { static_assert(mesh_type::dim - mesh_type::order == sizeof...(fieldsT)); // the metric space type - using metric_space_type = geometry::metric_space; + using metric_space_type = geometry::euclidean_metric_space; // get the metric volume form constexpr auto w = metric_space_type::w; diff --git a/tests/mito.lib/fem/block_grad_grad.cc b/tests/mito.lib/fem/block_grad_grad.cc index ca207d8c..5603340a 100644 --- a/tests/mito.lib/fem/block_grad_grad.cc +++ b/tests/mito.lib/fem/block_grad_grad.cc @@ -10,7 +10,7 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell diff --git a/tests/mito.lib/fem/block_grad_grad_segment.cc b/tests/mito.lib/fem/block_grad_grad_segment.cc index cfe3d336..190c6758 100644 --- a/tests/mito.lib/fem/block_grad_grad_segment.cc +++ b/tests/mito.lib/fem/block_grad_grad_segment.cc @@ -10,7 +10,7 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell diff --git a/tests/mito.lib/fem/block_mass.cc b/tests/mito.lib/fem/block_mass.cc index 1c5177a7..c9f2604b 100644 --- a/tests/mito.lib/fem/block_mass.cc +++ b/tests/mito.lib/fem/block_mass.cc @@ -10,7 +10,7 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell diff --git a/tests/mito.lib/fem/block_mass_segment.cc b/tests/mito.lib/fem/block_mass_segment.cc index e9112996..8d2c484d 100644 --- a/tests/mito.lib/fem/block_mass_segment.cc +++ b/tests/mito.lib/fem/block_mass_segment.cc @@ -10,7 +10,7 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell diff --git a/tests/mito.lib/fem/isoparametric_segment.cc b/tests/mito.lib/fem/isoparametric_segment.cc index ddbb86ca..53dd05df 100644 --- a/tests/mito.lib/fem/isoparametric_segment.cc +++ b/tests/mito.lib/fem/isoparametric_segment.cc @@ -10,7 +10,7 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell diff --git a/tests/mito.lib/fem/isoparametric_triangle.cc b/tests/mito.lib/fem/isoparametric_triangle.cc index 991dac20..3722233f 100644 --- a/tests/mito.lib/fem/isoparametric_triangle.cc +++ b/tests/mito.lib/fem/isoparametric_triangle.cc @@ -10,7 +10,7 @@ // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // the type of discretization node using discretization_node_t = mito::discrete::discretization_node_t; // the type of cell diff --git a/tests/mito.lib/geometry/euclidean_metric_space.cc b/tests/mito.lib/geometry/euclidean_metric_space.cc index ac74c396..beaf199d 100644 --- a/tests/mito.lib/geometry/euclidean_metric_space.cc +++ b/tests/mito.lib/geometry/euclidean_metric_space.cc @@ -14,7 +14,7 @@ using mito::geometry::CARTESIAN; using coordinates_t = mito::geometry::coordinates_t<2, CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Manifolds, EuclideanMetricSpace) diff --git a/tests/mito.lib/geometry/polar_metric_space.cc b/tests/mito.lib/geometry/polar_metric_space.cc index 8bfcaf41..74e849f2 100644 --- a/tests/mito.lib/geometry/polar_metric_space.cc +++ b/tests/mito.lib/geometry/polar_metric_space.cc @@ -14,7 +14,7 @@ using mito::geometry::POLAR; using coordinates_t = mito::geometry::coordinates_t<2, POLAR>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Manifolds, PolarMetricSpace) diff --git a/tests/mito.lib/geometry/segment_2D.cc b/tests/mito.lib/geometry/segment_2D.cc index bb363d20..e5ced456 100644 --- a/tests/mito.lib/geometry/segment_2D.cc +++ b/tests/mito.lib/geometry/segment_2D.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Geometry, Segment2D) diff --git a/tests/mito.lib/geometry/spherical_metric_space.cc b/tests/mito.lib/geometry/spherical_metric_space.cc index 929765ec..ac1faa5e 100644 --- a/tests/mito.lib/geometry/spherical_metric_space.cc +++ b/tests/mito.lib/geometry/spherical_metric_space.cc @@ -14,7 +14,7 @@ using mito::geometry::SPHERICAL; using coordinates_t = mito::geometry::coordinates_t<3, SPHERICAL>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Manifolds, SphericalMetricSpace) diff --git a/tests/mito.lib/geometry/tetrahedron_3D.cc b/tests/mito.lib/geometry/tetrahedron_3D.cc index 071b49cd..3994167b 100644 --- a/tests/mito.lib/geometry/tetrahedron_3D.cc +++ b/tests/mito.lib/geometry/tetrahedron_3D.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Geometry, Tetrahedron3D) diff --git a/tests/mito.lib/geometry/triangle_2D.cc b/tests/mito.lib/geometry/triangle_2D.cc index 0377cef0..c6268c58 100644 --- a/tests/mito.lib/geometry/triangle_2D.cc +++ b/tests/mito.lib/geometry/triangle_2D.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Geometry, Triangle2D) diff --git a/tests/mito.lib/geometry/triangle_3D.cc b/tests/mito.lib/geometry/triangle_3D.cc index b9ef7e48..6a70237c 100644 --- a/tests/mito.lib/geometry/triangle_3D.cc +++ b/tests/mito.lib/geometry/triangle_3D.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Geometry, Triangle3D) diff --git a/tests/mito.lib/manifolds/euclidean_gradient.cc b/tests/mito.lib/manifolds/euclidean_gradient.cc index 6a77e91c..563de16b 100644 --- a/tests/mito.lib/manifolds/euclidean_gradient.cc +++ b/tests/mito.lib/manifolds/euclidean_gradient.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Manifolds, CartesianGradient) diff --git a/tests/mito.lib/manifolds/manifold_elements_view.cc b/tests/mito.lib/manifolds/manifold_elements_view.cc index 6b43c1f9..148aa429 100644 --- a/tests/mito.lib/manifolds/manifold_elements_view.cc +++ b/tests/mito.lib/manifolds/manifold_elements_view.cc @@ -12,7 +12,7 @@ using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Manifolds, ElementView) diff --git a/tests/mito.lib/manifolds/polar_gradient.cc b/tests/mito.lib/manifolds/polar_gradient.cc index 32057c60..46442ba3 100644 --- a/tests/mito.lib/manifolds/polar_gradient.cc +++ b/tests/mito.lib/manifolds/polar_gradient.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::POLAR>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // pi sixth constexpr auto pi_sixth = std::numbers::pi / 6.0; diff --git a/tests/mito.lib/manifolds/spherical_gradient.cc b/tests/mito.lib/manifolds/spherical_gradient.cc index a1473062..d227ad94 100644 --- a/tests/mito.lib/manifolds/spherical_gradient.cc +++ b/tests/mito.lib/manifolds/spherical_gradient.cc @@ -11,7 +11,7 @@ using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::SPHERICAL>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; // pi sixth constexpr auto pi_sixth = std::numbers::pi / 6.0; diff --git a/tests/mito.lib/mesh/disk_change_coordinates.cc b/tests/mito.lib/mesh/disk_change_coordinates.cc index 5538a9c7..782375fd 100644 --- a/tests/mito.lib/mesh/disk_change_coordinates.cc +++ b/tests/mito.lib/mesh/disk_change_coordinates.cc @@ -29,7 +29,7 @@ area_change_coordinates(std::string mesh_file_name) -> mito::tensor::scalar_t auto coord_system_changed = mito::geometry::coordinate_system(coord_system); // the metric space - using metric_space_t = mito::geometry::metric_space; + using metric_space_t = mito::geometry::euclidean_metric_space; // loop over the mesh cells auto area = 0.0; diff --git a/tests/mito.lib/mesh/disk_polar_cartesian.cc b/tests/mito.lib/mesh/disk_polar_cartesian.cc index 3634cf16..7428bc4a 100644 --- a/tests/mito.lib/mesh/disk_polar_cartesian.cc +++ b/tests/mito.lib/mesh/disk_polar_cartesian.cc @@ -26,7 +26,7 @@ area(std::string mesh_file_name) -> mito::tensor::scalar_t auto mesh = mito::io::summit::reader>(filestream, coord_system); // the metric space - using metric_space_t = mito::geometry::metric_space; + using metric_space_t = mito::geometry::euclidean_metric_space; // loop over the mesh cells auto area = 0.0; diff --git a/tests/mito.lib/mesh/half_ball.cc b/tests/mito.lib/mesh/half_ball.cc index 11cd49aa..a0dc6f76 100644 --- a/tests/mito.lib/mesh/half_ball.cc +++ b/tests/mito.lib/mesh/half_ball.cc @@ -25,7 +25,8 @@ TEST(Mesh, HalfBall) mito::io::summit::reader>(fileStream, coord_system); // the metric space - using cartesian_metric_space_t = mito::geometry::metric_space; + using cartesian_metric_space_t = + mito::geometry::euclidean_metric_space; // loop over the mesh cells auto volume_cartesian = 0.0; @@ -38,7 +39,8 @@ TEST(Mesh, HalfBall) mito::geometry::coordinate_system(coord_system); // the metric space - using spherical_metric_space_t = mito::geometry::metric_space; + using spherical_metric_space_t = + mito::geometry::euclidean_metric_space; // loop over the mesh cells auto volume_spherical = 0.0; diff --git a/tests/mito.lib/mesh/tetra_cube_3D.cc b/tests/mito.lib/mesh/tetra_cube_3D.cc index 50efc071..ff9aa145 100644 --- a/tests/mito.lib/mesh/tetra_cube_3D.cc +++ b/tests/mito.lib/mesh/tetra_cube_3D.cc @@ -13,7 +13,7 @@ using coordinates_t = mito::geometry::coordinates_t<3, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Tetra, Cube) diff --git a/tests/mito.lib/mesh/tetra_rectangle_2D.cc b/tests/mito.lib/mesh/tetra_rectangle_2D.cc index 75b3bfaa..6d2cfc37 100644 --- a/tests/mito.lib/mesh/tetra_rectangle_2D.cc +++ b/tests/mito.lib/mesh/tetra_rectangle_2D.cc @@ -12,7 +12,7 @@ using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; // the metric space type -using metric_space_t = mito::geometry::metric_space; +using metric_space_t = mito::geometry::euclidean_metric_space; TEST(Tetra, Rectangle) From 24b1ae1656e556a7045a4544ae2dfb6528723f54 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 15:35:23 +0200 Subject: [PATCH 34/52] geometry: in factory methods {segment}, {triangle}, and {tetrahedron} infer the space dimension from the value of {D} of {node_t} --- lib/mito/geometry/factories.h | 16 +++--- tests/mito.lib/fem/block_grad_grad.cc | 2 +- tests/mito.lib/fem/block_grad_grad_segment.cc | 2 +- tests/mito.lib/fem/block_mass.cc | 2 +- tests/mito.lib/fem/block_mass_segment.cc | 2 +- tests/mito.lib/fem/isoparametric_segment.cc | 2 +- tests/mito.lib/fem/isoparametric_triangle.cc | 2 +- .../geometry/barycenter_segment_1D.cc | 2 +- .../geometry/barycenter_segment_2D.cc | 2 +- .../geometry/barycenter_segment_3D.cc | 2 +- .../geometry/barycenter_tetrahedron_3D.cc | 2 +- .../geometry/barycenter_triangle_2D.cc | 2 +- .../geometry/barycenter_triangle_3D.cc | 2 +- tests/mito.lib/geometry/cell_directors.cc | 6 +-- tests/mito.lib/geometry/segment_2D.cc | 2 +- tests/mito.lib/geometry/tetrahedron_3D.cc | 50 +++++++++---------- tests/mito.lib/geometry/triangle_2D.cc | 12 ++--- tests/mito.lib/geometry/triangle_3D.cc | 2 +- .../integration/quadrature_flip_segment_3D.cc | 2 +- .../quadrature/quadrature_segment_3D.cc | 2 +- 20 files changed, 59 insertions(+), 57 deletions(-) diff --git a/lib/mito/geometry/factories.h b/lib/mito/geometry/factories.h index 2de98c03..4e714ffb 100644 --- a/lib/mito/geometry/factories.h +++ b/lib/mito/geometry/factories.h @@ -53,32 +53,34 @@ namespace mito::geometry { // segment factory template - constexpr auto segment(typename geometric_simplex_t<1, D>::nodes_type && nodes) + constexpr auto segment(const node_t & node_0, const node_t & node_1) -> geometric_simplex_t<1, D> requires(D >= 1) { // all done - return geometric_simplex_t<1, D>(std::move(nodes)); + return geometric_simplex_t<1, D>({ node_0, node_1 }); } // triangle factory template - constexpr auto triangle(typename geometric_simplex_t<2, D>::nodes_type && nodes) + constexpr auto triangle( + const node_t & node_0, const node_t & node_1, const node_t & node_2) -> geometric_simplex_t<2, D> requires(D >= 2) { // all done - return geometric_simplex_t<2, D>(std::move(nodes)); + return geometric_simplex_t<2, D>({ node_0, node_1, node_2 }); } // tetrahedron factory template - constexpr auto tetrahedron(typename geometric_simplex_t<3, D>::nodes_type && nodes) - -> geometric_simplex_t<3, D> + constexpr auto tetrahedron( + const node_t & node_0, const node_t & node_1, const node_t & node_2, + const node_t & node_3) -> geometric_simplex_t<3, D> requires(D >= 3) { // all done - return geometric_simplex_t<3, D>(std::move(nodes)); + return geometric_simplex_t<3, D>({ node_0, node_1, node_2, node_3 }); } } diff --git a/tests/mito.lib/fem/block_grad_grad.cc b/tests/mito.lib/fem/block_grad_grad.cc index 5603340a..1733e0b7 100644 --- a/tests/mito.lib/fem/block_grad_grad.cc +++ b/tests/mito.lib/fem/block_grad_grad.cc @@ -39,7 +39,7 @@ TEST(Fem, IsoparametricTriangle) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // make a geometric simplex - auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // make a manifold element from the segment auto element = mito::manifolds::parametrized_element( diff --git a/tests/mito.lib/fem/block_grad_grad_segment.cc b/tests/mito.lib/fem/block_grad_grad_segment.cc index 190c6758..b098e52a 100644 --- a/tests/mito.lib/fem/block_grad_grad_segment.cc +++ b/tests/mito.lib/fem/block_grad_grad_segment.cc @@ -38,7 +38,7 @@ TEST(Fem, BlockGradGradSegment) auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // make a geometric simplex - auto segment = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // make a manifold element from the segment auto element = mito::manifolds::parametrized_element( diff --git a/tests/mito.lib/fem/block_mass.cc b/tests/mito.lib/fem/block_mass.cc index c9f2604b..722a44d6 100644 --- a/tests/mito.lib/fem/block_mass.cc +++ b/tests/mito.lib/fem/block_mass.cc @@ -39,7 +39,7 @@ TEST(Fem, IsoparametricTriangle) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // make a geometric simplex - auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // make a manifold element from the triangle auto element = mito::manifolds::parametrized_element( diff --git a/tests/mito.lib/fem/block_mass_segment.cc b/tests/mito.lib/fem/block_mass_segment.cc index 8d2c484d..a245108d 100644 --- a/tests/mito.lib/fem/block_mass_segment.cc +++ b/tests/mito.lib/fem/block_mass_segment.cc @@ -38,7 +38,7 @@ TEST(Fem, BlockMassSegment) auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // make a geometric simplex - auto segment = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // make a manifold element from the segment auto element = mito::manifolds::parametrized_element( diff --git a/tests/mito.lib/fem/isoparametric_segment.cc b/tests/mito.lib/fem/isoparametric_segment.cc index 53dd05df..2205a710 100644 --- a/tests/mito.lib/fem/isoparametric_segment.cc +++ b/tests/mito.lib/fem/isoparametric_segment.cc @@ -100,7 +100,7 @@ TEST(Fem, IsoparametricSegment) auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // make a geometric simplex - auto segment = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // make a manifold element from the segment auto element = mito::manifolds::parametrized_element( diff --git a/tests/mito.lib/fem/isoparametric_triangle.cc b/tests/mito.lib/fem/isoparametric_triangle.cc index 3722233f..e98a91c6 100644 --- a/tests/mito.lib/fem/isoparametric_triangle.cc +++ b/tests/mito.lib/fem/isoparametric_triangle.cc @@ -102,7 +102,7 @@ TEST(Fem, IsoparametricTriangle) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // make a geometric simplex - auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // make a manifold element from the triangle auto element = mito::manifolds::parametrized_element( diff --git a/tests/mito.lib/geometry/barycenter_segment_1D.cc b/tests/mito.lib/geometry/barycenter_segment_1D.cc index 4bf641cd..1e86afa2 100644 --- a/tests/mito.lib/geometry/barycenter_segment_1D.cc +++ b/tests/mito.lib/geometry/barycenter_segment_1D.cc @@ -21,7 +21,7 @@ TEST(Barycenter, Segment1D) auto node_1 = mito::geometry::node(coord_system, { 1.0 }); // build a segment embedded in 1D - auto segment = mito::geometry::segment<1>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // compute the barycenter position auto barycenter = mito::geometry::barycenter(segment, coord_system); diff --git a/tests/mito.lib/geometry/barycenter_segment_2D.cc b/tests/mito.lib/geometry/barycenter_segment_2D.cc index 9531a989..839d3bee 100644 --- a/tests/mito.lib/geometry/barycenter_segment_2D.cc +++ b/tests/mito.lib/geometry/barycenter_segment_2D.cc @@ -21,7 +21,7 @@ TEST(Barycenter, Segment2D) auto node_1 = mito::geometry::node(coord_system, { 1.0, 0.0 }); // build a segment embedded in 2D - auto segment = mito::geometry::segment<2>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // compute the barycenter position auto barycenter = mito::geometry::barycenter(segment, coord_system); diff --git a/tests/mito.lib/geometry/barycenter_segment_3D.cc b/tests/mito.lib/geometry/barycenter_segment_3D.cc index 834f080e..e5b3eaf1 100644 --- a/tests/mito.lib/geometry/barycenter_segment_3D.cc +++ b/tests/mito.lib/geometry/barycenter_segment_3D.cc @@ -21,7 +21,7 @@ TEST(Barycenter, Segment3D) auto node_1 = mito::geometry::node(coord_system, { 1.0, 0.0, 0.0 }); // build a segment embedded in 3D - auto segment = mito::geometry::segment<3>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // compute the barycenter position auto barycenter = mito::geometry::barycenter(segment, coord_system); diff --git a/tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc b/tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc index ae5d434b..779a2ec4 100644 --- a/tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc +++ b/tests/mito.lib/geometry/barycenter_tetrahedron_3D.cc @@ -23,7 +23,7 @@ TEST(Barycenter, Tetrahedron3D) auto node_3 = mito::geometry::node(coord_system, { 0.0, 0.0, 1.0 }); // build a tetrahedron embedded in 3D - auto tetrahedron = mito::geometry::tetrahedron<3>({ node_0, node_1, node_2, node_3 }); + auto tetrahedron = mito::geometry::tetrahedron(node_0, node_1, node_2, node_3); // compute the barycenter position auto barycenter = mito::geometry::barycenter(tetrahedron, coord_system); diff --git a/tests/mito.lib/geometry/barycenter_triangle_2D.cc b/tests/mito.lib/geometry/barycenter_triangle_2D.cc index 3e7f27fe..5299c7e8 100644 --- a/tests/mito.lib/geometry/barycenter_triangle_2D.cc +++ b/tests/mito.lib/geometry/barycenter_triangle_2D.cc @@ -22,7 +22,7 @@ TEST(Barycenter, Triangle2D) auto node_2 = mito::geometry::node(coord_system, { 0.5, 0.5 }); // build a triangle embedded in 2D - auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // compute the barycenter position auto barycenter = mito::geometry::barycenter(triangle, coord_system); diff --git a/tests/mito.lib/geometry/barycenter_triangle_3D.cc b/tests/mito.lib/geometry/barycenter_triangle_3D.cc index 66827db2..2302c769 100644 --- a/tests/mito.lib/geometry/barycenter_triangle_3D.cc +++ b/tests/mito.lib/geometry/barycenter_triangle_3D.cc @@ -22,7 +22,7 @@ TEST(Barycenter, Triangle3D) auto node_2 = mito::geometry::node(coord_system, { 0.5, 0.5, 0.0 }); // build a triangle embedded in 3D - auto triangle = mito::geometry::triangle<3>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // compute the barycenter position auto barycenter = mito::geometry::barycenter(triangle, coord_system); diff --git a/tests/mito.lib/geometry/cell_directors.cc b/tests/mito.lib/geometry/cell_directors.cc index 596e6842..1b478d35 100644 --- a/tests/mito.lib/geometry/cell_directors.cc +++ b/tests/mito.lib/geometry/cell_directors.cc @@ -21,7 +21,7 @@ TEST(Director, Segment) auto vertex_1 = mito::geometry::node(coord_system, { 1.0, 0.0, 0.0 }); // build a segment embedded in 3D - auto segment = mito::geometry::segment<3>({ vertex_0, vertex_1 }); + auto segment = mito::geometry::segment(vertex_0, vertex_1); // compute the cell directors // get the directors of the segment @@ -43,7 +43,7 @@ TEST(Director, Triangle) auto vertex_2 = mito::geometry::node(coord_system, { 0.0, 1.0, 0.0 }); // build a triangle embedded in 3D - auto triangle = mito::geometry::triangle<3>({ vertex_0, vertex_1, vertex_2 }); + auto triangle = mito::geometry::triangle(vertex_0, vertex_1, vertex_2); // compute the cell directors // get the directors of the triangle @@ -67,7 +67,7 @@ TEST(Director, Tetrahedron) auto vertex_3 = mito::geometry::node(coord_system, { 0.0, 0.0, 1.0 }); // build a tetrahedron embedded in 3D - auto tetrahedron = mito::geometry::tetrahedron<3>({ vertex_0, vertex_1, vertex_2, vertex_3 }); + auto tetrahedron = mito::geometry::tetrahedron(vertex_0, vertex_1, vertex_2, vertex_3); // compute the cell directors // get the directors of the tetrahedron diff --git a/tests/mito.lib/geometry/segment_2D.cc b/tests/mito.lib/geometry/segment_2D.cc index e5ced456..3ccad460 100644 --- a/tests/mito.lib/geometry/segment_2D.cc +++ b/tests/mito.lib/geometry/segment_2D.cc @@ -24,7 +24,7 @@ TEST(Geometry, Segment2D) auto node_1 = mito::geometry::node(coord_system, { 0.5, 0.5 }); // build segment from the nodes - auto segment = mito::geometry::segment<2>({ node_0, node_1 }); + auto segment = mito::geometry::segment(node_0, node_1); // the normal vector to the segment constexpr auto v = mito::tensor::vector_t<2>{ 0.5, -0.5 }; diff --git a/tests/mito.lib/geometry/tetrahedron_3D.cc b/tests/mito.lib/geometry/tetrahedron_3D.cc index 3994167b..b8786a6a 100644 --- a/tests/mito.lib/geometry/tetrahedron_3D.cc +++ b/tests/mito.lib/geometry/tetrahedron_3D.cc @@ -29,127 +29,127 @@ TEST(Geometry, Tetrahedron3D) auto node_4 = mito::geometry::node(coord_system, { 0.0, 0.0, 1.0 }); // build tetrahedron with a positive volume (reference tetrahedron) - auto tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_2, node_3, node_4 }); + auto tetrahedron = mito::geometry::tetrahedron(node_1, node_2, node_3, node_4); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_2, node_3, node_4 }); + tetrahedron = mito::geometry::tetrahedron(node_1, node_2, node_3, node_4); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_3, node_4, node_2 }); + tetrahedron = mito::geometry::tetrahedron(node_1, node_3, node_4, node_2); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_4, node_2, node_3 }); + tetrahedron = mito::geometry::tetrahedron(node_1, node_4, node_2, node_3); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_1, node_4, node_3 }); + tetrahedron = mito::geometry::tetrahedron(node_2, node_1, node_4, node_3); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_3, node_1, node_4 }); + tetrahedron = mito::geometry::tetrahedron( node_2, node_3, node_1, node_4 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_4, node_3, node_1 }); + tetrahedron = mito::geometry::tetrahedron( node_2, node_4, node_3, node_1 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_1, node_2, node_4 }); + tetrahedron = mito::geometry::tetrahedron( node_3, node_1, node_2, node_4 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_2, node_4, node_1 }); + tetrahedron = mito::geometry::tetrahedron( node_3, node_2, node_4, node_1 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_4, node_1, node_2 }); + tetrahedron = mito::geometry::tetrahedron( node_3, node_4, node_1, node_2 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_1, node_3, node_2 }); + tetrahedron = mito::geometry::tetrahedron( node_4, node_1, node_3, node_2 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_2, node_1, node_3 }); + tetrahedron = mito::geometry::tetrahedron( node_4, node_2, node_1, node_3 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an even permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_3, node_2, node_1 }); + tetrahedron = mito::geometry::tetrahedron( node_4, node_3, node_2, node_1 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), 1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_2, node_4, node_3 }); + tetrahedron = mito::geometry::tetrahedron( node_1, node_2, node_4, node_3 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_3, node_2, node_4 }); + tetrahedron = mito::geometry::tetrahedron( node_1, node_3, node_2, node_4 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_1, node_4, node_3, node_2 }); + tetrahedron = mito::geometry::tetrahedron( node_1, node_4, node_3, node_2 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_1, node_3, node_4 }); + tetrahedron = mito::geometry::tetrahedron( node_2, node_1, node_3, node_4 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_3, node_4, node_1 }); + tetrahedron = mito::geometry::tetrahedron( node_2, node_3, node_4, node_1 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_2, node_4, node_1, node_3 }); + tetrahedron = mito::geometry::tetrahedron( node_2, node_4, node_1, node_3 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_1, node_4, node_2 }); + tetrahedron = mito::geometry::tetrahedron( node_3, node_1, node_4, node_2 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_2, node_1, node_4 }); + tetrahedron = mito::geometry::tetrahedron( node_3, node_2, node_1, node_4 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_3, node_4, node_2, node_1 }); + tetrahedron = mito::geometry::tetrahedron( node_3, node_4, node_2, node_1 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_1, node_2, node_3 }); + tetrahedron = mito::geometry::tetrahedron( node_4, node_1, node_2, node_3 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_2, node_3, node_1 }); + tetrahedron = mito::geometry::tetrahedron( node_4, node_2, node_3, node_1 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); // create a tetrahedron from an odd permutation of the vertices with respect to the reference - tetrahedron = mito::geometry::tetrahedron<3>({ node_4, node_3, node_1, node_2 }); + tetrahedron = mito::geometry::tetrahedron( node_4, node_3, node_1, node_2 ); // check that the volume of tetrahedron is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(tetrahedron, coord_system, w), -1.0 / 6.0); } diff --git a/tests/mito.lib/geometry/triangle_2D.cc b/tests/mito.lib/geometry/triangle_2D.cc index c6268c58..78b52022 100644 --- a/tests/mito.lib/geometry/triangle_2D.cc +++ b/tests/mito.lib/geometry/triangle_2D.cc @@ -28,32 +28,32 @@ TEST(Geometry, Triangle2D) auto node_2 = mito::geometry::node(coord_system, { 0.0, 1.0 }); // build triangle with a positive volume (reference triangle) - auto triangle = mito::geometry::triangle<2>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), 0.5); // create a triangle from an even permutation of the vertices with respect to the reference - triangle = mito::geometry::triangle<2>({ node_1, node_2, node_0 }); + triangle = mito::geometry::triangle(node_1, node_2, node_0); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), 0.5); // create a triangle from an even permutation of the vertices with respect to the reference - triangle = mito::geometry::triangle<2>({ node_2, node_0, node_1 }); + triangle = mito::geometry::triangle(node_2, node_0, node_1); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), 0.5); // create a triangle from an odd permutation of the vertices with respect to the reference - triangle = mito::geometry::triangle<2>({ node_0, node_2, node_1 }); + triangle = mito::geometry::triangle(node_0, node_2, node_1); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), -0.5); // create a triangle from an odd permutation of the vertices with respect to the reference - triangle = mito::geometry::triangle<2>({ node_1, node_0, node_2 }); + triangle = mito::geometry::triangle(node_1, node_0, node_2); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), -0.5); // create a triangle from an odd permutation of the vertices with respect to the reference - triangle = mito::geometry::triangle<2>({ node_2, node_1, node_0 }); + triangle = mito::geometry::triangle(node_2, node_1, node_0); // check that the volume of triangle is correct EXPECT_DOUBLE_EQ(mito::geometry::volume(triangle, coord_system, w), -0.5); } diff --git a/tests/mito.lib/geometry/triangle_3D.cc b/tests/mito.lib/geometry/triangle_3D.cc index 6a70237c..ba59b234 100644 --- a/tests/mito.lib/geometry/triangle_3D.cc +++ b/tests/mito.lib/geometry/triangle_3D.cc @@ -30,7 +30,7 @@ TEST(Geometry, Triangle3D) auto node_2 = mito::geometry::node(coord_system, x_2); // build triangle with a positive volume (reference triangle) - auto triangle = mito::geometry::triangle<3>({ node_0, node_1, node_2 }); + auto triangle = mito::geometry::triangle(node_0, node_1, node_2); // the normal vector to the submanifold constexpr auto cross = mito::tensor::cross(x_1 - x_0, x_2 - x_0); diff --git a/tests/mito.lib/integration/quadrature_flip_segment_3D.cc b/tests/mito.lib/integration/quadrature_flip_segment_3D.cc index 1499fe5d..f813a934 100644 --- a/tests/mito.lib/integration/quadrature_flip_segment_3D.cc +++ b/tests/mito.lib/integration/quadrature_flip_segment_3D.cc @@ -28,7 +28,7 @@ TEST(Quadrature, FlipSegment) // create nodes auto node_0 = mito::geometry::node(coord_system, x_0); auto node_1 = mito::geometry::node(coord_system, x_1); - auto segment0 = mito::geometry::segment<3>({ node_0, node_1 }); + auto segment0 = mito::geometry::segment(node_0, node_1); // construct an orthogonal set {v_1}, {v_2}, {v_3} such that {v_1} is parallel to the segment constexpr auto v_1 = (x_1 - x_0) / mito::tensor::norm(x_1 - x_0); diff --git a/tests/mito.lib/quadrature/quadrature_segment_3D.cc b/tests/mito.lib/quadrature/quadrature_segment_3D.cc index 0ebc0ef7..fd944600 100644 --- a/tests/mito.lib/quadrature/quadrature_segment_3D.cc +++ b/tests/mito.lib/quadrature/quadrature_segment_3D.cc @@ -28,7 +28,7 @@ TEST(Quadrature, Segment3D) // create nodes auto node_0 = mito::geometry::node(coord_system, x_0); auto node_1 = mito::geometry::node(coord_system, x_1); - auto segment0 = mito::geometry::segment<3>({ node_0, node_1 }); + auto segment0 = mito::geometry::segment(node_0, node_1); // construct an orthogonal set {v_1}, {v_2}, {v_3} such that {v_1} is parallel to the segment constexpr auto v_1 = (x_1 - x_0) / mito::tensor::norm(x_1 - x_0); From 23831358a68abe02f422257acd4cf64b529aae46 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 15:42:24 +0200 Subject: [PATCH 35/52] manifolds: remove unused method --- lib/mito/manifolds/Manifold.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/mito/manifolds/Manifold.h b/lib/mito/manifolds/Manifold.h index c2c15413..179ec75e 100644 --- a/lib/mito/manifolds/Manifold.h +++ b/lib/mito/manifolds/Manifold.h @@ -76,8 +76,6 @@ namespace mito::manifolds { // return an iterable view of the manifold elements constexpr auto elements() const noexcept { return manifold_elements_view_type{ *this }; } - constexpr auto nElements() const noexcept -> int { return std::size(_mesh.cells()); } - constexpr auto print() const -> void { // make a channel From 7a155bb98ec52ce1b3543b205e52e70f31252eff Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 15:45:29 +0200 Subject: [PATCH 36/52] manifolds: in class {Manifold} rename {volume_form} to {metric_volume_form} --- lib/mito/manifolds/Manifold.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/mito/manifolds/Manifold.h b/lib/mito/manifolds/Manifold.h index 179ec75e..1472072d 100644 --- a/lib/mito/manifolds/Manifold.h +++ b/lib/mito/manifolds/Manifold.h @@ -9,15 +9,15 @@ namespace mito::manifolds { - template + template requires(cellT::dim == coordsT::dim) class Manifold { private: // typedef for node using node_type = cellT::node_type; - // the volume form type - using volume_form_type = volumeFormT; + // the metric volume form type + using metric_volume_form_type = metricVolumeFormT; // the physical dimension of the manifold (that is that of the cell) static constexpr int D = cellT::dim; // the dimension of the manifold (that is that of the cell) @@ -25,7 +25,7 @@ namespace mito::manifolds { public: // my type - using manifold_type = Manifold; + using manifold_type = Manifold; // my element view type using manifold_elements_view_type = manifold_elements_view_t; // typedef for cell type @@ -44,10 +44,10 @@ namespace mito::manifolds { public: constexpr Manifold( const mesh_type & mesh, const coordinate_system_type & coordinate_system, - volume_form_type volume_form) : + metric_volume_form_type metric_volume_form) : _mesh(mesh), _atlas(coordinate_system), - _volume_form(volume_form) + _metric_volume_form(metric_volume_form) {} // destructor @@ -105,7 +105,7 @@ namespace mito::manifolds { // get the parametrization of this cell auto phi = _atlas.parametrization(cell); // get the metric volume form of this cell - auto w = _volume_form; + auto w = _metric_volume_form; // assemble and return the manifold element return parametrized_element(cell, phi, w); } @@ -115,8 +115,8 @@ namespace mito::manifolds { const mesh_type & _mesh; // the atlas atlas_type _atlas; - // the volume form - volume_form_type _volume_form; + // the metric volume form + metric_volume_form_type _metric_volume_form; // frienship with the manifold elements view friend manifold_elements_view_type; From 7e08ab965f086244bf700eb8df441c3a60cd577a Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:04:08 +0200 Subject: [PATCH 37/52] mito: consistency fix after rev. a9e3bfc --- lib/mito/fem/blocks/L2NormBlock.h | 2 +- lib/mito/fem/blocks/forward.h | 4 +-- lib/mito/geometry/GeometricSimplex.h | 2 +- lib/mito/manifolds/Atlas.h | 2 +- lib/mito/quadrature/QuadratureTable.h | 2 +- tests/mito.lib/fem/isoparametric_triangle.cc | 4 +-- .../fem/shape_functions_triangle_p1.cc | 2 +- .../fem/shape_functions_triangle_p2.cc | 28 +++++++++---------- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index bb4256ac..7541096b 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -10,7 +10,7 @@ namespace mito::fem::blocks { template - // require that {functionT} is a function in barycentric coordinates + // require that {functionT} is a function in parametric coordinates requires(std::is_same_v< typename functionT::input_type, typename quadratureRuleT::quadrature_point_type>) class L2NormBlock { diff --git a/lib/mito/fem/blocks/forward.h b/lib/mito/fem/blocks/forward.h index e0cae9d2..909b6f19 100644 --- a/lib/mito/fem/blocks/forward.h +++ b/lib/mito/fem/blocks/forward.h @@ -21,9 +21,9 @@ namespace mito::fem::blocks { template class SourceTermBlock; - // L2 norm block for a function defined at quadrature points in barycentric coordinates + // L2 norm block for a function defined at quadrature points in parametric coordinates template - // require that {functionT} is a function in barycentric coordinates + // require that {functionT} is a function in parametric coordinates requires(std::is_same_v< typename functionT::input_type, typename quadratureRuleT::quadrature_point_type>) class L2NormBlock; diff --git a/lib/mito/geometry/GeometricSimplex.h b/lib/mito/geometry/GeometricSimplex.h index f1d8baf6..f706ec24 100644 --- a/lib/mito/geometry/GeometricSimplex.h +++ b/lib/mito/geometry/GeometricSimplex.h @@ -57,7 +57,7 @@ namespace mito::geometry { // the reference simplex type using reference_simplex_type = reference_simplex_t; - // type of a point in barycentric coordinates + // type of a point in parametric coordinates using parametric_coordinates_type = reference_simplex_type::parametric_coordinates_type; private: diff --git a/lib/mito/manifolds/Atlas.h b/lib/mito/manifolds/Atlas.h index 3c008d0b..7d1b2ca5 100644 --- a/lib/mito/manifolds/Atlas.h +++ b/lib/mito/manifolds/Atlas.h @@ -61,7 +61,7 @@ namespace mito::manifolds { // get the origin of the coordinate system auto origin = coord_system.origin(); // assemble the parametrization as x0 * xi<0> + ... - // where {xi} are the barycentric coordinates on the reference simplex and the + // where {xi} are the parametric coordinates on the reference simplex and the // {xa} are the position vectors of the nodes return ( ((cell.template xi() diff --git a/lib/mito/quadrature/QuadratureTable.h b/lib/mito/quadrature/QuadratureTable.h index eefc63c7..3269fc79 100644 --- a/lib/mito/quadrature/QuadratureTable.h +++ b/lib/mito/quadrature/QuadratureTable.h @@ -14,7 +14,7 @@ namespace mito::quadrature { class Table { public: - // the type of quadrature points' barycentric coordinates + // the type of quadrature points' parametric coordinates using quadrature_point_type = typename elementT::parametric_coordinates_type; // the type of quadrature weights using quadrature_weight_type = double; diff --git a/tests/mito.lib/fem/isoparametric_triangle.cc b/tests/mito.lib/fem/isoparametric_triangle.cc index e98a91c6..13a70f12 100644 --- a/tests/mito.lib/fem/isoparametric_triangle.cc +++ b/tests/mito.lib/fem/isoparametric_triangle.cc @@ -38,7 +38,7 @@ test_partition_of_unity(const auto & element) // loop on the quadrature points mito::tensor::constexpr_for_1([&]() { - // the barycentric coordinates of the quadrature point + // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); // compute the sum of the shape functions at {xi} for all nodes @@ -68,7 +68,7 @@ test_gradient_consistency(const auto & element) // loop on the quadrature points mito::tensor::constexpr_for_1([&]() { - // the barycentric coordinates of the quadrature point + // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); // compute the sum of the shape functions at {xi} for all nodes diff --git a/tests/mito.lib/fem/shape_functions_triangle_p1.cc b/tests/mito.lib/fem/shape_functions_triangle_p1.cc index db8e9ad2..482b339b 100644 --- a/tests/mito.lib/fem/shape_functions_triangle_p1.cc +++ b/tests/mito.lib/fem/shape_functions_triangle_p1.cc @@ -9,7 +9,7 @@ // first order shape functions type using shape_t = mito::fem::ShapeTriangleP1; -// the barycentric coordinates type +// the parametric coordinates type using parametric_coordinates_type = shape_t::reference_element_type::parametric_coordinates_type; diff --git a/tests/mito.lib/fem/shape_functions_triangle_p2.cc b/tests/mito.lib/fem/shape_functions_triangle_p2.cc index 48a4673a..ce3886bb 100644 --- a/tests/mito.lib/fem/shape_functions_triangle_p2.cc +++ b/tests/mito.lib/fem/shape_functions_triangle_p2.cc @@ -9,8 +9,8 @@ // second order shape functions type using shape_t = mito::fem::ShapeTriangleP2; -// the barycentric coordinates type -using barycentric_coordinates_t = shape_t::reference_element_type::parametric_coordinates_type; +// the parametric coordinates type +using parametric_coordinates_t = shape_t::reference_element_type::parametric_coordinates_type; TEST(Fem, ShapeTriangleP2) @@ -18,18 +18,18 @@ TEST(Fem, ShapeTriangleP2) // second order shape functions constexpr auto element = shape_t(); - // node 0 in barycentric coordinates - constexpr auto n0 = barycentric_coordinates_t{ 0.0, 0.0 }; - // node 1 in barycentric coordinates - constexpr auto n1 = barycentric_coordinates_t{ 1.0, 0.0 }; - // node 2 in barycentric coordinates - constexpr auto n2 = barycentric_coordinates_t{ 0.0, 1.0 }; - // node 3 in barycentric coordinates - constexpr auto n3 = barycentric_coordinates_t{ 0.5, 0.0 }; - // node 4 in barycentric coordinates - constexpr auto n4 = barycentric_coordinates_t{ 0.5, 0.5 }; - // node 5 in barycentric coordinates - constexpr auto n5 = barycentric_coordinates_t{ 0.0, 0.5 }; + // node 0 in parametric coordinates + constexpr auto n0 = parametric_coordinates_t{ 0.0, 0.0 }; + // node 1 in parametric coordinates + constexpr auto n1 = parametric_coordinates_t{ 1.0, 0.0 }; + // node 2 in parametric coordinates + constexpr auto n2 = parametric_coordinates_t{ 0.0, 1.0 }; + // node 3 in parametric coordinates + constexpr auto n3 = parametric_coordinates_t{ 0.5, 0.0 }; + // node 4 in parametric coordinates + constexpr auto n4 = parametric_coordinates_t{ 0.5, 0.5 }; + // node 5 in parametric coordinates + constexpr auto n5 = parametric_coordinates_t{ 0.0, 0.5 }; // the shape functions at node 0 constexpr auto phi_0 = element.shape<0>(); From 35ac669fb13a94a5792108c87f80973ff954432a Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:07:09 +0200 Subject: [PATCH 38/52] fem/blocks: use uniform initializer in method {compute} --- lib/mito/fem/blocks/GradGradBlock.h | 2 +- lib/mito/fem/blocks/L2NormBlock.h | 2 +- lib/mito/fem/blocks/MassBlock.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mito/fem/blocks/GradGradBlock.h b/lib/mito/fem/blocks/GradGradBlock.h index 2243f45f..b95b5499 100644 --- a/lib/mito/fem/blocks/GradGradBlock.h +++ b/lib/mito/fem/blocks/GradGradBlock.h @@ -35,7 +35,7 @@ namespace mito::fem::blocks { constexpr int n_quads = quadrature_rule_type::npoints; // the elementary matrix - elementary_block_type elementary_matrix; + elementary_block_type elementary_matrix{}; // loop on the quadrature points tensor::constexpr_for_1([&]() { diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 7541096b..5b053e44 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -42,7 +42,7 @@ namespace mito::fem::blocks { constexpr int n_quads = quadrature_rule_type::npoints; // the elementary contribution to the L2 norm - auto elementary_contribution = elementary_block_type{}; + elementary_block_type elementary_contribution = elementary_block_type{}; // loop on the quadrature points tensor::constexpr_for_1([&]() { diff --git a/lib/mito/fem/blocks/MassBlock.h b/lib/mito/fem/blocks/MassBlock.h index 76fbe758..d32a31a3 100644 --- a/lib/mito/fem/blocks/MassBlock.h +++ b/lib/mito/fem/blocks/MassBlock.h @@ -35,7 +35,7 @@ namespace mito::fem::blocks { constexpr int n_quads = quadrature_rule_type::npoints; // the elementary matrix - elementary_block_type elementary_matrix; + elementary_block_type elementary_matrix{}; // loop on the quadrature points tensor::constexpr_for_1([&]() { From 0ae5f25de313d18a317e6919a79e55286151e79e Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:08:07 +0200 Subject: [PATCH 39/52] fem/blocks: in {SourceTermBlock} replace {elementary_rhs} with {elementary_vector} --- lib/mito/fem/blocks/SourceTermBlock.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mito/fem/blocks/SourceTermBlock.h b/lib/mito/fem/blocks/SourceTermBlock.h index 252ec57c..f1a3bdcc 100644 --- a/lib/mito/fem/blocks/SourceTermBlock.h +++ b/lib/mito/fem/blocks/SourceTermBlock.h @@ -43,8 +43,8 @@ namespace mito::fem::blocks { // the number of quadrature points per element constexpr int n_quads = quadrature_rule_type::npoints; - // the elementary rhs - elementary_block_type elementary_rhs{}; + // the elementary vector + elementary_block_type elementary_vector{}; // loop on the quadrature points tensor::constexpr_for_1([&]() { @@ -65,13 +65,13 @@ namespace mito::fem::blocks { tensor::constexpr_for_1([&]() { // evaluate the a-th shape function at {xi} auto phi_a = element.template shape()(xi); - // populate the elementary contribution to the rhs - elementary_rhs[{ a }] += factor * _source_field(coord) * phi_a; + // populate the elementary contribution to the vector + elementary_vector[{ a }] += factor * _source_field(coord) * phi_a; }); }); // all done - return elementary_rhs; + return elementary_vector; } private: From e79e2008ce57a86fed91cd9719612853b8f18318 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:08:37 +0200 Subject: [PATCH 40/52] mito: consistency fix after rev. a9e3bfc --- lib/mito/fem/blocks/L2NormBlock.h | 2 +- lib/mito/fem/blocks/SourceTermBlock.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 5b053e44..89590fb5 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -46,7 +46,7 @@ namespace mito::fem::blocks { // loop on the quadrature points tensor::constexpr_for_1([&]() { - // the barycentric coordinates of the quadrature point + // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); // the quadrature weight at this point scaled with the area of the canonical simplex diff --git a/lib/mito/fem/blocks/SourceTermBlock.h b/lib/mito/fem/blocks/SourceTermBlock.h index f1a3bdcc..6d4c548e 100644 --- a/lib/mito/fem/blocks/SourceTermBlock.h +++ b/lib/mito/fem/blocks/SourceTermBlock.h @@ -48,7 +48,7 @@ namespace mito::fem::blocks { // loop on the quadrature points tensor::constexpr_for_1([&]() { - // the barycentric coordinates of the quadrature point + // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); // the coordinates of the quadrature point From f7ecdb45a21825b2a8051dd8c806c011e6ed2f12 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:10:24 +0200 Subject: [PATCH 41/52] fem/blocks: add concept {element_of_type_c} --- lib/mito/fem/blocks/forward.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/mito/fem/blocks/forward.h b/lib/mito/fem/blocks/forward.h index 909b6f19..97d18c1a 100644 --- a/lib/mito/fem/blocks/forward.h +++ b/lib/mito/fem/blocks/forward.h @@ -27,6 +27,10 @@ namespace mito::fem::blocks { requires(std::is_same_v< typename functionT::input_type, typename quadratureRuleT::quadrature_point_type>) class L2NormBlock; + + // concept of {T} being a finite element of type {elementT} + template + concept element_of_type_c = std::same_as; } From 642c81633f341fd41ada359bf02aec3505116b86 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:29:26 +0200 Subject: [PATCH 42/52] fem/blocks: clarify roles of {finiteElementT} and {elementT} in method {compute} --- lib/mito/fem/blocks/GradGradBlock.h | 17 ++++++++++------- lib/mito/fem/blocks/L2NormBlock.h | 19 +++++++++++-------- lib/mito/fem/blocks/MassBlock.h | 17 ++++++++++------- lib/mito/fem/blocks/SourceTermBlock.h | 17 ++++++++++------- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/lib/mito/fem/blocks/GradGradBlock.h b/lib/mito/fem/blocks/GradGradBlock.h index b95b5499..7bcbcd1e 100644 --- a/lib/mito/fem/blocks/GradGradBlock.h +++ b/lib/mito/fem/blocks/GradGradBlock.h @@ -9,12 +9,12 @@ namespace mito::fem::blocks { - template + template class GradGradBlock { public: // my template parameters - using element_type = elementT; + using element_type = finiteElementT; using elementary_block_type = tensor::matrix_t; using quadrature_rule_type = quadratureRuleT; @@ -24,9 +24,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - template - requires(std::is_same_v) - auto compute(const elementType & element) const -> elementary_block_type + template + requires element_of_type_c + auto compute(const elementT & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; @@ -42,9 +42,12 @@ namespace mito::fem::blocks { // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); + // the measure of the canonical simplex + constexpr auto measure = + element_type::mesh_cell_type::reference_simplex_type::measure; + // the quadrature weight at this point scaled with the area of the canonical simplex - constexpr auto w = - elementType::canonical_element_type::measure * quadrature_rule.weight(q); + constexpr auto w = measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 89590fb5..5bc9cec1 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -9,7 +9,7 @@ namespace mito::fem::blocks { - template + template // require that {functionT} is a function in parametric coordinates requires(std::is_same_v< typename functionT::input_type, typename quadratureRuleT::quadrature_point_type>) @@ -17,7 +17,7 @@ namespace mito::fem::blocks { public: // my template parameters - using element_type = elementT; + using element_type = finiteElementT; using elementary_block_type = tensor::scalar_t; using quadrature_rule_type = quadratureRuleT; @@ -34,24 +34,27 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - template - requires(std::is_same_v) - auto compute(const elementType & element) const -> elementary_block_type + template + requires element_of_type_c + auto compute(const elementT & element) const -> elementary_block_type { // the number of quadrature points per element constexpr int n_quads = quadrature_rule_type::npoints; // the elementary contribution to the L2 norm - elementary_block_type elementary_contribution = elementary_block_type{}; + elementary_block_type elementary_contribution{}; // loop on the quadrature points tensor::constexpr_for_1([&]() { // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); + // the measure of the canonical simplex + constexpr auto measure = + element_type::mesh_cell_type::reference_simplex_type::measure; + // the quadrature weight at this point scaled with the area of the canonical simplex - constexpr auto w = - elementType::canonical_element_type::measure * quadrature_rule.weight(q); + constexpr auto w = measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/MassBlock.h b/lib/mito/fem/blocks/MassBlock.h index d32a31a3..b57199b0 100644 --- a/lib/mito/fem/blocks/MassBlock.h +++ b/lib/mito/fem/blocks/MassBlock.h @@ -9,12 +9,12 @@ namespace mito::fem::blocks { - template + template class MassBlock { public: // my template parameters - using element_type = elementT; + using element_type = finiteElementT; using elementary_block_type = tensor::matrix_t; using quadrature_rule_type = quadratureRuleT; @@ -24,9 +24,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - template - requires(std::is_same_v) - auto compute(const elementType & element) const -> elementary_block_type + template + requires(element_of_type_c) + auto compute(const elementT & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; @@ -42,9 +42,12 @@ namespace mito::fem::blocks { // the parametric coordinates of the quadrature point constexpr auto xi = quadrature_rule.point(q); + // the measure of the canonical simplex + constexpr auto measure = + element_type::mesh_cell_type::reference_simplex_type::measure; + // the quadrature weight at this point scaled with the area of the canonical simplex - constexpr auto w = - elementType::canonical_element_type::measure * quadrature_rule.weight(q); + constexpr auto w = measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); diff --git a/lib/mito/fem/blocks/SourceTermBlock.h b/lib/mito/fem/blocks/SourceTermBlock.h index 6d4c548e..9c9c565e 100644 --- a/lib/mito/fem/blocks/SourceTermBlock.h +++ b/lib/mito/fem/blocks/SourceTermBlock.h @@ -11,12 +11,12 @@ namespace mito::fem::blocks { // TOFIX: the source does not need to be necessarily a scalar field, it can be some other field // see if we can use {field_c} instead of {scalar_field_c} - template + template class SourceTermBlock { public: // my template parameters - using element_type = elementT; + using element_type = finiteElementT; using elementary_block_type = tensor::vector_t; using quadrature_rule_type = quadratureRuleT; @@ -33,9 +33,9 @@ namespace mito::fem::blocks { public: // compute the elementary contribution of this block - template - requires(std::is_same_v) - auto compute(const elementType & element) const -> elementary_block_type + template + requires(element_of_type_c) + auto compute(const elementT & element) const -> elementary_block_type { // the number of nodes per element constexpr int n_nodes = element_type::n_nodes; @@ -54,9 +54,12 @@ namespace mito::fem::blocks { // the coordinates of the quadrature point auto coord = element.parametrization()(xi); + // the measure of the canonical simplex + constexpr auto measure = + element_type::mesh_cell_type::reference_simplex_type::measure; + // the quadrature weight at this point scaled with the area of the canonical simplex - constexpr auto w = - elementType::canonical_element_type::measure * quadrature_rule.weight(q); + constexpr auto w = measure * quadrature_rule.weight(q); // precompute the common factor auto factor = w * tensor::determinant(element.jacobian()(xi)); From b33dafe91b9a240c1a9eadb7a4965bafc21a5f39 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:30:14 +0200 Subject: [PATCH 43/52] fem/blocks: readability improvements --- lib/mito/fem/blocks/L2NormBlock.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mito/fem/blocks/L2NormBlock.h b/lib/mito/fem/blocks/L2NormBlock.h index 5bc9cec1..4e0be6dc 100644 --- a/lib/mito/fem/blocks/L2NormBlock.h +++ b/lib/mito/fem/blocks/L2NormBlock.h @@ -42,7 +42,7 @@ namespace mito::fem::blocks { constexpr int n_quads = quadrature_rule_type::npoints; // the elementary contribution to the L2 norm - elementary_block_type elementary_contribution{}; + elementary_block_type norm{}; // loop on the quadrature points tensor::constexpr_for_1([&]() { @@ -60,11 +60,11 @@ namespace mito::fem::blocks { auto factor = w * tensor::determinant(element.jacobian()(xi)); // populate the elementary contribution to the matrix - elementary_contribution += factor * _function(xi) * _function(xi); + norm += factor * _function(xi) * _function(xi); }); // all done - return elementary_contribution; + return norm; } private: From 9be085f3f08b40031170992e34db9782b2711c45 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 16:35:06 +0200 Subject: [PATCH 44/52] fem: require that isoparametric element are built on top of a parametrized element --- lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h | 2 +- lib/mito/fem/elements/seg1/forward.h | 2 +- lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h | 2 +- lib/mito/fem/elements/tri1/forward.h | 2 +- lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h | 2 +- lib/mito/fem/elements/tri2/forward.h | 2 +- lib/mito/manifolds/forward.h | 9 +++++++++ 7 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h index 6bae15a0..09760dcf 100644 --- a/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h +++ b/lib/mito/fem/elements/seg1/IsoparametricSegmentP1.h @@ -14,7 +14,7 @@ namespace mito::fem { - template + template class IsoparametricSegmentP1 : public utilities::Invalidatable { public: diff --git a/lib/mito/fem/elements/seg1/forward.h b/lib/mito/fem/elements/seg1/forward.h index 8d151773..37e87e6a 100644 --- a/lib/mito/fem/elements/seg1/forward.h +++ b/lib/mito/fem/elements/seg1/forward.h @@ -10,7 +10,7 @@ namespace mito::fem { // forward declaration of the class {IsoparametricSegmentP1} - template + template class IsoparametricSegmentP1; } diff --git a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h index 86797d6e..c6c56e35 100644 --- a/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h +++ b/lib/mito/fem/elements/tri1/IsoparametricTriangleP1.h @@ -14,7 +14,7 @@ namespace mito::fem { - template + template class IsoparametricTriangleP1 : public utilities::Invalidatable { public: diff --git a/lib/mito/fem/elements/tri1/forward.h b/lib/mito/fem/elements/tri1/forward.h index becdaae0..05e9bf6a 100644 --- a/lib/mito/fem/elements/tri1/forward.h +++ b/lib/mito/fem/elements/tri1/forward.h @@ -10,7 +10,7 @@ namespace mito::fem { // forward declaration of the class {IsoparametricTriangleP1} - template + template class IsoparametricTriangleP1; } diff --git a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h index 2ef55175..5f6e41aa 100644 --- a/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h +++ b/lib/mito/fem/elements/tri2/IsoparametricTriangleP2.h @@ -14,7 +14,7 @@ namespace mito::fem { - template + template class IsoparametricTriangleP2 : public utilities::Invalidatable { public: diff --git a/lib/mito/fem/elements/tri2/forward.h b/lib/mito/fem/elements/tri2/forward.h index f79d2bb2..e515b042 100644 --- a/lib/mito/fem/elements/tri2/forward.h +++ b/lib/mito/fem/elements/tri2/forward.h @@ -10,7 +10,7 @@ namespace mito::fem { // forward declaration of the class {IsoparametricTriangleP2} - template + template class IsoparametricTriangleP2; } diff --git a/lib/mito/manifolds/forward.h b/lib/mito/manifolds/forward.h index 382d5d5f..cb6154e8 100644 --- a/lib/mito/manifolds/forward.h +++ b/lib/mito/manifolds/forward.h @@ -35,6 +35,15 @@ namespace mito::manifolds { const Manifold &) { }(c); }; + + // concept of a parametrized element + template + concept parametrized_element_c = requires(F c) { + // require that F only binds to {ParametrizedElement} specializations with 1D cells + []( + const ParametrizedElement &) { + }(c); + }; } From 361bd60900c20ad3effbdd267d35348af5975346 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 19:43:39 +0200 Subject: [PATCH 45/52] fem: in function {finite_element} require that {finiteElementTraits} and {parametrizedElementT} are compatibile --- lib/mito/fem/elements/api.h | 1 + lib/mito/fem/elements/forward.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/lib/mito/fem/elements/api.h b/lib/mito/fem/elements/api.h index 1890c6b4..30d9ff29 100644 --- a/lib/mito/fem/elements/api.h +++ b/lib/mito/fem/elements/api.h @@ -11,6 +11,7 @@ namespace mito::fem { // factory of finite element from a parametrized element template + requires compatible_element_type_c constexpr auto finite_element( const parametrizedElementT & element, const typename finiteElementTraits::connectivity_type & connectivity) diff --git a/lib/mito/fem/elements/forward.h b/lib/mito/fem/elements/forward.h index 36e247d2..9ecbc31a 100644 --- a/lib/mito/fem/elements/forward.h +++ b/lib/mito/fem/elements/forward.h @@ -18,6 +18,11 @@ namespace mito::fem { template struct isoparametric_simplex; + // concept of {parametrizedElementT} being compatible with finite elements of type + // {finiteElementT} + template + concept compatible_element_type_c = std::same_as< + typename finiteElementT::mesh_cell_type, typename parametrizedElementT::cell_type>; } From 9bb31eac910374c231423640f693c6c4cdf5651c Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 19:44:01 +0200 Subject: [PATCH 46/52] fem: add compatibility check in {function_space} --- lib/mito/fem/api.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/mito/fem/api.h b/lib/mito/fem/api.h index 85d2e19c..6e351d1a 100644 --- a/lib/mito/fem/api.h +++ b/lib/mito/fem/api.h @@ -23,6 +23,9 @@ namespace mito::fem { // function space factory template < class elementT, manifolds::manifold_c manifoldT, constraints::constraint_c constraintsT> + // require compatibility between the manifold cell and the finite element cell + requires( + std::is_same_v) constexpr auto function_space(const manifoldT & manifold, const constraintsT & constraints); // function space elements view alias From 60359060dc846aad557d9573b7b2f3842a47335e Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 20:11:58 +0200 Subject: [PATCH 47/52] manifolds: remove {manifold} factory function with implicit assumption of Euclidean metric space --- .../mito.lib/integration/integration.cc | 4 +++- benchmarks/mito.lib/pdes/poisson.cc | 4 +++- extensions/mito/mito.cc | 9 ++++---- lib/mito/manifolds/api.h | 6 ----- lib/mito/manifolds/factories.h | 22 +------------------ tests/mito.lib/fem/fem_field.cc | 4 +++- .../integration/divergence_theorem.cc | 4 +++- .../integration/quadrature_load_mesh_2D.cc | 4 +++- .../quadrature_load_mesh_2D_mpi.cc | 4 +++- .../quadrature/quadrature_segment_1D.cc | 4 +++- .../quadrature/quadrature_triangle_2D.cc | 4 +++- tutorial/4_divergence_theorem_2D/main.cc | 4 +++- 12 files changed, 33 insertions(+), 40 deletions(-) diff --git a/benchmarks/mito.lib/integration/integration.cc b/benchmarks/mito.lib/integration/integration.cc index 87678179..c7b81d97 100644 --- a/benchmarks/mito.lib/integration/integration.cc +++ b/benchmarks/mito.lib/integration/integration.cc @@ -8,6 +8,8 @@ // cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // the function extracting the {x_0} components of a 2D vector constexpr auto x_0 = mito::geometry::cartesian::x_0<2>; @@ -67,7 +69,7 @@ main() auto tetra_mesh = mito::mesh::tetra(mesh, coord_system, subdivisions); // create manifold from the mesh - auto manifold = mito::manifolds::manifold(tetra_mesh, coord_system); + auto manifold = mito::manifolds::manifold(tetra_mesh, coord_system, metric_space_t::w); // instantiate a scalar field auto f = mito::functions::cos(x_0 * x_1); diff --git a/benchmarks/mito.lib/pdes/poisson.cc b/benchmarks/mito.lib/pdes/poisson.cc index 85040fdf..4cca32bd 100644 --- a/benchmarks/mito.lib/pdes/poisson.cc +++ b/benchmarks/mito.lib/pdes/poisson.cc @@ -8,6 +8,8 @@ // cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // simplicial cells in 2D using cell_t = mito::geometry::triangle_t<2>; @@ -57,7 +59,7 @@ main() // auto mesh = mito::mesh::tetra(original_mesh, coord_system, subdivisions); // create the body manifold - auto manifold = mito::manifolds::manifold(mesh, coord_system); + auto manifold = mito::manifolds::manifold(mesh, coord_system, metric_space_t::w); // get the boundary mesh auto boundary_mesh = mito::mesh::boundary(mesh); diff --git a/extensions/mito/mito.cc b/extensions/mito/mito.cc index 7c15abbe..3ca9644c 100644 --- a/extensions/mito/mito.cc +++ b/extensions/mito/mito.cc @@ -135,10 +135,11 @@ PYBIND11_MODULE(mito, m) // done ; - + // alias for a the euclidean metric space in 2D + using euclidean_metric_2D_t = mito::geometry::euclidean_metric_space; // alias for a manifold of triangles embedded in 2D - using manifold_triangle_2D_t = decltype(mito::manifolds::manifold( - std::declval(), std::declval())); + using manifold_triangle_2D_t = mito::manifolds::manifold_t< + cell_2D_t, coordinates_2D_t, std::remove_cvref_t>; // the mito manifold interface mito::py::class_(m, "ManifoldTriangle2D") // the constructor @@ -147,7 +148,7 @@ PYBIND11_MODULE(mito, m) mito::py::init( [](const mesh_triangle_2D_t & mesh, const coordinate_system_2D_t & coord_system) { // create the manifold - return mito::manifolds::manifold(mesh, coord_system); + return mito::manifolds::manifold(mesh, coord_system, euclidean_metric_2D_t::w); })) // done ; diff --git a/lib/mito/manifolds/api.h b/lib/mito/manifolds/api.h index 012ec7a9..5740a0a6 100644 --- a/lib/mito/manifolds/api.h +++ b/lib/mito/manifolds/api.h @@ -35,12 +35,6 @@ namespace mito::manifolds { template using manifold_t = Manifold; - // factory of manifolds from a mesh and a coordinate system - template - constexpr auto manifold( - const mesh::mesh_t & mesh, - const geometry::coordinate_system_t & coordinate_system); - // factory submanifold from a mesh, a coordinate system and set of normal fields template constexpr auto submanifold( diff --git a/lib/mito/manifolds/factories.h b/lib/mito/manifolds/factories.h index 4db45e42..9c7ce140 100644 --- a/lib/mito/manifolds/factories.h +++ b/lib/mito/manifolds/factories.h @@ -38,27 +38,7 @@ namespace mito::manifolds { return manifold_t(mesh, coordinate_system, volume_form); } - // factory of manifolds from a mesh and a coordinate system - template - constexpr auto manifold( - const mesh::mesh_t & mesh, - const geometry::coordinate_system_t & coordinate_system) - { - // the mesh type - using mesh_type = mesh::mesh_t; - - // assert that the manifold is of the highest dimension - static_assert(mesh_type::dim == mesh_type::order); - - // the metric space type - using metric_space_type = geometry::euclidean_metric_space; - - // get the metric volume form - constexpr auto volume_form = metric_space_type::w; - - // return a new manifold - return manifold(mesh, coordinate_system, volume_form); - } + // TOFIX: this function only works for Euclidean metric spaces // factory of submanifolds from a mesh, a coordinate system and set of normal fields template diff --git a/tests/mito.lib/fem/fem_field.cc b/tests/mito.lib/fem/fem_field.cc index 2335269f..f2e3c572 100644 --- a/tests/mito.lib/fem/fem_field.cc +++ b/tests/mito.lib/fem/fem_field.cc @@ -9,6 +9,8 @@ // cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the euclidean metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // simplicial cells in 2D using cell_t = mito::geometry::triangle_t<2>; @@ -32,7 +34,7 @@ TEST(Fem, FemField) auto mesh = mito::io::summit::reader(fileStream, coord_system); // create the body manifold - auto manifold = mito::manifolds::manifold(mesh, coord_system); + auto manifold = mito::manifolds::manifold(mesh, coord_system, metric_space_t::w); // TOFIX: it should not be mandatory to set constraints to create a function space, let's remove // this bit once we implement constraints properly diff --git a/tests/mito.lib/integration/divergence_theorem.cc b/tests/mito.lib/integration/divergence_theorem.cc index 1a1f60bd..09440bca 100644 --- a/tests/mito.lib/integration/divergence_theorem.cc +++ b/tests/mito.lib/integration/divergence_theorem.cc @@ -13,6 +13,8 @@ using mito::quadrature::GAUSS; using mito::tensor::_; // the type of coordinates using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the euclidean metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // the function extracting the {x_0} component of a 2D vector constexpr auto x0 = mito::geometry::cartesian::x_0<2>; @@ -71,7 +73,7 @@ TEST(DivergenceTheorem, Mesh2D) mesh.insert({ node_4, node_0, node_3 }); // create the body manifold - auto bodyManifold = mito::manifolds::manifold(mesh, coord_system); + auto bodyManifold = mito::manifolds::manifold(mesh, coord_system, metric_space_t::w); // create the body integrator auto bodyIntegrator = mito::quadrature::integrator(bodyManifold); diff --git a/tests/mito.lib/integration/quadrature_load_mesh_2D.cc b/tests/mito.lib/integration/quadrature_load_mesh_2D.cc index 5c0ea629..f8a171ee 100644 --- a/tests/mito.lib/integration/quadrature_load_mesh_2D.cc +++ b/tests/mito.lib/integration/quadrature_load_mesh_2D.cc @@ -9,6 +9,8 @@ // cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the euclidean metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // the function extracting the {x_0} components of a 2D vector constexpr auto x_0 = mito::geometry::cartesian::x_0<2>; @@ -27,7 +29,7 @@ TEST(Quadrature, LoadMeshTriangles) // load mesh std::ifstream fileStream("square.summit"); auto mesh = mito::io::summit::reader>(fileStream, coord_system); - auto manifold = mito::manifolds::manifold(mesh, coord_system); + auto manifold = mito::manifolds::manifold(mesh, coord_system, metric_space_t::w); // instantiate a scalar field auto f = mito::functions::cos(x_0 * x_1); diff --git a/tests/mito.lib/integration/quadrature_load_mesh_2D_mpi.cc b/tests/mito.lib/integration/quadrature_load_mesh_2D_mpi.cc index 5a80aec8..1eafa14e 100644 --- a/tests/mito.lib/integration/quadrature_load_mesh_2D_mpi.cc +++ b/tests/mito.lib/integration/quadrature_load_mesh_2D_mpi.cc @@ -14,6 +14,8 @@ // cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the euclidean metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // the function extracting the {x_0} components of a 2D vector constexpr auto x_0 = mito::geometry::cartesian::x_0<2>; @@ -46,7 +48,7 @@ TEST(Quadrature, LoadMeshTrianglesMPI) auto mesh_partition = mito::mesh::metis::partition(mesh, n_tasks, task_id); // build the manifold on the partitioned mesh - auto manifold = mito::manifolds::manifold(mesh_partition, coord_system); + auto manifold = mito::manifolds::manifold(mesh_partition, coord_system, metric_space_t::w); // instantiate a scalar field auto f = mito::functions::cos(x_0 * x_1); diff --git a/tests/mito.lib/quadrature/quadrature_segment_1D.cc b/tests/mito.lib/quadrature/quadrature_segment_1D.cc index 74ad8dbc..5e28489b 100644 --- a/tests/mito.lib/quadrature/quadrature_segment_1D.cc +++ b/tests/mito.lib/quadrature/quadrature_segment_1D.cc @@ -9,6 +9,8 @@ // cartesian coordinates in 1D using coordinates_t = mito::geometry::coordinates_t<1, mito::geometry::CARTESIAN>; +// the euclidean metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // strip namespace using mito::tensor::vector_t; @@ -34,7 +36,7 @@ TEST(Quadrature, Segment) auto tetra_mesh = mito::mesh::tetra(mesh, coord_system, 12); // an integrator with degree of exactness 2 on segment (0, 1) - auto manifold = mito::manifolds::manifold(tetra_mesh, coord_system); + auto manifold = mito::manifolds::manifold(tetra_mesh, coord_system, metric_space_t::w); auto integrator = mito::quadrature::integrator(manifold); // a scalar function diff --git a/tests/mito.lib/quadrature/quadrature_triangle_2D.cc b/tests/mito.lib/quadrature/quadrature_triangle_2D.cc index ed06c870..092ce533 100644 --- a/tests/mito.lib/quadrature/quadrature_triangle_2D.cc +++ b/tests/mito.lib/quadrature/quadrature_triangle_2D.cc @@ -13,6 +13,8 @@ using mito::quadrature::GAUSS; // alias for a set of cartesian coordinates in 2D using coordinates_t = mito::geometry::coordinates_t<2, mito::geometry::CARTESIAN>; +// the euclidean metric space type +using metric_space_t = mito::geometry::euclidean_metric_space; // the function extracting the {x_0} components of a 2D vector constexpr auto x_0 = mito::geometry::cartesian::x_0<2>; @@ -63,7 +65,7 @@ TEST(Quadrature, Square) mesh.insert({ node_4, node_0, node_3 }); // This instantiates a quad rule on the cells (pairing cell type and degree of exactness) - auto bodyManifold = mito::manifolds::manifold(mesh, coord_system); + auto bodyManifold = mito::manifolds::manifold(mesh, coord_system, metric_space_t::w); auto bodyIntegrator = mito::quadrature::integrator(bodyManifold); diff --git a/tutorial/4_divergence_theorem_2D/main.cc b/tutorial/4_divergence_theorem_2D/main.cc index 876615d2..d0d8c70e 100644 --- a/tutorial/4_divergence_theorem_2D/main.cc +++ b/tutorial/4_divergence_theorem_2D/main.cc @@ -13,6 +13,8 @@ using mito::quadrature::GAUSS; // the type of coordinates using coordinates_t = geometry::cartesian::coordinates_t<2>; +// the euclidean metric space type +using metric_space_t = geometry::euclidean_metric_space; // the function extracting the {x_0} component of a 2D vector constexpr auto x_0 = geometry::cartesian::x_0<2>; @@ -77,7 +79,7 @@ main() mesh.insert({ node_4, node_0, node_3 }); // create the body manifold - auto bodyManifold = manifolds::manifold(mesh, coord_system); + auto bodyManifold = manifolds::manifold(mesh, coord_system, metric_space_t::w); // create the body integrator auto bodyIntegrator = quadrature::integrator(bodyManifold); From b96318cd6dba73125a51ec0e7857af810fd62e05 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 20:16:21 +0200 Subject: [PATCH 48/52] tutorial: adjust tutorials to use {operator} namespace (rev. cd653dd) --- tutorial/3_fields/main.cc | 1 + tutorial/4_divergence_theorem_2D/main.cc | 1 + tutorial/5_divergence_theorem_2D_in_3D/main.cc | 1 + 3 files changed, 3 insertions(+) diff --git a/tutorial/3_fields/main.cc b/tutorial/3_fields/main.cc index 4141a651..4cbc787c 100644 --- a/tutorial/3_fields/main.cc +++ b/tutorial/3_fields/main.cc @@ -10,6 +10,7 @@ // strip namespace using namespace mito; using namespace mito::fields; +using namespace mito::operators; using namespace mito::tensor; // the type of coordinates diff --git a/tutorial/4_divergence_theorem_2D/main.cc b/tutorial/4_divergence_theorem_2D/main.cc index d0d8c70e..d7fed817 100644 --- a/tutorial/4_divergence_theorem_2D/main.cc +++ b/tutorial/4_divergence_theorem_2D/main.cc @@ -9,6 +9,7 @@ // strip namespace using namespace mito; using namespace mito::fields; +using namespace mito::operators; using mito::quadrature::GAUSS; // the type of coordinates diff --git a/tutorial/5_divergence_theorem_2D_in_3D/main.cc b/tutorial/5_divergence_theorem_2D_in_3D/main.cc index e2a6e452..86a05d03 100644 --- a/tutorial/5_divergence_theorem_2D_in_3D/main.cc +++ b/tutorial/5_divergence_theorem_2D_in_3D/main.cc @@ -9,6 +9,7 @@ // strip namespace using namespace mito; using namespace mito::fields; +using namespace mito::operators; using mito::quadrature::GAUSS; // the type of coordinates From c096d02eed90c513384f606c171dee637e020ff1 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Mon, 22 Jun 2026 20:20:09 +0200 Subject: [PATCH 49/52] manifolds: remove addressed {TOFIX} (rev. 6035906) --- lib/mito/manifolds/factories.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/mito/manifolds/factories.h b/lib/mito/manifolds/factories.h index 9c7ce140..7836f4df 100644 --- a/lib/mito/manifolds/factories.h +++ b/lib/mito/manifolds/factories.h @@ -38,8 +38,6 @@ namespace mito::manifolds { return manifold_t(mesh, coordinate_system, volume_form); } - // TOFIX: this function only works for Euclidean metric spaces - // factory of submanifolds from a mesh, a coordinate system and set of normal fields template constexpr auto submanifold( From a3e17b6f6b30121ff9dddd436a0d8def47583a76 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi Date: Thu, 25 Jun 2026 20:46:07 +0200 Subject: [PATCH 50/52] manifolds: remove unused {print} method --- lib/mito/manifolds/Manifold.h | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/lib/mito/manifolds/Manifold.h b/lib/mito/manifolds/Manifold.h index 1472072d..18699b36 100644 --- a/lib/mito/manifolds/Manifold.h +++ b/lib/mito/manifolds/Manifold.h @@ -76,28 +76,6 @@ namespace mito::manifolds { // return an iterable view of the manifold elements constexpr auto elements() const noexcept { return manifold_elements_view_type{ *this }; } - constexpr auto print() const -> void - { - // make a channel - journal::info_t channel("mito.manifold"); - - // print the element set of the manifold - channel << "Element set: " << journal::endl; - - for (const auto & e : _mesh.cells()) { - // print the elemental composition - channel << "Composition: " << journal::endl; - channel << e; - // and the coordinates of the vertices - channel << "Vertices: " << journal::endl; - auto nodes = e.nodes(); - for (const auto & v : nodes) { - channel << coordinates(v) << journal::endl; - } - channel << journal::endl; - } - } - public: // return the manifold element associated to a cell constexpr auto element(const cell_type & cell) const From d794a33511cbc82a3dc576527ca03339b0b3cd78 Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi <62774069+biancagi@users.noreply.github.com> Date: Thu, 25 Jun 2026 20:48:15 +0200 Subject: [PATCH 51/52] manifolds: in class {ParametrizedElement} return cell, parametrization and metric volume form by reference Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- lib/mito/manifolds/ParametrizedElement.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mito/manifolds/ParametrizedElement.h b/lib/mito/manifolds/ParametrizedElement.h index cbebb343..b8b17f53 100644 --- a/lib/mito/manifolds/ParametrizedElement.h +++ b/lib/mito/manifolds/ParametrizedElement.h @@ -51,13 +51,13 @@ namespace mito::manifolds { public: // return the underlying cell - constexpr auto cell() const -> cell_type { return _cell; } + constexpr auto cell() const -> const cell_type & { return _cell; } // return the parametrization of this element in physical space - constexpr auto parametrization() const -> parametrization_type { return _parametrization; } + constexpr auto parametrization() const -> const parametrization_type & { return _parametrization; } // return the metric volume form of this element - constexpr auto metric_volume_form() const -> metric_volume_form_type + constexpr auto metric_volume_form() const -> const metric_volume_form_type & { return _metric_volume_form; } From ef4380b292313082540beeeb3c2be11f7435a55f Mon Sep 17 00:00:00 2001 From: Bianca Giovanardi <62774069+biancagi@users.noreply.github.com> Date: Thu, 25 Jun 2026 20:48:45 +0200 Subject: [PATCH 52/52] fem: remove redundant forward declaration Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- lib/mito/fem/forward.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/mito/fem/forward.h b/lib/mito/fem/forward.h index 67a167f0..706f9826 100644 --- a/lib/mito/fem/forward.h +++ b/lib/mito/fem/forward.h @@ -26,10 +26,6 @@ namespace mito::fem { template class FunctionSpaceElementsView; - // class function space elements view - template - class FunctionSpaceElementsView; - template concept compatible_assembly_blocks_c = std::is_same_v;