diff --git a/.arcconfig b/.arcconfig index def1b2165..e17567c1b 100644 --- a/.arcconfig +++ b/.arcconfig @@ -1,7 +1,7 @@ { "repository.callsign" : "AKAPRIV", "phabricator.uri" : "https://c4science.ch/", - "load" : [ ".linters/clang-format-linter" ], "history.immutable" : true, + "load" : [ ".linters/clang-format-linter" ], "projects": "akantu-developers" } diff --git a/.arclint b/.arclint index f98064824..50876d186 100644 --- a/.arclint +++ b/.arclint @@ -1,19 +1,23 @@ { "linters": { "format": { "type": "clang-format", "include": [ "(\\.cc$)", "(\\.hh$)" ], "exclude": "(^third-party/)" }, "python": { - "type": "pyflakes", - "bin": "pyflakes3", + "type": "flake8", "include": [ "(\\.py$)" ], - "exclude": "(^third-party/)" + "exclude": "(^third-party/)", + "severity.rules": { + "(^E)": "error", + "(^W)": "warning", + "(^F)": "advice" + } }, "merges": { "type": "merge-conflict" } } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c723f373..fe21ba339 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,194 +1,198 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Jun 14 2010 # @date last modification: Fri Jan 22 2016 # # @brief main configuration file # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # # @section DESCRIPTION #------------------------------------------------------------------------------- # _ _ # | | | | # __ _| | ____ _ _ __ | |_ _ _ # / _` | |/ / _` | '_ \| __| | | | # | (_| | < (_| | | | | |_| |_| | # \__,_|_|\_\__,_|_| |_|\__|\__,_| # #=============================================================================== #=============================================================================== # CMake Project #=============================================================================== cmake_minimum_required(VERSION 3.1.3) # add this options before PROJECT keyword set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) project(Akantu) enable_language(CXX) #=============================================================================== # Misc. config for cmake #=============================================================================== set(AKANTU_CMAKE_DIR "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules") + set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries.") +set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL + "Enable/Disable output of compile commands during generation" FORCE) + mark_as_advanced(BUILD_SHARED_LIBS) if(NOT AKANTU_TARGETS_EXPORT) set(AKANTU_TARGETS_EXPORT AkantuTargets) endif() include(CMakeVersionGenerator) include(CMakePackagesSystem) include(CMakeFlagsHandling) include(AkantuPackagesSystem) include(AkantuMacros) include(AkantuCleaning) #cmake_activate_debug_message() #=============================================================================== # Version Number #=============================================================================== # AKANTU version number. An even minor number corresponds to releases. set(AKANTU_MAJOR_VERSION 3) set(AKANTU_MINOR_VERSION 0) set(AKANTU_PATCH_VERSION 0) define_project_version() #=============================================================================== # Options #=============================================================================== # Debug set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DAKANTU_NDEBUG" CACHE STRING "Flags used by the compiler during release builds" FORCE) #add_flags(cxx "-Wall -Wextra -pedantic -Werror") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") add_flags(cxx "-Wall -Wextra -pedantic") # -Weffc++ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG_INIT} -ggdb3" CACHE STRING "Flags used by the compiler during debug builds" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT} -ggdb3" CACHE STRING "Flags used by the compiler during debug builds" FORCE) else() add_flags(cxx "-Wall") endif() option(AKANTU_EXAMPLES "Activate examples" OFF) option(AKANTU_TESTS "Activate tests" OFF) set(AKANTU_PREFERRED_PYTHON_VERSION 3 CACHE STRING "Preferred version for python related things") mark_as_advanced(AKANTU_PREFERRED_PYTHON_VERSION) include(AkantuExtraCompilationProfiles) #=============================================================================== # Dependencies #=============================================================================== declare_akantu_types() package_list_packages(${PROJECT_SOURCE_DIR}/packages EXTRA_PACKAGES_FOLDER ${PROJECT_SOURCE_DIR}/extra_packages NO_AUTO_COMPILE_FLAGS) ## meta option \todo better way to do it when multiple package give enable the ## same feature if(AKANTU_SCOTCH) set(AKANTU_PARTITIONER ON) else() set(AKANTU_PARTITIONER OFF) endif() if(AKANTU_MUMPS) set(AKANTU_SOLVER ON) else() set(AKANTU_SOLVER OFF) endif() #=============================================================================== # Akantu library #=============================================================================== add_subdirectory(src) #=============================================================================== # Documentation #=============================================================================== if(AKANTU_DOCUMENTATION_DOXYGEN OR AKANTU_DOCUMENTATION_MANUAL) add_subdirectory(doc) else() set(AKANTU_DOC_EXCLUDE_FILES "${PROJECT_SOURCE_DIR}/doc/manual" CACHE INTERNAL "") endif() #=============================================================================== # Examples and tests #=============================================================================== include(AkantuTestsMacros) include(AkantuExampleMacros) if(AKANTU_TESTS) option(AKANTU_BUILD_ALL_TESTS "Build all tests" ON) find_package(GMSH REQUIRED) # package_is_activated(pybind11 _pybind11_act) # if(_pybind11_act) # find_package(pybind11 CONFIG REQUIRED QUIET) # to get the pybind11_add_module macro # endif() endif() if(AKANTU_EXAMPLES) find_package(GMSH REQUIRED) add_subdirectory(examples) endif() # tests add_test_tree(test) #=============================================================================== # Python interface #=============================================================================== package_is_activated(python_interface _python_act) if(_python_act) if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") set(AKANTU_PYTHON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) else() set(AKANTU_PYTHON_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}") endif() add_subdirectory(python) endif() #=============================================================================== # Install and Packaging #=============================================================================== include(AkantuInstall) option(AKANTU_DISABLE_CPACK "This option commands the generation of extra info for the \"make package\" target" ON) mark_as_advanced(AKANTU_DISABLE_CPACK) if(NOT AKANTU_DISABLE_CPACK) include(AkantuCPack) endif() diff --git a/Jenkinsfile b/Jenkinsfile index cfa30bfd5..8921bb666 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,128 +1,185 @@ pipeline { parameters {string(defaultValue: '', description: 'api-token', name: 'API_TOKEN') - string(defaultValue: '', description: 'buildable phid', name: 'TARGET_PHID') + string(defaultValue: '', description: 'buildable phid', name: 'BUILD_TARGET_PHID') string(defaultValue: '', description: 'Commit id', name: 'COMMIT_ID') string(defaultValue: '', description: 'Diff id', name: 'DIFF_ID') - } + } options { disableConcurrentBuilds() } + environment { + PHABRICATOR_HOST = 'https://c4science.ch/api/' + PYTHONPATH = sh returnStdout: true, script: 'echo ${WORKSPACE}/test/ci/script/' + BLA_VENDOR = 'OpenBLAS' + OMPI_MCA_plm = 'isolated' + OMPI_MCA_btl = 'tcp,self' + } + agent { dockerfile { + filename 'Dockerfile' + dir 'test/ci' additionalBuildArgs '--tag akantu-environment' } } + stages { + stage('Lint') { + steps { + sh """ + arc lint --output json --rev ${GIT_PREVIOUS_COMMIT}^1 | jq . -srM | tee lint.json + ./test/ci/scripts/hbm send-arc-lint -f lint.json + """ + } + } stage('Configure') { steps { - sh """ - env - mkdir -p build - cd build - cmake -DAKANTU_COHESIVE_ELEMENT:BOOL=TRUE -DAKANTU_IMPLICIT:BOOL=TRUE -DAKANTU_PARALLEL:BOOL=TRUE -DAKANTU_PYTHON_INTERFACE:BOOL=TRUE -DAKANTU_TESTS:BOOL=TRUE .. - """ + sh """#!/bin/bash + set -o pipefail + mkdir -p build + cd build + cmake -DAKANTU_COHESIVE_ELEMENT:BOOL=TRUE \ + -DAKANTU_IMPLICIT:BOOL=TRUE \ + -DAKANTU_PARALLEL:BOOL=TRUE \ + -DAKANTU_PYTHON_INTERFACE:BOOL=TRUE \ + -DAKANTU_TESTS:BOOL=TRUE .. | tee configure.txt + """ + } + post { + failure { + uploadArtifact('configure.txt', 'Configure') + deleteDir() + } } } stage('Compile') { steps { - sh 'make -C build/src || true' + sh '''#!/bin/bash + set -o pipefail + make -C build/src | tee compilation.txt + ''' + } + post { + failure { + uploadArtifact('compilation.txt', 'Compilation') + } } } stage ('Warnings gcc') { steps { warnings(consoleParsers: [[parserName: 'GNU Make + GNU C Compiler (gcc)']]) } } stage('Compile python') { steps { - sh 'make -C build/python || true' + sh '''#!/bin/bash + set -o pipefail + make -C build/python | tee compilation_python.txt + ''' + } + post { + failure { + uploadArtifact('compilation_python.txt', 'Compilation_Python') + } } } stage('Compile tests') { steps { - sh 'make -C build/test || true' + sh '''#!/bin/bash + set -o pipefail + make -C build/test | tee compilation_test.txt + ''' + } + post { + failure { + uploadArtifact('compilation_test.txt', 'Compilation_Tests') + } } } stage('Tests') { steps { - sh """ - rm -rf build/gtest_reports - cd build/ - #source ./akantu_environement.sh - ctest -T test --no-compress-output || true - TAG=`head -n 1 < build/Testing/TAG` - if [ -e build/Testing/${TAG}/Test.xml ]; then - cp build/Testing/${TAG}/Test.xml CTestResults.xml - fi - """ + sh ''' + #rm -rf build/gtest_reports + cd build/ + #source ./akantu_environement.sh + + ctest -T test --no-compress-output || true + ''' + } + post { + always { + script { + def TAG = sh returnStdout: true, script: 'head -n 1 < build/Testing/TAG' + def TAG_ = TAG.trim() + + if (fileExists("build/Testing/${TAG}/Test.xml")) { + sh "cp build/Testing/${TAG}/Test.xml CTestResults.xml" + } + } + } } } } - environment { - BLA_VENDOR = 'OpenBLAS' - OMPI_MCA_plm = 'isolated' - OMPI_MCA_btl = 'tcp,self' - } + post { always { + createArtifact("./CTestResults.xml") + step([$class: 'XUnitBuilder', - thresholds: [ - [$class: 'SkippedThreshold', failureThreshold: '0'], - [$class: 'FailedThreshold', failureThreshold: '0']], - tools: [[$class: 'CTestType', pattern: 'CTestResults.xml']]]) - step([$class: 'XUnitBuilder', - thresholds: [ - [$class: 'SkippedThreshold', failureThreshold: '100'], - [$class: 'FailedThreshold', failureThreshold: '0']], - tools: [[$class: 'GoogleTestType', pattern: 'build/gtest_reports/**']]]) - archiveArtifacts artifacts: 'build/Testing/**', fingerprint: true - createartifact() + thresholds: [ + [$class: 'SkippedThreshold', failureThreshold: '0'], + [$class: 'FailedThreshold', failureThreshold: '0']], + tools: [ + [$class: 'CTestType', pattern: 'CTestResults.xml', skipNoTestFiles: true] + ]]) + + // step([$class: 'XUnitBuilder', + // thresholds: [ + // [$class: 'SkippedThreshold', failureThreshold: '100'], + // [$class: 'FailedThreshold', failureThreshold: '0']], + // tools: [ + // [$class: 'GoogleTestType', pattern: 'build/gtest_reports/**', skipNoTestFiles: true] + // ]]) } success { - send_fail_pass('pass') + passed() } failure { - emailext( - body: '''${SCRIPT, template="groovy-html.template"}''', - mimeType: 'text/html', - subject: "[Jenkins] ${currentBuild.fullDisplayName} Failed", - recipientProviders: [[$class: 'CulpritsRecipientProvider']], - to: 'akantu-admins@akantu.ch', - replyTo: 'akantu-admins@akantu.ch', - attachLog: true, - compressLog: false) - send_fail_pass('fail') + // emailext( + // body: '''${SCRIPT, template="groovy-html.template"}''', + // mimeType: 'text/html', + // subject: "[Jenkins] ${currentBuild.fullDisplayName} Failed", + // recipientProviders: [[$class: 'CulpritsRecipientProvider']], + // to: 'akantu-admins@akantu.ch', + // replyTo: 'akantu-admins@akantu.ch', + // attachLog: true, + // compressLog: false) + failed() } } } -def send_fail_pass(state) { - sh """ -set +x -curl https://c4science.ch/api/harbormaster.sendmessage \ --d api.token=${API_TOKEN} \ --d buildTargetPHID=${TARGET_PHID} \ --d type=${state} -""" +def failed() { + sh "./test/ci/scripts/hbm failed" +} + +def passed() { + sh "./test/ci/scripts/hbm passed" +} + +def createArtifact(artifact) { + sh "./test/ci/scripts/hbm send-uri -k 'Jenkins URI' -u ${BUILD_URL} -l 'View Jenkins result'" + sh "./test/ci/scripts/hbm send-ctest-results -f ${artifact}" } -def createartifact() { - sh """ set +x -curl https://c4science.ch/api/harbormaster.createartifact \ --d api.token=${API_TOKEN} \ --d buildTargetPHID=${TARGET_PHID} \ --d artifactKey="Jenkins URI" \ --d artifactType=uri \ --d artifactData[uri]=${BUILD_URL} \ --d artifactData[name]="View Jenkins result" \ --d artifactData[ui.external]=1 -""" +def uploadArtifact(artifact, name) { + sh "./test/ci/scripts/hbm upload-file -f ${artifact} -n \"${name}\" -v PHID-PROJ-5eqyu6ooyjktagbhf473" } diff --git a/cmake/AkantuCleaning.cmake b/cmake/AkantuCleaning.cmake index 39202265c..8fd50e667 100644 --- a/cmake/AkantuCleaning.cmake +++ b/cmake/AkantuCleaning.cmake @@ -1,85 +1,82 @@ #=============================================================================== # @file AkantuCleaning.cmake # # @author Nicolas Richart # # @date creation: Thu Jun 1, 2017 # # @brief set of tools to clean the code # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . #=============================================================================== # Adding clang-format target if executable is found find_program(CLANG_FORMAT "clang-format") mark_as_advanced(CLANG_FORMAT) macro(register_code_to_format) if(CLANG_FORMAT) add_custom_target( clang-format-all COMMAND ${CLANG_FORMAT} -i -style=file ${ARGN} ) endif() endmacro() # Adding clang-tidy target if executable is found find_program(CLANG_TIDY "clang-tidy") mark_as_advanced(CLANG_TIDY) macro(register_target_to_tidy target) if(CLANG_TIDY) option(AKANTU_CLANG_TIDY_AUTOFIX OFF) mark_as_advanced(AKANTU_CLANG_TIDY_AUTOFIX) set(_autofix_option) if(AKANTU_CLANG_TIDY_AUTOFIX) set(_autofix_option -fix) endif() get_target_property(_sources ${target} SOURCES) - set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL - "Enable/Disable output of compile commands during generation" FORCE) - file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/clang-tidy) set(_depends) foreach(_src ${_sources}) get_filename_component(_src_dir ${_src} DIRECTORY) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/clang-tidy/${_src_dir}) add_custom_command( OUTPUT ${PROJECT_BINARY_DIR}/clang-tidy/${_src}.yaml COMMAND ${CLANG_TIDY} -p=${PROJECT_BINARY_DIR} -export-fixes=${PROJECT_BINARY_DIR}/clang-tidy/${_src}.yaml ${_autofix_option} ${_src} COMMENT "Tidying ${_src}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) list(APPEND _depends ${PROJECT_BINARY_DIR}/clang-tidy/${_src}.yaml) endforeach() add_custom_target(clang-tidy DEPENDS ${_depends}) endif() endmacro() diff --git a/cmake/akantu_environement.csh.in b/cmake/akantu_environement.csh.in index 3bd1c5304..ced66f50d 100644 --- a/cmake/akantu_environement.csh.in +++ b/cmake/akantu_environement.csh.in @@ -1,2 +1,2 @@ -setenv PYTHONPATH $PYTHONPATH:"@PROJECT_BINARY_DIR@/python" +setenv PYTHONPATH $PYTHONPATH:"@PROJECT_BINARY_DIR@/python":"@PROJECT_BINARY_DIR@/test":"@PROJECT_SOURCE_DIR@/test/test_fe_engine" setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:"@PROJECT_BINARY_DIR@/src" diff --git a/cmake/akantu_environement.sh.in b/cmake/akantu_environement.sh.in index 762163e14..25623af38 100644 --- a/cmake/akantu_environement.sh.in +++ b/cmake/akantu_environement.sh.in @@ -1,2 +1,2 @@ -export PYTHONPATH=$PYTHONPATH:"@PROJECT_BINARY_DIR@/python":"@PROJECT_SOURCE_DIR@/test":"@PROJECT_SOURCE_DIR@/test/test_fe_engine" +export PYTHONPATH=$PYTHONPATH:"@PROJECT_BINARY_DIR@/python":"@PROJECT_SOURCE_DIR@/python":"@PROJECT_BINARY_DIR@/test":"@PROJECT_SOURCE_DIR@/test/test_fe_engine" export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:"@PROJECT_BINARY_DIR@/src" diff --git a/cmake/akantu_test_driver.sh b/cmake/akantu_test_driver.sh index a8a281918..452591ed8 100755 --- a/cmake/akantu_test_driver.sh +++ b/cmake/akantu_test_driver.sh @@ -1,145 +1,145 @@ #!/bin/bash set -o errexit set -o pipefail show_help() { cat << EOF Usage: ${0##*/} -n NAME -e EXECUTABLE [-p MPI_WRAPPER] [-s SCRIPT_FILE] [-r REFERENCE_FILE] [-w WORKING_DIR] [ARGS] Execute the test in the good configuration according to the options given -e EXECUTABLE Main executable of the test -n NAME Name of the test -p MPI_WRAPPER Executes the test for multiple parallel configuration -s SCRIPT_FILE Script to execute after the execution of the test to postprocess the results -r REFERENCE_FILE Reference file to compare with if the name of the file contains a this will be used for the different configuration when -p is given -w WORKING_DIR The directory in which to execute the test -E ENVIRONMENT_FILE File to source before running tests -h Print this helps EOF } full_redirect() { local nproc=$1 shift local name=$1 shift local sout=".lastout" local serr=".lasterr" if [ ${nproc} -ne 0 ]; then sout="-${nproc}${sout}" serr="-${nproc}${serr}" fi echo "Run $*" (($* | tee "${name}${sout}") 3>&1 1>&2 2>&3 | tee "${name}${serr}") 3>&1 1>&2 2>&3 lastout="${name}${sout}" } name= executable= parallel= postprocess_script= reference= working_dir= envi= parallel_processes="2" while : do case "$1" in -e) executable=$2 shift 2 ;; -E) envi="$2" shift 2 ;; -h | --help) show_help exit 0 ;; -n) name="$2" shift 2 ;; -N) parallel_processes="$2" shift 2 ;; -p) parallel="$2" shift 2 ;; -r) reference="$2" shift 2 ;; -s) postprocess_script="$2" shift 2 ;; -w) working_dir="$2" shift 2 ;; --) # End of all options shift break ;; -*) echo "Error: Unknown option: $1" >&2 show_help exit 1 ;; *) #No more options break ;; esac done _args=$@ if [ -n "${envi}" ]; then source ${envi} fi if [ -z "${name}" -o -z "${executable}" ]; then echo "Missing executable or name" show_help exit 1 fi if [ -n "${working_dir}" ]; then current_directory=$PWD echo "Entering directory ${working_dir}" cd "${working_dir}" fi if [ -z "${parallel}" ]; then echo "Executing the test ${name}" full_redirect 0 ${name} "${executable} ${_args}" else #for i in ${parallel_processes}; do i=${parallel_processes} echo "Executing the test ${name} for ${i} procs" full_redirect $i ${name}_$i "${parallel} ${i} ${executable} ${_args}" #done fi if [ -n "${postprocess_script}" ]; then echo "Executing the test ${name} post-processing" full_redirect 0 ${name}_pp ./${postprocess_script} fi if [ -n "${reference}" ]; then echo "Comparing last generated output to the reference file" - diff ${lastout} ${reference} + diff -w ${lastout} ${reference} fi diff --git a/examples/boundary_conditions/predefined_bc/predefined_bc.cc b/examples/boundary_conditions/predefined_bc/predefined_bc.cc index 8810ff5f6..2dc36fe21 100644 --- a/examples/boundary_conditions/predefined_bc/predefined_bc.cc +++ b/examples/boundary_conditions/predefined_bc/predefined_bc.cc @@ -1,63 +1,62 @@ /** * @file predefined_bc.cc * * @author Nicolas Richart * * @date creation: Wed Dec 16 2015 * @date last modification: Mon Jan 18 2016 * * @brief boundary condition example * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char * argv[]) { initialize("material.dat", argc, argv); Mesh mesh(2); mesh.read("square.msh"); - mesh.createGroupsFromMeshData("physical_names"); // model initialization SolidMechanicsModel model(mesh); model.initFull(); // Dirichlet boundary conditions model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x"); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y"); // output in a paraview file model.setBaseName("plate"); model.addDumpFieldVector("displacement"); model.addDumpField("blocked_dofs"); - model.addDumpField("force"); + model.addDumpField("external_force"); model.dump(); finalize(); return EXIT_SUCCESS; } diff --git a/examples/boundary_conditions/predefined_bc/square.geo b/examples/boundary_conditions/predefined_bc/square.geo index 3c299d0ec..cf29e6b07 100644 --- a/examples/boundary_conditions/predefined_bc/square.geo +++ b/examples/boundary_conditions/predefined_bc/square.geo @@ -1,29 +1,29 @@ // Mesh size h = 0.005; // Dimensions of the square Lx = 0.01; Ly = 0.01; // ------------------------------------------ // Geometry // ------------------------------------------ Point(1) = { 0.0, 0.0, 0.0, h}; Point(2) = { Lx, 0.0, 0.0, h}; Point(3) = { Lx, Ly, 0.0, h}; Point(4) = { 0.0, Ly, 0.0, h}; Line(1) = {1, 2}; Line(2) = {2, 3}; Line(3) = {3, 4}; Line(4) = {4, 1}; Line Loop(1) = {1:4}; Plane Surface(1) = {1}; -Physical Surface(1) = {1}; +Physical Surface("steel") = {1}; Physical Line("Fixed_y") = {1}; Physical Line("Fixed_x") = {4}; Physical Line("Traction") = {2}; Physical Line("Free") = {3}; diff --git a/examples/boundary_conditions/user_defined_bc/fine_mesh.geo b/examples/boundary_conditions/user_defined_bc/fine_mesh.geo index b22399597..f8165adb5 100644 --- a/examples/boundary_conditions/user_defined_bc/fine_mesh.geo +++ b/examples/boundary_conditions/user_defined_bc/fine_mesh.geo @@ -1,29 +1,29 @@ // Mesh size h = 0.1; // Dimensions of the square Lx = 2; Ly = 2; // ------------------------------------------ // Geometry // ------------------------------------------ Point(1) = { 0.0, 0.0, 0.0, h}; Point(2) = { Lx, 0.0, 0.0, h}; Point(3) = { Lx, Ly, 0.0, h}; Point(4) = { 0.0, Ly, 0.0, h}; Line(1) = {1, 2}; Line(2) = {2, 3}; Line(3) = {3, 4}; Line(4) = {4, 1}; Line Loop(1) = {1:4}; Plane Surface(1) = {1}; -Physical Surface(1) = {1}; +Physical Surface("steel") = {1}; Physical Line("Fixed_y") = {1}; Physical Line("Fixed_x") = {4}; Physical Line("Traction") = {2}; Physical Line("Free") = {3}; diff --git a/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc index 3bdbbee4a..80bc7bcc7 100644 --- a/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc +++ b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc @@ -1,89 +1,88 @@ /** * @file user_defined_bc.cc * * @author Aurelia Isabel Cuba Ramos * * @date creation: Wed Dec 16 2015 * @date last modification: Mon Jan 18 2016 * * @brief user-defined boundary condition example * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ using namespace akantu; class SineBoundary : public BC::Dirichlet::DirichletFunctor { public: SineBoundary(Real amp, Real phase, BC::Axis ax = _x) : DirichletFunctor(ax), amplitude(amp), phase(phase) {} public: inline void operator()(__attribute__((unused)) UInt node, Vector & flags, Vector & primal, const Vector & coord) const { DIRICHLET_SANITY_CHECK; flags(axis) = true; primal(axis) = -amplitude * std::sin(phase * coord(1)); } protected: Real amplitude; Real phase; }; /* -------------------------------------------------------------------------- */ int main(int argc, char * argv[]) { initialize("material.dat", argc, argv); UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); mesh.read("fine_mesh.msh"); SolidMechanicsModel model(mesh); /// model initialization model.initFull(); /// boundary conditions - mesh.createGroupsFromMeshData("physical_names"); Vector traction(2, 0.2); model.applyBC(SineBoundary(.2, 10., _x), "Fixed_x"); model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Fixed_y"); model.applyBC(BC::Neumann::FromTraction(traction), "Traction"); // output a paraview file with the boundary conditions model.setBaseName("plate"); model.addDumpFieldVector("displacement"); - model.addDumpFieldVector("force"); + model.addDumpFieldVector("external_force"); model.addDumpField("blocked_dofs"); model.dump(); finalize(); return EXIT_SUCCESS; } diff --git a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc index a5c165c81..df76899ae 100644 --- a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc +++ b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc @@ -1,125 +1,126 @@ /** * @file cohesive_extrinsic.cc * * @author Seyedeh Mohadeseh Taheri Mousavi * @author Marco Vocialta * * @date creation: Mon Jan 18 2016 * * @brief Test for cohesive elements * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "solid_mechanics_model_cohesive.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char * argv[]) { initialize("material.dat", argc, argv); const UInt spatial_dimension = 2; const UInt max_steps = 1000; Mesh mesh(spatial_dimension); mesh.read("triangle.msh"); SolidMechanicsModelCohesive model(mesh); /// model initialization model.initFull( - SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true)); + _analysis_method = _explicit_lumped_mass, + _is_extrinsic = true); Real time_step = model.getStableTimeStep() * 0.05; model.setTimeStep(time_step); std::cout << "Time step: " << time_step << std::endl; CohesiveElementInserter & inserter = model.getElementInserter(); inserter.setLimit(_y, 0.30, 0.20); model.updateAutomaticInsertion(); Array & position = mesh.getNodes(); Array & velocity = model.getVelocity(); Array & boundary = model.getBlockedDOFs(); Array & displacement = model.getDisplacement(); UInt nb_nodes = mesh.getNbNodes(); /// boundary conditions for (UInt n = 0; n < nb_nodes; ++n) { if (position(n, 1) > 0.99 || position(n, 1) < -0.99) boundary(n, 1) = true; if (position(n, 0) > 0.99 || position(n, 0) < -0.99) boundary(n, 0) = true; } model.setBaseName("extrinsic"); model.addDumpFieldVector("displacement"); model.addDumpField("velocity"); model.addDumpField("acceleration"); - model.addDumpField("residual"); + model.addDumpField("internal_force"); model.addDumpField("stress"); model.addDumpField("grad_u"); model.dump(); /// initial conditions Real loading_rate = 0.5; Real disp_update = loading_rate * time_step; for (UInt n = 0; n < nb_nodes; ++n) { velocity(n, 1) = loading_rate * position(n, 1); } /// Main loop for (UInt s = 1; s <= max_steps; ++s) { /// update displacement on extreme nodes for (UInt n = 0; n < nb_nodes; ++n) { if (position(n, 1) > 0.99 || position(n, 1) < -0.99) displacement(n, 1) += disp_update * position(n, 1); } model.checkCohesiveStress(); model.solveStep(); if (s % 10 == 0) { model.dump(); std::cout << "passing step " << s << "/" << max_steps << std::endl; } } Real Ed = model.getEnergy("dissipated"); Real Edt = 200 * std::sqrt(2); std::cout << Ed << " " << Edt << std::endl; if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) { std::cout << "The dissipated energy is incorrect" << std::endl; return EXIT_FAILURE; } finalize(); return EXIT_SUCCESS; } diff --git a/examples/cohesive_element/cohesive_extrinsic/material.dat b/examples/cohesive_element/cohesive_extrinsic/material.dat index 788956e3d..490b0b039 100644 --- a/examples/cohesive_element/cohesive_extrinsic/material.dat +++ b/examples/cohesive_element/cohesive_extrinsic/material.dat @@ -1,14 +1,14 @@ material elastic [ name = steel rho = 1e3 # density E = 1e3 # young's modulus nu = 0.001 # poisson's ratio ] material cohesive_linear [ name = cohesive beta = 1 - G_cI = 100 - G_cII = 100 + G_c = 100 + kappa = 1 sigma_c = 100 uniform [0, 0] ] diff --git a/examples/cohesive_element/cohesive_extrinsic_ig_tg/material.dat b/examples/cohesive_element/cohesive_extrinsic_ig_tg/material.dat index 7dcb6ff29..9220b0096 100644 --- a/examples/cohesive_element/cohesive_extrinsic_ig_tg/material.dat +++ b/examples/cohesive_element/cohesive_extrinsic_ig_tg/material.dat @@ -1,20 +1,20 @@ material elastic [ name = steel rho = 1e3 # density E = 1e3 # young's modulus nu = 0.0 # poisson's ratio ] material cohesive_linear [ name = tg_cohesive beta = 0 - G_cI = 10 + G_c = 10 sigma_c = 100 ] material cohesive_linear [ name = ig_cohesive beta = 0 - G_cI = 10 + G_c = 10 sigma_c = 20 ] diff --git a/examples/embedded/embedded.cc b/examples/embedded/embedded.cc index a8e36c6ab..9f13a5610 100644 --- a/examples/embedded/embedded.cc +++ b/examples/embedded/embedded.cc @@ -1,104 +1,98 @@ /** * @file embedded.cc * * @author Lucas Frerot * * @date creation: Tue Dec 01 2015 * @date last modification: Mon Jan 18 2016 * * @brief This code gives an example of a simulation using the embedded model * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "embedded_interface_model.hh" #include "non_linear_solver.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char * argv[]) { initialize("material.dat", argc, argv); const UInt dim = 2; // Loading the concrete mesh Mesh mesh(dim); mesh.read("concrete.msh"); - // Necessary to define physical names - mesh.createGroupsFromMeshData("physical_names"); - // Loading the reinforcement mesh Mesh reinforcement_mesh(dim, "reinforcement_mesh"); // Exception is raised because reinforcement // mesh contains only segments, i.e. 1D elements try { reinforcement_mesh.read("reinforcement.msh"); } catch (debug::Exception & e) { } - // Necessary to define physical names as well - reinforcement_mesh.createGroupsFromMeshData("physical_names"); - // Model creation EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim); model.initFull(EmbeddedInterfaceModelOptions(_static)); // Boundary conditions model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked"); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked"); Vector force(dim); force(0) = 0.0; force(1) = -1.0; model.applyBC(BC::Neumann::FromTraction(force), "Force"); // Dumping the concrete model.setBaseName("concrete"); model.addDumpFieldVector("displacement"); - model.addDumpFieldVector("force"); - model.addDumpFieldVector("residual"); + model.addDumpFieldVector("external_force"); + model.addDumpFieldVector("internal_force"); model.addDumpFieldTensor("stress"); // Dumping the reinforcement model.setBaseNameToDumper("reinforcement", "reinforcement"); model.addDumpFieldTensorToDumper( "reinforcement", "stress_embedded"); // dumping stress in reinforcement auto & solver = model.getNonLinearSolver(); solver.set("max_iterations", 1); solver.set("threshold", 1e-6); solver.set("convergence_type", SolveConvergenceCriteria::_residual); model.solveStep(); // Dumping model model.dump(); model.dump("reinforcement"); finalize(); return EXIT_SUCCESS; } diff --git a/examples/implicit/implicit_dynamic.cc b/examples/implicit/implicit_dynamic.cc index 3ba97796a..210be4f38 100644 --- a/examples/implicit/implicit_dynamic.cc +++ b/examples/implicit/implicit_dynamic.cc @@ -1,148 +1,148 @@ /** * @file implicit_dynamic.cc * * @author Nicolas Richart * * @date creation: Sun Oct 19 2014 * * @brief This code refers to the implicit dynamic example from the user manual * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "communicator.hh" #include "non_linear_solver.hh" #include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; /* -------------------------------------------------------------------------- */ const Real bar_length = 10.; const Real bar_height = 1.; const Real bar_depth = 1.; const Real F = 5e3; const Real L = bar_length; const Real I = bar_depth * bar_height * bar_height * bar_height / 12.; const Real E = 12e7; const Real rho = 1000; const Real m = rho * bar_height * bar_depth; static Real w(UInt n) { return n * n * M_PI * M_PI / (L * L) * sqrt(E * I / m); } static Real analytical_solution(Real time) { return 2 * F * L * L * L / (pow(M_PI, 4) * E * I) * ((1. - cos(w(1) * time)) + (1. - cos(w(3) * time)) / 81. + (1. - cos(w(5) * time)) / 625.); } const UInt spatial_dimension = 2; const Real time_step = 1e-4; const Real max_time = 0.62; /* -------------------------------------------------------------------------- */ int main(int argc, char * argv[]) { initialize("material_dynamic.dat", argc, argv); Mesh mesh(spatial_dimension); const auto & comm = Communicator::getStaticCommunicator(); Int prank = comm.whoAmI(); if (prank == 0) mesh.read("beam.msh"); mesh.distribute(); SolidMechanicsModel model(mesh); /// model initialization model.initFull(_analysis_method = _implicit_dynamic); Material & mat = model.getMaterial(0); mat.setParam("E", E); mat.setParam("rho", rho); - Array & force = model.getForce(); + Array & force = model.getExternalForce(); Array & displacment = model.getDisplacement(); // boundary conditions model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "blocked"); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "blocked"); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "roller"); const Array & trac_nodes = mesh.getElementGroup("traction").getNodes(); bool dump_node = false; if (trac_nodes.size() > 0 && mesh.isLocalOrMasterNode(trac_nodes(0))) { force(trac_nodes(0), 1) = F; dump_node = true; } // output setup std::ofstream pos; pos.open("position.csv"); if (!pos.good()) AKANTU_ERROR("Cannot open file \"position.csv\""); pos << "id,time,position,solution" << std::endl; model.setBaseName("dynamic"); model.addDumpFieldVector("displacement"); model.addDumpField("velocity"); model.addDumpField("acceleration"); - model.addDumpField("force"); - model.addDumpField("residual"); + model.addDumpField("external_force"); + model.addDumpField("internal_force"); model.dump(); model.setTimeStep(time_step); auto & solver = model.getNonLinearSolver(); solver.set("max_iterations", 100); solver.set("threshold", 1e-12); solver.set("convergence_type", SolveConvergenceCriteria::_solution); /// time loop Real time = 0.; for (UInt s = 1; time < max_time; ++s, time += time_step) { if (prank == 0) std::cout << s << "\r" << std::flush; model.solveStep(); if (dump_node) pos << s << "," << time << "," << displacment(trac_nodes(0), 1) << "," << analytical_solution(s * time_step) << std::endl; if (s % 100 == 0) model.dump(); } std::cout << std::endl; pos.close(); finalize(); return EXIT_SUCCESS; } diff --git a/examples/io/dumper/dumpable_interface.cc b/examples/io/dumper/dumpable_interface.cc index 2f89815c5..dc4edaa50 100644 --- a/examples/io/dumper/dumpable_interface.cc +++ b/examples/io/dumper/dumpable_interface.cc @@ -1,186 +1,185 @@ /** * @file dumpable_interface.cc * * @author Fabian Barras * @author Nicolas Richart * * @date creation: Mon Aug 17 2015 * @date last modification: Mon Aug 31 2015 * * @brief Example of dumper::Dumpable interface. * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "element_group.hh" #include "group_manager_inline_impl.cc" #include "mesh.hh" /* -------------------------------------------------------------------------- */ #include "dumpable_inline_impl.hh" #include "dumper_iohelper_paraview.hh" /* -------------------------------------------------------------------------- */ #include "locomotive_tools.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char * argv[]) { /* In this example, we present dumper::Dumpable which is an interface for other classes who want to dump themselves. Several classes of Akantu inheritate from Dumpable (Model, Mesh, ...). In this example we reproduce the same tasks as example_dumper_low_level.cc using this time Dumpable interface inherted by Mesh, NodeGroup and ElementGroup. It is then advised to read first example_dumper_low_level.cc. */ initialize(argc, argv); // To start let us load the swiss train mesh and its mesh data information. UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); mesh.read("swiss_train.msh"); - mesh.createGroupsFromMeshData("physical_names"); /* swiss_train.msh has the following physical groups that can be viewed with GMSH: "$MeshFormat 2.2 0 8 $EndMeshFormat $PhysicalNames 6 2 1 "red" 2 2 "white" 2 3 "lwheel_1" 2 4 "lwheel_2" 2 5 "rwheel_2" 2 6 "rwheel_1" $EndPhysicalNames ..." */ // Grouping nodes and elements belonging to train wheels (=four mesh data). ElementGroup & wheels_elements = mesh.createElementGroup("wheels", spatial_dimension); wheels_elements.append(mesh.getElementGroup("lwheel_1")); wheels_elements.append(mesh.getElementGroup("lwheel_2")); wheels_elements.append(mesh.getElementGroup("rwheel_1")); wheels_elements.append(mesh.getElementGroup("rwheel_2")); const Array & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes(); const Array & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes(); const Array & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes(); const Array & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes(); Array & node = mesh.getNodes(); UInt nb_nodes = mesh.getNbNodes(); // This time a 2D Array is created and a padding size of 3 is passed to // NodalField in order to warp train deformation on Paraview. Array displacement(nb_nodes, spatial_dimension); // Create an ElementTypeMapArray for the colour ElementTypeMapArray colour("colour"); colour.initialize(mesh, _with_nb_element = true); /* ------------------------------------------------------------------------ */ /* Creating dumpers */ /* ------------------------------------------------------------------------ */ // Create dumper for the complete mesh and register it as default dumper. DumperParaview dumper("train", "./paraview/dumpable", false); mesh.registerExternalDumper(dumper, "train", true); mesh.addDumpMesh(mesh); // The dumper for the filtered mesh can be directly taken from the // ElementGroup and then registered as "wheels_elements" dumper. DumperIOHelper & wheels = mesh.getGroupDumper("paraview_wheels", "wheels"); mesh.registerExternalDumper(wheels, "wheels"); mesh.setDirectoryToDumper("wheels", "./paraview/dumpable"); // Arrays and ElementTypeMapArrays can be added as external fields directly mesh.addDumpFieldExternal("displacement", displacement); ElementTypeMapArrayFilter filtered_colour( colour, wheels_elements.getElements()); dumper::Field * colour_field_wheel = new dumper::ElementalField(filtered_colour); mesh.addDumpFieldExternal("color", colour_field_wheel); mesh.addDumpFieldExternalToDumper("wheels", "displacement", displacement); mesh.addDumpFieldExternalToDumper("wheels", "colour", colour); // For some specific cases the Fields should be created, as when you want to // pad an array dumper::Field * displacement_vector_field = mesh.createNodalField(&displacement, "all", 3); mesh.addDumpFieldExternal("displacement_as_paraview_vector", displacement_vector_field); mesh.addDumpFieldExternalToDumper("wheels", "displacement_as_paraview_vector", displacement_vector_field); /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ // Fill the ElementTypeMapArray colour. fillColour(mesh, colour); /// Apply displacement and wheels rotation. Real tot_displacement = 50.; Real radius = 1.; UInt nb_steps = 100; Real theta = tot_displacement / radius; Vector l_center(spatial_dimension); Vector r_center(spatial_dimension); for (UInt i = 0; i < spatial_dimension; ++i) { l_center(i) = node(14, i); r_center(i) = node(2, i); } for (UInt i = 0; i < nb_steps; ++i) { displacement.clear(); Real step_ratio = Real(i) / Real(nb_steps); Real angle = step_ratio * theta; applyRotation(l_center, angle, node, displacement, lnode_1); applyRotation(l_center, angle, node, displacement, lnode_2); applyRotation(r_center, angle, node, displacement, rnode_1); applyRotation(r_center, angle, node, displacement, rnode_2); for (UInt j = 0; j < nb_nodes; ++j) { displacement(j, _x) += step_ratio * tot_displacement; } /// Dump call is finally made through Dumpable interface. mesh.dump(); mesh.dump("wheels"); } finalize(); return 0; } diff --git a/examples/io/dumper/dumper_low_level.cc b/examples/io/dumper/dumper_low_level.cc index 83d5c577d..72d587b18 100644 --- a/examples/io/dumper/dumper_low_level.cc +++ b/examples/io/dumper/dumper_low_level.cc @@ -1,194 +1,193 @@ /** * @file dumper_low_level.cc * * @author Fabian Barras * @author Nicolas Richart * * @date creation: Mon Aug 17 2015 * * @brief Example of dumper::DumperIOHelper low-level methods. * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "element_group.hh" #include "group_manager.hh" #include "mesh.hh" #include "dumper_elemental_field.hh" #include "dumper_nodal_field.hh" #include "dumper_iohelper_paraview.hh" #include "locomotive_tools.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char * argv[]) { /* This example aims at illustrating how to manipulate low-level methods of DumperIOHelper. The aims is to visualize a colorized moving train with Paraview */ initialize(argc, argv); // To start let us load the swiss train mesh and its mesh data information. // We aknowledge here a weel-known swiss industry for mesh donation. UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); mesh.read("swiss_train.msh"); - mesh.createGroupsFromMeshData("physical_names"); Array & nodes = mesh.getNodes(); UInt nb_nodes = mesh.getNbNodes(); /* swiss_train.msh has the following physical groups that can be viewed with GMSH: "$MeshFormat 2.2 0 8 $EndMeshFormat $PhysicalNames 6 2 1 "red" 2 2 "white" 2 3 "lwheel_1" 2 4 "lwheel_2" 2 5 "rwheel_2" 2 6 "rwheel_1" $EndPhysicalNames ..." */ // Grouping nodes and elements belonging to train wheels (=four mesh data) ElementGroup & wheels_elements = mesh.createElementGroup("wheels", spatial_dimension); wheels_elements.append(mesh.getElementGroup("lwheel_1")); wheels_elements.append(mesh.getElementGroup("lwheel_2")); wheels_elements.append(mesh.getElementGroup("rwheel_1")); wheels_elements.append(mesh.getElementGroup("rwheel_2")); const Array & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes(); const Array & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes(); const Array & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes(); const Array & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes(); /* Note this Array is constructed with three components in order to warp train deformation on Paraview. A more appropriate way to do this is to set a padding in the NodalField (See example_dumpable_interface.cc.) */ Array displacement(nb_nodes, 3); // ElementalField are constructed with an ElementTypeMapArray. ElementTypeMapArray colour; colour.initialize(mesh, _with_nb_element = true); /* ------------------------------------------------------------------------ */ /* Dumper creation */ /* ------------------------------------------------------------------------ */ // Creation of two DumperParaview. One for full mesh, one for a filtered // mesh. DumperParaview dumper("train", "./paraview/dumper", false); DumperParaview wheels("wheels", "./paraview/dumper", false); // Register the full mesh dumper.registerMesh(mesh); // Register a filtered mesh limited to nodes and elements from wheels groups wheels.registerFilteredMesh(mesh, wheels_elements.getElements(), wheels_elements.getNodes()); // Generate an output file of the two mesh registered. dumper.dump(); wheels.dump(); /* At this stage no fields are attached to the two dumpers. To do so, a dumper::Field object has to be created. Several types of dumper::Field exist. In this example we present two of them. NodalField to describe nodal displacements of our train. ElementalField handling the color of our different part. */ // NodalField are constructed with an Array. dumper::Field * displ_field = new dumper::NodalField(displacement); dumper::Field * colour_field = new dumper::ElementalField(colour); // Register the freshly created fields to our dumper. dumper.registerField("displacement", displ_field); dumper.registerField("colour", colour_field); // For the dumper wheels, fields have to be filtered at registration. // Filtered NodalField can be simply registered by adding an Array // listing the nodes. dumper::Field * displ_field_wheel = new dumper::NodalField( displacement, 0, 0, &(wheels_elements.getNodes())); wheels.registerField("displacement", displ_field_wheel); // For the ElementalField, an ElementTypeMapArrayFilter has to be created. ElementTypeMapArrayFilter filtered_colour( colour, wheels_elements.getElements()); dumper::Field * colour_field_wheel = new dumper::ElementalField(filtered_colour); wheels.registerField("colour", colour_field_wheel); /* ------------------------------------------------------------------------ */ // Now that the dumpers are created and the fields are associated, let's // paint and move the train! // Fill the ElementTypeMapArray colour according to mesh data information. fillColour(mesh, colour); // Apply displacement and wheels rotation. Real tot_displacement = 50.; Real radius = 1.; UInt nb_steps = 100; Real theta = tot_displacement / radius; Vector l_center(3); Vector r_center(3); for (UInt i = 0; i < spatial_dimension; ++i) { l_center(i) = nodes(14, i); r_center(i) = nodes(2, i); } for (UInt i = 0; i < nb_steps; ++i) { displacement.clear(); Real angle = (Real)i / (Real)nb_steps * theta; applyRotation(l_center, angle, nodes, displacement, lnode_1); applyRotation(l_center, angle, nodes, displacement, lnode_2); applyRotation(r_center, angle, nodes, displacement, rnode_1); applyRotation(r_center, angle, nodes, displacement, rnode_2); for (UInt j = 0; j < nb_nodes; ++j) { displacement(j, 0) += (Real)i / (Real)nb_steps * tot_displacement; } // Output results after each moving steps for main and wheel dumpers. dumper.dump(); wheels.dump(); } finalize(); return 0; } diff --git a/examples/io/parser/example_parser.cc b/examples/io/parser/example_parser.cc index 02e6a2f07..ae8c01b92 100644 --- a/examples/io/parser/example_parser.cc +++ b/examples/io/parser/example_parser.cc @@ -1,88 +1,87 @@ /** * @file example_parser.cc * * @author Fabian Barras * * @date creation: Mon Dec 14 2015 * @date last modification: Mon Jan 18 2016 * * @brief Example on how to parse input text file * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "non_linear_solver.hh" #include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char * argv[]) { // Precise in initialize the name of the text input file to parse. initialize("input_file.dat", argc, argv); // Get the user ParserSection. const ParserSection & usersect = getUserParser(); // getParameterValue() allows to extract data associated to a given parameter // name // and cast it in the desired type set as template paramter. Mesh mesh(usersect.getParameterValue("spatial_dimension")); mesh.read(usersect.getParameterValue("mesh_file")); // getParameter() can be used with variable declaration (destination type is // explicitly known). - UInt max_iter = usersect.getParameter("max_nb_iterations"); + Int max_iter = usersect.getParameter("max_nb_iterations"); Real precision = usersect.getParameter("precision"); // Following NumPy convention, data can be interpreted as Vector or Matrix // structures. Matrix eigen_stress = usersect.getParameter("stress"); SolidMechanicsModel model(mesh); - mesh.createGroupsFromMeshData("physical_names"); model.initFull(SolidMechanicsModelOptions(_static)); model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), usersect.getParameterValue("outter_crust")); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), usersect.getParameterValue("outter_crust")); model.applyBC(BC::Neumann::FromStress(eigen_stress), usersect.getParameterValue("inner_holes")); model.setDirectory("./paraview"); model.setBaseName("swiss_cheese"); model.addDumpFieldVector("displacement"); auto & solver = model.getNonLinearSolver(); solver.set("max_iterations", max_iter); solver.set("threshold", precision); model.solveStep(); model.dump(); finalize(); return EXIT_SUCCESS; } diff --git a/examples/new_material/local_material_damage.cc b/examples/new_material/local_material_damage.cc index a3e79a20c..25f70524d 100644 --- a/examples/new_material/local_material_damage.cc +++ b/examples/new_material/local_material_damage.cc @@ -1,108 +1,112 @@ /** * @file local_material_damage.cc * * @author Guillaume Anciaux * @author Marion Estelle Chambart * @author Nicolas Richart * * @date creation: Mon Jan 18 2016 * * @brief Specialization of the material class for the damage material * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "local_material_damage.hh" #include "solid_mechanics_model.hh" namespace akantu { /* -------------------------------------------------------------------------- */ LocalMaterialDamage::LocalMaterialDamage(SolidMechanicsModel & model, const ID & id) : Material(model, id), damage("damage", *this) { AKANTU_DEBUG_IN(); this->registerParam("E", E, 0., _pat_parsable, "Young's modulus"); this->registerParam("nu", nu, 0.5, _pat_parsable, "Poisson's ratio"); this->registerParam("lambda", lambda, _pat_readable, "First Lamé coefficient"); this->registerParam("mu", mu, _pat_readable, "Second Lamé coefficient"); this->registerParam("kapa", kpa, _pat_readable, "Bulk coefficient"); this->registerParam("Yd", Yd, 50., _pat_parsmod); this->registerParam("Sd", Sd, 5000., _pat_parsmod); damage.initialize(1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); lambda = nu * E / ((1 + nu) * (1 - 2 * nu)); mu = E / (2 * (1 + nu)); kpa = lambda + 2. / 3. * mu; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real * dam = damage(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type); computeStressOnQuad(grad_u, sigma, *dam); ++dam; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Material::computePotentialEnergy(el_type, ghost_type); if (ghost_type != _not_ghost) return; Real * epot = potential_energy(el_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type); computePotentialEnergyOnQuad(grad_u, sigma, *epot); epot++; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } -/* -------------------------------------------------------------------------- */ +static bool material_is_alocated_local_damage [[gnu::unused]] = + MaterialFactory::getInstance().registerAllocator( + "local_damage", [](UInt, const ID &, SolidMechanicsModel & model, const ID & id) -> std::unique_ptr { + return std::make_unique(model, id); + }); } // akantu diff --git a/examples/new_material/new_local_material.cc b/examples/new_material/new_local_material.cc index 26dc9a14a..9c8559f0f 100644 --- a/examples/new_material/new_local_material.cc +++ b/examples/new_material/new_local_material.cc @@ -1,103 +1,103 @@ /** * @file new_local_material.cc * * @author Guillaume Anciaux * @author Marion Estelle Chambart * @author Nicolas Richart * * @date creation: Thu Aug 06 2015 * @date last modification: Mon Jan 18 2016 * * @brief test of the class SolidMechanicsModel * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "local_material_damage.hh" #include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ using namespace akantu; #define bar_length 10. #define bar_height 4. akantu::Real eps = 1e-10; int main(int argc, char * argv[]) { akantu::initialize("material.dat", argc, argv); UInt max_steps = 10000; Real epot, ekin; const UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); mesh.read("barre_trou.msh"); /// model creation SolidMechanicsModel model(mesh); /// model initialization model.initFull(_analysis_method = _explicit_lumped_mass); std::cout << model.getMaterial(0) << std::endl; Real time_step = model.getStableTimeStep(); model.setTimeStep(time_step / 10.); /// Dirichlet boundary conditions model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x"); model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y"); // Neumann boundary condition Matrix stress(2, 2); stress.eye(3e2); model.applyBC(BC::Neumann::FromStress(stress), "Traction"); model.setBaseName("local_material"); model.addDumpField("displacement"); model.addDumpField("velocity"); model.addDumpField("acceleration"); - model.addDumpField("force"); - model.addDumpField("residual"); + model.addDumpField("external_force"); + model.addDumpField("internal_force"); model.addDumpField("grad_u"); model.addDumpField("stress"); model.addDumpField("damage"); model.dump(); for (UInt s = 0; s < max_steps; ++s) { model.solveStep(); epot = model.getEnergy("potential"); ekin = model.getEnergy("kinetic"); if (s % 100 == 0) std::cout << s << " " << epot << " " << ekin << " " << epot + ekin << std::endl; if (s % 100 == 0) model.dump(); } akantu::finalize(); return EXIT_SUCCESS; } diff --git a/examples/new_material/viscoelastic_maxwell/material_viscoelastic_maxwell_energies.cc b/examples/new_material/viscoelastic_maxwell/material_viscoelastic_maxwell_energies.cc index 49f3b4ddd..79e7d170e 100644 --- a/examples/new_material/viscoelastic_maxwell/material_viscoelastic_maxwell_energies.cc +++ b/examples/new_material/viscoelastic_maxwell/material_viscoelastic_maxwell_energies.cc @@ -1,181 +1,180 @@ /** * @file material_viscoelastic_maxwell_energies.cc * * @author Emil Gallyamov * * @date creation: Tue Nov 20 2018 * @date last modification: * * @brief Example of using viscoelastic material and computing energies * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include #include #include /* -------------------------------------------------------------------------- */ #include "material_viscoelastic_maxwell.hh" #include "non_linear_solver.hh" #include "solid_mechanics_model.hh" #include "sparse_matrix.hh" using namespace akantu; /* -------------------------------------------------------------------------- */ /* Main */ /* -------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { akantu::initialize("material_viscoelastic_maxwell.dat", argc, argv); // sim data Real eps = 0.1; const UInt dim = 2; Real sim_time = 100.; Real T = 10.; Mesh mesh(dim); mesh.read("material_viscoelastic_maxwell_mesh.msh"); SolidMechanicsModel model(mesh); /* ------------------------------------------------------------------------ */ /* Initialization */ /* ------------------------------------------------------------------------ */ model.initFull(_analysis_method = _static); std::cout << model.getMaterial(0) << std::endl; std::stringstream filename_sstr; filename_sstr << "material_viscoelastic_maxwell_output.out"; std::ofstream output_data; output_data.open(filename_sstr.str().c_str()); Material &mat = model.getMaterial(0); Real time_step = 0.1; UInt nb_nodes = mesh.getNbNodes(); const Array &coordinate = mesh.getNodes(); Array &displacement = model.getDisplacement(); Array &blocked = model.getBlockedDOFs(); /// Setting time step model.setTimeStep(time_step); model.setBaseName("dynamic"); model.addDumpFieldVector("displacement"); model.addDumpField("blocked_dofs"); model.addDumpField("external_force"); model.addDumpField("internal_force"); model.addDumpField("grad_u"); model.addDumpField("stress"); model.addDumpField("strain"); UInt max_steps = sim_time / time_step + 1; Real time = 0.; auto &solver = model.getNonLinearSolver(); solver.set("max_iterations", 10); solver.set("threshold", 1e-7); solver.set("convergence_type", SolveConvergenceCriteria::_residual); /* ------------------------------------------------------------------------ */ /* Main loop */ /* ------------------------------------------------------------------------ */ for (UInt s = 0; s <= max_steps; ++s) { std::cout << "Time Step = " << time_step << "s" << std::endl; std::cout << "Time = " << time << std::endl; // impose displacement Real epsilon = 0; if (time < T) { epsilon = eps * time / T; } else { epsilon = eps; } for (UInt n = 0; n < nb_nodes; ++n) { if (Math::are_float_equal(coordinate(n, 0), 0.0)) { displacement(n, 0) = 0; blocked(n, 0) = true; displacement(n, 1) = epsilon * coordinate(n, 1); blocked(n, 1) = true; } else if (Math::are_float_equal(coordinate(n, 1), 0.0)) { displacement(n, 0) = epsilon * coordinate(n, 0); blocked(n, 0) = true; displacement(n, 1) = 0; blocked(n, 1) = true; } else if (Math::are_float_equal(coordinate(n, 0), 0.001)) { displacement(n, 0) = epsilon * coordinate(n, 0); blocked(n, 0) = true; displacement(n, 1) = epsilon * coordinate(n, 1); blocked(n, 1) = true; } else if (Math::are_float_equal(coordinate(n, 1), 0.001)) { displacement(n, 0) = epsilon * coordinate(n, 0); blocked(n, 0) = true; displacement(n, 1) = epsilon * coordinate(n, 1); blocked(n, 1) = true; } } try { model.solveStep(); } catch (debug::Exception &e) { } // for debugging // auto int_force = model.getInternalForce(); // auto &K = model.getDOFManager().getMatrix("K"); // K.saveMatrix("K.mtx"); Int nb_iter = solver.get("nb_iterations"); Real error = solver.get("error"); bool converged = solver.get("converged"); if (converged) { std::cout << "Converged in " << nb_iter << " iterations" << std::endl; } else { std::cout << "Didn't converge after " << nb_iter << " iterations. Error is " << error << std::endl; return EXIT_FAILURE; } model.dump(); Real epot = mat.getEnergy("potential"); Real edis = mat.getEnergy("dissipated"); Real work = mat.getEnergy("work"); // data output output_data << s * time_step << " " << epsilon - << " " << epot << " " << edis << " " << - work << std::endl; + << " " << epot << " " << edis << " " << work << std::endl; time += time_step; } output_data.close(); finalize(); } diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt index 9bea05474..c2e3d6d10 100644 --- a/examples/python/CMakeLists.txt +++ b/examples/python/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(plate-hole) add_subdirectory(custom-material) +add_subdirectory(stiffness_matrix) package_add_files_to_package( examples/python/README.rst ) diff --git a/examples/python/stiffness_matrix/CMakeLists.txt b/examples/python/stiffness_matrix/CMakeLists.txt new file mode 100644 index 000000000..1b507413b --- /dev/null +++ b/examples/python/stiffness_matrix/CMakeLists.txt @@ -0,0 +1,3 @@ +register_example(stiffness_matrix + SCRIPT stiffness_matrix.py + FILES_TO_COPY material.dat plate.geo) diff --git a/examples/python/stiffness_matrix/material.dat b/examples/python/stiffness_matrix/material.dat new file mode 100644 index 000000000..8f20aa1e1 --- /dev/null +++ b/examples/python/stiffness_matrix/material.dat @@ -0,0 +1,6 @@ +material elastic [ + name = steel + rho = 7800 # density + E = 2.1e11 # young's modulus + nu = 0.3 # poisson's ratio +] diff --git a/examples/python/stiffness_matrix/plate.geo b/examples/python/stiffness_matrix/plate.geo new file mode 100644 index 000000000..635cd9d48 --- /dev/null +++ b/examples/python/stiffness_matrix/plate.geo @@ -0,0 +1,22 @@ +h1 = 0.1; +h2 = h1; +Point(1) = {0, 0, 0, h1}; +Point(2) = {4, 0, 0, h2}; +Point(3) = {4, 4, 0, h2}; +Point(4) = {0, 4, 0, h2}; +Point(5) = {1, 0, 0, h1}; +Point(6) = {0, 1, 0, h1}; +Circle(1) = {5, 1, 6}; +Line(2) = {6, 4}; +Line(3) = {4, 3}; +Line(4) = {3, 2}; +Line(5) = {2, 5}; +Line Loop(6) = {-1, -2, -3, -4, -5}; +Plane Surface(7) = {6}; +Physical Surface(8) = {7}; +Physical Line("XBlocked") = {2}; +Physical Line("YBlocked") = {5}; +Physical Line("Traction") = {3}; + +Physical Point("XBlocked") = {5}; +Physical Point("YBlocked") = {5}; diff --git a/examples/python/stiffness_matrix/plate.msh b/examples/python/stiffness_matrix/plate.msh new file mode 100644 index 000000000..5425a1257 --- /dev/null +++ b/examples/python/stiffness_matrix/plate.msh @@ -0,0 +1,6237 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$PhysicalNames +5 +0 12 "XBlocked" +0 13 "YBlocked" +1 9 "XBlocked" +1 10 "YBlocked" +1 11 "Traction" +$EndPhysicalNames +$Nodes +2092 +1 4 0 0 +2 4 4 0 +3 0 4 0 +4 1 0 0 +5 0 1 0 +6 0.9951847266502585 0.09801714055230534 0 +7 0.9807852803038259 0.1950903225158687 0 +8 0.9569403355024331 0.2902846780119318 0 +9 0.9238795320817892 0.3826834334019886 0 +10 0.8819212636904032 0.4713967380569389 0 +11 0.8314696113679687 0.5555702344182949 0 +12 0.7730104520841969 0.6343932857215511 0 +13 0.7071067795733449 0.7071067827997501 0 +14 0.634393282646958 0.7730104546074502 0 +15 0.5555702316245595 0.8314696132346829 0 +16 0.471396735522105 0.8819212650453002 0 +17 0.3826834312318057 0.9238795329807084 0 +18 0.2902846763682919 0.9569403360010258 0 +19 0.1950903214145686 0.980785280522888 0 +20 0.0980171400302339 0.995184726701678 0 +21 0 1.099999999999506 0 +22 0 1.199999999999012 0 +23 0 1.299999999998518 0 +24 0 1.399999999998024 0 +25 0 1.499999999997529 0 +26 0 1.599999999997035 0 +27 0 1.699999999996541 0 +28 0 1.799999999996047 0 +29 0 1.899999999995552 0 +30 0 1.999999999995116 0 +31 0 2.099999999995333 0 +32 0 2.199999999995579 0 +33 0 2.299999999995825 0 +34 0 2.399999999996071 0 +35 0 2.499999999996318 0 +36 0 2.599999999996564 0 +37 0 2.699999999996809 0 +38 0 2.799999999997055 0 +39 0 2.8999999999973 0 +40 0 2.999999999997546 0 +41 0 3.099999999997791 0 +42 0 3.199999999998036 0 +43 0 3.299999999998282 0 +44 0 3.399999999998528 0 +45 0 3.499999999998773 0 +46 0 3.599999999999018 0 +47 0 3.699999999999264 0 +48 0 3.79999999999951 0 +49 0 3.899999999999755 0 +50 0.09999999999981146 4 0 +51 0.1999999999995986 4 0 +52 0.2999999999994113 4 0 +53 0.3999999999992587 4 0 +54 0.4999999999990951 4 0 +55 0.5999999999988144 4 0 +56 0.6999999999985229 4 0 +57 0.7999999999982315 4 0 +58 0.89999999999794 4 0 +59 0.9999999999976484 4 0 +60 1.099999999997357 4 0 +61 1.199999999997066 4 0 +62 1.299999999996774 4 0 +63 1.399999999996483 4 0 +64 1.499999999996191 4 0 +65 1.5999999999959 4 0 +66 1.699999999995608 4 0 +67 1.799999999995317 4 0 +68 1.899999999995025 4 0 +69 1.999999999994777 4 0 +70 2.099999999994997 4 0 +71 2.19999999999526 4 0 +72 2.299999999995524 4 0 +73 2.399999999995787 4 0 +74 2.49999999999605 4 0 +75 2.599999999996314 4 0 +76 2.699999999996577 4 0 +77 2.79999999999684 4 0 +78 2.899999999997104 4 0 +79 2.999999999997367 4 0 +80 3.09999999999763 4 0 +81 3.199999999997893 4 0 +82 3.299999999998157 4 0 +83 3.39999999999842 4 0 +84 3.499999999998683 4 0 +85 3.599999999998947 4 0 +86 3.69999999999921 4 0 +87 3.799999999999474 4 0 +88 3.899999999999737 4 0 +89 4 3.899999999999583 0 +90 4 3.799999999999167 0 +91 4 3.699999999998751 0 +92 4 3.599999999998334 0 +93 4 3.499999999998004 0 +94 4 3.399999999998612 0 +95 4 3.299999999999305 0 +96 4 3.199999999999999 0 +97 4 3.100000000000693 0 +98 4 3.000000000001386 0 +99 4 2.90000000000208 0 +100 4 2.800000000002774 0 +101 4 2.700000000003467 0 +102 4 2.60000000000416 0 +103 4 2.500000000004854 0 +104 4 2.400000000005547 0 +105 4 2.300000000006241 0 +106 4 2.200000000006934 0 +107 4 2.100000000007628 0 +108 4 2.000000000008235 0 +109 4 1.900000000007906 0 +110 4 1.800000000007489 0 +111 4 1.700000000007074 0 +112 4 1.600000000006657 0 +113 4 1.500000000006241 0 +114 4 1.400000000005825 0 +115 4 1.300000000005409 0 +116 4 1.200000000004993 0 +117 4 1.100000000004577 0 +118 4 1.000000000004161 0 +119 4 0.9000000000037449 0 +120 4 0.8000000000033287 0 +121 4 0.7000000000029125 0 +122 4 0.6000000000024963 0 +123 4 0.5000000000020806 0 +124 4 0.4000000000016639 0 +125 4 0.3000000000012486 0 +126 4 0.200000000000832 0 +127 4 0.1000000000004162 0 +128 3.900000000001324 0 0 +129 3.800000000002422 0 0 +130 3.700000000002307 0 0 +131 3.60000000000252 0 0 +132 3.500000000003786 0 0 +133 3.400000000003746 0 0 +134 3.300000000003589 0 0 +135 3.200000000003433 0 0 +136 3.100000000003276 0 0 +137 3.000000000003119 0 0 +138 2.900000000002963 0 0 +139 2.800000000002806 0 0 +140 2.70000000000265 0 0 +141 2.600000000002494 0 0 +142 2.500000000002337 0 0 +143 2.400000000002181 0 0 +144 2.300000000002025 0 0 +145 2.200000000001869 0 0 +146 2.100000000001713 0 0 +147 2.000000000001557 0 0 +148 1.900000000001402 0 0 +149 1.800000000001246 0 0 +150 1.70000000000109 0 0 +151 1.600000000000934 0 0 +152 1.500000000000778 0 0 +153 1.400000000000623 0 0 +154 1.300000000000467 0 0 +155 1.200000000000311 0 0 +156 1.100000000000156 0 0 +157 2.059834627972047 2.071774407501231 0 +158 1.179280626212892 2.824332137761062 0 +159 2.821717920519497 1.181487301489158 0 +160 2.870938197227737 2.862589013298715 0 +161 1.761378395153983 1.074185380680933 0 +162 1.035484802949141 1.795528417091771 0 +163 3.102742231376358 2.001710484125938 0 +164 2.015012089200159 3.111498742109454 0 +165 2.342691263812367 0.6851327556972823 0 +166 0.6872170268250173 3.312782973174925 0 +167 3.312782973175087 0.6872170268250323 0 +168 0.6739082941492394 2.406757063345106 0 +169 3.332204160367965 3.329525279815482 0 +170 2.237171745500607 1.445084285476748 0 +171 1.13899392508689 1.141146650770716 0 +172 1.484218361160645 2.247347889035101 0 +173 1.457886491409792 3.376365688120475 0 +174 3.387364630303134 1.46154719733819 0 +175 1.631308858990636 1.657056642292305 0 +176 3.379085752096072 2.556282456602916 0 +177 2.563355365756499 3.383482555865657 0 +178 2.3317382890251 2.614947874529122 0 +179 0.5717547177498667 1.464626073045153 0 +180 1.455405182348013 0.5659811143906933 0 +181 2.583354504629948 1.898951587349129 0 +182 2.827383607678683 0.5144880702972171 0 +183 1.821837563867549 2.635878027794323 0 +184 0.5026107168072008 2.843301296015982 0 +185 2.777314918780683 2.382404323221444 0 +186 0.492241060473887 1.913773319495745 0 +187 1.917393548985615 0.4776808319217449 0 +188 1.866680055451452 3.548209232193982 0 +189 3.53113793330113 1.879339311000612 0 +190 2.927202178455239 1.608307152495156 0 +191 1.052217083126269 3.561121849162911 0 +192 3.563724772669571 1.056047184525339 0 +193 3.545336529523794 2.961461455573517 0 +194 2.953852897388042 3.556204885139878 0 +195 1.562860310508591 2.971810856634471 0 +196 1.054892758104844 2.208690050120225 0 +197 2.172093552538404 1.059286661229019 0 +198 2.489142698551071 2.990975546615491 0 +199 3.61433970795542 0.3895760791093845 0 +200 0.4025590449029198 3.597440955097092 0 +201 1.135552600278538 0.791727815712713 0 +202 3.612699217763244 3.612699217763224 0 +203 2.395548413661271 2.245692637967394 0 +204 3.623066073997228 2.268966480746184 0 +205 2.268966480745472 3.623066073995068 0 +206 0.7733992919148471 1.13866827770248 0 +207 1.046458714038827 3.187634184523169 0 +208 3.171591349738888 1.055518966283827 0 +209 1.474312788273057 1.293764999033996 0 +210 1.990120795289137 1.705225795902449 0 +211 2.68577987344284 0.8565112689566434 0 +212 1.720978341687657 2.005466972306212 0 +213 0.8357033652419018 2.69652523332488 0 +214 3.154165813951709 0.3711737959388691 0 +215 2.487450590830798 0.3685732849922235 0 +216 3.187132605141837 3.00225913027513 0 +217 0.9280601470672928 1.459358833449071 0 +218 0.3583130920826133 3.165173658664609 0 +219 1.474898283587542 2.61842238457653 0 +220 1.369194161187577 1.923742820454392 0 +221 0.3423053607095761 2.515577518116112 0 +222 2.610797378315194 1.45012679644447 0 +223 2.855862450576572 3.238288358082068 0 +224 1.912702044559522 1.360680046777973 0 +225 1.41298968388584 0.9838813227792947 0 +226 3.033982948505735 2.577475400758868 0 +227 1.319878445711294 1.600532130010072 0 +228 2.048689277592323 2.414163926588466 0 +229 0.7321832434003049 3.665055177461772 0 +230 3.665055177461519 0.7321832434001063 0 +231 2.498751912297174 1.129893961421254 0 +232 3.666697543819277 3.280823248254657 0 +233 3.277822869100524 3.666915351882116 0 +234 1.957309923060282 0.8040736926546496 0 +235 0.7985684815523527 2.023170400249038 0 +236 1.573502726814574 3.675628650731362 0 +237 3.67709582378063 1.5835195167348 0 +238 0.3234045513543287 1.275563970784248 0 +239 1.259558737202446 0.3155193572049318 0 +240 0.3204798939025587 1.651703698491485 0 +241 2.972583691341996 0.7876889875643716 0 +242 1.177586337115621 2.509860260997754 0 +243 0.7797651899086815 3.008855274687577 0 +244 1.648509895738948 0.3129293938507431 0 +245 0.3223524611193754 2.220163695183995 0 +246 2.088412779243467 2.804647359007034 0 +247 3.684817001808269 2.676894969583816 0 +248 2.67245088468384 3.686928371454458 0 +249 2.260501749569738 1.843434389774715 0 +250 3.099697544640006 1.323845570551229 0 +251 3.218059876235646 1.7216153179124 0 +252 2.182604004369282 0.3106432090262924 0 +253 3.301271669725211 2.265861849347764 0 +254 2.258753072355335 3.299955498890597 0 +255 2.643102078402434 2.665401682304939 0 +256 1.742547197029971 3.259126165188637 0 +257 1.773543862352646 2.306085510407776 0 +258 0.7568463992276776 1.715336072589943 0 +259 2.80862265446359 2.082080337698757 0 +260 1.674023845327693 0.7842551502146167 0 +261 1.297598363586556 3.71196989899947 0 +262 3.711969898999516 1.297598363586833 0 +263 1.312004134495224 3.118940753599327 0 +264 3.033493504208013 2.27882147750712 0 +265 0.9069134788155497 0.8929476437510191 0 +266 1.836882454649946 2.905376447741898 0 +267 2.74619966855217 0.2615749641392818 0 +268 0.2580304911749545 2.931266187083996 0 +269 1.142226567742575 0.5214613259019345 0 +270 2.462057489028428 1.672172253988223 0 +271 0.9193947663696417 2.450591799519246 0 +272 2.579324886520474 0.6017848732173925 0 +273 3.392128227738654 0.2519862423505305 0 +274 2.031773760493745 3.748177463331111 0 +275 3.748177463330362 2.031773760494034 0 +276 3.35880145404556 2.799498392044847 0 +277 0.5804319054520376 2.615832795588139 0 +278 3.093888556952874 3.348418956169651 0 +279 0.2498735122629235 3.399958073184745 0 +280 0.5147604603040064 1.131713299283271 0 +281 2.841622645764675 1.828975287970894 0 +282 1.20670443664021 3.379898906519365 0 +283 3.375762564506549 1.221485062606774 0 +284 2.234050343077273 3.001689371253065 0 +285 2.357191138255083 0.9089790920358494 0 +286 2.541419218029784 2.438914692101256 0 +287 0.2479914286883235 1.948323191545799 0 +288 0.565349458734029 2.160695311288353 0 +289 2.018136610736282 3.368965287127441 0 +290 3.362289936450845 2.020362848989265 0 +291 3.742071444512653 2.446427953816554 0 +292 2.442735672760505 3.726704176943481 0 +293 2.108988677248498 0.5891863199461874 0 +294 1.884149777427906 0.2381899141158837 0 +295 2.706753702586548 3.045237537058853 0 +296 3.762121509717302 0.2376674659586799 0 +297 0.2352688827835619 3.750804041991312 0 +298 1.692924662024964 1.426512378855439 0 +299 1.715649574224005 0.5297955599286037 0 +300 0.9428409098550121 3.769022638040231 0 +301 3.769022638039702 0.9428409098541822 0 +302 3.101352584701159 0.582129665375014 0 +303 1.169249497942303 1.397451048679616 0 +304 1.794213320099831 3.765040622063467 0 +305 3.767911372083121 1.794675211084742 0 +306 0.9117849323506159 3.375122471940709 0 +307 3.367946888625958 0.9108978927636622 0 +308 3.769140274698623 3.068436834916203 0 +309 3.068436834915941 3.769140274698342 0 +310 1.275733323371447 2.134637451424288 0 +311 3.440326402403763 1.678297414855112 0 +312 2.832448872593704 1.40472897314227 0 +313 3.092953256311199 2.806671683026898 0 +314 2.971179854689692 0.230891645751323 0 +315 3.758170817193186 3.773551046495502 0 +316 3.384728092476857 3.127634068384491 0 +317 0.5474133810259891 3.064603500117769 0 +318 0.227474261627206 2.704006141458169 0 +319 1.973457841414909 1.146411547935172 0 +320 2.777581733168567 3.430889707439454 0 +321 1.648984965995719 2.492757736068411 0 +322 0.5348237167661489 3.77614966830608 0 +323 3.775778105279163 0.5348207345937327 0 +324 0.4930921247327604 3.387723883970225 0 +325 1.010588472652612 2.950906805844175 0 +326 1.638205751263605 2.762111278299866 0 +327 1.39238280159913 2.82411801530613 0 +328 2.298169795178504 1.238496080803737 0 +329 2.656249048009742 2.207728473884726 0 +330 2.692670968964814 1.651694850547039 0 +331 3.381796307190958 0.5019020412356975 0 +332 3.78102686140263 3.476014673190904 0 +333 3.471597477764715 3.762535415186073 0 +334 1.657894936289693 3.468702951049163 0 +335 1.37161479481024 0.7518757206540253 0 +336 2.295144253171705 2.063798416815118 0 +337 1.910511578684842 1.916754473063199 0 +338 0.5206949925417212 1.726677412237421 0 +339 0.2150534933837839 1.464603154685763 0 +340 2.441675536893859 3.217859709642753 0 +341 0.8588579449862448 2.219931130424579 0 +342 2.968022078671691 1.008261429786912 0 +343 2.182423694506801 0.8322834837091798 0 +344 2.992023422283888 3.051607302919298 0 +345 1.455953775996943 0.2147565716401785 0 +346 1.106517393740884 2.013702130291513 0 +347 2.279746251341666 2.400322367712852 0 +348 2.352987129440272 2.812885705464612 0 +349 1.545157381461528 3.186457697388496 0 +350 2.838406726760743 2.589625092076281 0 +351 3.78947991566244 2.855172053082031 0 +352 2.856211107627051 3.791175128384409 0 +353 3.227813685865641 2.443849888798401 0 +354 1.221827063312749 0.9795691505220536 0 +355 1.56745818300293 1.872825624426246 0 +356 0.9443599954363798 1.250518016918117 0 +357 0.7491189856141806 1.33838303155936 0 +358 2.326457535638262 0.4828693372981284 0 +359 1.821137400712481 1.585922173466009 0 +360 3.033705298479149 1.82070787895002 0 +361 1.320543229452085 1.160254870337756 0 +362 1.527500510240728 2.067279592334253 0 +363 1.058279798566907 1.585027999096453 0 +364 2.128437622435213 2.602581882368729 0 +365 2.04773825482977 1.507360141184439 0 +366 1.363150893879319 2.442617217833059 0 +367 1.047268241070969 2.669297943049992 0 +368 2.362077009574105 0.1972146386831222 0 +369 0.4792638061715729 2.338380170071132 0 +370 0.2048037627547484 2.379339023944357 0 +371 3.531490820144457 3.429699021115271 0 +372 1.561392992539696 1.116908430680444 0 +373 1.893807547821784 2.141773965236879 0 +374 3.120123303097877 1.543050392001625 0 +375 1.487717100837181 1.518629941443007 0 +376 0.9559163333688548 0.7112372685199755 0 +377 3.562143040610156 2.445548357697457 0 +378 2.461658824426795 3.540253367341872 0 +379 3.181470686403084 0.8408132719301035 0 +380 2.084057597793002 1.334073687789064 0 +381 2.672393360245708 1.044629142222181 0 +382 1.249700229966213 1.750415871300841 0 +383 2.625531871453455 2.841751316713368 0 +384 2.198055273499019 1.640218240141193 0 +385 0.7122773696376163 0.9412858094959899 0 +386 1.736821831005247 1.827174787622758 0 +387 2.628484296650622 1.256746613116387 0 +388 2.192638202149752 2.216862573136349 0 +389 3.525597745665366 2.068949590958754 0 +390 2.068949590958981 3.525597745663776 0 +391 0.8482648701230362 3.187715700669532 0 +392 3.583906467041797 0.1870855363973309 0 +393 3.228127529281009 2.670909634964932 0 +394 2.667490200599336 3.234499393832801 0 +395 2.804473069211954 0.728454785188305 0 +396 0.6991078725154467 2.837404608106253 0 +397 0.6318655152214488 3.498854370616963 0 +398 1.785913412173669 1.253496650392086 0 +399 2.426950300350325 1.376701758184164 0 +400 1.129126119358137 3.815582931416936 0 +401 3.815582931415531 1.129126119358637 0 +402 1.714428585068926 3.060299746153868 0 +403 1.21724056163091 2.317636418714232 0 +404 3.492160150273963 0.6459372598903914 0 +405 1.317580079363991 3.518005674838809 0 +406 3.516902277564004 1.318781968961099 0 +407 1.291553134127144 2.661938807511112 0 +408 2.48103497268005 2.054986699317706 0 +409 3.189133147918144 3.194834907331018 0 +410 3.815316035912248 2.269909899289583 0 +411 2.269909899281465 3.815316035913397 0 +412 3.230767971162939 3.493792596021344 0 +413 1.453977049994229 1.710035024346884 0 +414 0.1835010023883578 3.574009241398438 0 +415 1.888468166470664 2.452074655938097 0 +416 1.860987523194935 0.6405254759153309 0 +417 0.6719715478350933 1.863019046955623 0 +418 1.454659059138316 3.837419142767541 0 +419 3.837419142768367 1.454659059138927 0 +420 2.565352982008434 0.1865280092313415 0 +421 2.054805932922362 0.1828544331136762 0 +422 0.9873070428828996 1.058230967350739 0 +423 1.175812784835197 3.012670162042959 0 +424 2.099166490873588 1.888440182176859 0 +425 3.21692866429548 0.1848624435649664 0 +426 0.1855020467660105 3.102013628664847 0 +427 2.49776153078304 0.7887185570769714 0 +428 0.7606288522037205 1.53549404501676 0 +429 2.992070859390117 0.4027768888971235 0 +430 1.924283655580719 0.9739907309840322 0 +431 0.1700346142617001 1.151464375851993 0 +432 1.611173483600221 0.9535185580776246 0 +433 1.34133914440125 1.423267647921739 0 +434 1.150863656483822 0.1708489366271618 0 +435 3.358744955132912 1.837073371837715 0 +436 1.433019975600422 0.3915967022687767 0 +437 0.1802356857833756 1.777202584223009 0 +438 0.3980202063862963 1.424673087889608 0 +439 3.506529295977527 2.696674774842824 0 +440 2.669432460982581 0.4257032711143908 0 +441 0.8561819268411557 1.843277289328229 0 +442 0.9006711031900096 1.633473490381253 0 +443 0.8848084450409309 3.552697611269749 0 +444 3.556214500256146 0.8714652513856758 0 +445 2.958191729711847 2.438261967307575 0 +446 3.054731806848779 1.158060854348299 0 +447 0.4175160163356187 2.693193246955799 0 +448 3.448226156222159 3.592608922325167 0 +449 0.7746015872888905 2.527228916193465 0 +450 1.651789231265723 2.166555723093964 0 +451 2.014425852177011 2.237885753964746 0 +452 1.291221903162731 0.6013980021795415 0 +453 0.5934165414762637 1.280209180688178 0 +454 2.843464528172957 0.8834244415457141 0 +455 0.1714036742665409 2.106136654022946 0 +456 3.572658534121014 3.129982292050098 0 +457 2.933446365595081 1.958137261760317 0 +458 2.474755204791245 2.705226550485325 0 +459 0.1653741663522051 2.546555444225318 0 +460 0.7985817657307593 3.840452367420107 0 +461 3.840452367419745 0.7985817657300047 0 +462 3.845447726293479 3.205343607134695 0 +463 3.224039702080563 3.828834640206977 0 +464 1.109002126473783 0.3635871137324646 0 +465 0.9578484389051235 2.084752477835057 0 +466 1.645384991087739 3.830901546221694 0 +467 3.836536721105117 1.643571038324591 0 +468 2.943744979110507 2.721823410803916 0 +469 0.3519505371116962 1.839005412731398 0 +470 3.253712830261891 1.342437716252702 0 +471 2.176697398495803 3.160650654090192 0 +472 0.8620760462684842 2.862036654221911 0 +473 2.871023764706943 2.242734370789131 0 +474 2.089339404971878 0.4445808268705499 0 +475 0.3530933982380186 1.110867456680898 0 +476 2.654490168168414 2.044637562790233 0 +477 1.919802624826116 2.774318497630564 0 +478 0.5408274909237663 3.230621404562402 0 +479 1.982129957823278 2.935356942930343 0 +480 3.167828582168225 2.158044948624643 0 +481 1.724357664006089 0.1647087102023513 0 +482 3.836388375341087 2.58838482537443 0 +483 2.59529920471189 3.834018537280368 0 +484 3.411025394276466 2.386562394986903 0 +485 2.382016690465396 3.402055379378732 0 +486 1.494552971863298 3.534009901620554 0 +487 3.542435664100062 1.487673344221009 0 +488 2.521401366199022 0.9529700238565812 0 +489 1.519293493102087 0.7247957467091809 0 +490 1.063141715062176 2.375810411251471 0 +491 0.3833176500063405 3.836206570771334 0 +492 3.836206570771298 0.3833176500061273 0 +493 0.4219904273129147 2.977118300777086 0 +494 1.047280189367525 0.9131755667005498 0 +495 1.910641465772125 3.232874190550187 0 +496 3.841723686040489 3.611951781911646 0 +497 3.616379533437431 3.83668801407894 0 +498 0.1619674331178227 3.272724209387151 0 +499 0.3725630497884945 2.051742951666508 0 +500 2.332645744284949 1.083433497940692 0 +501 1.611874126654288 2.31966850093356 0 +502 2.989690045834238 2.129680695302295 0 +503 1.793953813188203 0.8887882468464816 0 +504 3.115142241701744 3.61342160603712 0 +505 3.59662190566537 1.724650626497505 0 +506 2.426268374595524 1.813923204620897 0 +507 1.850787876761274 3.387114938516668 0 +508 3.481825130201853 3.263807907464889 0 +509 2.636694135190061 3.530359228765468 0 +510 2.801423056270832 3.590817752953383 0 +511 1.734297555845727 3.618286151821405 0 +512 0.1537501562230263 1.610865205364459 0 +513 3.203765882101414 1.882473550676482 0 +514 2.925040118052554 3.37664889056016 0 +515 2.782349594886054 2.736019415251163 0 +516 0.6909647909698883 3.153957725201881 0 +517 3.468890837353488 2.232119788465666 0 +518 2.232119788465419 3.468890837351501 0 +519 2.947224902051028 0.6154998116680466 0 +520 1.795224519794395 0.3753248591878189 0 +521 2.951657909643901 1.282377832431224 0 +522 2.97911629859309 1.458536086808604 0 +523 3.359479699675572 2.965968707880403 0 +524 1.411071911522405 2.991520130241402 0 +525 3.275597667982976 1.573918021946387 0 +526 0.1570195461136941 1.317639393721025 0 +527 3.617580271766343 2.81821208789993 0 +528 2.692256612865069 2.507223859567237 0 +529 3.231360099453441 0.4989258517814038 0 +530 1.971862478739484 2.589071801407324 0 +531 2.22112031204417 0.15538055409286 0 +532 0.4644071945663256 1.573697980554958 0 +533 2.223587733438285 2.726425851906205 0 +534 3.022758576933321 3.206571067778175 0 +535 0.7081928719109518 2.147218288772624 0 +536 1.188208128842623 3.218782587501654 0 +537 1.336138515357571 3.279825180760635 0 +538 1.316479679647896 0.1616465602323707 0 +539 1.236489264226976 1.277501817418631 0 +540 2.57126190459388 3.11461442823519 0 +541 2.400715703397181 1.527531275115869 0 +542 2.07419073973068 0.9410948038852622 0 +543 1.578722339984011 0.4488399790123233 0 +544 0.6259685467225118 1.612737368631532 0 +545 3.205988225782758 1.193090422428567 0 +546 1.063550177807407 3.334861890599807 0 +547 3.344614268129882 1.056194646022858 0 +548 3.628541478077315 0.5562273215613819 0 +549 1.605002972938738 3.32619157627361 0 +550 2.787940272409521 1.540253540990276 0 +551 1.998614701167213 0.3234100367865851 0 +552 2.843251410110152 0.1452161489873671 0 +553 0.5568903368296736 3.630510534217226 0 +554 0.7731214060522043 3.43292483945681 0 +555 3.436470536147741 0.7738182618699557 0 +556 1.924149709836608 3.844102633070397 0 +557 3.844102633069999 1.924149709838499 0 +558 1.19232754761791 3.61101751729255 0 +559 3.610906544501012 1.192620778445465 0 +560 2.360472925506892 3.081723577395516 0 +561 0.6184525479869795 2.028196598243418 0 +562 1.003468018659819 2.814779719283176 0 +563 2.436343289289312 0.5724860222832083 0 +564 0.1442518231236271 2.831394262462602 0 +565 0.5009755860060475 2.496172610915493 0 +566 1.886250120957764 3.043210505896673 0 +567 1.511780057265402 2.459729336614024 0 +568 0.9920690837567985 0.5659913796199709 0 +569 0.5630467014473601 0.9890701418421604 0 +570 3.051872095623048 1.659075843353325 0 +571 1.636564162927949 1.254390158237335 0 +572 3.849373099469633 1.283912557706584 0 +573 1.283912557704733 3.849373099469684 0 +574 3.226046719715106 2.859533463818221 0 +575 2.402329941802018 2.478508099414592 0 +576 1.309386518881663 0.4580408771075242 0 +577 2.851723085145537 3.014429637170567 0 +578 0.1366469595097899 2.251270127804502 0 +579 1.235136241352968 1.935715333704102 0 +580 0.8157605811377111 0.779638354601389 0 +581 1.699007933238032 2.912279413897355 0 +582 2.839970433953512 0.3709613693333687 0 +583 1.764633446080337 2.763300201845539 0 +584 0.3524370590986902 2.835743783409123 0 +585 2.815097951345079 1.030288764573291 0 +586 0.9811105260138233 1.937446580950801 0 +587 2.488564392569297 2.847518083570912 0 +588 1.578408447782779 0.1517967458057528 0 +589 3.307972838836815 0.3615736520863292 0 +590 1.430412665357608 3.663950599920594 0 +591 3.663950599921208 1.430412665358237 0 +592 2.569376581324827 1.759998366636501 0 +593 1.284039558541333 2.914534253231311 0 +594 3.850783664981963 2.727521898998043 0 +595 2.740169962698114 3.865191357535297 0 +596 3.088479271139525 0.1429333464336701 0 +597 0.6475263881885183 3.8617345672802 0 +598 3.861734567280001 0.6475263881886852 0 +599 3.859981508061885 2.099301142334977 0 +600 2.099301142329858 3.859981508064915 0 +601 1.681882647731223 2.62896671985644 0 +602 2.375045964975701 1.947843744177729 0 +603 2.334055747428737 1.70943079109034 0 +604 2.111167022290734 1.185064147368108 0 +605 3.864388848641295 0.1356111513580877 0 +606 0.1356111513585576 3.864388848641594 0 +607 0.8498549813594372 1.034023878833271 0 +608 3.498385356761835 2.836982167160684 0 +609 1.909427992103722 3.681512490262065 0 +610 3.668984275139455 1.921559830418843 0 +611 2.328937703531009 0.3372684604745972 0 +612 3.450157182936054 0.130148725615795 0 +613 2.213351479972778 2.864645524663026 0 +614 2.52963266000397 2.578077111735796 0 +615 0.3490462491303749 3.304431916131806 0 +616 1.02971725710109 2.521358165224487 0 +617 2.723726390560445 1.936171224810097 0 +618 0.4244846109411758 1.246509875408939 0 +619 3.071803410098677 3.456069282457725 0 +620 2.818870941533197 1.693810890225884 0 +621 3.169342614441207 2.312074192982024 0 +622 1.076215597504916 1.305139697547695 0 +623 0.813494274205938 2.363999807266379 0 +624 2.711839235684585 0.5878870799500234 0 +625 3.106177250741949 0.7254573713245184 0 +626 2.547535807521222 2.299696956134432 0 +627 3.867310569608187 3.359126145271152 0 +628 3.348781779180769 3.862398027576236 0 +629 0.930944733855932 3.080602007708188 0 +630 3.088676578280559 0.942294374434417 0 +631 0.6441277408673993 2.950067266137776 0 +632 3.555615330085912 2.582027822500113 0 +633 1.09420764563601 0.6606825678367939 0 +634 3.865896454748271 2.971226006412794 0 +635 2.971226006412384 3.865896454747645 0 +636 3.000645185514544 2.911776292410107 0 +637 1.910157449444207 2.317816021288716 0 +638 3.344319204824967 3.477372908568264 0 +639 2.575746740951411 1.583924194273709 0 +640 2.532202196439062 3.670789701085769 0 +641 2.520417963827912 1.281076490822677 0 +642 1.965669921145465 0.6470530468159443 0 +643 3.46870437858362 0.3618452692371316 0 +644 2.119239535875724 1.754839582638957 0 +645 0.3137607663152027 2.337498702695499 0 +646 1.503423306043588 2.751320603724252 0 +647 0.1352975942078409 3.465628037200451 0 +648 1.510924406195453 0.8579426463939276 0 +649 1.055486891754392 3.696463336480772 0 +650 3.696463336480399 1.055486891753652 0 +651 1.26032044104648 0.8690264030668138 0 +652 2.697672807564673 0.1352784325327088 0 +653 3.053053525861448 2.416352955341754 0 +654 0.3645926345303707 3.463909803110229 0 +655 3.69423061295148 2.947515368521779 0 +656 2.951122523928955 3.69342407391153 0 +657 0.9371906954550685 2.321264567242178 0 +658 2.248827940483389 0.5884709149842313 0 +659 1.400994411241642 2.132908502925462 0 +660 0.6996789915726234 2.676138514582281 0 +661 3.851868227727428 3.872404728364453 0 +662 3.655911475298683 3.4094143459592 0 +663 0.136203172010892 2.989578230564493 0 +664 1.856658168102082 1.713773251106967 0 +665 1.340488362999639 2.269891249881114 0 +666 3.118785571851425 3.10146805784659 0 +667 0.9084434586035267 2.583399120223163 0 +668 2.245692355302648 0.9488992586775881 0 +669 1.588569067269883 0.6077155580620593 0 +670 1.839195905632046 0.7769228036425019 0 +671 3.708232277211016 2.169454107202549 0 +672 2.169454107200237 3.708232277209763 0 +673 2.175004893156951 2.479692354117571 0 +674 1.950385536504743 1.515514388917687 0 +675 2.344090525578449 3.866421270938012 0 +676 3.866421270937897 2.34409052558638 0 +677 2.751942304734239 2.909988215220346 0 +678 0.6439528785246064 1.095751679162562 0 +679 2.323661800340515 0.8201106550155342 0 +680 2.653040297852881 0.7219674465827419 0 +681 2.363072037599515 2.948606457132676 0 +682 2.175336547002597 1.99362187670956 0 +683 1.110072298487518 1.051122944554837 0 +684 2.67016473952873 2.367212384340949 0 +685 2.132027117479319 3.008574059205901 0 +686 3.698813697472334 0.1372043130692251 0 +687 2.703642686666393 1.791465218579397 0 +688 2.072481040873647 3.211213543741023 0 +689 1.962740070473541 0.1325319143384608 0 +690 0.28778788971596 3.048559609829127 0 +691 0.5731969575451714 2.733302272720804 0 +692 2.629805072575449 0.3064286428439933 0 +693 3.23053513330016 2.064035302774734 0 +694 3.222416841888281 1.449848896607668 0 +695 0.1275514480269877 3.701907099767871 0 +696 1.029604888859055 3.859040599290314 0 +697 3.859040599289789 1.02960488885971 0 +698 2.098900992226946 0.7327999282963764 0 +699 2.558628480972842 0.4762831804609204 0 +700 1.820056607657098 1.419446061940366 0 +701 3.357008295805735 2.678842524502579 0 +702 1.556001106726741 1.394980747592653 0 +703 0.4936744060291087 3.5154137963555 0 +704 1.1616189992882 2.113572072059807 0 +705 0.4305544319432842 2.220441678691854 0 +706 1.636823679360315 1.533060985890237 0 +707 1.207488604159484 1.522829511981371 0 +708 1.760580237838161 2.43232809631827 0 +709 3.207409853037337 3.317726394207158 0 +710 1.187204618323247 1.666227821188116 0 +711 1.158586825012992 3.474733219536652 0 +712 3.466445458089074 1.167970835270685 0 +713 2.686015474907243 1.383781773333556 0 +714 0.5725003882563956 2.29397495802805 0 +715 3.724375190918975 0.3425009281561815 0 +716 0.3507356426735739 3.713422775291573 0 +717 1.365595972915481 1.792589451469577 0 +718 2.482953733564715 0.1125698389859868 0 +719 0.6271624407610082 2.486358869544424 0 +720 2.324649322572025 3.20745916156955 0 +721 2.954220444739076 1.755154470611206 0 +722 3.516214415366508 0.4938579119194795 0 +723 1.732332915705652 0.662886537355258 0 +724 2.001265540944815 1.268331089285761 0 +725 0.8694906649027745 3.682089702224257 0 +726 3.682560437168644 0.8680926422394425 0 +727 3.405019272824062 1.340929328993928 0 +728 0.1255387431604453 1.880751897099578 0 +729 1.034254171592147 1.472048349955207 0 +730 3.675870227546043 2.361767255069084 0 +731 2.359947519497267 3.673017503185682 0 +732 2.233415635395458 0.7179024104851641 0 +733 0.4545437023338759 1.041110447065015 0 +734 1.244250080103297 0.7016611550356662 0 +735 3.365328070185063 2.13021194894757 0 +736 2.136407834371334 3.365550384772809 0 +737 3.319315114134596 0.1219016691523186 0 +738 1.173393333078459 2.634159065551659 0 +739 1.346497489948633 2.560393846176899 0 +740 2.780996041634777 3.325753653567214 0 +741 3.270016773702787 0.9457241324188101 0 +742 0.8204826593899186 1.262020261959596 0 +743 3.298726967593386 0.8074060149556935 0 +744 2.324023690708454 3.517598453848059 0 +745 3.515819254248615 2.322887039283115 0 +746 1.843871750064776 1.162511244830963 0 +747 2.601571042006285 2.985133102763348 0 +748 1.455884246745562 3.098395290399886 0 +749 1.462071370227847 1.100873805069356 0 +750 2.782235801401006 2.197611319470296 0 +751 2.543929142422488 3.268375165020156 0 +752 0.468065980404113 2.072003800359245 0 +753 2.30894209608736 2.181311767800101 0 +754 1.987025539132512 3.460944092892067 0 +755 3.462697795297729 1.976111438902177 0 +756 0.3137892682750516 1.537261026248144 0 +757 1.026425943264419 0.4418832957462677 0 +758 3.883456525254723 1.758250817119708 0 +759 1.748477596947679 3.896644057201927 0 +760 2.041985126598277 2.690454264958701 0 +761 3.088994171272046 0.4627192424565206 0 +762 3.54762351284305 1.611170753925144 0 +763 1.943008423836719 2.029127790095473 0 +764 2.420200258778605 2.32950136402475 0 +765 2.522371408429217 2.17161022263856 0 +766 2.04394274887751 1.058885651379554 0 +767 2.444351345780983 1.038457961143365 0 +768 2.756638069377926 3.141126626205315 0 +769 1.600802315859633 1.966110159821178 0 +770 3.697193539572305 2.524958654229454 0 +771 1.256865393338679 1.090301224633739 0 +772 0.8075188967339461 3.310592528105161 0 +773 1.663356046559012 1.154530055705898 0 +774 2.176054905567098 2.341029345406871 0 +775 3.885752480003205 0.2561174538405526 0 +776 0.2561174538405836 3.88575248000304 0 +777 0.6742673545177833 1.257173761576701 0 +778 2.086014930902106 1.637898902396836 0 +779 0.1145541016770048 2.657622255172016 0 +780 1.009224208247637 3.431056002368985 0 +781 3.419966385670245 1.003993584267401 0 +782 0.9487881426645498 3.267024340088187 0 +783 2.198418776461287 0.4189186254131071 0 +784 0.4887646748255104 1.398220183590468 0 +785 3.171417289739427 2.557403219732699 0 +786 1.07408120555331 3.061509765478563 0 +787 0.9877772178015273 0.8262192371410697 0 +788 2.907066288417342 1.135018866943918 0 +789 1.529966407819818 0.3092032660832263 0 +790 3.73234597646977 3.666413877517861 0 +791 1.62812721638642 3.088644023947093 0 +792 3.293308477875384 3.09278885364296 0 +793 3.339177899456913 3.223639202442695 0 +794 3.112682706410948 2.712557276399259 0 +795 1.374277169643194 1.276282365683437 0 +796 2.231098291100592 1.342349588206574 0 +797 1.824645477022099 1.977310343865122 0 +798 3.87037892263362 3.112678814134916 0 +799 3.117415256854828 3.880031462096306 0 +800 1.307144697403034 3.391931558755911 0 +801 0.8924680139977453 3.879141316949585 0 +802 3.87914131694963 0.8924680139973591 0 +803 1.826055499796637 0.5296080813543854 0 +804 3.074315773551567 0.2491857857655048 0 +805 3.690185667551209 3.159536962634009 0 +806 1.781186842625693 3.478832896258362 0 +807 0.8609042380615861 1.148502356825095 0 +808 1.375260798775272 2.728350555549284 0 +809 1.285924243901474 2.785815115822551 0 +810 0.6200441827608374 1.764081585571405 0 +811 1.297836109409008 2.015624839637594 0 +812 0.7611330293824731 0.8499912596662874 0 +813 3.574455031030824 3.719290122804986 0 +814 2.802839356061987 1.265427135159489 0 +815 2.014697518209281 0.5470321491495781 0 +816 3.755476746083172 3.890982422819569 0 +817 3.91853193555098 3.745762727999841 0 +818 1.562967690964321 2.854727975717946 0 +819 1.75768867487415 1.669024599152199 0 +820 2.682127043669165 3.37732299784653 0 +821 3.213998797199203 0.6145381871663933 0 +822 0.6003267929445212 3.384010920796706 0 +823 2.612750812990052 1.132644353905177 0 +824 3.442237911126326 1.556408365999378 0 +825 1.453425771849952 3.261746752941107 0 +826 3.106119151243139 2.919959684378059 0 +827 2.7333268040532 0.9698002881120947 0 +828 1.321465877599133 1.021729032185382 0 +829 2.044396633954246 1.411391413993765 0 +830 2.491812521477763 3.88259168451542 0 +831 3.882583128295084 2.493632103513048 0 +832 1.824692538355125 3.193742724709156 0 +833 1.976677213901003 1.823103794393664 0 +834 2.82005001393442 1.972199219530798 0 +835 0.7207690228651692 2.240829630042855 0 +836 3.465767774866197 1.791564107428806 0 +837 1.667335761396207 1.906893229943067 0 +838 3.389799133416257 0.6001527076014682 0 +839 0.8855122915108293 1.337348273553791 0 +840 2.935881133879944 0.0888619750926985 0 +841 1.485275116229121 1.933461254016063 0 +842 3.705415396113339 1.697719464690811 0 +843 0.1172291173456354 2.010864625502584 0 +844 0.6511480869442976 3.749823274703797 0 +845 3.749823274703248 0.651148086944056 0 +846 1.637901108332749 1.76326197159284 0 +847 3.393493027924526 3.695401920640087 0 +848 3.334000250729413 1.723731101129973 0 +849 1.732867201759396 2.115287388753228 0 +850 2.129509543579025 1.436217579188611 0 +851 0.5481791813450114 1.836736151190848 0 +852 2.157352780447042 2.090348123214422 0 +853 0.9286026688324061 1.735164159428418 0 +854 1.701042041842904 3.726282264677594 0 +855 3.446011886086007 3.024484249447701 0 +856 1.557128990432452 2.187851426812185 0 +857 1.575328063831735 2.592972245945564 0 +858 0.1079595229250833 2.444760128123287 0 +859 3.54530939124373 0.7461427051805463 0 +860 3.180070142191204 3.720937461437008 0 +861 1.109171877154531 1.885959678658777 0 +862 1.104563981757696 2.92068598691588 0 +863 2.412330746166333 1.220729496176213 0 +864 0.444969950251729 3.094440526990657 0 +865 0.4919804532130662 3.868354094652153 0 +866 3.868175226064776 0.4919323944076653 0 +867 2.496653237247236 1.476484378178679 0 +868 0.2651610503494787 2.595169023237112 0 +869 2.577541049852077 2.755285712626268 0 +870 2.471425968448659 0.2603370876366289 0 +871 0.3988363834330613 1.735910733081624 0 +872 1.196775247942562 0.4371611589013638 0 +873 1.549316683126209 3.897205118786266 0 +874 3.897780136631205 1.549131585909523 0 +875 1.685765490846459 0.4243109626133108 0 +876 0.7213482614637786 3.560709568083245 0 +877 3.868893732228179 3.512887244105264 0 +878 3.517064475262305 3.885520661309898 0 +879 0.6858389776788805 1.436053233302528 0 +880 1.888025231308167 1.262702298366713 0 +881 2.880879332194729 3.466714811715238 0 +882 1.073015702254326 0.2569506305613936 0 +883 1.251999391723154 2.422107970837778 0 +884 2.442854300191025 0.4638642167126922 0 +885 2.333287849571655 2.309985559527719 0 +886 1.520311499237852 1.632167623876231 0 +887 2.28686377043442 1.55693837047647 0 +888 2.861386909287301 0.2583761829319965 0 +889 2.492649994032669 0.6725355567868199 0 +890 0.4836669912663606 2.605428814032742 0 +891 1.731409065566251 3.375994296109083 0 +892 1.430179904451 2.03566011246042 0 +893 0.3625376812634424 1.943669386195892 0 +894 1.815884221390636 0.1110139853392071 0 +895 2.210069377014788 1.156322960657313 0 +896 3.632564245898937 2.017638166258614 0 +897 2.023645037512807 3.620298799614746 0 +898 0.9643755667184299 3.609756895489434 0 +899 3.623456816364824 0.9442749060073328 0 +900 2.781052386563794 3.697164938742127 0 +901 1.725482549635678 1.531909881908086 0 +902 1.929308564541641 1.610731582145474 0 +903 0.09625690095230713 1.45281417318208 0 +904 0.2961507540286087 1.382587503642281 0 +905 3.758613490834497 3.348526144648571 0 +906 1.361649245852058 0.8585030616785694 0 +907 1.025956634153133 1.172852820151616 0 +908 0.5324257500915718 2.954502327030737 0 +909 1.658469222644195 3.190625874506797 0 +910 2.90394215473874 3.109732544002673 0 +911 1.38518177916715 0.2938143941555495 0 +912 0.9530731010603338 2.189744931476155 0 +913 0.8534576296649545 2.116897086732415 0 +914 1.549395298086126 3.431772493570723 0 +915 3.684027350482094 3.518966092139768 0 +916 1.598518394729727 3.564980193002569 0 +917 3.274308702020414 2.536584253964411 0 +918 1.394040200022432 0.6448458704554095 0 +919 3.320064255145682 2.359118635593549 0 +920 3.688488850231116 0.4763666363504088 0 +921 3.075282980073826 1.034077142417748 0 +922 1.749814993719578 2.541816180184539 0 +923 0.8942152350682343 2.973877511796128 0 +924 1.421026909826471 1.586566629377054 0 +925 2.164225586457491 1.537286253144049 0 +926 0.2700792579970001 3.236961419420147 0 +927 2.845585526044278 2.472106272720011 0 +928 2.940839059486677 2.53834280090648 0 +929 0.4744111675078747 3.687641810076897 0 +930 2.993871439673206 0.5244900198604231 0 +931 0.9946655106304808 1.349442794369693 0 +932 1.486663338766761 1.195574730975554 0 +933 0.7618181179903611 1.819927526293137 0 +934 1.814680108258482 1.896259026086704 0 +935 1.450000000000701 0.09994826437245279 0 +936 2.083921573066413 2.520385337635493 0 +937 2.944557507330732 0.894762872486524 0 +938 1.189008091843481 3.707652338840785 0 +939 3.707641015086298 1.189038013356865 0 +940 0.2538829440750759 1.071065409513193 0 +941 2.388621920120174 3.299429057248854 0 +942 1.752315448835281 0.2725321441371857 0 +943 0.30975531593242 3.550752347441313 0 +944 1.313493010899037 1.6965003167187 0 +945 0.8129814286503976 1.42504480321467 0 +946 2.674837485327688 1.547075614967173 0 +947 1.019270275176082 1.688913155957389 0 +948 3.65422947835344 3.068942256563681 0 +949 1.645453519750736 1.047225614165719 0 +950 2.545321320209603 3.490521648338976 0 +951 0.9505050684710545 2.723299386671689 0 +952 2.283268494086329 2.507009505685398 0 +953 1.357834605415454 3.90522353326361 0 +954 3.905223533264484 1.35783460541975 0 +955 3.928772577666317 2.850881746559526 0 +956 2.841624754537061 3.898971536812052 0 +957 2.28059891046863 1.960705870023707 0 +958 0.9657812101128773 1.554666763548936 0 +959 0.252383029343749 2.47881516027599 0 +960 1.533314039097612 1.023594615948182 0 +961 3.606099214685888 0.2900791051701593 0 +962 2.368546455006744 2.715025155773595 0 +963 1.452894335659898 1.413837702727838 0 +964 2.934569399730218 1.850775731781142 0 +965 3.203151795366601 0.7331476188668345 0 +966 3.533329765040597 3.535542224937104 0 +967 2.722469043608067 1.141472563728236 0 +968 2.881586241960677 2.351092102703892 0 +969 2.563393871213384 1.045050377983005 0 +970 1.469499824571979 1.818988520511509 0 +971 2.314983842736284 0.1079901669990615 0 +972 0.08510903004957139 3.361455399625136 0 +973 0.5697711480944099 2.394259398266858 0 +974 1.129736291688676 1.746176255089517 0 +975 3.029754761993323 1.925421449936837 0 +976 2.124786636376385 2.900794376501304 0 +977 1.154860677091226 0.8778871795231226 0 +978 0.2497870181383652 2.815132329698426 0 +979 2.727471385250262 2.601782805787657 0 +980 3.761306466970639 2.764563797546234 0 +981 3.139050010232054 1.795658640981932 0 +982 2.38699219201927 2.092800089097032 0 +983 1.858252418727281 1.809497800263544 0 +984 1.89319211733114 0.8771894938150239 0 +985 3.31697011623651 3.768847406481017 0 +986 1.278351709415022 3.038377505330319 0 +987 3.566198582692455 3.330421395538968 0 +988 2.501232805514891 1.948406553422133 0 +989 1.85033975885031 2.231018901555825 0 +990 0.1034128259023925 3.17119111305229 0 +991 2.466192233437958 3.096087325553856 0 +992 2.773365526307189 0.8103450911869852 0 +993 2.875877400224612 0.7954793187903439 0 +994 1.990338911617731 2.143018996079962 0 +995 1.902831266342659 0.3712211446971615 0 +996 1.175851943214275 0.6143354393433885 0 +997 2.606545217029559 1.345101104195265 0 +998 0.2610627719249783 3.655766689794607 0 +999 3.29633599571572 3.565233097380286 0 +1000 2.140862693531194 0.1011652932644995 0 +1001 3.497621979733631 0.2708124568341287 0 +1002 2.877044763419377 1.487816967410871 0 +1003 1.403445180607868 2.330994468161879 0 +1004 1.194309471251377 2.218563682018832 0 +1005 3.298406314595806 1.925119829589195 0 +1006 0.2275183669840267 2.282543108944939 0 +1007 1.555572960062 1.710648223513001 0 +1008 1.124682109862836 2.740430089022239 0 +1009 1.54117685893819 3.777195146074747 0 +1010 3.780488673529011 1.544336615749449 0 +1011 3.195150662807035 2.775436468829788 0 +1012 1.227739360865125 3.121846246083751 0 +1013 2.08677743410697 2.172015529377247 0 +1014 2.718372960254881 2.291304665756615 0 +1015 2.691266163240552 2.76677887530607 0 +1016 0.8656026582244499 1.543556765013917 0 +1017 3.494892094239777 2.515916125824324 0 +1018 3.897018542987599 2.008674722630729 0 +1019 2.008674722625316 3.897018542989251 0 +1020 1.746279094043756 1.362331592052449 0 +1021 1.471565302800962 2.905963177818595 0 +1022 1.624353452454447 2.063165409051655 0 +1023 0.8027115438698081 1.630063784326991 0 +1024 2.038046771600237 1.974596243313558 0 +1025 2.329421115646014 1.384660456643221 0 +1026 3.447649916606791 3.359492989808023 0 +1027 0.4364080747228543 3.240546946916339 0 +1028 2.077558233370335 0.8250657311417663 0 +1029 2.231031325095525 2.622232689913834 0 +1030 0.2773068760884788 2.109323048242899 0 +1031 3.66419235459948 1.809258624704864 0 +1032 3.105830611857628 3.254006472013066 0 +1033 0.1045343788933244 1.704944721168399 0 +1034 0.8702215284228217 0.6449452071289303 0 +1035 0.4110233555023335 2.421616694330118 0 +1036 0.8816567455387687 1.949091310212737 0 +1037 0.09934980897351564 1.239808362085698 0 +1038 3.536839397550419 0.09158045448403219 0 +1039 3.60591401086433 2.145217894198668 0 +1040 2.146599227774581 3.606822668059356 0 +1041 2.085510425381887 0.2743073748293123 0 +1042 3.024473272799912 1.566765059850058 0 +1043 2.272005739513884 0.2450378034014907 0 +1044 3.078653139437407 1.441331809210173 0 +1045 2.347652717874299 3.769651408476359 0 +1046 3.771820455133793 2.348308910334456 0 +1047 3.240711749879908 0.3028866156872594 0 +1048 3.088450964522108 0.8406053348275719 0 +1049 0.6010647765400493 1.172507637670387 0 +1050 1.177755990788947 0.2773403882147153 0 +1051 3.187046838161961 1.623740420901475 0 +1052 1.432473447394547 2.526888446217809 0 +1053 0.2810248421595833 1.177633773915842 0 +1054 0.7846320470472846 2.905384822483747 0 +1055 0.8039749015606474 2.799828744220085 0 +1056 1.242095712220071 0.09936669877119428 0 +1057 1.34058843902899 3.626440749922009 0 +1058 3.626360327380437 1.340676040312352 0 +1059 3.594507060120967 0.6516200853030747 0 +1060 2.651937270753142 0.5320369344615893 0 +1061 2.260504423988299 3.10614541971578 0 +1062 2.169523487108732 3.277618002311698 0 +1063 0.3990728035868074 1.335642774990738 0 +1064 3.921314502219831 1.158121399109313 0 +1065 1.158121399104397 3.921314502220988 0 +1066 0.6013394276359404 2.869946542137099 0 +1067 0.07468044580069873 3.537016984971752 0 +1068 1.257449476570216 2.572688126495934 0 +1069 0.0925625821308424 2.343605684219368 0 +1070 1.99116461207686 2.837476779440271 0 +1071 3.277212867791562 2.165557236658804 0 +1072 0.7857344158975909 3.116062370966023 0 +1073 3.485235541673517 3.675947080497126 0 +1074 2.228219551209595 1.74043196685933 0 +1075 2.954100684251611 2.825439751163448 0 +1076 0.6466068401197732 3.598946225518107 0 +1077 1.755845724859957 2.973673615951766 0 +1078 1.41533991751569 3.457143885323363 0 +1079 3.473122727160369 1.413304071917961 0 +1080 1.119942539979709 2.289090323419615 0 +1081 2.473337176638517 3.333073341620888 0 +1082 1.393478049933722 0.4834550621479815 0 +1083 1.357694673992752 1.519456663538893 0 +1084 0.2885025321293806 1.754885178368088 0 +1085 2.071441542327643 3.432264134278972 0 +1086 3.43123534170815 2.068464792847241 0 +1087 0.2404902325887658 1.861124249877755 0 +1088 2.168891075092866 0.5277018589755835 0 +1089 1.673320053555721 0.868190948290432 0 +1090 0.09208579712759402 1.086533272607133 0 +1091 1.06081994493778 2.104344757322418 0 +1092 0.6164931588983247 0.914330843889867 0 +1093 2.447069072873209 2.619130632640894 0 +1094 1.077908387397119 0.08455145145779719 0 +1095 3.084922677930111 2.100956945217933 0 +1096 0.818829636212362 0.9167153812078268 0 +1097 2.843569706832968 0.6230559162984454 0 +1098 3.119656394891879 1.222360203471832 0 +1099 1.353475970904763 3.792639577062045 0 +1100 3.792639577062922 1.353475970905268 0 +1101 3.602513239270605 2.726543147152898 0 +1102 1.576721548996671 2.682933468913105 0 +1103 0.7418212907542183 1.05941193741462 0 +1104 3.674242970437188 3.751877521057464 0 +1105 1.865264391007665 1.045389920290052 0 +1106 0.6949314310644084 1.972260056601346 0 +1107 0.9699332647794543 0.9702576589916676 0 +1108 2.950329004542236 3.27893546677133 0 +1109 0.08080641425801555 1.551927768719558 0 +1110 1.751556461380648 2.20838832397606 0 +1111 1.713668685736537 0.9697388225921083 0 +1112 0.6901557268325239 3.052648143016045 0 +1113 1.244041607250149 1.445796693073529 0 +1114 1.059828432563326 0.7399662823613778 0 +1115 2.570596025485836 0.8699624939277535 0 +1116 2.464453731587551 0.8833008675596983 0 +1117 3.172383162105439 0.09573533268332263 0 +1118 3.908954655025066 2.258191455262179 0 +1119 2.258191455252923 3.908954655026577 0 +1120 1.966689200816214 2.402069786754868 0 +1121 0.5946021116490581 1.93652809733105 0 +1122 1.918211868194387 0.5689569524674245 0 +1123 1.987643491632662 0.8987939921963036 0 +1124 3.00084992737334 0.7032624265772194 0 +1125 3.448771878913326 2.922840442187118 0 +1126 1.926478246548656 2.675193443768483 0 +1127 0.08242708684634488 2.762363142040876 0 +1128 1.203603777581425 2.029676797137017 0 +1129 3.57851709832374 3.229577072263361 0 +1130 2.394531593312853 0.7439254256507023 0 +1131 3.297633442937608 1.139502608262589 0 +1132 3.458140301547003 1.252602809662204 0 +1133 2.557530340141275 0.08925731331606081 0 +1134 2.935081142021181 0.3247103661606204 0 +1135 3.401789779660401 2.292086884128508 0 +1136 2.289528809839392 3.400575771018321 0 +1137 1.877028046738374 2.554609135276593 0 +1138 0.754536291038492 2.430110130073517 0 +1139 2.101987272095641 2.272767162907904 0 +1140 0.4221138960926875 2.130078913233912 0 +1141 2.782509290529533 0.43829522874282 0 +1142 2.668095046319152 3.145878772223562 0 +1143 0.3310762962861318 2.753861880631531 0 +1144 0.08129906244081074 3.054980447196873 0 +1145 3.285421210414154 2.745849438369062 0 +1146 3.911954146224155 2.652363772641349 0 +1147 2.658201317148779 3.908608573721576 0 +1148 0.8319457517095624 1.75852418930541 0 +1149 2.980508063503861 3.464884765429219 0 +1150 3.356221469743186 1.619302867755422 0 +1151 2.912487214787764 2.0604503676992 0 +1152 3.265772104040442 1.80691926988758 0 +1153 0.7612233162971922 3.225007403057486 0 +1154 1.662466001717419 2.990875589109379 0 +1155 0.4507252106958405 1.819702613452004 0 +1156 1.247120832901041 3.460557863480834 0 +1157 0.7828725234974913 1.916935804912784 0 +1158 0.09115728694088836 2.164777592710826 0 +1159 1.237577500558641 0.5272241904871061 0 +1160 3.483619298168946 3.172429089991688 0 +1161 1.153151262280964 2.397237123342282 0 +1162 2.628199427058487 0.9557048983258198 0 +1163 3.06925517230353 0.3489105577836617 0 +1164 3.916320760687348 1.8500149720897 0 +1165 1.850014972086892 3.916320760683442 0 +1166 1.914789124861006 3.128219864692634 0 +1167 2.197415705729726 1.900183434929278 0 +1168 2.184950693355679 1.274126136519223 0 +1169 2.681473507551453 3.784938102310941 0 +1170 3.008840549586146 2.02939286734042 0 +1171 3.436582039500598 3.477424248532378 0 +1172 1.58174322524097 0.7971277059569275 0 +1173 3.168945485068594 3.42523555594649 0 +1174 3.276666040081038 3.407890941817394 0 +1175 1.969887554122038 0.2297661090609846 0 +1176 2.740070656183196 1.450678024105727 0 +1177 3.08225022657696 3.011790757587991 0 +1178 2.379432612649845 1.633120991762465 0 +1179 2.733527406616587 2.017128316582169 0 +1180 0.6556029635844207 1.339013034052397 0 +1181 3.782378788435553 0.08633378997066479 0 +1182 1.646474298291315 0.09748701796244216 0 +1183 1.64510550825189 0.2134757538219485 0 +1184 2.92209016387187 1.381323783425803 0 +1185 0.4782663252806323 1.484323703560381 0 +1186 0.6466509383058181 3.229503504730803 0 +1187 2.570707108035035 2.018720223133697 0 +1188 1.837407701096341 3.635822404776135 0 +1189 1.105228282764001 3.249047784955501 0 +1190 1.518809888143107 2.345138092988467 0 +1191 0.2278658381163489 3.491241302948644 0 +1192 1.92647972679042 3.32636395452477 0 +1193 2.479908193924937 1.570383544309506 0 +1194 0.5053537096432252 2.75884244943965 0 +1195 1.626120339047855 0.6958817802643865 0 +1196 3.729625828673493 2.262788798125887 0 +1197 2.262494044785682 3.729027998791074 0 +1198 1.126683299977364 3.136693505818045 0 +1199 2.334749139809292 0.5826792827320457 0 +1200 2.035727971729293 0.07865641150191914 0 +1201 2.889945146781856 3.626534996120655 0 +1202 0.6244620066415507 2.212271922853943 0 +1203 2.858717233922135 2.679326222977423 0 +1204 2.866590319227921 2.775781600589863 0 +1205 0.7660234449963224 2.633238908984713 0 +1206 0.7308744350948413 3.910321880832448 0 +1207 3.910321880832041 0.7308744350964493 0 +1208 3.025931420167944 2.491562106000043 0 +1209 2.783836593137453 2.830962180448997 0 +1210 3.33911126669199 2.459591461110494 0 +1211 2.964124933895896 2.216118971578599 0 +1212 3.441835153929273 1.882996766182525 0 +1213 2.603625316955282 2.126587278927227 0 +1214 1.675821110984599 2.263256510195811 0 +1215 3.300120480264932 0.5644414376312586 0 +1216 0.8569080808270375 3.45238747364461 0 +1217 3.643359387617963 2.443486709882816 0 +1218 1.909366778059646 0.7191783457934222 0 +1219 1.384614080401136 3.173268264267227 0 +1220 0.08454412275974696 3.783616967848025 0 +1221 2.740477464686988 3.518236585058067 0 +1222 3.137913970980108 1.126137236977026 0 +1223 2.660345515254121 0.2220916747658663 0 +1224 3.469275884004443 0.9192117069892577 0 +1225 2.596581998914311 3.735959065309755 0 +1226 0.9698367340475949 3.525253762401756 0 +1227 3.018727447160177 3.634075276301401 0 +1228 3.275497103598998 1.247037265211849 0 +1229 1.640220693450802 1.352339285572863 0 +1230 3.197090835834127 1.976212001153905 0 +1231 2.885293621618437 2.151592713123629 0 +1232 1.536456812644633 3.066058817362204 0 +1233 1.833428693892511 3.293877528821626 0 +1234 2.133379504228494 2.692734766875708 0 +1235 1.247330763399449 0.2182179142142165 0 +1236 2.001986152147496 0.4179480084393306 0 +1237 2.897125706247477 0.4456397162903215 0 +1238 0.431659223814854 1.160186052061649 0 +1239 1.452771857063831 0.7888860533770339 0 +1240 0.2140725817719659 1.247686677202292 0 +1241 0.2611984624263327 3.147643546120191 0 +1242 3.765729393686691 3.564011997817779 0 +1243 1.017327979068555 0.356466142682185 0 +1244 0.9561434510466229 1.848284751265182 0 +1245 3.207987526479966 3.605180540019387 0 +1246 0.6058065961370057 3.130409211899351 0 +1247 2.73656046500855 0.3520983305768869 0 +1248 3.305526515534871 0.213439151309317 0 +1249 3.914323246811438 3.270482384063765 0 +1250 3.261636332666994 3.925533799292932 0 +1251 3.466931333745001 2.620362139047978 0 +1252 0.2043976041515167 2.189035704485017 0 +1253 2.612933359900929 3.62409757580517 0 +1254 1.161643329229339 1.320183995311647 0 +1255 0.2156560742591181 3.010111862368921 0 +1256 0.6842945926096636 3.40540540251723 0 +1257 0.8717441127526067 2.518678130365066 0 +1258 3.166147747210029 1.385820843656495 0 +1259 3.413767477463009 0.692566201719326 0 +1260 1.31007301408043 0.9409410024087155 0 +1261 1.306240076799924 2.340337978037568 0 +1262 2.374555481474864 1.306620432101412 0 +1263 2.706458399269103 2.1126288815589 0 +1264 2.883038529313471 0.9699424416636944 0 +1265 3.263921674674652 2.943221292893352 0 +1266 0.3461862704046446 3.914172845616784 0 +1267 3.914172845616985 0.3461862704058466 0 +1268 0.3560521229395531 1.019663260808509 0 +1269 0.08594631355573851 1.801705234004476 0 +1270 1.833053530378198 2.375983350004326 0 +1271 1.966274339733091 1.06537335219924 0 +1272 0.5519338062352535 1.554170755754769 0 +1273 1.684634730157585 2.362603947594776 0 +1274 2.919204027082925 2.942467153407841 0 +1275 2.986579939597811 2.350618017704059 0 +1276 3.674404790984364 0.2256004304739446 0 +1277 0.3746278420889281 2.603019326865542 0 +1278 0.7689747603857149 3.75614964210616 0 +1279 3.756228097930029 0.7687417566081018 0 +1280 1.972776457237245 2.488729107266807 0 +1281 3.437886422016437 2.745281325879549 0 +1282 1.284048859245684 1.864804326103405 0 +1283 1.232201787918872 1.190212673785638 0 +1284 3.022201396706091 2.668885707047994 0 +1285 0.2307213238014169 1.570356721775672 0 +1286 1.902284672924405 2.959641283713836 0 +1287 1.962861238022061 3.031251979622744 0 +1288 2.711025460314807 3.604088895957291 0 +1289 2.023632228793357 2.331344917155797 0 +1290 2.418554103299741 0.3204761297302348 0 +1291 0.4297879115008413 2.891468893506734 0 +1292 3.654224465369008 3.918974330110306 0 +1293 3.921168428892883 3.653265294913739 0 +1294 0.6676514444539098 2.580938340355224 0 +1295 2.471658970337032 3.439697404083247 0 +1296 1.48652627849133 0.4721900354441777 0 +1297 1.21265332506194 2.729761442650065 0 +1298 2.907429782839316 0.7089068743477884 0 +1299 2.591147709841081 2.512309504157192 0 +1300 3.032325844967398 1.253320177871915 0 +1301 1.337536207088546 0.3715874103152346 0 +1302 2.580718719424351 0.383739618820578 0 +1303 1.753216416717566 2.683186142797756 0 +1304 3.793367264079075 2.666919191758346 0 +1305 1.961605076068356 3.543078178520171 0 +1306 3.573406580782776 1.955238000361051 0 +1307 0.9535085156583787 2.885539458672141 0 +1308 2.776749722503586 0.08770568947082474 0 +1309 2.581968949391908 0.7014397321077399 0 +1310 1.030675753160931 3.777222648646885 0 +1311 3.777222648646153 1.030675753160303 0 +1312 0.224509451164491 1.676415241326316 0 +1313 3.308906767871159 1.404366210421792 0 +1314 3.063209490380366 2.18796973967264 0 +1315 0.07688806704362161 2.549848261072341 0 +1316 0.7160468446726665 1.620173391161437 0 +1317 1.244604263089294 3.299670267579508 0 +1318 1.282218080508496 3.20205554996535 0 +1319 2.162646677477031 0.9785370897769188 0 +1320 2.103691407068428 3.102438604228709 0 +1321 1.109567783788373 3.405079690921869 0 +1322 3.397203731895424 1.122586626973827 0 +1323 2.490136287462755 1.750209135176757 0 +1324 1.007547393887269 2.452174555781474 0 +1325 3.92409541523975 1.650136205911612 0 +1326 1.648635854230627 3.924950144441977 0 +1327 0.8540366003907645 3.061133611661512 0 +1328 1.952528030848272 3.756376206815338 0 +1329 3.75717086641937 1.9514245878184 0 +1330 1.908664137751151 2.859915143913129 0 +1331 2.159484851293796 0.2115647779546885 0 +1332 2.430090939733314 2.78449635464748 0 +1333 1.560826976498233 0.2256300273744693 0 +1334 1.756752448093598 0.8105477452380316 0 +1335 2.353104222912683 1.875531766753743 0 +1336 1.799722987927939 0.9830255514891411 0 +1337 1.004604196856948 2.287427924717941 0 +1338 0.07388362555705599 1.349999999998271 0 +1339 1.193187353446031 2.913417108443222 0 +1340 2.403386298869316 1.129998628781795 0 +1341 2.872298353953179 3.322330453278112 0 +1342 2.558173074708319 2.906903345030988 0 +1343 0.213813923151651 2.020146921767641 0 +1344 0.519375045230718 3.3107801126131 0 +1345 1.350000000000545 0.07335987139041956 0 +1346 3.220456399816774 2.24189921094362 0 +1347 0.09137463608672891 2.902089233933194 0 +1348 2.25262939593144 1.049709108723617 0 +1349 3.919857902786406 3.428048221276673 0 +1350 3.428436345919514 3.921527645317839 0 +1351 3.547010370783487 3.048152245503007 0 +1352 1.600925374724594 2.418656897639106 0 +1353 1.371681505738017 0.5674430628372547 0 +1354 1.109586526664594 3.642395356775562 0 +1355 3.642749732055484 1.110179848627187 0 +1356 3.926161115665893 1.454210611666511 0 +1357 1.454237054122119 3.926078970258555 0 +1358 1.557905405087 2.265988717425664 0 +1359 3.760151322335828 3.242120103204345 0 +1360 0.5761247733432595 3.918101084382457 0 +1361 3.91807979050323 0.576119052058101 0 +1362 2.552230975284258 2.663247723369262 0 +1363 2.77078267430545 2.526283056330962 0 +1364 1.501622443919131 3.617902443378877 0 +1365 3.627926687473216 1.510081008297285 0 +1366 0.8027235718766679 3.597701302768454 0 +1367 1.980422797284833 3.192181857651246 0 +1368 3.535734660802081 0.9862857386546288 0 +1369 3.920095467894916 3.029967211807963 0 +1370 3.033295202026547 3.921604600887147 0 +1371 3.402107738545476 3.274644085127238 0 +1372 3.603776913966021 3.491441099789381 0 +1373 1.075412361074497 0.8340642582716008 0 +1374 2.106502948843397 0.3639044600725054 0 +1375 0.3460333569809211 2.93184374025069 0 +1376 0.6289347898978475 2.114944727475828 0 +1377 1.931813903982209 2.214302727625225 0 +1378 1.624984236440902 0.529163661094309 0 +1379 2.404629945367361 2.874705809803714 0 +1380 0.6584009383306146 1.536307434628561 0 +1381 0.7148425870436977 2.061532681396182 0 +1382 3.786228627702059 3.156733027050562 0 +1383 2.550084908735623 1.672361688216388 0 +1384 3.386533797548727 0.4027395809616048 0 +1385 0.3868425962836078 1.58975745774686 0 +1386 1.526747214173147 3.312314463662523 0 +1387 1.772431256104482 0.4592009418841464 0 +1388 3.779770855601251 0.4489975515966834 0 +1389 2.649496767421509 1.964804682828844 0 +1390 1.369441627862461 2.913772653338854 0 +1391 3.779177343132642 2.96005374624349 0 +1392 2.96099792474477 3.778437891945146 0 +1393 2.730854274685718 1.227690258334825 0 +1394 0.4470537260334009 3.776354983819607 0 +1395 0.07273179897764091 3.252475560974007 0 +1396 3.608821438752493 0.805115929491394 0 +1397 3.305474942602659 0.4569901519917022 0 +1398 3.233482122099705 0.4066810918918684 0 +1399 2.569062608666159 3.925043759103473 0 +1400 3.926185129972065 2.566876140307568 0 +1401 2.905341079675171 0.5442043544867046 0 +1402 2.504863176337455 1.385215289640758 0 +1403 2.518930886438244 1.841544404363716 0 +1404 2.481664404969563 2.512145192967345 0 +1405 1.081221925378859 2.823238676488214 0 +1406 3.112450095559005 2.49589298523394 0 +1407 0.8631462674005352 3.790932797630012 0 +1408 3.790966154698314 0.8630472011681241 0 +1409 3.117684836669404 1.900364000970852 0 +1410 1.737343236738075 0.0746419427008001 0 +1411 3.186783307730926 1.285765336928779 0 +1412 2.73793529784501 0.5163605075696384 0 +1413 2.893736515129174 1.222745906284177 0 +1414 1.109534668774564 0.4486495148563678 0 +1415 2.808499218891896 2.300123973210968 0 +1416 3.422582527851509 2.46452337660978 0 +1417 3.141057452711026 3.528278152339401 0 +1418 0.8755241045973496 2.77774959478657 0 +1419 3.010590150192278 1.356789210049824 0 +1420 1.346915447238004 2.089225447242709 0 +1421 2.291775952394095 2.907342860134434 0 +1422 2.768419277085044 1.629573497284564 0 +1423 2.933520280148406 2.632773370663765 0 +1424 1.702010612961118 3.553285600933104 0 +1425 0.2458726959227379 3.325384319242053 0 +1426 2.625441161232382 3.444777899381434 0 +1427 0.9515310686865587 3.180009553608588 0 +1428 0.5359775128185545 1.63529118591443 0 +1429 3.248297836020324 0.0768910029399619 0 +1430 3.275000931355966 1.65448282064538 0 +1431 1.250872868742469 1.364496608065638 0 +1432 2.181218134184681 3.073776139918899 0 +1433 2.795338598561189 3.074558077864832 0 +1434 3.024660344371399 2.760648255632374 0 +1435 3.522470851210821 2.163943959799009 0 +1436 2.164084912203593 3.522563571329973 0 +1437 0.8975454562686469 0.7972156308861686 0 +1438 3.792262900455316 1.714539810265887 0 +1439 1.089789848819307 2.470532770057698 0 +1440 1.410378465045481 3.563838041678227 0 +1441 3.575116380599882 1.416821516511324 0 +1442 0.5956958474449926 1.686428693754326 0 +1443 1.018298131080795 2.014778217515027 0 +1444 1.765505634731516 2.857209015262239 0 +1445 3.297147960348496 2.611264170160647 0 +1446 3.791582306795019 2.513309498580107 0 +1447 3.626762252458767 2.907069897642707 0 +1448 3.70690476593878 2.866240968890544 0 +1449 2.707836475922011 2.43058490393176 0 +1450 1.723481092710421 3.805614905735883 0 +1451 3.35297721632837 3.045560779507764 0 +1452 2.595735191287261 3.195903619935909 0 +1453 1.291336487001836 2.498708489059314 0 +1454 1.241396169115422 3.787872101058637 0 +1455 3.787870213765241 1.241401156035003 0 +1456 1.843516012587896 2.718538203050118 0 +1457 3.357027874836703 3.613916371600203 0 +1458 0.8243848429639036 3.925983113040428 0 +1459 3.925983113040283 0.8243848429661773 0 +1460 1.156734036188881 0.712464876857012 0 +1461 1.50925233004349 0.6403937613877793 0 +1462 1.893497934959851 3.465858111323357 0 +1463 3.185728196587829 0.9582301074493139 0 +1464 2.271254036153399 2.789252450480671 0 +1465 3.124543734799922 1.698805924984099 0 +1466 0.5037735027742616 3.154314091716758 0 +1467 3.543044554731786 0.3424663970960335 0 +1468 2.346390148564679 0.997024418221286 0 +1469 2.448951272112661 3.629902530732702 0 +1470 2.771866726193921 3.7871087192322 0 +1471 1.187506548776575 1.844659743425163 0 +1472 2.901729369511871 1.053685823382423 0 +1473 0.6470251200078561 1.012687675908316 0 +1474 2.008398449770677 1.593325027946569 0 +1475 2.877851170140376 3.712619982028833 0 +1476 2.617464156954275 1.818829097574532 0 +1477 3.493867688913353 2.411244933923627 0 +1478 2.404264444525385 3.488798131953357 0 +1479 2.237242969600634 3.216132068839943 0 +1480 3.216674429028267 3.09392946595012 0 +1481 0.8817721532941925 2.037051395773251 0 +1482 2.172963705462534 2.793638430715379 0 +1483 3.695475607985863 2.075116459341303 0 +1484 2.076347826812788 3.693582809804408 0 +1485 3.349211483876483 1.538520084104824 0 +1486 0.3605637886608622 1.196828740768292 0 +1487 0.1934032441306264 3.185911915763111 0 +1488 2.634344573496625 0.07690776750431214 0 +1489 1.69746268120616 1.292773281997244 0 +1490 3.512821678191148 1.720014821533889 0 +1491 3.564999856002894 1.798776192632164 0 +1492 3.705491296661077 0.5798238038899115 0 +1493 2.237767387339757 0.07499702082273756 0 +1494 3.383414669001509 1.937964532971431 0 +1495 2.011112693260864 0.9904058804192974 0 +1496 3.817829389478703 0.3048987306324406 0 +1497 0.3064867204931145 3.817148834148147 0 +1498 1.809932519881355 0.2013791920168878 0 +1499 3.338572618076361 2.880339044924916 0 +1500 2.338622357845699 1.468032896710853 0 +1501 2.519742920885073 3.784750370010252 0 +1502 1.095930203652389 2.567441266725316 0 +1503 0.5798865438154527 3.705745710777608 0 +1504 3.820831962761451 3.70443453251426 0 +1505 0.211657084819924 1.377030499802256 0 +1506 0.3102949324089604 2.423466779488452 0 +1507 0.3979939937249383 3.384572636542435 0 +1508 2.767690661766431 0.180846496167357 0 +1509 3.154016757808556 0.5212680610521717 0 +1510 1.373129880446546 0.2131727295745916 0 +1511 2.305528306186888 1.154454795135944 0 +1512 1.53462919729573 0.07915094627664035 0 +1513 1.089061481203419 1.38364987183263 0 +1514 3.009473184710042 3.37101897469519 0 +1515 1.65308252702281 3.638104329819924 0 +1516 1.058931699017278 0.1707697891940034 0 +1517 3.027468514667211 3.120498780733223 0 +1518 0.08114717836456288 2.082335513952625 0 +1519 0.1780132322835161 2.909358561547906 0 +1520 1.840104793693312 1.349275249902897 0 +1521 2.626055893739618 3.304795051398253 0 +1522 2.734574899173276 0.6696110497025697 0 +1523 0.4869906166781569 0.9546663337437576 0 +1524 3.631689159600597 1.654265090462065 0 +1525 2.405336381496067 1.727941380111727 0 +1526 1.574342975519504 2.508074089706039 0 +1527 1.016293018065306 0.6472361642550417 0 +1528 3.14432128767408 3.801885616943228 0 +1529 0.9838064829621977 2.606750937295563 0 +1530 0.9122781650021874 0.5522441816350339 0 +1531 2.382665608558369 0.4133508676834647 0 +1532 0.1930760425188846 2.627513372538476 0 +1533 2.513766632588333 0.554429320476998 0 +1534 3.917640559109127 0.975069666382948 0 +1535 0.975069666380191 3.917640559109627 0 +1536 1.51465944869893 0.387140320517488 0 +1537 3.463491684610928 0.5479820028308983 0 +1538 1.127206115014697 0.9783021589768777 0 +1539 0.4256616284103879 2.532642023828573 0 +1540 0.4877508091893218 3.019446338607671 0 +1541 2.286708134745548 2.689365272265592 0 +1542 0.4387068433749763 1.984823937442526 0 +1543 3.033361643261467 0.07659002877041404 0 +1544 3.535253598768508 3.80715511320116 0 +1545 1.199337818996968 0.3558141375800665 0 +1546 0.3985442984391803 2.303713851687339 0 +1547 2.550718605632539 1.199996967889554 0 +1548 2.61968384162807 2.293669301680853 0 +1549 0.3933078451514718 1.511068422277235 0 +1550 2.86333569537713 1.318897812196858 0 +1551 3.921056801413622 2.160580067508899 0 +1552 2.160580067500212 3.921056801415517 0 +1553 0.5799473080058455 1.376195161478029 0 +1554 2.53242520571084 3.581829116779529 0 +1555 2.939580338368828 3.188616496797094 0 +1556 1.500544496319288 3.700449919571734 0 +1557 3.70791467408149 1.507004489365714 0 +1558 3.098161908830629 3.699161944708717 0 +1559 2.399579294777938 0.08647544330900057 0 +1560 0.3025031970778838 1.994875431004501 0 +1561 1.936567880907724 3.931488387348617 0 +1562 3.931488387348989 1.936567880915014 0 +1563 1.512912541870833 0.9334500448897669 0 +1564 2.872980333305913 1.762335375134944 0 +1565 3.2034326011366 1.534601864448208 0 +1566 2.62836593541201 2.585678396105715 0 +1567 2.726264646752731 2.685591441915982 0 +1568 3.03522021594315 3.289309441072216 0 +1569 2.674988387001798 2.93382844230436 0 +1570 1.249419580179273 3.92508696418534 0 +1571 3.92508696418519 1.249419580185043 0 +1572 2.360636175056073 2.4086883383331 0 +1573 2.243210738670611 2.292758922650514 0 +1574 2.85293327119491 1.600088154462411 0 +1575 2.103227546846695 3.777791673872853 0 +1576 3.77787379235478 2.103174124336824 0 +1577 0.5158560780114216 1.213408805422945 0 +1578 1.784104194381761 3.695509209259262 0 +1579 1.842787218204757 0.4426071718090514 0 +1580 2.410770553622533 0.6504527151812812 0 +1581 3.2602348583183 1.029130899914418 0 +1582 3.835149015389113 1.84309710628299 0 +1583 1.836711046322432 3.833528856526566 0 +1584 1.069499675129467 0.5826224001914875 0 +1585 2.546941730970722 3.04203877845758 0 +1586 2.621946288694431 3.064153491169334 0 +1587 1.803310133885346 0.6988206754710271 0 +1588 3.547022065221374 0.5683731147531744 0 +1589 0.1662389710741322 1.057134889182891 0 +1590 2.2331647986416 3.545833316089593 0 +1591 3.545436090817217 2.232784950440861 0 +1592 0.7859293416031172 2.180602954625746 0 +1593 2.40283159900753 0.8342615223970899 0 +1594 2.001348815250117 2.760545736486642 0 +1595 2.849264154959757 3.39202589740979 0 +1596 0.5492149132084119 3.462681632043354 0 +1597 1.047710451515371 1.009299923050727 0 +1598 0.07285196059977567 1.630716391397405 0 +1599 3.921795325957766 0.07820467404261429 0 +1600 0.07820467404236921 3.921795325957534 0 +1601 0.6490285560993361 2.761491171201237 0 +1602 2.249038364683301 0.5076370463145191 0 +1603 2.740125474512703 1.713134091727404 0 +1604 1.69630222430263 1.606948008552048 0 +1605 3.331452454499371 0.9859918078992596 0 +1606 0.6992818248147659 1.156256477142512 0 +1607 0.08503369573057429 3.629840600296656 0 +1608 1.371551444487735 3.066516609692536 0 +1609 1.75517401715549 1.171872148351953 0 +1610 3.033961878640952 0.6230542006381314 0 +1611 2.851176453299891 0.06435676271017807 0 +1612 1.601682740085412 3.256014413617784 0 +1613 2.825004396123989 2.926050813040661 0 +1614 1.441323320838073 2.415572304983854 0 +1615 3.305708110793783 2.082832606077341 0 +1616 3.401584416632043 0.834261656009047 0 +1617 3.372666474202253 0.7590538322758109 0 +1618 3.145105087740993 0.6549656459849222 0 +1619 2.250858640384251 0.8670703422317603 0 +1620 0.5640705119937182 3.54880079873207 0 +1621 2.289260063119284 0.4133939233592683 0 +1622 1.765258608097766 0.5955238291359123 0 +1623 1.843562585357576 0.3059279997218909 0 +1624 1.382708753566534 3.345319644893516 0 +1625 3.628737102491837 0.0751885767606759 0 +1626 0.7194210872688263 3.823696346468543 0 +1627 3.823712037633013 0.7193744865134595 0 +1628 2.450196547041083 2.421764043038347 0 +1629 0.1706629362184031 3.389359989818877 0 +1630 1.668315534643555 0.6149533510656847 0 +1631 3.266235561952376 3.250471575793743 0 +1632 0.7977579398798851 0.7094224221732186 0 +1633 0.5335984927238667 2.676620923195333 0 +1634 1.72045383880377 0.3462743399472646 0 +1635 3.046848585427254 3.542155661284124 0 +1636 1.268034135521514 3.587166796051303 0 +1637 3.586966731831404 1.268375166814833 0 +1638 2.054863394720445 2.612913813682829 0 +1639 0.07190547229929611 1.946365104510955 0 +1640 2.077147847761444 3.300090033023181 0 +1641 3.137901446637067 0.198716238175238 0 +1642 1.72993663211541 3.146512318211003 0 +1643 2.629161254854967 2.437642456027922 0 +1644 1.685416835137881 2.820019777272922 0 +1645 1.030670182821473 2.879030129440717 0 +1646 1.565047154037695 1.214827329748953 0 +1647 1.485079026397039 2.81782139064771 0 +1648 0.448662833262732 1.655754415101437 0 +1649 1.315162434699539 0.6824437918301682 0 +1650 2.340067777811115 1.78879190403168 0 +1651 0.7563022868700154 3.369264147866726 0 +1652 0.821127120566764 3.388058292202803 0 +1653 1.039602630954641 1.873179397764949 0 +1654 2.410529189251455 3.008991049347703 0 +1655 2.180908606651674 1.825465911275828 0 +1656 2.317749292062836 3.011773255453999 0 +1657 1.400042286679188 1.191492107310143 0 +1658 3.691698906503997 3.834414666912356 0 +1659 1.997551581536458 3.271948144436307 0 +1660 1.574429181083249 1.30206050403716 0 +1661 3.093119770712749 2.335238651437906 0 +1662 2.520701305026 3.176105097245248 0 +1663 1.787402135170563 3.561614113356335 0 +1664 3.757100130196142 1.631314737089756 0 +1665 3.216209302823797 1.113181618941043 0 +1666 1.023487204623406 3.259878346905865 0 +1667 0.9878493314498911 3.333269912059358 0 +1668 3.388799567168821 0.1697277564410672 0 +1669 1.487567716844431 3.006749654491312 0 +1670 2.094106759069041 0.5262239526548697 0 +1671 2.76762507902555 2.984015453776603 0 +1672 1.390157955468772 1.350502303355869 0 +1673 1.923797264973822 1.755120682918565 0 +1674 0.4843800434853062 3.583978381869352 0 +1675 0.331028193858473 3.629345691906146 0 +1676 2.444513393753088 2.156997559559867 0 +1677 1.594600612300423 0.3729280598690756 0 +1678 0.5705352024347654 1.072724207901937 0 +1679 1.10990164789612 1.655915976922772 0 +1680 2.359641728703672 2.020635310082927 0 +1681 3.590714961357378 0.4814904314866549 0 +1682 2.170351138149433 0.6556054647449613 0 +1683 2.542303227879652 0.2959345595417892 0 +1684 1.045151395127584 2.750063809401564 0 +1685 3.478563091701318 0.8407185367120245 0 +1686 3.915950316137869 3.919373066243998 0 +1687 1.312787768283595 1.233945975010091 0 +1688 0.8397436784653579 2.439622556112611 0 +1689 3.675740403001883 2.76191375010443 0 +1690 0.7907737731648754 3.512598391937689 0 +1691 1.044742767854818 1.095338617202359 0 +1692 2.616415845151206 0.7865216907109682 0 +1693 1.816359213115695 2.483605792750195 0 +1694 3.390690502831009 0.07832696781338135 0 +1695 1.80842504853068 3.076048018715101 0 +1696 2.026379764271384 1.20068349224694 0 +1697 0.5208680593354493 2.23388816728771 0 +1698 2.019942485496749 3.813908004690644 0 +1699 3.814054134370665 2.019749674575577 0 +1700 3.155330853111689 2.389369791167539 0 +1701 1.669893076908029 3.303717278381569 0 +1702 2.284801421822533 1.648672814738806 0 +1703 1.649951951945478 3.390580023356752 0 +1704 1.540576572429604 0.5440473515652235 0 +1705 0.8670749794636721 2.304326230664048 0 +1706 2.398247504602684 3.150782443540419 0 +1707 2.187626714365218 2.938616031657315 0 +1708 2.750856928724336 3.22588232688984 0 +1709 3.930808278479989 2.753029723036676 0 +1710 2.749999999996711 3.939441555029031 0 +1711 3.39427146356916 3.787183501044861 0 +1712 1.83793760438455 2.991589974403855 0 +1713 2.018474533304848 0.7373416334093416 0 +1714 0.1636988582825096 2.754103626166418 0 +1715 3.277043154597676 2.006878194828341 0 +1716 2.7055130639135 2.856661805998629 0 +1717 1.152977178821985 3.314556854679617 0 +1718 3.33102992892511 0.2907833296862493 0 +1719 0.5698481003270679 2.547201612015426 0 +1720 3.536611960618634 2.773023756901179 0 +1721 2.978507292523893 1.668194880535637 0 +1722 3.04698314606619 1.732932939902703 0 +1723 2.1447961701169 0.8966034390154003 0 +1724 0.9534422452793885 2.522158784734832 0 +1725 3.927084965432026 0.1752138422146596 0 +1726 0.1752138422148087 3.927084965432018 0 +1727 0.15531765772371 1.530113404745506 0 +1728 2.187902320307708 2.553390038664684 0 +1729 1.993670838667006 1.908447391026302 0 +1730 2.751737794838935 1.062311057357088 0 +1731 2.692464307589433 3.460317283698191 0 +1732 1.388841997013786 2.635989083588724 0 +1733 3.842698337096554 3.039547893593202 0 +1734 3.045898450296706 3.843707880947346 0 +1735 2.641842214819702 1.721140056992857 0 +1736 0.318521480116917 1.456697277663459 0 +1737 2.043413638899863 1.769691099544738 0 +1738 2.421658521502244 1.457410795175903 0 +1739 1.403887170247588 2.220204154617262 0 +1740 3.279613467141828 3.021947080213043 0 +1741 2.772129964009466 1.869209280336265 0 +1742 0.6507368290597413 2.314191981637996 0 +1743 3.154581045315235 2.079432734448843 0 +1744 0.4371762643485649 3.321960101037993 0 +1745 2.943639799716814 3.927723840830931 0 +1746 3.93109192510033 2.944345633267523 0 +1747 1.260518906022437 0.3876245882218242 0 +1748 0.8944367477884232 2.37568864486709 0 +1749 3.010734789048939 0.2972674487791944 0 +1750 0.05918172210318954 2.249999999995701 0 +1751 3.41192285162805 3.20083559186132 0 +1752 3.926954069827535 1.07434636398664 0 +1753 1.074346363982041 3.926954069829558 0 +1754 1.338189130842829 2.18427455814803 0 +1755 1.449394535008416 0.7101594305166858 0 +1756 1.132778607161709 1.481314271869598 0 +1757 0.6022024634385283 3.296419999844445 0 +1758 0.5386994888341013 0.9142916395511537 0 +1759 3.4858039582712 3.096277310757406 0 +1760 2.423401575275495 3.926360211650424 0 +1761 3.926360211651667 2.42340157528157 0 +1762 1.624789905653667 2.910891915361458 0 +1763 3.829169271176686 3.285119676864506 0 +1764 0.445706865679362 3.455710319422503 0 +1765 0.9565496174353711 0.4851734628558195 0 +1766 1.513407720624633 0.1535027745084896 0 +1767 3.45683030343619 0.4535028256467518 0 +1768 2.372239928080051 3.585944470343345 0 +1769 3.58568761215556 2.375650129433714 0 +1770 0.8400903804032871 2.599784847060658 0 +1771 2.711274918523224 0.7622352220547022 0 +1772 1.38284770214469 1.663790962972037 0 +1773 2.652621142011181 0.6371102682715464 0 +1774 3.011812114139846 0.94503114772689 0 +1775 3.377615354949829 2.215338590726915 0 +1776 2.215360078500892 3.377532805560918 0 +1777 1.924001974570742 0.2935792660670965 0 +1778 1.83983405177116 2.813109584907248 0 +1779 2.91707607135434 0.1749901145971723 0 +1780 1.282981643047213 1.511611748427584 0 +1781 0.8400364363633486 0.8473016540225382 0 +1782 2.868129853035919 3.551788962550393 0 +1783 2.580480571456754 2.367502964600047 0 +1784 1.57801474209264 0.8820459807217358 0 +1785 3.851786957736469 0.06024671532690562 0 +1786 1.840172450598385 1.509334778533977 0 +1787 0.4231302849452846 2.796068591659802 0 +1788 1.075287362354987 3.487957716777127 0 +1789 3.487957716777825 1.075287362354746 0 +1790 0.4265373765622615 3.927989036419776 0 +1791 3.927989036420225 0.4265373765635883 0 +1792 3.108520404020107 1.618726680723053 0 +1793 2.864456772639764 1.89846370979422 0 +1794 1.433473467828511 1.881024137359981 0 +1795 1.215313428403883 0.7878267999464319 0 +1796 1.315503310988161 2.8578383731312 0 +1797 3.64365175184407 3.680680221740969 0 +1798 1.251587018617978 2.859187397677869 0 +1799 0.7110345632234438 3.48023696096563 0 +1800 0.3818892075009742 3.051259386978072 0 +1801 0.8719982909337856 3.262937739230212 0 +1802 3.528575150669091 1.216532425834081 0 +1803 2.981293107618266 1.096753740016595 0 +1804 3.92115789817037 3.839944231674591 0 +1805 3.824952122655881 3.92861119877013 0 +1806 2.38784144101852 2.553079170655921 0 +1807 2.111542436608227 1.10506220891593 0 +1808 3.156730470873551 2.85573815281828 0 +1809 0.9507662097101337 1.146001652850278 0 +1810 3.189868095938071 2.919753111665733 0 +1811 3.5732025254452 2.655513264789012 0 +1812 1.484475420742904 2.135447255287907 0 +1813 0.5608332833751802 2.07765600880628 0 +1814 2.484305785755531 2.257284799954194 0 +1815 1.101659093384359 2.996521966495303 0 +1816 0.05942723887245367 3.852325862238582 0 +1817 2.970135245437476 1.191379562982688 0 +1818 3.41858070916894 2.841037401451229 0 +1819 2.242492669251302 0.7903856556996407 0 +1820 1.372739892406041 3.713451120270962 0 +1821 3.713442913889956 1.372748831312925 0 +1822 3.399709845783072 1.757666498812902 0 +1823 0.06761470107827222 1.161052791683583 0 +1824 3.942836372091612 3.34999999999896 0 +1825 3.34999999999828 3.942836372091731 0 +1826 3.93940462621578 0.6506456964791505 0 +1827 0.6506465138030419 3.939407668198732 0 +1828 0.6227779381202061 2.67756567309226 0 +1829 3.492386132811168 0.1872403389373486 0 +1830 1.00665856075202 2.146883054188463 0 +1831 2.06571445978013 0.6635038159747838 0 +1832 1.462587361042387 3.180658876676409 0 +1833 1.935185537676068 3.40184927687686 0 +1834 1.963513376442017 1.431591815680277 0 +1835 0.3145655793221229 2.667674168932582 0 +1836 1.447838597049103 0.8874372781506024 0 +1837 3.010501662462103 0.1613350385074078 0 +1838 1.452698405452025 0.3172390205964036 0 +1839 0.4902584739435909 2.4126072183959 0 +1840 2.240385355742757 2.120951450339613 0 +1841 1.182010252067503 1.046014854190112 0 +1842 2.38832383430959 0.5151475617953724 0 +1843 2.900785743625371 1.681315153910873 0 +1844 0.06549073128021538 2.835998428158677 0 +1845 3.285163258684287 1.492616624186429 0 +1846 3.123793533760205 2.613066710791086 0 +1847 1.369747501394001 1.089005819833358 0 +1848 1.212395165092393 3.859845919670318 0 +1849 3.859845542211085 1.212396162478916 0 +1850 0.6704076469148359 0.846553051790109 0 +1851 1.127579303169778 2.193136226562103 0 +1852 0.908419411449555 1.072587265660212 0 +1853 0.3517861791152756 2.139883385194454 0 +1854 3.928852794371104 3.174923713152989 0 +1855 3.180618258319582 3.926879980319243 0 +1856 1.216619544987623 3.532131305315618 0 +1857 1.245768247773941 3.65822034123329 0 +1858 3.658199371673176 1.245807386930855 0 +1859 0.4190840690671366 1.889919402714701 0 +1860 1.716111568706814 1.738382763804493 0 +1861 1.297160001275288 1.941702736266353 0 +1862 1.159430665125227 0.06600751598504201 0 +1863 0.9827649935742109 3.69401696179216 0 +1864 3.696378737761873 0.9791818796779271 0 +1865 3.092795284645546 3.175475857140414 0 +1866 0.9441371989665406 2.004623996457374 0 +1867 2.436142560055393 1.898491487893735 0 +1868 0.5053495198470491 1.303501791347699 0 +1869 2.941436260430511 1.537650997854886 0 +1870 2.506559411736796 2.784832682730146 0 +1871 2.939621987433074 2.287478802142258 0 +1872 2.554294391970862 2.828509223616166 0 +1873 3.814078228875514 2.180007292825552 0 +1874 2.179994728740068 3.814042829654241 0 +1875 1.134104148294062 3.551559494143402 0 +1876 3.550059895793676 1.13643973917625 0 +1877 2.132454391551841 2.419552324161948 0 +1878 3.373118773842153 3.406115787104623 0 +1879 3.687690738049174 3.60855428139592 0 +1880 0.5288169712106989 2.002163626946377 0 +1881 0.1678186117538876 3.797293887650369 0 +1882 2.081564123731123 1.252455710641819 0 +1883 0.7346617242553706 2.340703726408592 0 +1884 3.444477381640916 2.146594586533211 0 +1885 2.147668485033537 3.446313222048927 0 +1886 3.25416635439065 0.8733738577024937 0 +1887 0.1826301203439464 2.462367439142238 0 +1888 0.9027840073804878 2.647227927428444 0 +1889 3.554949294056362 2.88617000218287 0 +1890 3.668683657404825 0.6342005082197061 0 +1891 2.572295201383177 2.226096172203332 0 +1892 3.798691064853937 0.170586834839442 0 +1893 2.787134011984349 2.657974430930077 0 +1894 1.862648856384138 3.744556060396175 0 +1895 3.745827099912307 1.871049818323236 0 +1896 2.27181796277183 0.6595543122468573 0 +1897 2.563069674753707 1.510423746207816 0 +1898 1.127044571077516 1.236147018973182 0 +1899 3.2323799130177 2.335362261472149 0 +1900 3.600544199965148 1.872834391823507 0 +1901 0.9996677878302107 3.033906875358323 0 +1902 1.015195402373392 3.114237340984363 0 +1903 2.836377919140226 3.15708464643086 0 +1904 2.345136711219636 3.940347227523002 0 +1905 3.940347227522926 2.345136711228383 0 +1906 2.808338993342554 0.9493634029811686 0 +1907 0.5784129334266908 3.838014130830914 0 +1908 3.836606792024645 0.5791997204751393 0 +1909 3.289163282325789 2.820150796669734 0 +1910 1.156325473811427 1.946834351382367 0 +1911 0.8855465419184729 0.9781297161787053 0 +1912 3.128752813990125 2.2500139500834 0 +1913 0.4146747936485421 3.524062396737327 0 +1914 0.05510344782529207 3.449999999998651 0 +1915 3.534519855691029 3.618734986904931 0 +1916 1.025891562656161 1.254577494033337 0 +1917 2.819969728040132 1.100710729579019 0 +1918 3.2497257074022 3.74638371500178 0 +1919 3.019489327916094 3.714847892313027 0 +1920 0.977976037691014 0.9006500266460766 0 +1921 0.848284394764246 1.688895315789076 0 +1922 1.153739207363775 1.583015799310295 0 +1923 3.325797962419926 1.305438677652833 0 +1924 0.9336822004413423 3.461886807841042 0 +1925 3.643866273606963 2.590819388316471 0 +1926 3.935611370492622 2.073711186498093 0 +1927 2.073711186489032 3.935611370493937 0 +1928 3.461290233172473 1.479733244869134 0 +1929 2.80937614115145 1.470869376412286 0 +1930 2.426757546077464 0.9561464725633558 0 +1931 1.987127084336288 1.345572694082096 0 +1932 1.388361332156785 0.1482668742842604 0 +1933 1.557034347421935 1.484310157704566 0 +1934 2.447823533631378 1.314068693385045 0 +1935 2.925741119792182 3.035259828732804 0 +1936 2.813698287871407 3.511689563943307 0 +1937 0.8262117532039572 1.099876322262709 0 +1938 2.705329995716212 1.305921687812951 0 +1939 3.576250825771451 3.929923949681176 0 +1940 3.929923949681328 3.576250825771139 0 +1941 3.151049016903565 0.2788846147546514 0 +1942 3.53164138690515 0.4204564857492393 0 +1943 1.621639873651149 1.45257096652582 0 +1944 0.2937957390771364 3.457991912373982 0 +1945 0.4312190294372077 3.166938793398132 0 +1946 1.810767944418323 2.157458385261322 0 +1947 2.805071208598668 0.3059931133917603 0 +1948 1.57250106896494 2.118132356349511 0 +1949 2.103001435552336 2.005186984326322 0 +1950 1.74430826117045 1.930677340738981 0 +1951 2.288126281508648 1.311023428057485 0 +1952 3.827622545563297 3.425842800738986 0 +1953 1.273676130332964 2.248382695349726 0 +1954 2.701505221673446 3.293650684706928 0 +1955 0.9801968341649396 2.375772185012954 0 +1956 1.887714360692023 1.434800561891344 0 +1957 1.31000282240804 0.5309483394888851 0 +1958 0.872548508687373 0.724930370757958 0 +1959 0.8163464662828709 1.329174951843359 0 +1960 1.908533103942389 1.115672701881163 0 +1961 0.7948833734283233 0.9866762004575208 0 +1962 2.157882322871611 1.693347173009079 0 +1963 1.888299799183196 0.1641674544834197 0 +1964 0.2982353842559823 2.869825945845114 0 +1965 3.172403792917091 0.4521536086241666 0 +1966 1.293620590529676 0.7781520717109134 0 +1967 0.2978921786130694 1.911125959062584 0 +1968 0.9493556257231938 0.6243308402317904 0 +1969 1.92593696449041 3.61762803708896 0 +1970 3.851690609432803 2.808599595646966 0 +1971 0.3175485271732766 3.384514602224571 0 +1972 0.6409295821599778 3.672031165000739 0 +1973 3.599511610955513 2.517126176408439 0 +1974 1.941733893509046 1.200638603164536 0 +1975 1.887163617717177 0.0757377203959276 0 +1976 0.1653829178448519 2.314189486228291 0 +1977 1.645870732173286 2.565587171846648 0 +1978 1.109939640764034 3.732786428474681 0 +1979 3.732821433731327 1.110003237036982 0 +1980 0.7195577154342672 2.950872022886279 0 +1981 3.631461404011416 2.984955201937179 0 +1982 2.167523727150046 0.7590071123461813 0 +1983 1.06158548648911 1.946286942989503 0 +1984 1.785106532283115 1.751570640389992 0 +1985 1.458556523597148 2.694051111957598 0 +1986 3.741202460200453 2.593547754640437 0 +1987 0.6997440152007066 2.492078562664468 0 +1988 1.617214179353217 3.741722803796511 0 +1989 1.513764565519746 2.541217300611993 0 +1990 0.7310932099225346 0.7776203876063673 0 +1991 2.905643939187359 3.850249391943163 0 +1992 3.855201361017611 2.898965099094596 0 +1993 0.9782709905597797 1.629254867819728 0 +1994 3.026555493006623 2.843974053826593 0 +1995 1.680520262530775 2.712580793731048 0 +1996 1.563109492163478 2.779357228519261 0 +1997 1.104107798238184 1.821551578354554 0 +1998 2.467137977385655 2.921064462544037 0 +1999 3.837672931247764 3.804513281644702 0 +2000 0.1638245325777317 1.95203200599583 0 +2001 3.375621810181219 3.544453793899675 0 +2002 0.1447988612412425 1.390023540218601 0 +2003 0.9539987314467158 3.840707368588306 0 +2004 3.840707368587813 0.9539987314460742 0 +2005 1.738622597948698 0.7382191153643035 0 +2006 0.6157737673939392 3.028129608662391 0 +2007 2.674969078373672 1.879905181913044 0 +2008 1.230045914278177 1.587431078600433 0 +2009 2.768467771061651 0.8869297487723697 0 +2010 1.529428156155162 1.993817538400322 0 +2011 3.830139802887685 2.428195094518686 0 +2012 2.428239322308597 3.826079853755658 0 +2013 1.58753801674461 1.585218025971029 0 +2014 1.866126395564913 1.643935229793767 0 +2015 1.332111654987949 2.982293540063684 0 +2016 2.762684132905733 2.461021391282823 0 +2017 1.062437585549966 0.5117272001166526 0 +2018 2.791562007632058 1.776488357329131 0 +2019 2.164521676266544 1.369310354098897 0 +2020 0.2468974215693463 1.322016014495494 0 +2021 2.292546725967111 0.1764057907941336 0 +2022 1.751687905508979 2.622461767658264 0 +2023 1.702283837632029 1.221291686444982 0 +2024 0.673722851000353 1.694264136849802 0 +2025 1.986609935376957 3.686262634486104 0 +2026 3.699619681006363 1.989647676176436 0 +2027 1.688847286980146 2.433115208041857 0 +2028 1.823781872130299 2.075788273600143 0 +2029 0.7611853566370909 1.214025569328324 0 +2030 0.9213334098505088 2.261261620965805 0 +2031 0.5659629536496441 2.797546571686068 0 +2032 0.8795234272233842 3.126270893149644 0 +2033 2.097500959552822 2.352227339868737 0 +2034 2.622266053540128 1.638580976095375 0 +2035 3.158154726554038 1.470930761184833 0 +2036 2.098109659834294 1.008416992820498 0 +2037 1.241352650354306 2.972181873733011 0 +2038 3.1047736038089 0.07162203660538465 0 +2039 0.7422528553310462 2.734104530069907 0 +2040 2.04435390969199 2.896554768855168 0 +2041 3.408810312635303 0.3240309869978105 0 +2042 2.498243331649828 2.359042885256798 0 +2043 0.186982934571148 3.650995857437691 0 +2044 1.316776939788571 0.2635881056004892 0 +2045 3.017607454900133 2.981235557964646 0 +2046 3.275997347523221 3.169721214767359 0 +2047 3.45757069176295 0.05960435111913348 0 +2048 3.443692494486444 3.843449504023513 0 +2049 1.442168157177367 3.747517584277937 0 +2050 3.749309263542159 1.44377293863842 0 +2051 1.614628947834425 2.228909029313887 0 +2052 3.732764201446112 3.422522833932041 0 +2053 2.324085060998782 3.331303116623039 0 +2054 3.478635725880304 0.7170693145259101 0 +2055 2.368320910330023 0.270453961635059 0 +2056 0.3534616684832106 3.236778485283225 0 +2057 2.778461332126438 0.5775936736256007 0 +2058 2.254245257398949 0.3450524043349512 0 +2059 2.654905266726688 1.191671475805817 0 +2060 2.043234669331405 1.130094965969267 0 +2061 2.226625839649554 2.046986102356209 0 +2062 0.7721981823550148 2.105884282355201 0 +2063 2.441618316450645 0.1855964965801898 0 +2064 2.299352937348265 0.7434461140211043 0 +2065 1.437452739231275 2.766347589899458 0 +2066 1.913202237694319 1.685757308373445 0 +2067 2.211211379293518 2.418676129793203 0 +2068 1.419197374924317 1.481517463358777 0 +2069 0.7013779931636519 1.773777422720721 0 +2070 1.321457328581801 1.324702412598578 0 +2071 3.229294154351279 2.594104457027973 0 +2072 0.7961486677966976 2.278856484528319 0 +2073 2.428233118051292 1.994788896364315 0 +2074 2.533915018520765 2.101931675881031 0 +2075 3.708297193008199 3.01072620183793 0 +2076 2.052123193665945 2.998067067636232 0 +2077 0.4946308516474572 2.149127313277892 0 +2078 1.759897658485525 1.454169102319309 0 +2079 1.544134813299544 1.78797406794842 0 +2080 0.9308451286716636 2.815250699025041 0 +2081 1.033124487420764 3.637549642777658 0 +2082 3.626418009355705 1.021909408207677 0 +2083 3.014033803997902 0.8597333548237855 0 +2084 1.636666484012636 1.8362693072521 0 +2085 1.261569320389015 1.653838971674516 0 +2086 3.052080312597294 0.78477561303702 0 +2087 3.128884766877511 0.7893747303978593 0 +2088 1.8597240109073 0.9455210001222609 0 +2089 1.957126331984594 0.05738520924726151 0 +2090 0.06267632996556947 2.967099710904274 0 +2091 2.771673341806578 1.354905900958475 0 +2092 0.8791955552089566 1.220333672846057 0 +$EndNodes +$Elements +4128 +1 15 2 12 5 4 +2 15 2 13 5 4 +3 1 2 9 2 5 21 +4 1 2 9 2 21 22 +5 1 2 9 2 22 23 +6 1 2 9 2 23 24 +7 1 2 9 2 24 25 +8 1 2 9 2 25 26 +9 1 2 9 2 26 27 +10 1 2 9 2 27 28 +11 1 2 9 2 28 29 +12 1 2 9 2 29 30 +13 1 2 9 2 30 31 +14 1 2 9 2 31 32 +15 1 2 9 2 32 33 +16 1 2 9 2 33 34 +17 1 2 9 2 34 35 +18 1 2 9 2 35 36 +19 1 2 9 2 36 37 +20 1 2 9 2 37 38 +21 1 2 9 2 38 39 +22 1 2 9 2 39 40 +23 1 2 9 2 40 41 +24 1 2 9 2 41 42 +25 1 2 9 2 42 43 +26 1 2 9 2 43 44 +27 1 2 9 2 44 45 +28 1 2 9 2 45 46 +29 1 2 9 2 46 47 +30 1 2 9 2 47 48 +31 1 2 9 2 48 49 +32 1 2 9 2 49 3 +33 1 2 11 3 3 50 +34 1 2 11 3 50 51 +35 1 2 11 3 51 52 +36 1 2 11 3 52 53 +37 1 2 11 3 53 54 +38 1 2 11 3 54 55 +39 1 2 11 3 55 56 +40 1 2 11 3 56 57 +41 1 2 11 3 57 58 +42 1 2 11 3 58 59 +43 1 2 11 3 59 60 +44 1 2 11 3 60 61 +45 1 2 11 3 61 62 +46 1 2 11 3 62 63 +47 1 2 11 3 63 64 +48 1 2 11 3 64 65 +49 1 2 11 3 65 66 +50 1 2 11 3 66 67 +51 1 2 11 3 67 68 +52 1 2 11 3 68 69 +53 1 2 11 3 69 70 +54 1 2 11 3 70 71 +55 1 2 11 3 71 72 +56 1 2 11 3 72 73 +57 1 2 11 3 73 74 +58 1 2 11 3 74 75 +59 1 2 11 3 75 76 +60 1 2 11 3 76 77 +61 1 2 11 3 77 78 +62 1 2 11 3 78 79 +63 1 2 11 3 79 80 +64 1 2 11 3 80 81 +65 1 2 11 3 81 82 +66 1 2 11 3 82 83 +67 1 2 11 3 83 84 +68 1 2 11 3 84 85 +69 1 2 11 3 85 86 +70 1 2 11 3 86 87 +71 1 2 11 3 87 88 +72 1 2 11 3 88 2 +73 1 2 10 5 1 128 +74 1 2 10 5 128 129 +75 1 2 10 5 129 130 +76 1 2 10 5 130 131 +77 1 2 10 5 131 132 +78 1 2 10 5 132 133 +79 1 2 10 5 133 134 +80 1 2 10 5 134 135 +81 1 2 10 5 135 136 +82 1 2 10 5 136 137 +83 1 2 10 5 137 138 +84 1 2 10 5 138 139 +85 1 2 10 5 139 140 +86 1 2 10 5 140 141 +87 1 2 10 5 141 142 +88 1 2 10 5 142 143 +89 1 2 10 5 143 144 +90 1 2 10 5 144 145 +91 1 2 10 5 145 146 +92 1 2 10 5 146 147 +93 1 2 10 5 147 148 +94 1 2 10 5 148 149 +95 1 2 10 5 149 150 +96 1 2 10 5 150 151 +97 1 2 10 5 151 152 +98 1 2 10 5 152 153 +99 1 2 10 5 153 154 +100 1 2 10 5 154 155 +101 1 2 10 5 155 156 +102 1 2 10 5 156 4 +103 2 2 8 7 159 1413 814 +104 2 2 8 7 1413 1550 814 +105 2 2 8 7 252 1331 1043 +106 2 2 8 7 668 1619 285 +107 2 2 8 7 232 905 662 +108 2 2 8 7 628 1250 463 +109 2 2 8 7 808 809 407 +110 2 2 8 7 327 809 808 +111 2 2 8 7 764 885 203 +112 2 2 8 7 163 1409 1230 +113 2 2 8 7 763 797 337 +114 2 2 8 7 484 1135 745 +115 2 2 8 7 744 1136 485 +116 2 2 8 7 417 851 810 +117 2 2 8 7 420 1488 652 +118 2 2 8 7 20 1090 5 +119 2 2 8 7 360 964 721 +120 2 2 8 7 715 1276 296 +121 2 2 8 7 673 1728 936 +122 2 2 8 7 863 1547 641 +123 2 2 8 7 1246 2006 1112 +124 2 2 8 7 231 1547 863 +125 2 2 8 7 807 2029 206 +126 2 2 8 7 437 1087 728 +127 2 2 8 7 1644 1762 818 +128 2 2 8 7 371 987 662 +129 2 2 8 7 285 1619 679 +130 2 2 8 7 662 987 232 +131 2 2 8 7 807 2092 2029 +132 2 2 8 7 278 1173 619 +133 2 2 8 7 416 1122 642 +134 2 2 8 7 1741 1793 834 +135 2 2 8 7 463 985 628 +136 2 2 8 7 4 1094 6 +137 2 2 8 7 396 1980 631 +138 2 2 8 7 302 930 761 +139 2 2 8 7 762 824 487 +140 2 2 8 7 1213 1263 329 +141 2 2 8 7 891 1233 507 +142 2 2 8 7 329 1263 750 +143 2 2 8 7 424 1737 644 +144 2 2 8 7 357 945 879 +145 2 2 8 7 320 820 740 +146 2 2 8 7 594 1304 1146 +147 2 2 8 7 645 1006 245 +148 2 2 8 7 445 1275 653 +149 2 2 8 7 551 1374 1236 +150 2 2 8 7 357 2029 742 +151 2 2 8 7 370 1006 645 +152 2 2 8 7 879 945 428 +153 2 2 8 7 5 1090 21 +154 2 2 8 7 936 1728 364 +155 2 2 8 7 595 1470 956 +156 2 2 8 7 630 1463 921 +157 2 2 8 7 516 1246 1112 +158 2 2 8 7 245 1546 645 +159 2 2 8 7 921 1463 208 +160 2 2 8 7 644 1737 778 +161 2 2 8 7 800 1317 537 +162 2 2 8 7 777 2029 357 +163 2 2 8 7 778 1737 210 +164 2 2 8 7 282 1317 800 +165 2 2 8 7 229 1278 844 +166 2 2 8 7 845 1279 230 +167 2 2 8 7 1348 1511 895 +168 2 2 8 7 1033 1269 27 +169 2 2 8 7 326 1644 818 +170 2 2 8 7 1146 1304 482 +171 2 2 8 7 683 1841 171 +172 2 2 8 7 390 1040 897 +173 2 2 8 7 896 1039 389 +174 2 2 8 7 240 1285 756 +175 2 2 8 7 356 931 839 +176 2 2 8 7 675 1119 411 +177 2 2 8 7 410 1118 676 +178 2 2 8 7 443 898 725 +179 2 2 8 7 726 899 444 +180 2 2 8 7 156 1094 4 +181 2 2 8 7 699 884 215 +182 2 2 8 7 771 1847 361 +183 2 2 8 7 637 1377 451 +184 2 2 8 7 257 989 637 +185 2 2 8 7 751 1081 340 +186 2 2 8 7 27 1269 28 +187 2 2 8 7 914 1386 549 +188 2 2 8 7 619 1514 278 +189 2 2 8 7 267 1247 692 +190 2 2 8 7 617 1741 834 +191 2 2 8 7 355 837 769 +192 2 2 8 7 914 1078 173 +193 2 2 8 7 486 1078 914 +194 2 2 8 7 311 824 762 +195 2 2 8 7 987 1026 508 +196 2 2 8 7 371 1026 987 +197 2 2 8 7 828 1847 771 +198 2 2 8 7 887 925 170 +199 2 2 8 7 447 1787 1143 +200 2 2 8 7 753 1573 388 +201 2 2 8 7 762 1365 237 +202 2 2 8 7 733 1238 475 +203 2 2 8 7 753 1676 203 +204 2 2 8 7 666 1177 216 +205 2 2 8 7 640 1501 292 +206 2 2 8 7 280 1238 733 +207 2 2 8 7 354 977 651 +208 2 2 8 7 1251 1281 701 +209 2 2 8 7 618 1063 238 +210 2 2 8 7 638 999 412 +211 2 2 8 7 217 931 729 +212 2 2 8 7 896 1306 610 +213 2 2 8 7 815 1236 474 +214 2 2 8 7 565 973 719 +215 2 2 8 7 354 828 771 +216 2 2 8 7 2029 2092 742 +217 2 2 8 7 709 1032 409 +218 2 2 8 7 268 1375 690 +219 2 2 8 7 278 1032 709 +220 2 2 8 7 871 1084 240 +221 2 2 8 7 630 1048 379 +222 2 2 8 7 469 1084 871 +223 2 2 8 7 849 1022 212 +224 2 2 8 7 29 1269 728 +225 2 2 8 7 450 1022 849 +226 2 2 8 7 379 1463 630 +227 2 2 8 7 62 1570 953 +228 2 2 8 7 954 1571 115 +229 2 2 8 7 240 1312 1285 +230 2 2 8 7 806 891 507 +231 2 2 8 7 1087 2000 728 +232 2 2 8 7 789 1333 244 +233 2 2 8 7 387 997 641 +234 2 2 8 7 259 1231 750 +235 2 2 8 7 956 1470 352 +236 2 2 8 7 750 1231 473 +237 2 2 8 7 717 1772 413 +238 2 2 8 7 702 963 209 +239 2 2 8 7 423 1198 786 +240 2 2 8 7 238 1486 618 +241 2 2 8 7 1610 1618 625 +242 2 2 8 7 66 759 67 +243 2 2 8 7 110 758 111 +244 2 2 8 7 1278 1626 844 +245 2 2 8 7 845 1627 1279 +246 2 2 8 7 964 975 457 +247 2 2 8 7 360 975 964 +248 2 2 8 7 805 1129 456 +249 2 2 8 7 718 1559 142 +250 2 2 8 7 232 1129 805 +251 2 2 8 7 769 837 212 +252 2 2 8 7 884 1531 215 +253 2 2 8 7 713 1176 222 +254 2 2 8 7 164 1320 688 +255 2 2 8 7 365 925 778 +256 2 2 8 7 688 1320 471 +257 2 2 8 7 349 1386 825 +258 2 2 8 7 631 1066 396 +259 2 2 8 7 778 925 384 +260 2 2 8 7 216 1480 666 +261 2 2 8 7 215 1531 1290 +262 2 2 8 7 1306 1900 610 +263 2 2 8 7 745 1477 484 +264 2 2 8 7 485 1478 744 +265 2 2 8 7 412 1174 638 +266 2 2 8 7 334 916 914 +267 2 2 8 7 914 916 486 +268 2 2 8 7 674 1834 365 +269 2 2 8 7 447 1633 1194 +270 2 2 8 7 890 1633 447 +271 2 2 8 7 769 841 355 +272 2 2 8 7 982 1676 753 +273 2 2 8 7 748 1232 349 +274 2 2 8 7 380 850 829 +275 2 2 8 7 237 1524 762 +276 2 2 8 7 637 1270 257 +277 2 2 8 7 760 1126 530 +278 2 2 8 7 1040 1484 897 +279 2 2 8 7 896 1483 1039 +280 2 2 8 7 1158 1252 578 +281 2 2 8 7 174 1313 727 +282 2 2 8 7 1182 1512 151 +283 2 2 8 7 742 1959 357 +284 2 2 8 7 923 1054 472 +285 2 2 8 7 243 1054 923 +286 2 2 8 7 451 1289 637 +287 2 2 8 7 1134 1237 582 +288 2 2 8 7 171 1841 771 +289 2 2 8 7 885 1573 753 +290 2 2 8 7 670 984 503 +291 2 2 8 7 292 1469 640 +292 2 2 8 7 880 1931 224 +293 2 2 8 7 1103 1606 678 +294 2 2 8 7 256 1233 891 +295 2 2 8 7 704 1128 310 +296 2 2 8 7 724 1931 880 +297 2 2 8 7 720 2053 254 +298 2 2 8 7 522 1419 1044 +299 2 2 8 7 373 2028 763 +300 2 2 8 7 206 1606 1103 +301 2 2 8 7 222 997 713 +302 2 2 8 7 420 2063 718 +303 2 2 8 7 637 1120 415 +304 2 2 8 7 415 1270 637 +305 2 2 8 7 927 928 350 +306 2 2 8 7 692 1223 267 +307 2 2 8 7 445 928 927 +308 2 2 8 7 392 1625 686 +309 2 2 8 7 760 1594 1126 +310 2 2 8 7 1421 1656 284 +311 2 2 8 7 1075 1274 160 +312 2 2 8 7 636 1274 1075 +313 2 2 8 7 746 880 398 +314 2 2 8 7 763 2028 797 +315 2 2 8 7 641 1547 387 +316 2 2 8 7 349 1232 791 +317 2 2 8 7 1124 1610 625 +318 2 2 8 7 427 1130 889 +319 2 2 8 7 698 1831 1682 +320 2 2 8 7 176 1251 701 +321 2 2 8 7 130 1181 686 +322 2 2 8 7 234 984 670 +323 2 2 8 7 200 929 716 +324 2 2 8 7 349 1612 1386 +325 2 2 8 7 365 1474 674 +326 2 2 8 7 36 779 37 +327 2 2 8 7 676 1046 410 +328 2 2 8 7 411 1045 675 +329 2 2 8 7 715 920 199 +330 2 2 8 7 645 1506 370 +331 2 2 8 7 414 1067 647 +332 2 2 8 7 140 1308 652 +333 2 2 8 7 185 968 927 +334 2 2 8 7 927 968 445 +335 2 2 8 7 731 1197 205 +336 2 2 8 7 204 1196 730 +337 2 2 8 7 569 1678 733 +338 2 2 8 7 1043 1331 531 +339 2 2 8 7 287 2000 1087 +340 2 2 8 7 652 1488 140 +341 2 2 8 7 745 1135 517 +342 2 2 8 7 518 1136 744 +343 2 2 8 7 170 925 850 +344 2 2 8 7 203 885 753 +345 2 2 8 7 429 1237 1134 +346 2 2 8 7 961 1276 715 +347 2 2 8 7 455 1252 1158 +348 2 2 8 7 1143 1787 584 +349 2 2 8 7 203 1814 764 +350 2 2 8 7 197 1348 895 +351 2 2 8 7 810 851 338 +352 2 2 8 7 841 970 355 +353 2 2 8 7 644 1655 424 +354 2 2 8 7 51 776 52 +355 2 2 8 7 125 775 126 +356 2 2 8 7 642 1218 416 +357 2 2 8 7 975 1409 163 +358 2 2 8 7 944 1772 717 +359 2 2 8 7 504 1245 860 +360 2 2 8 7 454 993 937 +361 2 2 8 7 1522 2057 1097 +362 2 2 8 7 936 1280 228 +363 2 2 8 7 937 993 241 +364 2 2 8 7 18 1268 940 +365 2 2 8 7 187 1236 815 +366 2 2 8 7 647 1191 414 +367 2 2 8 7 1375 1800 690 +368 2 2 8 7 1682 1982 698 +369 2 2 8 7 941 2053 720 +370 2 2 8 7 936 1877 673 +371 2 2 8 7 681 1656 1421 +372 2 2 8 7 441 1244 1036 +373 2 2 8 7 1036 1244 586 +374 2 2 8 7 380 2019 850 +375 2 2 8 7 829 850 365 +376 2 2 8 7 495 1233 832 +377 2 2 8 7 832 1233 256 +378 2 2 8 7 244 1333 1183 +379 2 2 8 7 828 1260 225 +380 2 2 8 7 400 1753 696 +381 2 2 8 7 697 1752 401 +382 2 2 8 7 431 1240 1037 +383 2 2 8 7 923 1901 629 +384 2 2 8 7 695 1220 47 +385 2 2 8 7 705 1546 245 +386 2 2 8 7 337 1729 763 +387 2 2 8 7 882 1243 8 +388 2 2 8 7 355 2084 837 +389 2 2 8 7 870 2063 420 +390 2 2 8 7 524 1669 748 +391 2 2 8 7 340 941 720 +392 2 2 8 7 1814 2042 764 +393 2 2 8 7 1056 1235 434 +394 2 2 8 7 382 944 717 +395 2 2 8 7 900 1169 248 +396 2 2 8 7 588 1512 1182 +397 2 2 8 7 733 1678 280 +398 2 2 8 7 220 892 811 +399 2 2 8 7 841 892 220 +400 2 2 8 7 340 1081 941 +401 2 2 8 7 142 1559 143 +402 2 2 8 7 750 1014 329 +403 2 2 8 7 1464 1541 962 +404 2 2 8 7 386 1950 837 +405 2 2 8 7 402 1642 791 +406 2 2 8 7 652 1223 420 +407 2 2 8 7 819 1604 359 +408 2 2 8 7 653 1208 445 +409 2 2 8 7 651 1260 354 +410 2 2 8 7 952 1572 575 +411 2 2 8 7 749 1847 225 +412 2 2 8 7 487 1365 762 +413 2 2 8 7 1700 1899 353 +414 2 2 8 7 934 1950 386 +415 2 2 8 7 1739 1812 172 +416 2 2 8 7 409 1865 666 +417 2 2 8 7 228 1280 1120 +418 2 2 8 7 245 1853 705 +419 2 2 8 7 1601 2039 396 +420 2 2 8 7 395 1522 1097 +421 2 2 8 7 933 1157 417 +422 2 2 8 7 204 1039 671 +423 2 2 8 7 672 1040 205 +424 2 2 8 7 710 2085 382 +425 2 2 8 7 509 1554 950 +426 2 2 8 7 1253 1554 509 +427 2 2 8 7 510 1201 900 +428 2 2 8 7 483 1169 1147 +429 2 2 8 7 372 960 949 +430 2 2 8 7 1147 1169 595 +431 2 2 8 7 805 948 308 +432 2 2 8 7 912 913 465 +433 2 2 8 7 442 1993 853 +434 2 2 8 7 932 1646 209 +435 2 2 8 7 341 913 912 +436 2 2 8 7 316 2046 792 +437 2 2 8 7 379 965 743 +438 2 2 8 7 793 2046 316 +439 2 2 8 7 1091 1851 196 +440 2 2 8 7 743 965 167 +441 2 2 8 7 797 2028 212 +442 2 2 8 7 199 961 715 +443 2 2 8 7 281 1793 1741 +444 2 2 8 7 1201 1475 900 +445 2 2 8 7 1646 1660 209 +446 2 2 8 7 662 1372 371 +447 2 2 8 7 62 953 63 +448 2 2 8 7 114 954 115 +449 2 2 8 7 853 1993 947 +450 2 2 8 7 384 925 887 +451 2 2 8 7 857 1102 219 +452 2 2 8 7 1012 1198 423 +453 2 2 8 7 372 932 749 +454 2 2 8 7 720 1061 560 +455 2 2 8 7 1130 1580 889 +456 2 2 8 7 337 983 833 +457 2 2 8 7 51 1726 776 +458 2 2 8 7 775 1725 126 +459 2 2 8 7 949 960 432 +460 2 2 8 7 761 930 429 +461 2 2 8 7 334 891 806 +462 2 2 8 7 363 958 729 +463 2 2 8 7 356 1916 931 +464 2 2 8 7 679 1593 285 +465 2 2 8 7 426 1144 663 +466 2 2 8 7 834 1151 259 +467 2 2 8 7 353 1899 919 +468 2 2 8 7 167 965 821 +469 2 2 8 7 457 1151 834 +470 2 2 8 7 253 1135 919 +471 2 2 8 7 172 1812 856 +472 2 2 8 7 919 1135 484 +473 2 2 8 7 791 909 349 +474 2 2 8 7 225 1260 906 +475 2 2 8 7 7 882 8 +476 2 2 8 7 196 1337 912 +477 2 2 8 7 767 969 231 +478 2 2 8 7 359 1604 901 +479 2 2 8 7 947 974 162 +480 2 2 8 7 663 1255 426 +481 2 2 8 7 743 1886 379 +482 2 2 8 7 741 1886 307 +483 2 2 8 7 307 1886 743 +484 2 2 8 7 692 1247 440 +485 2 2 8 7 729 1756 363 +486 2 2 8 7 488 969 767 +487 2 2 8 7 868 959 221 +488 2 2 8 7 684 1014 185 +489 2 2 8 7 1033 1312 437 +490 2 2 8 7 549 1703 914 +491 2 2 8 7 459 959 868 +492 2 2 8 7 179 1380 1272 +493 2 2 8 7 729 958 217 +494 2 2 8 7 742 2092 839 +495 2 2 8 7 839 2092 356 +496 2 2 8 7 212 2028 849 +497 2 2 8 7 748 1669 1232 +498 2 2 8 7 705 1697 369 +499 2 2 8 7 353 917 785 +500 2 2 8 7 961 1001 392 +501 2 2 8 7 413 970 717 +502 2 2 8 7 493 1291 908 +503 2 2 8 7 382 974 710 +504 2 2 8 7 777 1180 453 +505 2 2 8 7 18 940 19 +506 2 2 8 7 228 1877 936 +507 2 2 8 7 357 1180 777 +508 2 2 8 7 714 973 369 +509 2 2 8 7 310 1128 811 +510 2 2 8 7 413 924 886 +511 2 2 8 7 225 1847 828 +512 2 2 8 7 773 1646 372 +513 2 2 8 7 444 1685 859 +514 2 2 8 7 571 1646 773 +515 2 2 8 7 369 1697 714 +516 2 2 8 7 699 1060 272 +517 2 2 8 7 440 1060 699 +518 2 2 8 7 838 1215 331 +519 2 2 8 7 719 973 168 +520 2 2 8 7 791 1642 909 +521 2 2 8 7 666 1480 409 +522 2 2 8 7 734 996 452 +523 2 2 8 7 841 1794 970 +524 2 2 8 7 981 1722 1465 +525 2 2 8 7 403 1161 1080 +526 2 2 8 7 773 949 161 +527 2 2 8 7 648 1239 1172 +528 2 2 8 7 1172 1239 489 +529 2 2 8 7 365 1834 829 +530 2 2 8 7 1517 1555 910 +531 2 2 8 7 749 960 372 +532 2 2 8 7 421 1175 689 +533 2 2 8 7 764 1572 885 +534 2 2 8 7 202 1372 915 +535 2 2 8 7 66 1326 759 +536 2 2 8 7 758 1325 111 +537 2 2 8 7 763 1729 1024 +538 2 2 8 7 1337 2030 912 +539 2 2 8 7 225 960 749 +540 2 2 8 7 833 1737 424 +541 2 2 8 7 240 1648 871 +542 2 2 8 7 815 1831 642 +543 2 2 8 7 1106 1121 417 +544 2 2 8 7 372 949 773 +545 2 2 8 7 293 1831 815 +546 2 2 8 7 704 1851 1091 +547 2 2 8 7 561 1121 1106 +548 2 2 8 7 723 2005 1195 +549 2 2 8 7 702 1933 963 +550 2 2 8 7 590 1440 1364 +551 2 2 8 7 1365 1441 591 +552 2 2 8 7 719 1719 565 +553 2 2 8 7 380 1931 724 +554 2 2 8 7 194 1227 1201 +555 2 2 8 7 226 1423 928 +556 2 2 8 7 795 1657 209 +557 2 2 8 7 1201 1227 656 +558 2 2 8 7 797 934 337 +559 2 2 8 7 551 1175 1041 +560 2 2 8 7 285 1468 668 +561 2 2 8 7 272 1773 1309 +562 2 2 8 7 1644 1995 583 +563 2 2 8 7 721 1722 360 +564 2 2 8 7 344 1517 910 +565 2 2 8 7 1041 1175 421 +566 2 2 8 7 396 2039 1055 +567 2 2 8 7 310 1004 704 +568 2 2 8 7 1933 2013 375 +569 2 2 8 7 997 1938 713 +570 2 2 8 7 883 1453 242 +571 2 2 8 7 727 1079 174 +572 2 2 8 7 406 1079 727 +573 2 2 8 7 725 1863 300 +574 2 2 8 7 301 1864 726 +575 2 2 8 7 298 1229 1020 +576 2 2 8 7 366 1052 739 +577 2 2 8 7 417 1157 1106 +578 2 2 8 7 195 1021 818 +579 2 2 8 7 522 1044 1042 +580 2 2 8 7 503 1334 670 +581 2 2 8 7 690 1800 218 +582 2 2 8 7 714 1742 973 +583 2 2 8 7 973 1742 168 +584 2 2 8 7 1042 1044 374 +585 2 2 8 7 560 1706 720 +586 2 2 8 7 500 1468 767 +587 2 2 8 7 720 1706 340 +588 2 2 8 7 1236 1374 474 +589 2 2 8 7 1229 1489 1020 +590 2 2 8 7 28 1269 29 +591 2 2 8 7 738 1068 407 +592 2 2 8 7 242 1068 738 +593 2 2 8 7 439 1281 1251 +594 2 2 8 7 1385 1648 240 +595 2 2 8 7 966 1372 202 +596 2 2 8 7 1682 1831 293 +597 2 2 8 7 800 1624 1078 +598 2 2 8 7 424 1167 682 +599 2 2 8 7 471 1062 688 +600 2 2 8 7 222 1176 946 +601 2 2 8 7 953 1570 573 +602 2 2 8 7 572 1571 954 +603 2 2 8 7 375 2013 886 +604 2 2 8 7 359 1786 902 +605 2 2 8 7 902 1786 674 +606 2 2 8 7 154 1345 1056 +607 2 2 8 7 348 1464 962 +608 2 2 8 7 763 994 373 +609 2 2 8 7 297 998 716 +610 2 2 8 7 538 1235 1056 +611 2 2 8 7 842 1031 505 +612 2 2 8 7 946 1422 330 +613 2 2 8 7 305 1031 842 +614 2 2 8 7 615 1425 926 +615 2 2 8 7 328 1511 863 +616 2 2 8 7 693 1071 480 +617 2 2 8 7 900 1470 1169 +618 2 2 8 7 361 1283 771 +619 2 2 8 7 1054 1980 396 +620 2 2 8 7 716 1394 491 +621 2 2 8 7 185 1449 684 +622 2 2 8 7 863 1511 1340 +623 2 2 8 7 456 948 805 +624 2 2 8 7 778 1962 644 +625 2 2 8 7 671 1196 204 +626 2 2 8 7 205 1197 672 +627 2 2 8 7 851 1155 338 +628 2 2 8 7 565 1539 1035 +629 2 2 8 7 1037 1240 526 +630 2 2 8 7 859 1396 444 +631 2 2 8 7 349 1832 748 +632 2 2 8 7 367 1502 738 +633 2 2 8 7 716 1675 200 +634 2 2 8 7 217 945 839 +635 2 2 8 7 767 1340 500 +636 2 2 8 7 1313 1923 727 +637 2 2 8 7 493 1800 1375 +638 2 2 8 7 137 840 138 +639 2 2 8 7 670 1218 234 +640 2 2 8 7 378 1295 950 +641 2 2 8 7 492 1388 715 +642 2 2 8 7 963 1933 375 +643 2 2 8 7 474 1670 815 +644 2 2 8 7 336 982 753 +645 2 2 8 7 624 2057 1522 +646 2 2 8 7 811 1128 579 +647 2 2 8 7 875 1378 543 +648 2 2 8 7 1284 1423 226 +649 2 2 8 7 299 1378 875 +650 2 2 8 7 321 2027 922 +651 2 2 8 7 753 1840 336 +652 2 2 8 7 170 2019 796 +653 2 2 8 7 384 1962 778 +654 2 2 8 7 860 1558 504 +655 2 2 8 7 730 1769 204 +656 2 2 8 7 205 1768 731 +657 2 2 8 7 382 2085 944 +658 2 2 8 7 216 1177 826 +659 2 2 8 7 338 1155 871 +660 2 2 8 7 284 1707 1421 +661 2 2 8 7 695 2043 297 +662 2 2 8 7 1756 1922 363 +663 2 2 8 7 157 1949 852 +664 2 2 8 7 409 1631 709 +665 2 2 8 7 642 1122 815 +666 2 2 8 7 852 1949 682 +667 2 2 8 7 36 1315 779 +668 2 2 8 7 417 1121 851 +669 2 2 8 7 839 931 217 +670 2 2 8 7 901 1943 298 +671 2 2 8 7 706 1943 901 +672 2 2 8 7 850 925 365 +673 2 2 8 7 1133 1488 420 +674 2 2 8 7 732 1982 1682 +675 2 2 8 7 387 1938 997 +676 2 2 8 7 86 816 87 +677 2 2 8 7 90 817 91 +678 2 2 8 7 901 1786 359 +679 2 2 8 7 173 1386 914 +680 2 2 8 7 210 1474 778 +681 2 2 8 7 682 1949 424 +682 2 2 8 7 901 2078 1786 +683 2 2 8 7 168 1987 719 +684 2 2 8 7 760 1234 246 +685 2 2 8 7 877 1242 332 +686 2 2 8 7 496 1242 877 +687 2 2 8 7 272 1533 699 +688 2 2 8 7 1078 1624 173 +689 2 2 8 7 626 2042 1814 +690 2 2 8 7 1082 1301 436 +691 2 2 8 7 473 1415 750 +692 2 2 8 7 685 1707 284 +693 2 2 8 7 246 1482 976 +694 2 2 8 7 976 1482 613 +695 2 2 8 7 204 1769 745 +696 2 2 8 7 744 1768 205 +697 2 2 8 7 546 1321 780 +698 2 2 8 7 781 1322 547 +699 2 2 8 7 581 1762 1644 +700 2 2 8 7 386 983 934 +701 2 2 8 7 823 969 381 +702 2 2 8 7 981 1152 513 +703 2 2 8 7 251 1152 981 +704 2 2 8 7 860 1245 233 +705 2 2 8 7 969 1162 381 +706 2 2 8 7 686 1276 392 +707 2 2 8 7 178 1029 952 +708 2 2 8 7 34 858 35 +709 2 2 8 7 738 1008 367 +710 2 2 8 7 362 2010 1022 +711 2 2 8 7 1173 1417 619 +712 2 2 8 7 705 1853 1140 +713 2 2 8 7 145 1000 146 +714 2 2 8 7 947 1679 974 +715 2 2 8 7 112 874 113 +716 2 2 8 7 64 873 65 +717 2 2 8 7 615 1971 1425 +718 2 2 8 7 242 1453 1068 +719 2 2 8 7 429 1163 761 +720 2 2 8 7 776 1881 297 +721 2 2 8 7 606 1881 776 +722 2 2 8 7 761 1163 214 +723 2 2 8 7 800 1078 405 +724 2 2 8 7 1215 1397 331 +725 2 2 8 7 367 1529 1502 +726 2 2 8 7 186 1155 851 +727 2 2 8 7 211 1162 1115 +728 2 2 8 7 171 1691 683 +729 2 2 8 7 850 2019 170 +730 2 2 8 7 922 2027 708 +731 2 2 8 7 209 1657 932 +732 2 2 8 7 886 924 375 +733 2 2 8 7 1126 1594 477 +734 2 2 8 7 686 1892 296 +735 2 2 8 7 196 1830 1091 +736 2 2 8 7 783 1088 474 +737 2 2 8 7 265 1437 787 +738 2 2 8 7 378 1478 1295 +739 2 2 8 7 1037 1338 23 +740 2 2 8 7 179 1553 879 +741 2 2 8 7 157 994 763 +742 2 2 8 7 1089 1172 260 +743 2 2 8 7 272 1309 889 +744 2 2 8 7 347 1572 952 +745 2 2 8 7 922 1137 183 +746 2 2 8 7 284 1432 685 +747 2 2 8 7 576 1301 1082 +748 2 2 8 7 296 1892 775 +749 2 2 8 7 629 1327 923 +750 2 2 8 7 853 947 162 +751 2 2 8 7 775 1892 605 +752 2 2 8 7 603 1650 1074 +753 2 2 8 7 218 1241 690 +754 2 2 8 7 690 1241 426 +755 2 2 8 7 821 1215 167 +756 2 2 8 7 1898 1916 907 +757 2 2 8 7 1294 1719 719 +758 2 2 8 7 1044 1419 250 +759 2 2 8 7 829 1931 380 +760 2 2 8 7 500 1511 1348 +761 2 2 8 7 704 1091 346 +762 2 2 8 7 360 1722 981 +763 2 2 8 7 333 1073 813 +764 2 2 8 7 689 1200 421 +765 2 2 8 7 1022 2010 769 +766 2 2 8 7 369 1546 705 +767 2 2 8 7 145 1493 1000 +768 2 2 8 7 241 1298 1124 +769 2 2 8 7 171 1898 907 +770 2 2 8 7 731 1469 292 +771 2 2 8 7 292 1045 731 +772 2 2 8 7 730 1046 291 +773 2 2 8 7 855 1125 193 +774 2 2 8 7 1286 1330 479 +775 2 2 8 7 1038 1625 392 +776 2 2 8 7 951 1529 367 +777 2 2 8 7 794 1011 313 +778 2 2 8 7 291 1217 730 +779 2 2 8 7 142 1133 718 +780 2 2 8 7 1065 1753 400 +781 2 2 8 7 401 1752 1064 +782 2 2 8 7 858 1069 370 +783 2 2 8 7 296 1276 686 +784 2 2 8 7 1275 1661 653 +785 2 2 8 7 686 1625 130 +786 2 2 8 7 690 1255 268 +787 2 2 8 7 688 1367 164 +788 2 2 8 7 41 990 42 +789 2 2 8 7 381 967 823 +790 2 2 8 7 488 1162 969 +791 2 2 8 7 733 1523 569 +792 2 2 8 7 601 1102 857 +793 2 2 8 7 167 1215 838 +794 2 2 8 7 425 1429 737 +795 2 2 8 7 1668 1829 273 +796 2 2 8 7 255 1015 869 +797 2 2 8 7 231 969 823 +798 2 2 8 7 565 1839 973 +799 2 2 8 7 453 1049 777 +800 2 2 8 7 717 1282 382 +801 2 2 8 7 464 1243 882 +802 2 2 8 7 527 1889 1720 +803 2 2 8 7 277 1719 1294 +804 2 2 8 7 816 1999 661 +805 2 2 8 7 1391 1733 308 +806 2 2 8 7 309 1734 1392 +807 2 2 8 7 325 1901 923 +808 2 2 8 7 1182 1183 588 +809 2 2 8 7 481 1183 1182 +810 2 2 8 7 426 1255 690 +811 2 2 8 7 964 1564 721 +812 2 2 8 7 699 1533 884 +813 2 2 8 7 1448 1689 980 +814 2 2 8 7 1102 1985 219 +815 2 2 8 7 908 1291 184 +816 2 2 8 7 763 1024 157 +817 2 2 8 7 346 1128 704 +818 2 2 8 7 550 1422 946 +819 2 2 8 7 701 1145 393 +820 2 2 8 7 692 1683 420 +821 2 2 8 7 1199 1602 358 +822 2 2 8 7 701 1445 176 +823 2 2 8 7 824 1928 487 +824 2 2 8 7 217 1016 945 +825 2 2 8 7 759 1326 466 +826 2 2 8 7 467 1325 758 +827 2 2 8 7 583 1995 1303 +828 2 2 8 7 480 1743 693 +829 2 2 8 7 314 1837 804 +830 2 2 8 7 1045 1197 731 +831 2 2 8 7 730 1196 1046 +832 2 2 8 7 315 1999 816 +833 2 2 8 7 804 1837 596 +834 2 2 8 7 696 1310 400 +835 2 2 8 7 401 1311 697 +836 2 2 8 7 502 1314 1211 +837 2 2 8 7 178 1093 962 +838 2 2 8 7 771 1841 354 +839 2 2 8 7 276 1145 701 +840 2 2 8 7 317 2006 1246 +841 2 2 8 7 212 1022 769 +842 2 2 8 7 962 1093 458 +843 2 2 8 7 1089 1784 1172 +844 2 2 8 7 134 1694 737 +845 2 2 8 7 879 1380 179 +846 2 2 8 7 547 1605 781 +847 2 2 8 7 781 1605 307 +848 2 2 8 7 166 1153 772 +849 2 2 8 7 296 1496 715 +850 2 2 8 7 716 1497 297 +851 2 2 8 7 418 1009 873 +852 2 2 8 7 874 1010 419 +853 2 2 8 7 491 1497 716 +854 2 2 8 7 715 1496 492 +855 2 2 8 7 873 1009 466 +856 2 2 8 7 467 1010 874 +857 2 2 8 7 1041 1374 551 +858 2 2 8 7 570 1721 1042 +859 2 2 8 7 420 1223 692 +860 2 2 8 7 847 1073 333 +861 2 2 8 7 479 1330 1070 +862 2 2 8 7 1195 2005 260 +863 2 2 8 7 282 1156 711 +864 2 2 8 7 407 1297 738 +865 2 2 8 7 747 1569 295 +866 2 2 8 7 832 1166 495 +867 2 2 8 7 359 2014 819 +868 2 2 8 7 819 2014 664 +869 2 2 8 7 447 1277 890 +870 2 2 8 7 951 1888 1529 +871 2 2 8 7 283 1132 727 +872 2 2 8 7 219 1732 1052 +873 2 2 8 7 1052 1732 739 +874 2 2 8 7 727 1132 406 +875 2 2 8 7 353 1210 917 +876 2 2 8 7 17 1523 733 +877 2 2 8 7 393 1445 701 +878 2 2 8 7 837 2084 386 +879 2 2 8 7 179 1185 784 +880 2 2 8 7 787 1920 265 +881 2 2 8 7 930 1237 429 +882 2 2 8 7 919 1210 353 +883 2 2 8 7 728 1639 29 +884 2 2 8 7 784 1185 438 +885 2 2 8 7 407 1068 739 +886 2 2 8 7 712 1132 283 +887 2 2 8 7 300 1407 725 +888 2 2 8 7 726 1408 301 +889 2 2 8 7 898 1863 725 +890 2 2 8 7 726 1864 899 +891 2 2 8 7 393 1011 794 +892 2 2 8 7 328 1951 1168 +893 2 2 8 7 674 1474 902 +894 2 2 8 7 847 985 233 +895 2 2 8 7 884 1533 563 +896 2 2 8 7 1074 1702 603 +897 2 2 8 7 388 1840 753 +898 2 2 8 7 512 1312 1033 +899 2 2 8 7 709 1631 169 +900 2 2 8 7 362 1812 892 +901 2 2 8 7 302 1618 1610 +902 2 2 8 7 1168 1951 796 +903 2 2 8 7 386 2084 846 +904 2 2 8 7 244 1183 942 +905 2 2 8 7 297 1881 695 +906 2 2 8 7 892 1812 659 +907 2 2 8 7 694 1258 470 +908 2 2 8 7 440 1302 692 +909 2 2 8 7 1080 1161 490 +910 2 2 8 7 640 1253 1225 +911 2 2 8 7 1225 1253 248 +912 2 2 8 7 942 1183 481 +913 2 2 8 7 827 1730 381 +914 2 2 8 7 470 1313 694 +915 2 2 8 7 585 1730 827 +916 2 2 8 7 198 1342 747 +917 2 2 8 7 885 1572 347 +918 2 2 8 7 900 1288 510 +919 2 2 8 7 248 1288 900 +920 2 2 8 7 770 1217 291 +921 2 2 8 7 290 1086 735 +922 2 2 8 7 736 1085 289 +923 2 2 8 7 172 1190 1003 +924 2 2 8 7 718 1133 420 +925 2 2 8 7 902 1474 210 +926 2 2 8 7 827 1162 211 +927 2 2 8 7 940 1268 475 +928 2 2 8 7 41 1144 990 +929 2 2 8 7 614 1362 1093 +930 2 2 8 7 1093 1362 458 +931 2 2 8 7 47 1607 695 +932 2 2 8 7 879 1553 1180 +933 2 2 8 7 385 1850 812 +934 2 2 8 7 238 1063 904 +935 2 2 8 7 945 1016 428 +936 2 2 8 7 1309 1773 680 +937 2 2 8 7 709 1173 278 +938 2 2 8 7 169 1174 709 +939 2 2 8 7 796 1025 170 +940 2 2 8 7 539 1898 1283 +941 2 2 8 7 724 1882 380 +942 2 2 8 7 904 1063 438 +943 2 2 8 7 273 1829 1001 +944 2 2 8 7 513 1152 1005 +945 2 2 8 7 1118 1873 1551 +946 2 2 8 7 1552 1874 1119 +947 2 2 8 7 699 1302 440 +948 2 2 8 7 215 1302 699 +949 2 2 8 7 1005 1152 435 +950 2 2 8 7 575 1806 952 +951 2 2 8 7 335 1239 906 +952 2 2 8 7 779 1315 459 +953 2 2 8 7 414 2043 1607 +954 2 2 8 7 231 1340 767 +955 2 2 8 7 270 1525 1178 +956 2 2 8 7 177 1081 751 +957 2 2 8 7 268 1519 978 +958 2 2 8 7 614 1566 1362 +959 2 2 8 7 961 1467 1001 +960 2 2 8 7 289 1085 754 +961 2 2 8 7 755 1086 290 +962 2 2 8 7 681 1998 1654 +963 2 2 8 7 754 1085 390 +964 2 2 8 7 389 1086 755 +965 2 2 8 7 186 1859 1155 +966 2 2 8 7 1062 1776 736 +967 2 2 8 7 1657 1847 749 +968 2 2 8 7 818 1996 326 +969 2 2 8 7 312 1184 1002 +970 2 2 8 7 819 1860 175 +971 2 2 8 7 209 1660 702 +972 2 2 8 7 701 1281 276 +973 2 2 8 7 452 1649 734 +974 2 2 8 7 1002 1184 522 +975 2 2 8 7 254 1776 1062 +976 2 2 8 7 1195 1630 723 +977 2 2 8 7 1042 1792 570 +978 2 2 8 7 740 1708 223 +979 2 2 8 7 802 1459 119 +980 2 2 8 7 58 1458 801 +981 2 2 8 7 388 1013 852 +982 2 2 8 7 1576 1699 599 +983 2 2 8 7 600 1698 1575 +984 2 2 8 7 931 1916 622 +985 2 2 8 7 289 1640 736 +986 2 2 8 7 740 1595 320 +987 2 2 8 7 717 1794 220 +988 2 2 8 7 161 1105 746 +989 2 2 8 7 627 1763 1249 +990 2 2 8 7 478 1344 1027 +991 2 2 8 7 1754 1953 310 +992 2 2 8 7 498 1629 972 +993 2 2 8 7 1392 1919 309 +994 2 2 8 7 1131 1665 1581 +995 2 2 8 7 948 2075 308 +996 2 2 8 7 762 1490 311 +997 2 2 8 7 505 1490 762 +998 2 2 8 7 943 998 414 +999 2 2 8 7 1141 1237 182 +1000 2 2 8 7 668 1723 1619 +1001 2 2 8 7 582 1237 1141 +1002 2 2 8 7 790 1242 496 +1003 2 2 8 7 256 1701 909 +1004 2 2 8 7 1131 1581 547 +1005 2 2 8 7 1138 1688 449 +1006 2 2 8 7 1364 1440 486 +1007 2 2 8 7 487 1441 1365 +1008 2 2 8 7 1960 1974 746 +1009 2 2 8 7 164 2076 1320 +1010 2 2 8 7 735 1615 290 +1011 2 2 8 7 841 2010 892 +1012 2 2 8 7 257 1270 708 +1013 2 2 8 7 882 1050 464 +1014 2 2 8 7 1028 1982 343 +1015 2 2 8 7 708 1273 257 +1016 2 2 8 7 412 1417 1173 +1017 2 2 8 7 739 1732 407 +1018 2 2 8 7 1569 1671 295 +1019 2 2 8 7 772 1801 306 +1020 2 2 8 7 808 2065 327 +1021 2 2 8 7 780 1667 546 +1022 2 2 8 7 414 1607 1067 +1023 2 2 8 7 306 1667 780 +1024 2 2 8 7 438 1063 784 +1025 2 2 8 7 813 1915 202 +1026 2 2 8 7 351 1448 980 +1027 2 2 8 7 166 1186 1153 +1028 2 2 8 7 921 1774 630 +1029 2 2 8 7 175 1007 886 +1030 2 2 8 7 212 1950 797 +1031 2 2 8 7 206 1937 807 +1032 2 2 8 7 886 1007 413 +1033 2 2 8 7 175 1860 846 +1034 2 2 8 7 112 1325 874 +1035 2 2 8 7 873 1326 65 +1036 2 2 8 7 390 1305 754 +1037 2 2 8 7 755 1306 389 +1038 2 2 8 7 993 1298 241 +1039 2 2 8 7 1188 1894 1578 +1040 2 2 8 7 846 1007 175 +1041 2 2 8 7 720 1479 1061 +1042 2 2 8 7 474 1374 783 +1043 2 2 8 7 154 1056 155 +1044 2 2 8 7 711 1321 282 +1045 2 2 8 7 283 1322 712 +1046 2 2 8 7 746 1609 161 +1047 2 2 8 7 157 1013 994 +1048 2 2 8 7 783 1374 252 +1049 2 2 8 7 751 1521 177 +1050 2 2 8 7 994 1013 451 +1051 2 2 8 7 883 1161 403 +1052 2 2 8 7 958 1016 217 +1053 2 2 8 7 746 1974 880 +1054 2 2 8 7 306 1801 782 +1055 2 2 8 7 755 1212 189 +1056 2 2 8 7 442 1016 958 +1057 2 2 8 7 449 1688 1257 +1058 2 2 8 7 379 1886 1463 +1059 2 2 8 7 774 1573 347 +1060 2 2 8 7 302 1610 930 +1061 2 2 8 7 1498 1623 942 +1062 2 2 8 7 660 2039 1601 +1063 2 2 8 7 733 1268 17 +1064 2 2 8 7 22 1037 23 +1065 2 2 8 7 768 1142 295 +1066 2 2 8 7 342 1774 921 +1067 2 2 8 7 794 1846 393 +1068 2 2 8 7 992 1771 395 +1069 2 2 8 7 1468 1930 767 +1070 2 2 8 7 852 1013 157 +1071 2 2 8 7 267 1508 888 +1072 2 2 8 7 220 1282 717 +1073 2 2 8 7 371 1171 1026 +1074 2 2 8 7 803 1122 416 +1075 2 2 8 7 294 1623 1498 +1076 2 2 8 7 1425 1629 498 +1077 2 2 8 7 187 1122 803 +1078 2 2 8 7 386 1984 983 +1079 2 2 8 7 1035 1546 369 +1080 2 2 8 7 743 1616 307 +1081 2 2 8 7 167 1617 743 +1082 2 2 8 7 917 1210 176 +1083 2 2 8 7 1056 1345 538 +1084 2 2 8 7 645 1546 1035 +1085 2 2 8 7 254 1479 720 +1086 2 2 8 7 658 1602 1199 +1087 2 2 8 7 752 1140 499 +1088 2 2 8 7 24 903 25 +1089 2 2 8 7 859 1685 555 +1090 2 2 8 7 34 1069 858 +1091 2 2 8 7 232 1359 905 +1092 2 2 8 7 888 1508 552 +1093 2 2 8 7 563 1533 889 +1094 2 2 8 7 934 983 337 +1095 2 2 8 7 909 1701 1612 +1096 2 2 8 7 889 1533 272 +1097 2 2 8 7 398 1609 746 +1098 2 2 8 7 376 1114 787 +1099 2 2 8 7 785 1406 353 +1100 2 2 8 7 779 1127 37 +1101 2 2 8 7 395 1771 1522 +1102 2 2 8 7 308 2075 1391 +1103 2 2 8 7 218 1800 864 +1104 2 2 8 7 410 1873 1118 +1105 2 2 8 7 1119 1874 411 +1106 2 2 8 7 848 1150 311 +1107 2 2 8 7 633 1584 996 +1108 2 2 8 7 786 1815 423 +1109 2 2 8 7 996 1584 269 +1110 2 2 8 7 971 1559 368 +1111 2 2 8 7 869 1015 383 +1112 2 2 8 7 1559 2063 368 +1113 2 2 8 7 748 1608 524 +1114 2 2 8 7 858 1315 35 +1115 2 2 8 7 744 1590 518 +1116 2 2 8 7 517 1591 745 +1117 2 2 8 7 832 1695 1166 +1118 2 2 8 7 205 1590 744 +1119 2 2 8 7 745 1591 204 +1120 2 2 8 7 1054 1055 472 +1121 2 2 8 7 1077 1712 1695 +1122 2 2 8 7 396 1055 1054 +1123 2 2 8 7 1320 2076 685 +1124 2 2 8 7 1077 1695 402 +1125 2 2 8 7 725 1278 229 +1126 2 2 8 7 230 1279 726 +1127 2 2 8 7 728 1269 437 +1128 2 2 8 7 727 1923 283 +1129 2 2 8 7 1344 1744 1027 +1130 2 2 8 7 747 1585 198 +1131 2 2 8 7 444 1396 726 +1132 2 2 8 7 1047 1398 214 +1133 2 2 8 7 589 1398 1047 +1134 2 2 8 7 1197 1874 672 +1135 2 2 8 7 671 1873 1196 +1136 2 2 8 7 295 1586 747 +1137 2 2 8 7 759 1165 67 +1138 2 2 8 7 110 1164 758 +1139 2 2 8 7 161 1609 773 +1140 2 2 8 7 813 1104 497 +1141 2 2 8 7 315 1104 790 +1142 2 2 8 7 636 1994 826 +1143 2 2 8 7 826 1994 313 +1144 2 2 8 7 1035 1839 565 +1145 2 2 8 7 361 1847 1657 +1146 2 2 8 7 1071 1775 253 +1147 2 2 8 7 735 1775 1071 +1148 2 2 8 7 726 1396 230 +1149 2 2 8 7 229 1366 725 +1150 2 2 8 7 302 1509 821 +1151 2 2 8 7 1178 1525 603 +1152 2 2 8 7 725 1366 443 +1153 2 2 8 7 821 1509 529 +1154 2 2 8 7 180 1461 918 +1155 2 2 8 7 530 1638 760 +1156 2 2 8 7 328 1168 895 +1157 2 2 8 7 307 1605 741 +1158 2 2 8 7 840 1611 138 +1159 2 2 8 7 507 1462 806 +1160 2 2 8 7 806 1462 188 +1161 2 2 8 7 910 1433 577 +1162 2 2 8 7 1190 1614 1003 +1163 2 2 8 7 929 1394 716 +1164 2 2 8 7 895 1168 604 +1165 2 2 8 7 892 2010 362 +1166 2 2 8 7 852 1840 388 +1167 2 2 8 7 888 1134 582 +1168 2 2 8 7 347 2067 774 +1169 2 2 8 7 989 1377 637 +1170 2 2 8 7 848 1152 251 +1171 2 2 8 7 851 1121 186 +1172 2 2 8 7 435 1152 848 +1173 2 2 8 7 738 1502 242 +1174 2 2 8 7 1074 1650 249 +1175 2 2 8 7 1115 1162 488 +1176 2 2 8 7 443 1226 898 +1177 2 2 8 7 1230 1409 513 +1178 2 2 8 7 715 1388 920 +1179 2 2 8 7 908 1540 493 +1180 2 2 8 7 310 1953 1004 +1181 2 2 8 7 1317 1717 536 +1182 2 2 8 7 768 1708 1142 +1183 2 2 8 7 1142 1708 394 +1184 2 2 8 7 774 1139 388 +1185 2 2 8 7 750 1263 259 +1186 2 2 8 7 737 1248 425 +1187 2 2 8 7 144 1559 971 +1188 2 2 8 7 988 1403 181 +1189 2 2 8 7 1427 1801 391 +1190 2 2 8 7 605 1725 775 +1191 2 2 8 7 776 1726 606 +1192 2 2 8 7 876 1076 397 +1193 2 2 8 7 537 1219 825 +1194 2 2 8 7 976 2076 2040 +1195 2 2 8 7 1049 1678 678 +1196 2 2 8 7 675 1904 1119 +1197 2 2 8 7 1118 1905 676 +1198 2 2 8 7 1281 1720 608 +1199 2 2 8 7 280 1678 1049 +1200 2 2 8 7 820 1954 740 +1201 2 2 8 7 1029 1234 364 +1202 2 2 8 7 533 1234 1029 +1203 2 2 8 7 9 1243 757 +1204 2 2 8 7 791 1154 402 +1205 2 2 8 7 475 1268 733 +1206 2 2 8 7 1138 1987 168 +1207 2 2 8 7 181 1187 988 +1208 2 2 8 7 313 1434 794 +1209 2 2 8 7 299 1387 803 +1210 2 2 8 7 812 1096 385 +1211 2 2 8 7 403 1080 1004 +1212 2 2 8 7 800 1156 282 +1213 2 2 8 7 757 1765 9 +1214 2 2 8 7 782 1801 1427 +1215 2 2 8 7 214 1965 761 +1216 2 2 8 7 1225 1501 640 +1217 2 2 8 7 737 1429 134 +1218 2 2 8 7 698 1982 1028 +1219 2 2 8 7 1254 1431 303 +1220 2 2 8 7 1852 1911 1107 +1221 2 2 8 7 1616 1685 1224 +1222 2 2 8 7 307 1616 1224 +1223 2 2 8 7 526 1338 1037 +1224 2 2 8 7 404 1059 859 +1225 2 2 8 7 967 1917 159 +1226 2 2 8 7 661 1805 816 +1227 2 2 8 7 499 1542 752 +1228 2 2 8 7 422 1852 1107 +1229 2 2 8 7 632 1251 1017 +1230 2 2 8 7 47 1220 48 +1231 2 2 8 7 515 1209 1015 +1232 2 2 8 7 609 1894 1188 +1233 2 2 8 7 859 1059 230 +1234 2 2 8 7 835 1202 535 +1235 2 2 8 7 810 2069 417 +1236 2 2 8 7 129 1181 130 +1237 2 2 8 7 599 1699 1018 +1238 2 2 8 7 1019 1698 600 +1239 2 2 8 7 576 1159 872 +1240 2 2 8 7 999 1245 412 +1241 2 2 8 7 814 1393 159 +1242 2 2 8 7 318 1714 779 +1243 2 2 8 7 739 1453 366 +1244 2 2 8 7 169 1631 793 +1245 2 2 8 7 1002 1869 1574 +1246 2 2 8 7 1035 1539 221 +1247 2 2 8 7 152 935 153 +1248 2 2 8 7 978 1964 268 +1249 2 2 8 7 602 1680 957 +1250 2 2 8 7 875 1677 244 +1251 2 2 8 7 932 1657 749 +1252 2 2 8 7 204 1591 1039 +1253 2 2 8 7 1040 1590 205 +1254 2 2 8 7 750 1415 1014 +1255 2 2 8 7 125 1267 775 +1256 2 2 8 7 776 1266 52 +1257 2 2 8 7 170 1500 887 +1258 2 2 8 7 407 1732 808 +1259 2 2 8 7 941 1081 485 +1260 2 2 8 7 1272 1380 544 +1261 2 2 8 7 887 1500 541 +1262 2 2 8 7 1587 1622 416 +1263 2 2 8 7 632 1811 1251 +1264 2 2 8 7 1379 1998 681 +1265 2 2 8 7 195 1154 791 +1266 2 2 8 7 978 1519 564 +1267 2 2 8 7 855 1451 523 +1268 2 2 8 7 957 1680 336 +1269 2 2 8 7 316 1451 855 +1270 2 2 8 7 881 1149 194 +1271 2 2 8 7 448 1073 847 +1272 2 2 8 7 411 1874 1197 +1273 2 2 8 7 1196 1873 410 +1274 2 2 8 7 811 1861 220 +1275 2 2 8 7 773 2023 571 +1276 2 2 8 7 988 1867 1403 +1277 2 2 8 7 822 1256 397 +1278 2 2 8 7 685 2076 976 +1279 2 2 8 7 579 1861 811 +1280 2 2 8 7 843 1518 30 +1281 2 2 8 7 757 1243 464 +1282 2 2 8 7 285 1930 1468 +1283 2 2 8 7 223 1341 740 +1284 2 2 8 7 434 1050 882 +1285 2 2 8 7 772 1651 166 +1286 2 2 8 7 678 1473 1103 +1287 2 2 8 7 405 1156 800 +1288 2 2 8 7 822 1596 324 +1289 2 2 8 7 1092 1850 385 +1290 2 2 8 7 177 1521 820 +1291 2 2 8 7 330 2034 946 +1292 2 2 8 7 815 1122 187 +1293 2 2 8 7 305 1438 758 +1294 2 2 8 7 762 1524 505 +1295 2 2 8 7 758 1438 467 +1296 2 2 8 7 992 993 454 +1297 2 2 8 7 395 993 992 +1298 2 2 8 7 339 1736 756 +1299 2 2 8 7 707 1922 1756 +1300 2 2 8 7 475 1053 940 +1301 2 2 8 7 1463 1886 741 +1302 2 2 8 7 1368 1789 781 +1303 2 2 8 7 761 1509 302 +1304 2 2 8 7 920 1492 548 +1305 2 2 8 7 323 1492 920 +1306 2 2 8 7 391 1153 1072 +1307 2 2 8 7 158 1297 809 +1308 2 2 8 7 1072 1153 516 +1309 2 2 8 7 930 1401 1237 +1310 2 2 8 7 843 1343 455 +1311 2 2 8 7 553 1503 929 +1312 2 2 8 7 929 1503 322 +1313 2 2 8 7 265 1781 1437 +1314 2 2 8 7 340 1662 751 +1315 2 2 8 7 446 1222 1098 +1316 2 2 8 7 1098 1222 545 +1317 2 2 8 7 957 1335 602 +1318 2 2 8 7 756 1285 339 +1319 2 2 8 7 682 2061 852 +1320 2 2 8 7 922 1693 1137 +1321 2 2 8 7 1179 1389 617 +1322 2 2 8 7 908 1066 631 +1323 2 2 8 7 604 1807 895 +1324 2 2 8 7 1254 1898 539 +1325 2 2 8 7 184 1066 908 +1326 2 2 8 7 1730 1917 967 +1327 2 2 8 7 940 1053 431 +1328 2 2 8 7 895 1807 197 +1329 2 2 8 7 189 1306 755 +1330 2 2 8 7 1952 2052 905 +1331 2 2 8 7 769 2010 841 +1332 2 2 8 7 297 2043 998 +1333 2 2 8 7 334 1424 916 +1334 2 2 8 7 874 1325 467 +1335 2 2 8 7 466 1326 873 +1336 2 2 8 7 1547 2059 387 +1337 2 2 8 7 323 1908 845 +1338 2 2 8 7 844 1907 322 +1339 2 2 8 7 555 2054 859 +1340 2 2 8 7 845 1908 598 +1341 2 2 8 7 597 1907 844 +1342 2 2 8 7 86 1292 816 +1343 2 2 8 7 817 1293 91 +1344 2 2 8 7 476 1263 1213 +1345 2 2 8 7 1277 1539 890 +1346 2 2 8 7 466 1450 759 +1347 2 2 8 7 249 1335 957 +1348 2 2 8 7 290 1494 755 +1349 2 2 8 7 758 1582 305 +1350 2 2 8 7 459 1315 858 +1351 2 2 8 7 1305 1462 754 +1352 2 2 8 7 754 1833 289 +1353 2 2 8 7 43 972 44 +1354 2 2 8 7 608 1818 1281 +1355 2 2 8 7 188 1462 1305 +1356 2 2 8 7 627 1952 905 +1357 2 2 8 7 1126 1137 530 +1358 2 2 8 7 664 1984 819 +1359 2 2 8 7 183 1137 1126 +1360 2 2 8 7 956 1710 595 +1361 2 2 8 7 192 1789 1368 +1362 2 2 8 7 826 2045 636 +1363 2 2 8 7 790 1504 315 +1364 2 2 8 7 496 1504 790 +1365 2 2 8 7 143 1559 144 +1366 2 2 8 7 1708 1903 223 +1367 2 2 8 7 256 1642 832 +1368 2 2 8 7 1039 1591 1435 +1369 2 2 8 7 1436 1590 1040 +1370 2 2 8 7 901 1604 706 +1371 2 2 8 7 99 955 100 +1372 2 2 8 7 77 956 78 +1373 2 2 8 7 306 1652 772 +1374 2 2 8 7 797 1950 934 +1375 2 2 8 7 1171 1878 1026 +1376 2 2 8 7 250 1411 1258 +1377 2 2 8 7 307 1224 781 +1378 2 2 8 7 229 1076 876 +1379 2 2 8 7 1450 1583 759 +1380 2 2 8 7 798 1854 462 +1381 2 2 8 7 463 1855 799 +1382 2 2 8 7 838 1259 167 +1383 2 2 8 7 756 1385 240 +1384 2 2 8 7 304 1583 1450 +1385 2 2 8 7 416 1622 803 +1386 2 2 8 7 246 1594 760 +1387 2 2 8 7 628 1825 1250 +1388 2 2 8 7 1249 1824 627 +1389 2 2 8 7 541 1178 887 +1390 2 2 8 7 639 1383 1193 +1391 2 2 8 7 464 1414 757 +1392 2 2 8 7 476 1389 1179 +1393 2 2 8 7 189 1212 836 +1394 2 2 8 7 1362 1566 255 +1395 2 2 8 7 865 1360 54 +1396 2 2 8 7 123 1361 866 +1397 2 2 8 7 1274 2045 1935 +1398 2 2 8 7 798 1382 308 +1399 2 2 8 7 1239 1836 906 +1400 2 2 8 7 462 1382 798 +1401 2 2 8 7 782 1667 306 +1402 2 2 8 7 651 1966 906 +1403 2 2 8 7 327 1796 809 +1404 2 2 8 7 1014 1548 329 +1405 2 2 8 7 723 1622 1587 +1406 2 2 8 7 906 1966 335 +1407 2 2 8 7 533 1541 1464 +1408 2 2 8 7 809 1798 158 +1409 2 2 8 7 931 1513 729 +1410 2 2 8 7 263 1012 986 +1411 2 2 8 7 1003 1739 172 +1412 2 2 8 7 244 1634 875 +1413 2 2 8 7 665 1739 1003 +1414 2 2 8 7 1193 1383 270 +1415 2 2 8 7 1520 1956 700 +1416 2 2 8 7 331 1537 838 +1417 2 2 8 7 771 1283 171 +1418 2 2 8 7 591 1441 1058 +1419 2 2 8 7 1057 1440 590 +1420 2 2 8 7 413 2079 970 +1421 2 2 8 7 633 1460 1114 +1422 2 2 8 7 1502 1529 616 +1423 2 2 8 7 580 1781 812 +1424 2 2 8 7 347 1573 885 +1425 2 2 8 7 1114 1460 201 +1426 2 2 8 7 552 1611 840 +1427 2 2 8 7 263 1318 1012 +1428 2 2 8 7 323 1388 866 +1429 2 2 8 7 388 1573 774 +1430 2 2 8 7 1095 1314 502 +1431 2 2 8 7 866 1388 492 +1432 2 2 8 7 311 1150 824 +1433 2 2 8 7 849 1110 450 +1434 2 2 8 7 839 1959 742 +1435 2 2 8 7 1017 1477 377 +1436 2 2 8 7 1125 1889 193 +1437 2 2 8 7 361 1687 1283 +1438 2 2 8 7 1219 1608 748 +1439 2 2 8 7 263 1608 1219 +1440 2 2 8 7 1069 1976 370 +1441 2 2 8 7 834 1179 617 +1442 2 2 8 7 202 1797 813 +1443 2 2 8 7 827 1906 585 +1444 2 2 8 7 883 1261 366 +1445 2 2 8 7 1029 1728 952 +1446 2 2 8 7 1153 1186 516 +1447 2 2 8 7 983 1673 833 +1448 2 2 8 7 780 1924 306 +1449 2 2 8 7 535 1592 835 +1450 2 2 8 7 384 1702 1074 +1451 2 2 8 7 1574 1869 190 +1452 2 2 8 7 791 1232 195 +1453 2 2 8 7 1098 1411 250 +1454 2 2 8 7 308 1733 798 +1455 2 2 8 7 837 1950 212 +1456 2 2 8 7 209 1672 795 +1457 2 2 8 7 997 1402 641 +1458 2 2 8 7 867 1402 222 +1459 2 2 8 7 1189 1198 536 +1460 2 2 8 7 983 1984 664 +1461 2 2 8 7 816 1805 87 +1462 2 2 8 7 90 1804 817 +1463 2 2 8 7 767 1930 488 +1464 2 2 8 7 295 1433 768 +1465 2 2 8 7 381 1162 827 +1466 2 2 8 7 482 1446 831 +1467 2 2 8 7 1032 1865 409 +1468 2 2 8 7 201 1795 977 +1469 2 2 8 7 1061 1479 471 +1470 2 2 8 7 573 1099 953 +1471 2 2 8 7 954 1100 572 +1472 2 2 8 7 291 1446 770 +1473 2 2 8 7 798 1369 97 +1474 2 2 8 7 80 1370 799 +1475 2 2 8 7 1007 2079 413 +1476 2 2 8 7 1041 1331 252 +1477 2 2 8 7 986 1012 423 +1478 2 2 8 7 865 1394 322 +1479 2 2 8 7 677 1671 1569 +1480 2 2 8 7 491 1394 865 +1481 2 2 8 7 1846 2071 393 +1482 2 2 8 7 977 1795 651 +1483 2 2 8 7 922 1977 321 +1484 2 2 8 7 523 1125 855 +1485 2 2 8 7 1073 1915 813 +1486 2 2 8 7 521 1550 1413 +1487 2 2 8 7 654 1913 943 +1488 2 2 8 7 943 1913 200 +1489 2 2 8 7 1596 1764 324 +1490 2 2 8 7 1424 1515 916 +1491 2 2 8 7 1012 1318 536 +1492 2 2 8 7 659 1812 1739 +1493 2 2 8 7 432 1111 949 +1494 2 2 8 7 1005 1230 513 +1495 2 2 8 7 789 1838 345 +1496 2 2 8 7 982 2073 408 +1497 2 2 8 7 1321 1788 780 +1498 2 2 8 7 781 1789 1322 +1499 2 2 8 7 779 1532 318 +1500 2 2 8 7 880 1520 398 +1501 2 2 8 7 413 1772 924 +1502 2 2 8 7 825 1624 537 +1503 2 2 8 7 173 1624 825 +1504 2 2 8 7 875 1387 299 +1505 2 2 8 7 914 1703 334 +1506 2 2 8 7 1813 2077 752 +1507 2 2 8 7 938 1454 400 +1508 2 2 8 7 401 1455 939 +1509 2 2 8 7 775 1496 296 +1510 2 2 8 7 297 1497 776 +1511 2 2 8 7 1680 2073 982 +1512 2 2 8 7 331 1767 1537 +1513 2 2 8 7 1085 1885 390 +1514 2 2 8 7 389 1884 1086 +1515 2 2 8 7 1016 1023 428 +1516 2 2 8 7 965 1618 821 +1517 2 2 8 7 1000 1200 146 +1518 2 2 8 7 975 1170 457 +1519 2 2 8 7 784 1553 179 +1520 2 2 8 7 899 1368 444 +1521 2 2 8 7 163 1170 975 +1522 2 2 8 7 442 1023 1016 +1523 2 2 8 7 316 1751 793 +1524 2 2 8 7 639 1897 946 +1525 2 2 8 7 946 1897 222 +1526 2 2 8 7 706 2013 1933 +1527 2 2 8 7 938 1354 558 +1528 2 2 8 7 559 1355 939 +1529 2 2 8 7 1134 1749 429 +1530 2 2 8 7 370 1506 959 +1531 2 2 8 7 476 1213 1187 +1532 2 2 8 7 778 1474 365 +1533 2 2 8 7 390 1885 1436 +1534 2 2 8 7 1435 1884 389 +1535 2 2 8 7 537 1624 800 +1536 2 2 8 7 259 1179 834 +1537 2 2 8 7 429 1749 1163 +1538 2 2 8 7 1093 1806 1404 +1539 2 2 8 7 1592 2072 835 +1540 2 2 8 7 489 1461 1195 +1541 2 2 8 7 844 1972 229 +1542 2 2 8 7 441 1148 853 +1543 2 2 8 7 804 1749 314 +1544 2 2 8 7 823 2059 1547 +1545 2 2 8 7 459 1532 779 +1546 2 2 8 7 1195 1461 669 +1547 2 2 8 7 252 2058 783 +1548 2 2 8 7 818 1762 195 +1549 2 2 8 7 460 1407 801 +1550 2 2 8 7 802 1408 461 +1551 2 2 8 7 399 1738 1025 +1552 2 2 8 7 1020 1520 700 +1553 2 2 8 7 1935 2045 344 +1554 2 2 8 7 1093 1404 614 +1555 2 2 8 7 803 1579 187 +1556 2 2 8 7 227 1083 924 +1557 2 2 8 7 40 1144 41 +1558 2 2 8 7 529 1215 821 +1559 2 2 8 7 219 1989 857 +1560 2 2 8 7 854 1515 511 +1561 2 2 8 7 391 1801 1153 +1562 2 2 8 7 159 1917 788 +1563 2 2 8 7 1153 1801 772 +1564 2 2 8 7 803 1622 299 +1565 2 2 8 7 567 1989 1052 +1566 2 2 8 7 97 1854 798 +1567 2 2 8 7 799 1855 80 +1568 2 2 8 7 1116 1593 427 +1569 2 2 8 7 1654 1998 198 +1570 2 2 8 7 596 1641 804 +1571 2 2 8 7 1416 1477 1017 +1572 2 2 8 7 1072 1112 243 +1573 2 2 8 7 516 1112 1072 +1574 2 2 8 7 1234 1638 364 +1575 2 2 8 7 441 1157 933 +1576 2 2 8 7 427 1593 1130 +1577 2 2 8 7 1406 1846 226 +1578 2 2 8 7 1285 1312 512 +1579 2 2 8 7 924 2068 375 +1580 2 2 8 7 345 1333 789 +1581 2 2 8 7 760 1638 1234 +1582 2 2 8 7 389 1306 896 +1583 2 2 8 7 897 1305 390 +1584 2 2 8 7 417 2069 933 +1585 2 2 8 7 863 1262 328 +1586 2 2 8 7 313 1808 826 +1587 2 2 8 7 1108 1514 514 +1588 2 2 8 7 427 1692 1115 +1589 2 2 8 7 826 1810 216 +1590 2 2 8 7 787 1437 376 +1591 2 2 8 7 319 1974 1960 +1592 2 2 8 7 857 1977 601 +1593 2 2 8 7 573 1454 1099 +1594 2 2 8 7 1100 1455 572 +1595 2 2 8 7 1149 1635 194 +1596 2 2 8 7 903 1109 25 +1597 2 2 8 7 830 1399 74 +1598 2 2 8 7 103 1400 831 +1599 2 2 8 7 341 2072 1592 +1600 2 2 8 7 424 1729 833 +1601 2 2 8 7 1234 1482 246 +1602 2 2 8 7 787 1373 494 +1603 2 2 8 7 788 1413 159 +1604 2 2 8 7 1526 1989 567 +1605 2 2 8 7 494 1920 787 +1606 2 2 8 7 1166 1695 566 +1607 2 2 8 7 801 1458 460 +1608 2 2 8 7 461 1459 802 +1609 2 2 8 7 1149 1514 619 +1610 2 2 8 7 793 1371 169 +1611 2 2 8 7 898 1226 191 +1612 2 2 8 7 836 1212 435 +1613 2 2 8 7 871 1155 469 +1614 2 2 8 7 308 1382 805 +1615 2 2 8 7 258 1148 933 +1616 2 2 8 7 1245 1417 412 +1617 2 2 8 7 1030 1560 499 +1618 2 2 8 7 933 1148 441 +1619 2 2 8 7 792 1451 316 +1620 2 2 8 7 244 1677 789 +1621 2 2 8 7 872 1159 269 +1622 2 2 8 7 1786 2078 700 +1623 2 2 8 7 543 1677 875 +1624 2 2 8 7 1720 1889 608 +1625 2 2 8 7 909 1642 256 +1626 2 2 8 7 536 1717 1189 +1627 2 2 8 7 314 1134 888 +1628 2 2 8 7 1359 1763 905 +1629 2 2 8 7 420 1683 870 +1630 2 2 8 7 1600 1726 50 +1631 2 2 8 7 127 1725 1599 +1632 2 2 8 7 873 1357 418 +1633 2 2 8 7 419 1356 874 +1634 2 2 8 7 523 1499 1125 +1635 2 2 8 7 682 1167 957 +1636 2 2 8 7 514 1149 881 +1637 2 2 8 7 799 1528 463 +1638 2 2 8 7 281 1564 964 +1639 2 2 8 7 250 1258 1044 +1640 2 2 8 7 809 1297 407 +1641 2 2 8 7 1461 1755 918 +1642 2 2 8 7 288 2077 1813 +1643 2 2 8 7 801 1535 58 +1644 2 2 8 7 119 1534 802 +1645 2 2 8 7 1282 1471 382 +1646 2 2 8 7 1309 1692 427 +1647 2 2 8 7 877 1349 93 +1648 2 2 8 7 84 1350 878 +1649 2 2 8 7 1128 1910 579 +1650 2 2 8 7 508 1160 1129 +1651 2 2 8 7 676 2011 1046 +1652 2 2 8 7 1045 2012 675 +1653 2 2 8 7 833 1673 210 +1654 2 2 8 7 207 1198 1189 +1655 2 2 8 7 1108 1568 1514 +1656 2 2 8 7 1319 1723 668 +1657 2 2 8 7 916 1364 486 +1658 2 2 8 7 236 1364 916 +1659 2 2 8 7 923 1307 325 +1660 2 2 8 7 472 1307 923 +1661 2 2 8 7 1619 1723 343 +1662 2 2 8 7 74 1760 830 +1663 2 2 8 7 831 1761 103 +1664 2 2 8 7 435 1822 836 +1665 2 2 8 7 1604 2013 706 +1666 2 2 8 7 166 1256 822 +1667 2 2 8 7 805 1359 232 +1668 2 2 8 7 924 1772 227 +1669 2 2 8 7 418 2049 1009 +1670 2 2 8 7 1010 2050 419 +1671 2 2 8 7 242 1161 883 +1672 2 2 8 7 995 1236 187 +1673 2 2 8 7 1113 1756 303 +1674 2 2 8 7 1273 1352 501 +1675 2 2 8 7 551 1236 995 +1676 2 2 8 7 949 1111 161 +1677 2 2 8 7 1402 1934 641 +1678 2 2 8 7 707 1756 1113 +1679 2 2 8 7 1025 1738 1500 +1680 2 2 8 7 264 1661 1275 +1681 2 2 8 7 830 1501 483 +1682 2 2 8 7 862 1815 325 +1683 2 2 8 7 176 1445 917 +1684 2 2 8 7 1406 1700 353 +1685 2 2 8 7 1009 2049 1556 +1686 2 2 8 7 1557 2050 1010 +1687 2 2 8 7 354 1260 828 +1688 2 2 8 7 382 1471 974 +1689 2 2 8 7 957 2061 682 +1690 2 2 8 7 336 2061 957 +1691 2 2 8 7 1000 1493 531 +1692 2 2 8 7 133 1694 134 +1693 2 2 8 7 834 1793 457 +1694 2 2 8 7 879 1180 357 +1695 2 2 8 7 1176 2091 312 +1696 2 2 8 7 867 1193 541 +1697 2 2 8 7 317 1466 864 +1698 2 2 8 7 785 1846 1406 +1699 2 2 8 7 817 1504 1293 +1700 2 2 8 7 1066 1601 396 +1701 2 2 8 7 366 1614 1052 +1702 2 2 8 7 768 1903 1708 +1703 2 2 8 7 862 1339 423 +1704 2 2 8 7 953 1099 418 +1705 2 2 8 7 419 1100 954 +1706 2 2 8 7 890 1719 277 +1707 2 2 8 7 565 1719 890 +1708 2 2 8 7 356 1809 907 +1709 2 2 8 7 1194 1787 447 +1710 2 2 8 7 227 1772 944 +1711 2 2 8 7 662 2052 915 +1712 2 2 8 7 915 2052 332 +1713 2 2 8 7 836 1822 311 +1714 2 2 8 7 952 1806 178 +1715 2 2 8 7 119 1459 120 +1716 2 2 8 7 57 1458 58 +1717 2 2 8 7 806 1424 334 +1718 2 2 8 7 188 1663 806 +1719 2 2 8 7 1129 1160 456 +1720 2 2 8 7 233 1918 860 +1721 2 2 8 7 1117 1429 425 +1722 2 2 8 7 527 1689 1448 +1723 2 2 8 7 146 1200 147 +1724 2 2 8 7 812 1990 580 +1725 2 2 8 7 946 2034 639 +1726 2 2 8 7 230 1890 845 +1727 2 2 8 7 813 1544 333 +1728 2 2 8 7 1076 1972 553 +1729 2 2 8 7 497 1544 813 +1730 2 2 8 7 1022 1948 362 +1731 2 2 8 7 910 1903 1433 +1732 2 2 8 7 738 1297 1008 +1733 2 2 8 7 853 1244 441 +1734 2 2 8 7 581 1444 1077 +1735 2 2 8 7 1077 1444 266 +1736 2 2 8 7 162 1244 853 +1737 2 2 8 7 210 1737 833 +1738 2 2 8 7 404 1259 838 +1739 2 2 8 7 537 1318 1219 +1740 2 2 8 7 907 1691 171 +1741 2 2 8 7 1177 1517 344 +1742 2 2 8 7 825 1832 349 +1743 2 2 8 7 666 1517 1177 +1744 2 2 8 7 1175 1963 689 +1745 2 2 8 7 320 1731 820 +1746 2 2 8 7 864 1945 218 +1747 2 2 8 7 1911 1961 1096 +1748 2 2 8 7 980 1304 594 +1749 2 2 8 7 338 1442 810 +1750 2 2 8 7 149 1975 894 +1751 2 2 8 7 811 1420 310 +1752 2 2 8 7 846 2084 2079 +1753 2 2 8 7 657 2030 1337 +1754 2 2 8 7 2055 2063 870 +1755 2 2 8 7 488 1116 1115 +1756 2 2 8 7 1273 2027 1352 +1757 2 2 8 7 833 1729 337 +1758 2 2 8 7 175 1604 819 +1759 2 2 8 7 1115 1116 427 +1760 2 2 8 7 824 1485 174 +1761 2 2 8 7 1319 1348 197 +1762 2 2 8 7 668 1348 1319 +1763 2 2 8 7 846 1860 386 +1764 2 2 8 7 24 1338 903 +1765 2 2 8 7 821 1618 302 +1766 2 2 8 7 541 1193 1178 +1767 2 2 8 7 1178 1193 270 +1768 2 2 8 7 1499 1818 1125 +1769 2 2 8 7 1465 1722 570 +1770 2 2 8 7 1343 1560 1030 +1771 2 2 8 7 303 1431 1113 +1772 2 2 8 7 1002 1574 550 +1773 2 2 8 7 31 1158 32 +1774 2 2 8 7 631 2006 908 +1775 2 2 8 7 211 2009 827 +1776 2 2 8 7 908 2006 317 +1777 2 2 8 7 618 1868 1063 +1778 2 2 8 7 1063 1868 784 +1779 2 2 8 7 566 1287 1166 +1780 2 2 8 7 1166 1287 164 +1781 2 2 8 7 120 1207 121 +1782 2 2 8 7 56 1206 57 +1783 2 2 8 7 33 1069 34 +1784 2 2 8 7 840 1779 552 +1785 2 2 8 7 816 1658 315 +1786 2 2 8 7 815 1670 293 +1787 2 2 8 7 505 1524 842 +1788 2 2 8 7 647 1629 1191 +1789 2 2 8 7 842 1524 237 +1790 2 2 8 7 553 1972 1503 +1791 2 2 8 7 578 1252 1006 +1792 2 2 8 7 159 1393 967 +1793 2 2 8 7 332 2052 1952 +1794 2 2 8 7 265 1911 1096 +1795 2 2 8 7 1421 1707 613 +1796 2 2 8 7 311 1822 848 +1797 2 2 8 7 324 1344 822 +1798 2 2 8 7 14 1990 1850 +1799 2 2 8 7 1267 1496 775 +1800 2 2 8 7 776 1497 1266 +1801 2 2 8 7 952 2067 347 +1802 2 2 8 7 673 2067 952 +1803 2 2 8 7 370 1887 858 +1804 2 2 8 7 1099 1454 261 +1805 2 2 8 7 262 1455 1100 +1806 2 2 8 7 483 1399 830 +1807 2 2 8 7 831 1400 482 +1808 2 2 8 7 820 1426 177 +1809 2 2 8 7 945 1959 839 +1810 2 2 8 7 357 1959 945 +1811 2 2 8 7 118 1752 1534 +1812 2 2 8 7 1535 1753 59 +1813 2 2 8 7 195 1669 1021 +1814 2 2 8 7 1209 1716 1015 +1815 2 2 8 7 333 1711 847 +1816 2 2 8 7 906 1260 651 +1817 2 2 8 7 646 1985 1102 +1818 2 2 8 7 191 2081 898 +1819 2 2 8 7 601 1995 1102 +1820 2 2 8 7 976 1707 685 +1821 2 2 8 7 854 1988 1515 +1822 2 2 8 7 220 1794 841 +1823 2 2 8 7 822 1757 166 +1824 2 2 8 7 257 1110 989 +1825 2 2 8 7 1077 1154 581 +1826 2 2 8 7 1444 1778 266 +1827 2 2 8 7 165 1580 1130 +1828 2 2 8 7 1047 1941 425 +1829 2 2 8 7 511 1578 854 +1830 2 2 8 7 440 1412 1060 +1831 2 2 8 7 135 2038 136 +1832 2 2 8 7 1184 1419 522 +1833 2 2 8 7 1815 1901 325 +1834 2 2 8 7 1392 1734 635 +1835 2 2 8 7 634 1733 1391 +1836 2 2 8 7 1141 1247 582 +1837 2 2 8 7 458 1362 869 +1838 2 2 8 7 1213 2074 1187 +1839 2 2 8 7 869 1362 255 +1840 2 2 8 7 1117 2038 135 +1841 2 2 8 7 298 2078 901 +1842 2 2 8 7 1163 1941 214 +1843 2 2 8 7 181 1389 1187 +1844 2 2 8 7 804 1941 1163 +1845 2 2 8 7 1211 1314 264 +1846 2 2 8 7 397 1596 822 +1847 2 2 8 7 424 1949 1024 +1848 2 2 8 7 1011 1909 574 +1849 2 2 8 7 601 1977 922 +1850 2 2 8 7 366 1261 1003 +1851 2 2 8 7 848 1822 435 +1852 2 2 8 7 11 1034 12 +1853 2 2 8 7 445 1208 928 +1854 2 2 8 7 928 1208 226 +1855 2 2 8 7 825 1386 173 +1856 2 2 8 7 326 1995 1644 +1857 2 2 8 7 621 1899 1700 +1858 2 2 8 7 823 1547 231 +1859 2 2 8 7 131 1038 132 +1860 2 2 8 7 886 2013 175 +1861 2 2 8 7 200 1674 929 +1862 2 2 8 7 139 1308 140 +1863 2 2 8 7 990 1144 426 +1864 2 2 8 7 853 1921 442 +1865 2 2 8 7 1083 2068 924 +1866 2 2 8 7 224 1520 880 +1867 2 2 8 7 16 1523 17 +1868 2 2 8 7 1537 1767 722 +1869 2 2 8 7 984 1123 430 +1870 2 2 8 7 174 1928 824 +1871 2 2 8 7 388 1139 1013 +1872 2 2 8 7 921 1222 446 +1873 2 2 8 7 208 1222 921 +1874 2 2 8 7 1083 1780 433 +1875 2 2 8 7 1042 1721 190 +1876 2 2 8 7 780 1788 1226 +1877 2 2 8 7 222 1897 867 +1878 2 2 8 7 1226 1788 191 +1879 2 2 8 7 619 1635 1149 +1880 2 2 8 7 1088 1682 293 +1881 2 2 8 7 456 1351 948 +1882 2 2 8 7 1053 1240 431 +1883 2 2 8 7 1515 1988 236 +1884 2 2 8 7 658 1682 1088 +1885 2 2 8 7 189 1900 1306 +1886 2 2 8 7 1066 2031 1601 +1887 2 2 8 7 408 1676 982 +1888 2 2 8 7 368 2063 2055 +1889 2 2 8 7 1089 1111 432 +1890 2 2 8 7 436 1296 1082 +1891 2 2 8 7 938 1978 1354 +1892 2 2 8 7 1355 1979 939 +1893 2 2 8 7 1249 1763 462 +1894 2 2 8 7 508 1129 987 +1895 2 2 8 7 233 1457 847 +1896 2 2 8 7 880 1974 724 +1897 2 2 8 7 221 1277 868 +1898 2 2 8 7 437 1312 1084 +1899 2 2 8 7 392 1276 961 +1900 2 2 8 7 222 1402 997 +1901 2 2 8 7 935 1345 153 +1902 2 2 8 7 150 1182 151 +1903 2 2 8 7 234 1123 984 +1904 2 2 8 7 434 1235 1050 +1905 2 2 8 7 589 2041 1384 +1906 2 2 8 7 1718 2041 589 +1907 2 2 8 7 455 1518 843 +1908 2 2 8 7 45 1067 46 +1909 2 2 8 7 43 1395 972 +1910 2 2 8 7 856 1948 450 +1911 2 2 8 7 433 1780 1113 +1912 2 2 8 7 1036 1157 441 +1913 2 2 8 7 398 1520 1020 +1914 2 2 8 7 966 1171 371 +1915 2 2 8 7 954 1356 419 +1916 2 2 8 7 418 1357 953 +1917 2 2 8 7 448 1171 966 +1918 2 2 8 7 423 1815 862 +1919 2 2 8 7 230 1396 859 +1920 2 2 8 7 54 1790 865 +1921 2 2 8 7 866 1791 123 +1922 2 2 8 7 1210 1416 176 +1923 2 2 8 7 1023 1316 428 +1924 2 2 8 7 1202 1697 288 +1925 2 2 8 7 1583 1894 556 +1926 2 2 8 7 557 1895 1582 +1927 2 2 8 7 714 1697 1202 +1928 2 2 8 7 882 1516 434 +1929 2 2 8 7 1213 1891 765 +1930 2 2 8 7 946 1176 550 +1931 2 2 8 7 856 1358 172 +1932 2 2 8 7 871 1648 338 +1933 2 2 8 7 403 1261 883 +1934 2 2 8 7 30 1518 31 +1935 2 2 8 7 484 1210 919 +1936 2 2 8 7 311 1490 836 +1937 2 2 8 7 929 1674 553 +1938 2 2 8 7 836 1491 189 +1939 2 2 8 7 215 1290 870 +1940 2 2 8 7 888 1947 267 +1941 2 2 8 7 957 1167 249 +1942 2 2 8 7 548 1890 1059 +1943 2 2 8 7 1046 2011 291 +1944 2 2 8 7 292 2012 1045 +1945 2 2 8 7 903 2002 339 +1946 2 2 8 7 928 1423 350 +1947 2 2 8 7 1081 1295 485 +1948 2 2 8 7 1141 1412 440 +1949 2 2 8 7 905 2052 662 +1950 2 2 8 7 869 1870 458 +1951 2 2 8 7 1383 2034 1735 +1952 2 2 8 7 1383 1735 592 +1953 2 2 8 7 210 2066 902 +1954 2 2 8 7 425 1941 1641 +1955 2 2 8 7 865 1790 491 +1956 2 2 8 7 492 1791 866 +1957 2 2 8 7 383 1872 869 +1958 2 2 8 7 329 1891 1213 +1959 2 2 8 7 838 1537 404 +1960 2 2 8 7 610 2026 896 +1961 2 2 8 7 356 2092 1809 +1962 2 2 8 7 50 1726 51 +1963 2 2 8 7 126 1725 127 +1964 2 2 8 7 1316 1380 428 +1965 2 2 8 7 415 1693 1270 +1966 2 2 8 7 978 1143 584 +1967 2 2 8 7 492 1496 1267 +1968 2 2 8 7 1266 1497 491 +1969 2 2 8 7 318 1143 978 +1970 2 2 8 7 193 1351 855 +1971 2 2 8 7 137 1543 840 +1972 2 2 8 7 414 1191 943 +1973 2 2 8 7 987 1129 232 +1974 2 2 8 7 854 1578 304 +1975 2 2 8 7 959 1506 221 +1976 2 2 8 7 970 1794 717 +1977 2 2 8 7 158 1339 862 +1978 2 2 8 7 1191 1629 279 +1979 2 2 8 7 40 2090 1144 +1980 2 2 8 7 237 1664 842 +1981 2 2 8 7 556 1894 1328 +1982 2 2 8 7 1329 1895 557 +1983 2 2 8 7 436 1301 911 +1984 2 2 8 7 846 2079 1007 +1985 2 2 8 7 863 1340 231 +1986 2 2 8 7 859 2054 404 +1987 2 2 8 7 1031 1491 505 +1988 2 2 8 7 177 1426 950 +1989 2 2 8 7 1480 2046 409 +1990 2 2 8 7 269 1159 996 +1991 2 2 8 7 950 1426 509 +1992 2 2 8 7 93 1940 877 +1993 2 2 8 7 878 1939 84 +1994 2 2 8 7 1198 1902 786 +1995 2 2 8 7 158 1405 1008 +1996 2 2 8 7 877 1940 496 +1997 2 2 8 7 497 1939 878 +1998 2 2 8 7 207 1902 1198 +1999 2 2 8 7 892 1420 811 +2000 2 2 8 7 450 2051 856 +2001 2 2 8 7 876 1366 229 +2002 2 2 8 7 469 1087 1084 +2003 2 2 8 7 342 1264 937 +2004 2 2 8 7 937 1264 454 +2005 2 2 8 7 703 1764 1596 +2006 2 2 8 7 1145 1909 1011 +2007 2 2 8 7 1084 1087 437 +2008 2 2 8 7 996 1159 452 +2009 2 2 8 7 408 2074 1676 +2010 2 2 8 7 1513 1756 729 +2011 2 2 8 7 842 1438 305 +2012 2 2 8 7 141 1133 142 +2013 2 2 8 7 920 1681 199 +2014 2 2 8 7 719 1987 1294 +2015 2 2 8 7 844 1626 597 +2016 2 2 8 7 598 1627 845 +2017 2 2 8 7 367 1684 951 +2018 2 2 8 7 1211 1231 502 +2019 2 2 8 7 951 1684 562 +2020 2 2 8 7 332 1242 915 +2021 2 2 8 7 902 2014 359 +2022 2 2 8 7 858 1887 459 +2023 2 2 8 7 1124 1298 519 +2024 2 2 8 7 860 1918 463 +2025 2 2 8 7 251 1430 848 +2026 2 2 8 7 116 1064 117 +2027 2 2 8 7 60 1065 61 +2028 2 2 8 7 548 1681 920 +2029 2 2 8 7 529 1397 1215 +2030 2 2 8 7 345 1838 911 +2031 2 2 8 7 446 1817 1803 +2032 2 2 8 7 904 1736 339 +2033 2 2 8 7 466 1988 854 +2034 2 2 8 7 536 1198 1012 +2035 2 2 8 7 1177 2045 826 +2036 2 2 8 7 847 1457 448 +2037 2 2 8 7 1013 1139 451 +2038 2 2 8 7 1174 1878 638 +2039 2 2 8 7 1293 1504 496 +2040 2 2 8 7 845 1492 323 +2041 2 2 8 7 343 1723 1028 +2042 2 2 8 7 622 1916 1898 +2043 2 2 8 7 322 1503 844 +2044 2 2 8 7 1850 1990 812 +2045 2 2 8 7 481 1410 894 +2046 2 2 8 7 30 1639 843 +2047 2 2 8 7 660 1828 1294 +2048 2 2 8 7 541 1738 867 +2049 2 2 8 7 582 1947 888 +2050 2 2 8 7 630 2083 1048 +2051 2 2 8 7 1270 1693 708 +2052 2 2 8 7 637 1289 1120 +2053 2 2 8 7 862 1405 158 +2054 2 2 8 7 463 1528 860 +2055 2 2 8 7 1027 1466 478 +2056 2 2 8 7 64 1357 873 +2057 2 2 8 7 874 1356 113 +2058 2 2 8 7 963 2068 433 +2059 2 2 8 7 304 1450 854 +2060 2 2 8 7 854 1450 466 +2061 2 2 8 7 397 1799 876 +2062 2 2 8 7 1028 1123 234 +2063 2 2 8 7 431 1589 940 +2064 2 2 8 7 1101 1811 247 +2065 2 2 8 7 641 1934 863 +2066 2 2 8 7 383 1569 1342 +2067 2 2 8 7 250 1300 1098 +2068 2 2 8 7 1342 1569 747 +2069 2 2 8 7 1003 1261 665 +2070 2 2 8 7 926 1241 218 +2071 2 2 8 7 1008 1297 158 +2072 2 2 8 7 1168 1882 604 +2073 2 2 8 7 425 1248 1047 +2074 2 2 8 7 625 1618 965 +2075 2 2 8 7 257 1273 1214 +2076 2 2 8 7 542 1123 1028 +2077 2 2 8 7 322 1907 865 +2078 2 2 8 7 866 1908 323 +2079 2 2 8 7 393 1145 1011 +2080 2 2 8 7 872 1414 464 +2081 2 2 8 7 855 1759 316 +2082 2 2 8 7 457 1170 1151 +2083 2 2 8 7 1151 1170 502 +2084 2 2 8 7 889 1309 427 +2085 2 2 8 7 269 1414 872 +2086 2 2 8 7 972 1395 498 +2087 2 2 8 7 376 1527 1114 +2088 2 2 8 7 1080 1851 1004 +2089 2 2 8 7 54 1360 55 +2090 2 2 8 7 122 1361 123 +2091 2 2 8 7 11 1530 1034 +2092 2 2 8 7 160 1613 1209 +2093 2 2 8 7 1209 1613 677 +2094 2 2 8 7 1686 1804 89 +2095 2 2 8 7 88 1805 1686 +2096 2 2 8 7 464 1545 872 +2097 2 2 8 7 1223 1508 267 +2098 2 2 8 7 257 1214 1110 +2099 2 2 8 7 652 1508 1223 +2100 2 2 8 7 325 1645 862 +2101 2 2 8 7 1258 2035 1044 +2102 2 2 8 7 363 1993 958 +2103 2 2 8 7 864 1540 317 +2104 2 2 8 7 503 1111 1089 +2105 2 2 8 7 955 1709 100 +2106 2 2 8 7 77 1710 956 +2107 2 2 8 7 947 1993 363 +2108 2 2 8 7 2079 2084 355 +2109 2 2 8 7 99 1746 955 +2110 2 2 8 7 956 1745 78 +2111 2 2 8 7 1034 1632 12 +2112 2 2 8 7 520 1387 875 +2113 2 2 8 7 670 1587 1218 +2114 2 2 8 7 868 1532 459 +2115 2 2 8 7 1925 1973 770 +2116 2 2 8 7 1218 1587 416 +2117 2 2 8 7 561 1381 1376 +2118 2 2 8 7 428 1380 879 +2119 2 2 8 7 358 1842 1199 +2120 2 2 8 7 1131 1322 283 +2121 2 2 8 7 547 1322 1131 +2122 2 2 8 7 563 1842 884 +2123 2 2 8 7 1105 2088 430 +2124 2 2 8 7 923 1327 243 +2125 2 2 8 7 684 1548 1014 +2126 2 2 8 7 534 1555 1517 +2127 2 2 8 7 1020 2078 298 +2128 2 2 8 7 700 2078 1020 +2129 2 2 8 7 1492 1890 548 +2130 2 2 8 7 960 1563 432 +2131 2 2 8 7 888 1779 314 +2132 2 2 8 7 552 1779 888 +2133 2 2 8 7 2040 2076 479 +2134 2 2 8 7 470 1923 1313 +2135 2 2 8 7 377 1769 1217 +2136 2 2 8 7 963 1672 209 +2137 2 2 8 7 446 1803 921 +2138 2 2 8 7 1217 1769 730 +2139 2 2 8 7 255 1567 1015 +2140 2 2 8 7 870 1683 215 +2141 2 2 8 7 1052 1614 567 +2142 2 2 8 7 294 1963 1175 +2143 2 2 8 7 312 1929 1176 +2144 2 2 8 7 868 1835 318 +2145 2 2 8 7 977 1373 201 +2146 2 2 8 7 494 1373 977 +2147 2 2 8 7 318 1532 868 +2148 2 2 8 7 332 1952 877 +2149 2 2 8 7 785 2071 1846 +2150 2 2 8 7 881 1595 514 +2151 2 2 8 7 320 1595 881 +2152 2 2 8 7 435 1494 1005 +2153 2 2 8 7 234 1713 1028 +2154 2 2 8 7 953 1357 63 +2155 2 2 8 7 114 1356 954 +2156 2 2 8 7 930 1610 519 +2157 2 2 8 7 1028 1713 698 +2158 2 2 8 7 502 1170 1095 +2159 2 2 8 7 1534 1752 697 +2160 2 2 8 7 696 1753 1535 +2161 2 2 8 7 1095 1170 163 +2162 2 2 8 7 261 1857 1057 +2163 2 2 8 7 1058 1858 262 +2164 2 2 8 7 1402 1738 399 +2165 2 2 8 7 665 1953 1754 +2166 2 2 8 7 867 1738 1402 +2167 2 2 8 7 1019 1927 69 +2168 2 2 8 7 108 1926 1018 +2169 2 2 8 7 994 1377 373 +2170 2 2 8 7 878 1544 497 +2171 2 2 8 7 186 1880 1542 +2172 2 2 8 7 988 1187 408 +2173 2 2 8 7 1114 1527 633 +2174 2 2 8 7 360 1409 975 +2175 2 2 8 7 872 1747 576 +2176 2 2 8 7 1528 1558 860 +2177 2 2 8 7 309 1558 1528 +2178 2 2 8 7 881 1936 320 +2179 2 2 8 7 37 1127 38 +2180 2 2 8 7 1446 2011 831 +2181 2 2 8 7 434 1862 1056 +2182 2 2 8 7 1168 2019 380 +2183 2 2 8 7 1811 1925 247 +2184 2 2 8 7 796 2019 1168 +2185 2 2 8 7 25 1109 26 +2186 2 2 8 7 527 1720 1101 +2187 2 2 8 7 530 1280 936 +2188 2 2 8 7 981 1409 360 +2189 2 2 8 7 875 1634 520 +2190 2 2 8 7 218 2056 926 +2191 2 2 8 7 926 2056 615 +2192 2 2 8 7 786 1901 1815 +2193 2 2 8 7 1037 1823 431 +2194 2 2 8 7 1336 2088 1105 +2195 2 2 8 7 718 2063 1559 +2196 2 2 8 7 918 1755 335 +2197 2 2 8 7 1092 1473 569 +2198 2 2 8 7 922 2022 601 +2199 2 2 8 7 1000 1331 421 +2200 2 2 8 7 183 2022 922 +2201 2 2 8 7 385 1473 1092 +2202 2 2 8 7 374 1792 1042 +2203 2 2 8 7 531 1331 1000 +2204 2 2 8 7 660 1294 1205 +2205 2 2 8 7 402 1154 1077 +2206 2 2 8 7 235 1157 1036 +2207 2 2 8 7 194 1782 881 +2208 2 2 8 7 709 1174 1173 +2209 2 2 8 7 1103 1473 385 +2210 2 2 8 7 1173 1174 412 +2211 2 2 8 7 713 2091 1176 +2212 2 2 8 7 893 1967 469 +2213 2 2 8 7 918 1353 180 +2214 2 2 8 7 1271 2060 319 +2215 2 2 8 7 1292 1658 816 +2216 2 2 8 7 933 2069 258 +2217 2 2 8 7 366 1453 883 +2218 2 2 8 7 457 1793 964 +2219 2 2 8 7 1774 2083 630 +2220 2 2 8 7 955 1970 1709 +2221 2 2 8 7 1038 1829 612 +2222 2 2 8 7 340 1706 991 +2223 2 2 8 7 439 1720 1281 +2224 2 2 8 7 1454 1848 400 +2225 2 2 8 7 401 1849 1455 +2226 2 2 8 7 7 1516 882 +2227 2 2 8 7 579 1471 1282 +2228 2 2 8 7 848 1430 1150 +2229 2 2 8 7 878 2048 1544 +2230 2 2 8 7 907 1916 356 +2231 2 2 8 7 1251 1811 439 +2232 2 2 8 7 264 1912 1661 +2233 2 2 8 7 335 1649 918 +2234 2 2 8 7 1005 1715 1230 +2235 2 2 8 7 894 1410 149 +2236 2 2 8 7 221 1506 1035 +2237 2 2 8 7 345 1932 935 +2238 2 2 8 7 893 1542 499 +2239 2 2 8 7 1765 2017 568 +2240 2 2 8 7 1544 2048 333 +2241 2 2 8 7 1575 1698 274 +2242 2 2 8 7 275 1699 1576 +2243 2 2 8 7 436 1536 1296 +2244 2 2 8 7 1341 1595 740 +2245 2 2 8 7 1094 1862 434 +2246 2 2 8 7 577 1935 910 +2247 2 2 8 7 659 1420 892 +2248 2 2 8 7 910 1935 344 +2249 2 2 8 7 241 2083 937 +2250 2 2 8 7 986 1608 263 +2251 2 2 8 7 1219 1318 263 +2252 2 2 8 7 350 1363 927 +2253 2 2 8 7 843 2000 1343 +2254 2 2 8 7 887 1702 384 +2255 2 2 8 7 1181 1892 686 +2256 2 2 8 7 452 1353 918 +2257 2 2 8 7 1803 1817 788 +2258 2 2 8 7 224 1956 1520 +2259 2 2 8 7 105 1118 106 +2260 2 2 8 7 71 1119 72 +2261 2 2 8 7 1607 2043 695 +2262 2 2 8 7 1279 1408 726 +2263 2 2 8 7 725 1407 1278 +2264 2 2 8 7 498 1487 926 +2265 2 2 8 7 421 1200 1000 +2266 2 2 8 7 469 1859 893 +2267 2 2 8 7 944 2085 227 +2268 2 2 8 7 1023 1921 258 +2269 2 2 8 7 927 2016 185 +2270 2 2 8 7 612 1829 1668 +2271 2 2 8 7 915 1372 662 +2272 2 2 8 7 415 1280 1137 +2273 2 2 8 7 966 1915 448 +2274 2 2 8 7 1137 1280 530 +2275 2 2 8 7 942 1623 520 +2276 2 2 8 7 437 1269 1033 +2277 2 2 8 7 148 1975 149 +2278 2 2 8 7 1379 1421 348 +2279 2 2 8 7 681 1421 1379 +2280 2 2 8 7 501 1352 1190 +2281 2 2 8 7 950 1295 177 +2282 2 2 8 7 812 1781 1096 +2283 2 2 8 7 1190 1352 567 +2284 2 2 8 7 1255 1519 268 +2285 2 2 8 7 1021 1390 327 +2286 2 2 8 7 663 1519 1255 +2287 2 2 8 7 524 1390 1021 +2288 2 2 8 7 1 1599 128 +2289 2 2 8 7 127 1599 1 +2290 2 2 8 7 3 1600 50 +2291 2 2 8 7 49 1600 3 +2292 2 2 8 7 458 1332 962 +2293 2 2 8 7 1060 1773 272 +2294 2 2 8 7 962 1332 348 +2295 2 2 8 7 952 1728 673 +2296 2 2 8 7 624 1773 1060 +2297 2 2 8 7 431 1823 1090 +2298 2 2 8 7 906 1836 225 +2299 2 2 8 7 779 1714 1127 +2300 2 2 8 7 734 1460 996 +2301 2 2 8 7 891 1701 256 +2302 2 2 8 7 371 1372 966 +2303 2 2 8 7 1106 1157 235 +2304 2 2 8 7 481 1498 942 +2305 2 2 8 7 334 1703 891 +2306 2 2 8 7 917 2071 785 +2307 2 2 8 7 894 1498 481 +2308 2 2 8 7 392 1829 1038 +2309 2 2 8 7 889 1580 563 +2310 2 2 8 7 45 1914 1067 +2311 2 2 8 7 890 1539 565 +2312 2 2 8 7 766 2060 1271 +2313 2 2 8 7 893 1859 1542 +2314 2 2 8 7 1299 1566 614 +2315 2 2 8 7 239 2044 1301 +2316 2 2 8 7 303 1756 1513 +2317 2 2 8 7 277 1633 890 +2318 2 2 8 7 352 1470 900 +2319 2 2 8 7 608 1889 1125 +2320 2 2 8 7 1024 1729 424 +2321 2 2 8 7 160 1204 1075 +2322 2 2 8 7 1075 1204 468 +2323 2 2 8 7 900 1475 352 +2324 2 2 8 7 912 2030 341 +2325 2 2 8 7 1542 1859 186 +2326 2 2 8 7 1471 1997 974 +2327 2 2 8 7 1301 2044 911 +2328 2 2 8 7 411 1197 1045 +2329 2 2 8 7 1046 1196 410 +2330 2 2 8 7 647 1914 972 +2331 2 2 8 7 339 1727 903 +2332 2 2 8 7 972 1914 44 +2333 2 2 8 7 920 1388 323 +2334 2 2 8 7 1097 1298 395 +2335 2 2 8 7 75 1147 76 +2336 2 2 8 7 101 1146 102 +2337 2 2 8 7 895 1511 328 +2338 2 2 8 7 519 1298 1097 +2339 2 2 8 7 1247 1947 582 +2340 2 2 8 7 968 1275 445 +2341 2 2 8 7 69 1927 70 +2342 2 2 8 7 107 1926 108 +2343 2 2 8 7 499 1560 893 +2344 2 2 8 7 847 1711 985 +2345 2 2 8 7 574 1499 1265 +2346 2 2 8 7 465 1830 912 +2347 2 2 8 7 539 1431 1254 +2348 2 2 8 7 904 2020 238 +2349 2 2 8 7 915 1879 202 +2350 2 2 8 7 177 1295 1081 +2351 2 2 8 7 905 1763 627 +2352 2 2 8 7 235 1481 913 +2353 2 2 8 7 1088 1670 474 +2354 2 2 8 7 1216 1924 443 +2355 2 2 8 7 1031 1900 1491 +2356 2 2 8 7 502 1231 1151 +2357 2 2 8 7 438 1736 904 +2358 2 2 8 7 226 1846 1284 +2359 2 2 8 7 443 1924 1226 +2360 2 2 8 7 1284 1846 794 +2361 2 2 8 7 433 2068 1083 +2362 2 2 8 7 1154 1762 581 +2363 2 2 8 7 339 1505 904 +2364 2 2 8 7 978 1714 318 +2365 2 2 8 7 564 1714 978 +2366 2 2 8 7 911 1838 436 +2367 2 2 8 7 912 1830 196 +2368 2 2 8 7 1290 2055 870 +2369 2 2 8 7 473 1231 1211 +2370 2 2 8 7 169 1371 1026 +2371 2 2 8 7 991 1654 198 +2372 2 2 8 7 1026 1371 508 +2373 2 2 8 7 943 1675 998 +2374 2 2 8 7 560 1654 991 +2375 2 2 8 7 1139 1289 451 +2376 2 2 8 7 322 1394 929 +2377 2 2 8 7 1741 2007 687 +2378 2 2 8 7 653 1700 1406 +2379 2 2 8 7 405 1856 1156 +2380 2 2 8 7 249 1655 1074 +2381 2 2 8 7 364 1638 936 +2382 2 2 8 7 519 1401 930 +2383 2 2 8 7 936 1638 530 +2384 2 2 8 7 120 1459 1207 +2385 2 2 8 7 1206 1458 57 +2386 2 2 8 7 656 1919 1392 +2387 2 2 8 7 317 1540 908 +2388 2 2 8 7 93 1349 94 +2389 2 2 8 7 83 1350 84 +2390 2 2 8 7 913 1481 465 +2391 2 2 8 7 1106 1381 561 +2392 2 2 8 7 89 1804 90 +2393 2 2 8 7 87 1805 88 +2394 2 2 8 7 971 1493 144 +2395 2 2 8 7 1340 1511 500 +2396 2 2 8 7 394 1521 1452 +2397 2 2 8 7 1452 1521 751 +2398 2 2 8 7 460 1626 1278 +2399 2 2 8 7 1279 1627 461 +2400 2 2 8 7 1542 1880 752 +2401 2 2 8 7 951 1418 213 +2402 2 2 8 7 909 1612 349 +2403 2 2 8 7 926 1425 498 +2404 2 2 8 7 792 2046 1480 +2405 2 2 8 7 913 2062 235 +2406 2 2 8 7 916 1515 236 +2407 2 2 8 7 911 1510 345 +2408 2 2 8 7 67 1165 68 +2409 2 2 8 7 109 1164 110 +2410 2 2 8 7 1050 1545 464 +2411 2 2 8 7 233 1245 999 +2412 2 2 8 7 250 1419 1300 +2413 2 2 8 7 198 1998 1342 +2414 2 2 8 7 991 1662 340 +2415 2 2 8 7 1067 1914 647 +2416 2 2 8 7 1011 1808 313 +2417 2 2 8 7 943 1944 654 +2418 2 2 8 7 1230 1743 163 +2419 2 2 8 7 921 1803 342 +2420 2 2 8 7 794 1434 1284 +2421 2 2 8 7 693 1743 1230 +2422 2 2 8 7 335 1966 1649 +2423 2 2 8 7 400 1978 938 +2424 2 2 8 7 939 1979 401 +2425 2 2 8 7 425 1641 1117 +2426 2 2 8 7 1117 1641 596 +2427 2 2 8 7 9 1765 10 +2428 2 2 8 7 1006 1252 245 +2429 2 2 8 7 1334 2005 670 +2430 2 2 8 7 341 1592 913 +2431 2 2 8 7 17 1268 18 +2432 2 2 8 7 991 1706 560 +2433 2 2 8 7 373 1377 989 +2434 2 2 8 7 1132 1802 406 +2435 2 2 8 7 247 1304 980 +2436 2 2 8 7 1299 1404 286 +2437 2 2 8 7 266 1778 1330 +2438 2 2 8 7 614 1404 1299 +2439 2 2 8 7 27 1598 1033 +2440 2 2 8 7 1224 1368 781 +2441 2 2 8 7 918 1649 452 +2442 2 2 8 7 485 2053 941 +2443 2 2 8 7 919 1899 253 +2444 2 2 8 7 354 1538 977 +2445 2 2 8 7 1057 1857 1636 +2446 2 2 8 7 1637 1858 1058 +2447 2 2 8 7 897 2025 1969 +2448 2 2 8 7 708 1693 922 +2449 2 2 8 7 179 1272 1185 +2450 2 2 8 7 1204 1209 515 +2451 2 2 8 7 1017 1251 176 +2452 2 2 8 7 160 1209 1204 +2453 2 2 8 7 13 1990 14 +2454 2 2 8 7 1185 1272 532 +2455 2 2 8 7 979 1363 350 +2456 2 2 8 7 261 1454 938 +2457 2 2 8 7 939 1455 262 +2458 2 2 8 7 974 1679 710 +2459 2 2 8 7 258 1921 1148 +2460 2 2 8 7 670 2005 1587 +2461 2 2 8 7 618 1486 1238 +2462 2 2 8 7 245 1252 1030 +2463 2 2 8 7 1746 1992 955 +2464 2 2 8 7 956 1991 1745 +2465 2 2 8 7 1030 1252 455 +2466 2 2 8 7 1131 1228 545 +2467 2 2 8 7 1031 1895 610 +2468 2 2 8 7 622 1513 931 +2469 2 2 8 7 283 1228 1131 +2470 2 2 8 7 305 1895 1031 +2471 2 2 8 7 251 1465 1051 +2472 2 2 8 7 1186 1246 516 +2473 2 2 8 7 1405 1684 1008 +2474 2 2 8 7 509 1288 1253 +2475 2 2 8 7 379 2087 965 +2476 2 2 8 7 1076 1620 397 +2477 2 2 8 7 965 2087 625 +2478 2 2 8 7 459 1887 959 +2479 2 2 8 7 980 1970 351 +2480 2 2 8 7 462 1854 1249 +2481 2 2 8 7 1250 1855 463 +2482 2 2 8 7 752 2077 1140 +2483 2 2 8 7 594 1970 980 +2484 2 2 8 7 1050 1235 239 +2485 2 2 8 7 1208 1406 226 +2486 2 2 8 7 1636 1856 405 +2487 2 2 8 7 992 2009 211 +2488 2 2 8 7 1254 1513 622 +2489 2 2 8 7 152 1512 935 +2490 2 2 8 7 303 1513 1254 +2491 2 2 8 7 1025 1262 399 +2492 2 2 8 7 574 1909 1499 +2493 2 2 8 7 558 1857 938 +2494 2 2 8 7 939 1858 559 +2495 2 2 8 7 377 1973 1017 +2496 2 2 8 7 207 1666 1427 +2497 2 2 8 7 938 1857 261 +2498 2 2 8 7 262 1858 939 +2499 2 2 8 7 1017 1973 632 +2500 2 2 8 7 1427 1666 782 +2501 2 2 8 7 31 1518 1158 +2502 2 2 8 7 395 1298 993 +2503 2 2 8 7 200 1675 943 +2504 2 2 8 7 1351 1981 948 +2505 2 2 8 7 1283 1898 171 +2506 2 2 8 7 453 1577 1049 +2507 2 2 8 7 238 1240 1053 +2508 2 2 8 7 790 1879 1242 +2509 2 2 8 7 1281 1818 276 +2510 2 2 8 7 1302 1683 692 +2511 2 2 8 7 266 1330 1286 +2512 2 2 8 7 1167 1655 249 +2513 2 2 8 7 511 1515 1424 +2514 2 2 8 7 935 1766 345 +2515 2 2 8 7 489 1195 1172 +2516 2 2 8 7 942 1634 244 +2517 2 2 8 7 520 1634 942 +2518 2 2 8 7 1090 1589 431 +2519 2 2 8 7 8 1243 9 +2520 2 2 8 7 1172 1195 260 +2521 2 2 8 7 1034 1958 1632 +2522 2 2 8 7 643 2041 1001 +2523 2 2 8 7 372 1646 932 +2524 2 2 8 7 1001 2041 273 +2525 2 2 8 7 255 1566 979 +2526 2 2 8 7 979 1566 528 +2527 2 2 8 7 940 1589 19 +2528 2 2 8 7 1551 1873 599 +2529 2 2 8 7 600 1874 1552 +2530 2 2 8 7 1649 1966 734 +2531 2 2 8 7 169 1878 1174 +2532 2 2 8 7 562 2080 951 +2533 2 2 8 7 648 1836 1239 +2534 2 2 8 7 528 1363 979 +2535 2 2 8 7 151 1512 152 +2536 2 2 8 7 937 1774 342 +2537 2 2 8 7 198 1585 991 +2538 2 2 8 7 638 1878 1171 +2539 2 2 8 7 215 1683 1302 +2540 2 2 8 7 1214 1273 501 +2541 2 2 8 7 116 1571 1064 +2542 2 2 8 7 1065 1570 61 +2543 2 2 8 7 991 1585 540 +2544 2 2 8 7 1212 1494 435 +2545 2 2 8 7 1051 1430 251 +2546 2 2 8 7 525 1430 1051 +2547 2 2 8 7 375 2068 963 +2548 2 2 8 7 2 1686 89 +2549 2 2 8 7 88 1686 2 +2550 2 2 8 7 1809 2092 807 +2551 2 2 8 7 1178 1702 887 +2552 2 2 8 7 74 1399 75 +2553 2 2 8 7 102 1400 103 +2554 2 2 8 7 999 1457 233 +2555 2 2 8 7 391 2032 1427 +2556 2 2 8 7 352 1991 956 +2557 2 2 8 7 543 1704 1296 +2558 2 2 8 7 1386 1612 549 +2559 2 2 8 7 185 1415 968 +2560 2 2 8 7 968 1415 473 +2561 2 2 8 7 1354 1978 649 +2562 2 2 8 7 650 1979 1355 +2563 2 2 8 7 1110 1214 450 +2564 2 2 8 7 695 1881 1220 +2565 2 2 8 7 984 2088 503 +2566 2 2 8 7 430 1271 1105 +2567 2 2 8 7 448 1915 1073 +2568 2 2 8 7 450 1948 1022 +2569 2 2 8 7 1082 1957 576 +2570 2 2 8 7 1578 1894 304 +2571 2 2 8 7 544 1442 1428 +2572 2 2 8 7 260 1334 1089 +2573 2 2 8 7 571 1660 1646 +2574 2 2 8 7 1314 1912 264 +2575 2 2 8 7 1089 1334 503 +2576 2 2 8 7 950 1554 378 +2577 2 2 8 7 103 1761 104 +2578 2 2 8 7 73 1760 74 +2579 2 2 8 7 363 1679 947 +2580 2 2 8 7 199 1467 961 +2581 2 2 8 7 757 2017 1765 +2582 2 2 8 7 1403 1867 506 +2583 2 2 8 7 213 1888 951 +2584 2 2 8 7 958 1993 442 +2585 2 2 8 7 770 1973 1217 +2586 2 2 8 7 501 2051 1214 +2587 2 2 8 7 1049 1606 777 +2588 2 2 8 7 1748 1955 271 +2589 2 2 8 7 503 1336 1111 +2590 2 2 8 7 463 1918 985 +2591 2 2 8 7 1094 1516 6 +2592 2 2 8 7 369 1839 1035 +2593 2 2 8 7 497 1658 1292 +2594 2 2 8 7 990 1395 42 +2595 2 2 8 7 1969 2025 609 +2596 2 2 8 7 1192 1233 495 +2597 2 2 8 7 504 1635 1417 +2598 2 2 8 7 507 1233 1192 +2599 2 2 8 7 26 1598 27 +2600 2 2 8 7 1378 1704 543 +2601 2 2 8 7 976 2040 246 +2602 2 2 8 7 574 1808 1011 +2603 2 2 8 7 962 1541 178 +2604 2 2 8 7 513 1409 981 +2605 2 2 8 7 434 1516 1094 +2606 2 2 8 7 136 1543 137 +2607 2 2 8 7 97 1369 98 +2608 2 2 8 7 79 1370 80 +2609 2 2 8 7 864 1800 1540 +2610 2 2 8 7 970 2079 355 +2611 2 2 8 7 1463 1581 208 +2612 2 2 8 7 592 1476 1403 +2613 2 2 8 7 258 1316 1023 +2614 2 2 8 7 741 1581 1463 +2615 2 2 8 7 406 1802 1637 +2616 2 2 8 7 1563 1784 432 +2617 2 2 8 7 130 1625 131 +2618 2 2 8 7 1221 1288 509 +2619 2 2 8 7 63 1357 64 +2620 2 2 8 7 113 1356 114 +2621 2 2 8 7 538 2044 1235 +2622 2 2 8 7 175 2013 1604 +2623 2 2 8 7 1294 1828 277 +2624 2 2 8 7 243 1327 1072 +2625 2 2 8 7 1407 2003 801 +2626 2 2 8 7 802 2004 1408 +2627 2 2 8 7 540 1662 991 +2628 2 2 8 7 1480 1740 792 +2629 2 2 8 7 15 1850 1092 +2630 2 2 8 7 225 1563 960 +2631 2 2 8 7 6 1516 7 +2632 2 2 8 7 1169 1225 248 +2633 2 2 8 7 1027 1945 1466 +2634 2 2 8 7 291 2011 1446 +2635 2 2 8 7 544 1428 1272 +2636 2 2 8 7 483 1225 1169 +2637 2 2 8 7 959 1887 370 +2638 2 2 8 7 350 1423 1203 +2639 2 2 8 7 259 1263 1179 +2640 2 2 8 7 1540 1800 493 +2641 2 2 8 7 1203 1204 515 +2642 2 2 8 7 544 1380 1316 +2643 2 2 8 7 1925 1986 247 +2644 2 2 8 7 426 1487 990 +2645 2 2 8 7 468 1204 1203 +2646 2 2 8 7 1261 1953 665 +2647 2 2 8 7 990 1487 498 +2648 2 2 8 7 106 1551 107 +2649 2 2 8 7 70 1552 71 +2650 2 2 8 7 1709 1970 594 +2651 2 2 8 7 1043 2055 611 +2652 2 2 8 7 1530 1968 1034 +2653 2 2 8 7 967 2059 823 +2654 2 2 8 7 1376 1381 535 +2655 2 2 8 7 498 1395 990 +2656 2 2 8 7 1108 1341 223 +2657 2 2 8 7 514 1341 1108 +2658 2 2 8 7 611 2058 1043 +2659 2 2 8 7 644 1962 1074 +2660 2 2 8 7 117 1752 118 +2661 2 2 8 7 59 1753 60 +2662 2 2 8 7 531 1493 971 +2663 2 2 8 7 1074 1962 384 +2664 2 2 8 7 1111 1336 161 +2665 2 2 8 7 669 1630 1195 +2666 2 2 8 7 451 1377 994 +2667 2 2 8 7 1358 2051 501 +2668 2 2 8 7 1392 1475 656 +2669 2 2 8 7 632 1973 1925 +2670 2 2 8 7 95 1249 96 +2671 2 2 8 7 81 1250 82 +2672 2 2 8 7 216 1740 1480 +2673 2 2 8 7 981 1465 251 +2674 2 2 8 7 432 1784 1089 +2675 2 2 8 7 567 1614 1190 +2676 2 2 8 7 1151 1231 259 +2677 2 2 8 7 1510 2044 538 +2678 2 2 8 7 368 2021 971 +2679 2 2 8 7 1246 1466 317 +2680 2 2 8 7 421 1331 1041 +2681 2 2 8 7 14 1850 15 +2682 2 2 8 7 455 1343 1030 +2683 2 2 8 7 1120 1280 415 +2684 2 2 8 7 282 1717 1317 +2685 2 2 8 7 672 1484 1040 +2686 2 2 8 7 1039 1483 671 +2687 2 2 8 7 1080 1337 196 +2688 2 2 8 7 404 1588 1059 +2689 2 2 8 7 490 1337 1080 +2690 2 2 8 7 280 1577 1238 +2691 2 2 8 7 830 2012 1501 +2692 2 2 8 7 783 1621 1602 +2693 2 2 8 7 996 1460 633 +2694 2 2 8 7 433 1672 963 +2695 2 2 8 7 270 1383 1323 +2696 2 2 8 7 1323 1383 592 +2697 2 2 8 7 1571 1849 1064 +2698 2 2 8 7 1065 1848 1570 +2699 2 2 8 7 1238 1577 618 +2700 2 2 8 7 508 1751 1160 +2701 2 2 8 7 1553 1868 453 +2702 2 2 8 7 1059 1588 548 +2703 2 2 8 7 430 2088 984 +2704 2 2 8 7 964 1793 281 +2705 2 2 8 7 424 1655 1167 +2706 2 2 8 7 202 1915 966 +2707 2 2 8 7 1676 2074 765 +2708 2 2 8 7 1287 2076 164 +2709 2 2 8 7 1020 1489 398 +2710 2 2 8 7 590 1820 1057 +2711 2 2 8 7 1058 1821 591 +2712 2 2 8 7 1057 1820 261 +2713 2 2 8 7 262 1821 1058 +2714 2 2 8 7 553 1620 1076 +2715 2 2 8 7 105 1905 1118 +2716 2 2 8 7 1119 1904 72 +2717 2 2 8 7 687 2007 1476 +2718 2 2 8 7 1259 1617 167 +2719 2 2 8 7 52 1266 53 +2720 2 2 8 7 124 1267 125 +2721 2 2 8 7 352 1475 1392 +2722 2 2 8 7 440 1247 1141 +2723 2 2 8 7 642 1713 1218 +2724 2 2 8 7 1010 1664 237 +2725 2 2 8 7 380 1882 1168 +2726 2 2 8 7 1009 1988 466 +2727 2 2 8 7 1082 1296 180 +2728 2 2 8 7 1404 1806 575 +2729 2 2 8 7 465 1443 1091 +2730 2 2 8 7 53 1790 54 +2731 2 2 8 7 123 1791 124 +2732 2 2 8 7 985 1918 233 +2733 2 2 8 7 350 1893 979 +2734 2 2 8 7 1001 1467 643 +2735 2 2 8 7 977 1538 494 +2736 2 2 8 7 96 1854 97 +2737 2 2 8 7 80 1855 81 +2738 2 2 8 7 1368 2082 192 +2739 2 2 8 7 1602 1621 358 +2740 2 2 8 7 899 2082 1368 +2741 2 2 8 7 46 1607 47 +2742 2 2 8 7 655 1448 1391 +2743 2 2 8 7 1391 1448 351 +2744 2 2 8 7 1218 1713 234 +2745 2 2 8 7 1097 1401 519 +2746 2 2 8 7 182 1401 1097 +2747 2 2 8 7 284 1656 1061 +2748 2 2 8 7 1148 1921 853 +2749 2 2 8 7 1061 1656 560 +2750 2 2 8 7 612 2047 1038 +2751 2 2 8 7 533 1482 1234 +2752 2 2 8 7 1032 1568 534 +2753 2 2 8 7 1144 2090 663 +2754 2 2 8 7 974 1997 162 +2755 2 2 8 7 278 1568 1032 +2756 2 2 8 7 381 1730 967 +2757 2 2 8 7 606 1726 1600 +2758 2 2 8 7 1599 1725 605 +2759 2 2 8 7 979 1567 255 +2760 2 2 8 7 92 1940 93 +2761 2 2 8 7 84 1939 85 +2762 2 2 8 7 283 1923 1228 +2763 2 2 8 7 1069 1750 578 +2764 2 2 8 7 972 1629 647 +2765 2 2 8 7 33 1750 1069 +2766 2 2 8 7 1332 1379 348 +2767 2 2 8 7 587 1379 1332 +2768 2 2 8 7 473 1871 968 +2769 2 2 8 7 1084 1312 240 +2770 2 2 8 7 576 1957 1159 +2771 2 2 8 7 971 2021 531 +2772 2 2 8 7 1070 1330 477 +2773 2 2 8 7 252 1374 1041 +2774 2 2 8 7 980 1689 247 +2775 2 2 8 7 1014 1415 185 +2776 2 2 8 7 1183 1333 588 +2777 2 2 8 7 1015 1567 515 +2778 2 2 8 7 180 1353 1082 +2779 2 2 8 7 1098 1300 446 +2780 2 2 8 7 1770 1888 213 +2781 2 2 8 7 1205 1770 213 +2782 2 2 8 7 144 1493 145 +2783 2 2 8 7 339 2002 1505 +2784 2 2 8 7 471 1432 1061 +2785 2 2 8 7 20 1589 1090 +2786 2 2 8 7 584 1964 978 +2787 2 2 8 7 1123 1495 430 +2788 2 2 8 7 213 1418 1055 +2789 2 2 8 7 1102 1995 326 +2790 2 2 8 7 176 1416 1017 +2791 2 2 8 7 1146 1709 594 +2792 2 2 8 7 595 1710 1147 +2793 2 2 8 7 480 1314 1095 +2794 2 2 8 7 1150 1430 525 +2795 2 2 8 7 101 1709 1146 +2796 2 2 8 7 1147 1710 76 +2797 2 2 8 7 1021 1647 818 +2798 2 2 8 7 300 2003 1407 +2799 2 2 8 7 1408 2004 301 +2800 2 2 8 7 1120 1289 228 +2801 2 2 8 7 1206 1626 460 +2802 2 2 8 7 461 1627 1207 +2803 2 2 8 7 85 1292 86 +2804 2 2 8 7 91 1293 92 +2805 2 2 8 7 597 1626 1206 +2806 2 2 8 7 1207 1627 598 +2807 2 2 8 7 1071 1346 480 +2808 2 2 8 7 1143 1835 447 +2809 2 2 8 7 1253 1288 248 +2810 2 2 8 7 1062 1479 254 +2811 2 2 8 7 1425 1971 279 +2812 2 2 8 7 478 1246 1186 +2813 2 2 8 7 1194 1633 691 +2814 2 2 8 7 973 1839 369 +2815 2 2 8 7 187 1579 995 +2816 2 2 8 7 995 1579 520 +2817 2 2 8 7 613 1707 976 +2818 2 2 8 7 336 1680 982 +2819 2 2 8 7 253 1346 1071 +2820 2 2 8 7 664 1673 983 +2821 2 2 8 7 835 1742 1202 +2822 2 2 8 7 736 1640 1062 +2823 2 2 8 7 1229 1943 702 +2824 2 2 8 7 298 1943 1229 +2825 2 2 8 7 408 2073 988 +2826 2 2 8 7 195 1762 1154 +2827 2 2 8 7 1028 1723 542 +2828 2 2 8 7 271 1724 1257 +2829 2 2 8 7 1257 1724 667 +2830 2 2 8 7 1531 1842 358 +2831 2 2 8 7 884 1842 1531 +2832 2 2 8 7 1179 1263 476 +2833 2 2 8 7 1018 1562 108 +2834 2 2 8 7 69 1561 1019 +2835 2 2 8 7 475 1486 1053 +2836 2 2 8 7 423 2037 986 +2837 2 2 8 7 468 1434 1075 +2838 2 2 8 7 542 1495 1123 +2839 2 2 8 7 985 1711 628 +2840 2 2 8 7 35 1315 36 +2841 2 2 8 7 1005 1494 290 +2842 2 2 8 7 271 1955 1324 +2843 2 2 8 7 1036 1481 235 +2844 2 2 8 7 19 1589 20 +2845 2 2 8 7 1161 1439 490 +2846 2 2 8 7 1114 1373 787 +2847 2 2 8 7 38 1844 39 +2848 2 2 8 7 201 1373 1114 +2849 2 2 8 7 140 1488 141 +2850 2 2 8 7 1193 1897 639 +2851 2 2 8 7 756 1736 1549 +2852 2 2 8 7 161 1336 1105 +2853 2 2 8 7 477 1456 1126 +2854 2 2 8 7 583 1778 1444 +2855 2 2 8 7 1027 2056 218 +2856 2 2 8 7 615 2056 1027 +2857 2 2 8 7 1039 1435 389 +2858 2 2 8 7 390 1436 1040 +2859 2 2 8 7 111 1325 112 +2860 2 2 8 7 65 1326 66 +2861 2 2 8 7 693 1615 1071 +2862 2 2 8 7 986 2015 1608 +2863 2 2 8 7 1248 1718 1047 +2864 2 2 8 7 799 1734 1528 +2865 2 2 8 7 1038 2047 132 +2866 2 2 8 7 469 1967 1087 +2867 2 2 8 7 1182 1410 481 +2868 2 2 8 7 264 1871 1211 +2869 2 2 8 7 1335 1650 506 +2870 2 2 8 7 1555 1903 910 +2871 2 2 8 7 405 1440 1057 +2872 2 2 8 7 1058 1441 406 +2873 2 2 8 7 223 1903 1555 +2874 2 2 8 7 678 1606 1049 +2875 2 2 8 7 679 2064 1130 +2876 2 2 8 7 368 2055 1043 +2877 2 2 8 7 1130 2064 165 +2878 2 2 8 7 1150 1485 824 +2879 2 2 8 7 1070 1594 246 +2880 2 2 8 7 784 1868 1553 +2881 2 2 8 7 1353 1957 1082 +2882 2 2 8 7 23 1338 24 +2883 2 2 8 7 1109 1727 512 +2884 2 2 8 7 1043 2058 252 +2885 2 2 8 7 579 1910 1471 +2886 2 2 8 7 326 1996 1102 +2887 2 2 8 7 1102 1996 646 +2888 2 2 8 7 1612 1701 549 +2889 2 2 8 7 636 2045 1274 +2890 2 2 8 7 1471 1910 861 +2891 2 2 8 7 1068 1453 739 +2892 2 2 8 7 1015 1716 383 +2893 2 2 8 7 867 1897 1193 +2894 2 2 8 7 1528 1734 309 +2895 2 2 8 7 1055 1418 472 +2896 2 2 8 7 196 1851 1080 +2897 2 2 8 7 1291 1375 584 +2898 2 2 8 7 1025 1500 170 +2899 2 2 8 7 989 1946 373 +2900 2 2 8 7 153 1345 154 +2901 2 2 8 7 1944 1971 654 +2902 2 2 8 7 520 1623 995 +2903 2 2 8 7 1465 1792 1051 +2904 2 2 8 7 246 2040 1070 +2905 2 2 8 7 399 1934 1402 +2906 2 2 8 7 401 1979 1311 +2907 2 2 8 7 1310 1978 400 +2908 2 2 8 7 346 1910 1128 +2909 2 2 8 7 1009 1556 236 +2910 2 2 8 7 237 1557 1010 +2911 2 2 8 7 134 1429 135 +2912 2 2 8 7 1060 1412 624 +2913 2 2 8 7 454 2009 992 +2914 2 2 8 7 759 1583 1165 +2915 2 2 8 7 1164 1582 758 +2916 2 2 8 7 1403 1476 181 +2917 2 2 8 7 178 1541 1029 +2918 2 2 8 7 1529 1888 667 +2919 2 2 8 7 1186 1757 478 +2920 2 2 8 7 1417 1635 619 +2921 2 2 8 7 1035 1506 645 +2922 2 2 8 7 1113 1780 707 +2923 2 2 8 7 1258 1411 470 +2924 2 2 8 7 221 1539 1277 +2925 2 2 8 7 135 1429 1117 +2926 2 2 8 7 1033 1598 512 +2927 2 2 8 7 1256 1799 397 +2928 2 2 8 7 504 1417 1245 +2929 2 2 8 7 1138 1883 623 +2930 2 2 8 7 1237 1401 182 +2931 2 2 8 7 168 1883 1138 +2932 2 2 8 7 1679 1922 710 +2933 2 2 8 7 1003 1614 366 +2934 2 2 8 7 1202 1376 535 +2935 2 2 8 7 288 1376 1202 +2936 2 2 8 7 522 1869 1002 +2937 2 2 8 7 370 1976 1006 +2938 2 2 8 7 1158 1518 455 +2939 2 2 8 7 1006 1976 578 +2940 2 2 8 7 1371 1751 508 +2941 2 2 8 7 482 1400 1146 +2942 2 2 8 7 1147 1399 483 +2943 2 2 8 7 1078 1440 405 +2944 2 2 8 7 406 1441 1079 +2945 2 2 8 7 42 1395 43 +2946 2 2 8 7 1640 1659 688 +2947 2 2 8 7 1095 1743 480 +2948 2 2 8 7 638 2001 999 +2949 2 2 8 7 504 1558 1227 +2950 2 2 8 7 661 1804 1686 +2951 2 2 8 7 1686 1805 661 +2952 2 2 8 7 211 1771 992 +2953 2 2 8 7 1061 1432 284 +2954 2 2 8 7 1062 1640 688 +2955 2 2 8 7 998 1675 716 +2956 2 2 8 7 998 2043 414 +2957 2 2 8 7 1275 1871 264 +2958 2 2 8 7 193 1981 1351 +2959 2 2 8 7 183 1456 1303 +2960 2 2 8 7 1303 1456 583 +2961 2 2 8 7 499 1853 1030 +2962 2 2 8 7 557 1562 1018 +2963 2 2 8 7 1019 1561 556 +2964 2 2 8 7 510 1288 1221 +2965 2 2 8 7 1549 1736 438 +2966 2 2 8 7 1205 1294 449 +2967 2 2 8 7 479 1287 1286 +2968 2 2 8 7 1029 1541 533 +2969 2 2 8 7 1034 1968 376 +2970 2 2 8 7 164 1367 1166 +2971 2 2 8 7 1286 1287 566 +2972 2 2 8 7 668 1468 1348 +2973 2 2 8 7 995 1777 551 +2974 2 2 8 7 1072 2032 391 +2975 2 2 8 7 374 1565 1051 +2976 2 2 8 7 1051 1565 525 +2977 2 2 8 7 235 1381 1106 +2978 2 2 8 7 1323 1525 270 +2979 2 2 8 7 694 2035 1258 +2980 2 2 8 7 1142 1452 540 +2981 2 2 8 7 1047 1718 589 +2982 2 2 8 7 394 1452 1142 +2983 2 2 8 7 467 1664 1010 +2984 2 2 8 7 447 1835 1277 +2985 2 2 8 7 1053 1486 238 +2986 2 2 8 7 58 1535 59 +2987 2 2 8 7 118 1534 119 +2988 2 2 8 7 1091 1830 465 +2989 2 2 8 7 444 1368 1224 +2990 2 2 8 7 1290 1531 611 +2991 2 2 8 7 1343 2000 287 +2992 2 2 8 7 1169 1470 595 +2993 2 2 8 7 1008 1684 367 +2994 2 2 8 7 290 1715 1005 +2995 2 2 8 7 402 1695 1642 +2996 2 2 8 7 1642 1695 832 +2997 2 2 8 7 95 1824 1249 +2998 2 2 8 7 1250 1825 82 +2999 2 2 8 7 1018 1699 557 +3000 2 2 8 7 556 1698 1019 +3001 2 2 8 7 354 1841 1538 +3002 2 2 8 7 764 1628 1572 +3003 2 2 8 7 654 1971 1507 +3004 2 2 8 7 1572 1628 575 +3005 2 2 8 7 149 1410 150 +3006 2 2 8 7 603 1702 1178 +3007 2 2 8 7 172 1358 1190 +3008 2 2 8 7 1004 1953 403 +3009 2 2 8 7 342 1803 1472 +3010 2 2 8 7 403 1953 1261 +3011 2 2 8 7 1001 1829 392 +3012 2 2 8 7 1002 1929 312 +3013 2 2 8 7 550 1929 1002 +3014 2 2 8 7 1164 1562 557 +3015 2 2 8 7 556 1561 1165 +3016 2 2 8 7 468 1423 1284 +3017 2 2 8 7 607 1937 1103 +3018 2 2 8 7 109 1562 1164 +3019 2 2 8 7 1165 1561 68 +3020 2 2 8 7 486 1440 1078 +3021 2 2 8 7 1079 1441 487 +3022 2 2 8 7 545 1411 1098 +3023 2 2 8 7 1103 1937 206 +3024 2 2 8 7 896 2026 1483 +3025 2 2 8 7 1484 2025 897 +3026 2 2 8 7 1472 1803 788 +3027 2 2 8 7 691 2031 1194 +3028 2 2 8 7 1004 1851 704 +3029 2 2 8 7 1483 2026 275 +3030 2 2 8 7 274 2025 1484 +3031 2 2 8 7 1194 2031 184 +3032 2 2 8 7 1142 1586 295 +3033 2 2 8 7 1021 1669 524 +3034 2 2 8 7 471 1479 1062 +3035 2 2 8 7 335 1755 1239 +3036 2 2 8 7 1378 1630 669 +3037 2 2 8 7 462 1763 1359 +3038 2 2 8 7 496 1940 1293 +3039 2 2 8 7 1292 1939 497 +3040 2 2 8 7 2015 2037 593 +3041 2 2 8 7 1391 2075 655 +3042 2 2 8 7 299 1630 1378 +3043 2 2 8 7 1112 1980 243 +3044 2 2 8 7 1647 1996 818 +3045 2 2 8 7 1687 2070 539 +3046 2 2 8 7 631 1980 1112 +3047 2 2 8 7 182 1412 1141 +3048 2 2 8 7 236 1988 1009 +3049 2 2 8 7 327 1647 1021 +3050 2 2 8 7 1228 1411 545 +3051 2 2 8 7 470 1411 1228 +3052 2 2 8 7 1079 1928 174 +3053 2 2 8 7 293 1670 1088 +3054 2 2 8 7 1121 1880 186 +3055 2 2 8 7 528 2016 1363 +3056 2 2 8 7 1071 1615 735 +3057 2 2 8 7 331 1397 1384 +3058 2 2 8 7 1384 1397 589 +3059 2 2 8 7 1199 1896 658 +3060 2 2 8 7 165 1896 1199 +3061 2 2 8 7 702 1660 1229 +3062 2 2 8 7 491 1790 1266 +3063 2 2 8 7 1267 1791 492 +3064 2 2 8 7 592 1403 1323 +3065 2 2 8 7 1091 1443 346 +3066 2 2 8 7 242 1502 1439 +3067 2 2 8 7 239 1545 1050 +3068 2 2 8 7 1447 1889 527 +3069 2 2 8 7 131 1625 1038 +3070 2 2 8 7 711 1788 1321 +3071 2 2 8 7 1322 1789 712 +3072 2 2 8 7 506 1650 1525 +3073 2 2 8 7 1166 1367 495 +3074 2 2 8 7 460 1458 1206 +3075 2 2 8 7 1207 1459 461 +3076 2 2 8 7 174 1845 1313 +3077 2 2 8 7 453 1868 1577 +3078 2 2 8 7 1049 1577 280 +3079 2 2 8 7 986 2037 2015 +3080 2 2 8 7 75 1399 1147 +3081 2 2 8 7 1146 1400 102 +3082 2 2 8 7 1387 1579 803 +3083 2 2 8 7 1691 1809 422 +3084 2 2 8 7 1042 1869 522 +3085 2 2 8 7 1107 1597 422 +3086 2 2 8 7 907 1809 1691 +3087 2 2 8 7 1501 2012 292 +3088 2 2 8 7 1180 1553 453 +3089 2 2 8 7 1096 1961 385 +3090 2 2 8 7 1136 2053 485 +3091 2 2 8 7 623 1688 1138 +3092 2 2 8 7 1187 1389 476 +3093 2 2 8 7 315 1658 1104 +3094 2 2 8 7 1137 1693 415 +3095 2 2 8 7 385 1961 1103 +3096 2 2 8 7 521 1817 1300 +3097 2 2 8 7 108 1562 109 +3098 2 2 8 7 68 1561 69 +3099 2 2 8 7 1190 1358 501 +3100 2 2 8 7 488 1930 1116 +3101 2 2 8 7 586 1866 1036 +3102 2 2 8 7 1449 2016 528 +3103 2 2 8 7 364 1728 1029 +3104 2 2 8 7 1113 1431 433 +3105 2 2 8 7 1027 1744 615 +3106 2 2 8 7 1160 1759 456 +3107 2 2 8 7 1090 1823 21 +3108 2 2 8 7 242 1439 1161 +3109 2 2 8 7 569 1758 1092 +3110 2 2 8 7 490 1439 1324 +3111 2 2 8 7 1018 1926 599 +3112 2 2 8 7 600 1927 1019 +3113 2 2 8 7 531 2021 1043 +3114 2 2 8 7 247 1986 1304 +3115 2 2 8 7 926 1487 1241 +3116 2 2 8 7 1139 2033 1289 +3117 2 2 8 7 495 1659 1192 +3118 2 2 8 7 1099 2049 418 +3119 2 2 8 7 419 2050 1100 +3120 2 2 8 7 1107 1920 494 +3121 2 2 8 7 1437 1781 580 +3122 2 2 8 7 376 1958 1034 +3123 2 2 8 7 289 1833 1192 +3124 2 2 8 7 442 1921 1023 +3125 2 2 8 7 1024 1949 157 +3126 2 2 8 7 1026 1878 169 +3127 2 2 8 7 484 1416 1210 +3128 2 2 8 7 796 1951 1025 +3129 2 2 8 7 1030 1853 245 +3130 2 2 8 7 218 1945 1027 +3131 2 2 8 7 783 1602 1088 +3132 2 2 8 7 478 1757 1344 +3133 2 2 8 7 610 1900 1031 +3134 2 2 8 7 1439 1502 616 +3135 2 2 8 7 534 1865 1032 +3136 2 2 8 7 1057 1636 405 +3137 2 2 8 7 406 1637 1058 +3138 2 2 8 7 223 1555 1108 +3139 2 2 8 7 1108 1555 534 +3140 2 2 8 7 21 1823 22 +3141 2 2 8 7 338 1648 1428 +3142 2 2 8 7 1191 1944 943 +3143 2 2 8 7 1296 1536 543 +3144 2 2 8 7 1126 1456 183 +3145 2 2 8 7 1510 1932 345 +3146 2 2 8 7 903 1727 1109 +3147 2 2 8 7 477 1594 1070 +3148 2 2 8 7 22 1823 1037 +3149 2 2 8 7 1155 1859 469 +3150 2 2 8 7 1597 1691 422 +3151 2 2 8 7 897 1969 1305 +3152 2 2 8 7 1067 1607 46 +3153 2 2 8 7 1581 1665 208 +3154 2 2 8 7 745 1769 1477 +3155 2 2 8 7 1478 1768 744 +3156 2 2 8 7 1477 1769 377 +3157 2 2 8 7 378 1768 1478 +3158 2 2 8 7 1227 1635 504 +3159 2 2 8 7 1044 2035 374 +3160 2 2 8 7 190 1869 1042 +3161 2 2 8 7 1690 1799 554 +3162 2 2 8 7 876 1799 1690 +3163 2 2 8 7 512 1598 1109 +3164 2 2 8 7 1043 2021 368 +3165 2 2 8 7 1199 1580 165 +3166 2 2 8 7 324 1744 1344 +3167 2 2 8 7 563 1580 1199 +3168 2 2 8 7 512 1727 1285 +3169 2 2 8 7 289 1659 1640 +3170 2 2 8 7 1413 1817 521 +3171 2 2 8 7 634 1992 1746 +3172 2 2 8 7 1745 1991 635 +3173 2 2 8 7 770 1986 1925 +3174 2 2 8 7 1485 1845 174 +3175 2 2 8 7 1187 2074 408 +3176 2 2 8 7 156 1862 1094 +3177 2 2 8 7 1048 2087 379 +3178 2 2 8 7 1338 2002 903 +3179 2 2 8 7 29 1639 30 +3180 2 2 8 7 805 1382 1359 +3181 2 2 8 7 1300 1419 521 +3182 2 2 8 7 1657 1687 361 +3183 2 2 8 7 150 1410 1182 +3184 2 2 8 7 795 1687 1657 +3185 2 2 8 7 783 2058 1621 +3186 2 2 8 7 39 1844 1347 +3187 2 2 8 7 1460 1795 201 +3188 2 2 8 7 536 1318 1317 +3189 2 2 8 7 1317 1318 537 +3190 2 2 8 7 1051 1792 374 +3191 2 2 8 7 734 1795 1460 +3192 2 2 8 7 788 1917 1472 +3193 2 2 8 7 540 1586 1142 +3194 2 2 8 7 1130 1593 679 +3195 2 2 8 7 755 1494 1212 +3196 2 2 8 7 141 1488 1133 +3197 2 2 8 7 521 1419 1184 +3198 2 2 8 7 214 1941 1047 +3199 2 2 8 7 1088 1602 658 +3200 2 2 8 7 1483 1576 671 +3201 2 2 8 7 672 1575 1484 +3202 2 2 8 7 275 1576 1483 +3203 2 2 8 7 1484 1575 274 +3204 2 2 8 7 640 1554 1253 +3205 2 2 8 7 1074 1655 644 +3206 2 2 8 7 1780 2008 707 +3207 2 2 8 7 813 1797 1104 +3208 2 2 8 7 484 1477 1416 +3209 2 2 8 7 155 1862 156 +3210 2 2 8 7 1109 1598 26 +3211 2 2 8 7 578 1750 1158 +3212 2 2 8 7 1469 1768 378 +3213 2 2 8 7 1188 1663 188 +3214 2 2 8 7 731 1768 1469 +3215 2 2 8 7 10 1530 11 +3216 2 2 8 7 1158 1750 32 +3217 2 2 8 7 935 1932 1345 +3218 2 2 8 7 1695 1712 566 +3219 2 2 8 7 653 1406 1208 +3220 2 2 8 7 1308 1508 652 +3221 2 2 8 7 552 1508 1308 +3222 2 2 8 7 39 2090 40 +3223 2 2 8 7 646 1996 1647 +3224 2 2 8 7 1104 1797 790 +3225 2 2 8 7 607 1961 1911 +3226 2 2 8 7 1052 1989 219 +3227 2 2 8 7 321 1977 1526 +3228 2 2 8 7 1526 1977 857 +3229 2 2 8 7 525 1485 1150 +3230 2 2 8 7 509 1731 1221 +3231 2 2 8 7 449 1770 1205 +3232 2 2 8 7 1110 1946 989 +3233 2 2 8 7 1551 1926 107 +3234 2 2 8 7 70 1927 1552 +3235 2 2 8 7 1238 1486 475 +3236 2 2 8 7 751 1662 1452 +3237 2 2 8 7 138 1611 139 +3238 2 2 8 7 534 1568 1108 +3239 2 2 8 7 247 1689 1101 +3240 2 2 8 7 1316 2024 544 +3241 2 2 8 7 1807 2036 197 +3242 2 2 8 7 1320 1432 471 +3243 2 2 8 7 1201 1782 194 +3244 2 2 8 7 61 1570 62 +3245 2 2 8 7 115 1571 116 +3246 2 2 8 7 1055 2039 213 +3247 2 2 8 7 1064 1752 117 +3248 2 2 8 7 60 1753 1065 +3249 2 2 8 7 863 1934 1262 +3250 2 2 8 7 607 1911 1852 +3251 2 2 8 7 243 1980 1054 +3252 2 2 8 7 1203 1423 468 +3253 2 2 8 7 494 1597 1107 +3254 2 2 8 7 1118 1551 106 +3255 2 2 8 7 71 1552 1119 +3256 2 2 8 7 1059 1890 230 +3257 2 2 8 7 1240 2020 526 +3258 2 2 8 7 656 1475 1201 +3259 2 2 8 7 1056 1862 155 +3260 2 2 8 7 318 1835 1143 +3261 2 2 8 7 266 1712 1077 +3262 2 2 8 7 514 1514 1149 +3263 2 2 8 7 687 2018 1741 +3264 2 2 8 7 1135 1775 517 +3265 2 2 8 7 518 1776 1136 +3266 2 2 8 7 312 1550 1184 +3267 2 2 8 7 1171 2001 638 +3268 2 2 8 7 1661 1912 621 +3269 2 2 8 7 448 2001 1171 +3270 2 2 8 7 555 1617 1259 +3271 2 2 8 7 685 1432 1320 +3272 2 2 8 7 795 2070 1687 +3273 2 2 8 7 1428 1442 338 +3274 2 2 8 7 316 1759 1160 +3275 2 2 8 7 285 1593 1116 +3276 2 2 8 7 572 1849 1571 +3277 2 2 8 7 1570 1848 573 +3278 2 2 8 7 1064 1849 401 +3279 2 2 8 7 400 1848 1065 +3280 2 2 8 7 1262 1951 328 +3281 2 2 8 7 136 2038 1543 +3282 2 2 8 7 1140 1853 499 +3283 2 2 8 7 1104 1658 497 +3284 2 2 8 7 436 1838 1536 +3285 2 2 8 7 1536 1838 789 +3286 2 2 8 7 648 1784 1563 +3287 2 2 8 7 723 1630 1622 +3288 2 2 8 7 12 1632 13 +3289 2 2 8 7 493 1375 1291 +3290 2 2 8 7 1622 1630 299 +3291 2 2 8 7 1366 1690 443 +3292 2 2 8 7 876 1690 1366 +3293 2 2 8 7 1464 1482 533 +3294 2 2 8 7 1514 1568 278 +3295 2 2 8 7 613 1482 1464 +3296 2 2 8 7 1101 1689 527 +3297 2 2 8 7 1092 1758 15 +3298 2 2 8 7 1421 1464 348 +3299 2 2 8 7 227 1780 1083 +3300 2 2 8 7 613 1464 1421 +3301 2 2 8 7 519 1610 1124 +3302 2 2 8 7 184 2031 1066 +3303 2 2 8 7 578 1976 1069 +3304 2 2 8 7 1257 1770 449 +3305 2 2 8 7 1070 2040 479 +3306 2 2 8 7 523 1740 1265 +3307 2 2 8 7 163 1743 1095 +3308 2 2 8 7 1491 1900 189 +3309 2 2 8 7 1422 1574 620 +3310 2 2 8 7 1278 1407 460 +3311 2 2 8 7 461 1408 1279 +3312 2 2 8 7 1797 1879 790 +3313 2 2 8 7 1294 1987 449 +3314 2 2 8 7 1101 1720 439 +3315 2 2 8 7 562 1684 1405 +3316 2 2 8 7 683 1691 1597 +3317 2 2 8 7 1367 1659 495 +3318 2 2 8 7 545 1665 1131 +3319 2 2 8 7 1274 1613 160 +3320 2 2 8 7 722 1681 1588 +3321 2 2 8 7 577 1613 1274 +3322 2 2 8 7 1588 1681 548 +3323 2 2 8 7 1295 1478 485 +3324 2 2 8 7 544 2024 1442 +3325 2 2 8 7 178 1806 1093 +3326 2 2 8 7 1075 1994 636 +3327 2 2 8 7 1124 2086 241 +3328 2 2 8 7 625 2086 1124 +3329 2 2 8 7 487 1928 1079 +3330 2 2 8 7 532 1549 1185 +3331 2 2 8 7 128 1785 129 +3332 2 2 8 7 229 1972 1076 +3333 2 2 8 7 1538 1841 683 +3334 2 2 8 7 1310 2003 300 +3335 2 2 8 7 301 2004 1311 +3336 2 2 8 7 696 2003 1310 +3337 2 2 8 7 1311 2004 697 +3338 2 2 8 7 1311 1979 650 +3339 2 2 8 7 649 1978 1310 +3340 2 2 8 7 1473 1678 569 +3341 2 2 8 7 1086 1884 735 +3342 2 2 8 7 736 1885 1085 +3343 2 2 8 7 1274 1935 577 +3344 2 2 8 7 100 1709 101 +3345 2 2 8 7 76 1710 77 +3346 2 2 8 7 678 1678 1473 +3347 2 2 8 7 1115 1692 211 +3348 2 2 8 7 1096 1781 265 +3349 2 2 8 7 1272 1428 532 +3350 2 2 8 7 378 1554 1469 +3351 2 2 8 7 555 1685 1616 +3352 2 2 8 7 287 1560 1343 +3353 2 2 8 7 865 1907 1360 +3354 2 2 8 7 1361 1908 866 +3355 2 2 8 7 1469 1554 640 +3356 2 2 8 7 132 2047 133 +3357 2 2 8 7 557 1582 1164 +3358 2 2 8 7 1165 1583 556 +3359 2 2 8 7 456 1759 1351 +3360 2 2 8 7 1087 1967 287 +3361 2 2 8 7 1504 1999 315 +3362 2 2 8 7 817 1999 1504 +3363 2 2 8 7 483 1501 1225 +3364 2 2 8 7 261 1820 1099 +3365 2 2 8 7 1100 1821 262 +3366 2 2 8 7 571 1489 1229 +3367 2 2 8 7 363 1922 1679 +3368 2 2 8 7 78 1745 79 +3369 2 2 8 7 98 1746 99 +3370 2 2 8 7 617 2007 1741 +3371 2 2 8 7 439 1811 1101 +3372 2 2 8 7 15 1758 16 +3373 2 2 8 7 1189 1717 546 +3374 2 2 8 7 1184 1550 521 +3375 2 2 8 7 1185 1549 438 +3376 2 2 8 7 1202 1742 714 +3377 2 2 8 7 1359 1382 462 +3378 2 2 8 7 32 1750 33 +3379 2 2 8 7 1323 1403 506 +3380 2 2 8 7 478 1466 1246 +3381 2 2 8 7 529 1398 1397 +3382 2 2 8 7 1397 1398 589 +3383 2 2 8 7 213 2039 1205 +3384 2 2 8 7 1205 2039 660 +3385 2 2 8 7 1284 1434 468 +3386 2 2 8 7 48 1816 49 +3387 2 2 8 7 1203 1893 350 +3388 2 2 8 7 1444 1644 583 +3389 2 2 8 7 1127 1714 564 +3390 2 2 8 7 616 1724 1324 +3391 2 2 8 7 1241 1487 426 +3392 2 2 8 7 1324 1724 271 +3393 2 2 8 7 1327 2032 1072 +3394 2 2 8 7 188 1969 1188 +3395 2 2 8 7 1188 1969 609 +3396 2 2 8 7 561 1880 1121 +3397 2 2 8 7 1339 2037 423 +3398 2 2 8 7 1199 1842 563 +3399 2 2 8 7 722 1942 1681 +3400 2 2 8 7 342 1472 1264 +3401 2 2 8 7 1206 1827 597 +3402 2 2 8 7 598 1826 1207 +3403 2 2 8 7 56 1827 1206 +3404 2 2 8 7 1207 1826 121 +3405 2 2 8 7 1565 1845 525 +3406 2 2 8 7 430 1495 1271 +3407 2 2 8 7 1271 1495 766 +3408 2 2 8 7 1248 1668 273 +3409 2 2 8 7 1188 1578 511 +3410 2 2 8 7 737 1668 1248 +3411 2 2 8 7 94 1824 95 +3412 2 2 8 7 82 1825 83 +3413 2 2 8 7 121 1826 122 +3414 2 2 8 7 55 1827 56 +3415 2 2 8 7 1107 1911 265 +3416 2 2 8 7 1264 1472 585 +3417 2 2 8 7 1103 1961 607 +3418 2 2 8 7 1097 2057 182 +3419 2 2 8 7 532 1648 1385 +3420 2 2 8 7 1163 1749 804 +3421 2 2 8 7 564 1519 1347 +3422 2 2 8 7 1347 1519 663 +3423 2 2 8 7 265 1920 1107 +3424 2 2 8 7 877 1952 1349 +3425 2 2 8 7 312 2091 1550 +3426 2 2 8 7 1105 1960 746 +3427 2 2 8 7 592 1735 1476 +3428 2 2 8 7 570 1792 1465 +3429 2 2 8 7 1775 1884 517 +3430 2 2 8 7 518 1885 1776 +3431 2 2 8 7 1476 1735 687 +3432 2 2 8 7 1574 1843 620 +3433 2 2 8 7 314 1749 1134 +3434 2 2 8 7 147 2089 148 +3435 2 2 8 7 1310 1863 649 +3436 2 2 8 7 650 1864 1311 +3437 2 2 8 7 300 1863 1310 +3438 2 2 8 7 1311 1864 301 +3439 2 2 8 7 1283 1687 539 +3440 2 2 8 7 737 1694 1668 +3441 2 2 8 7 1668 1694 612 +3442 2 2 8 7 1422 1603 330 +3443 2 2 8 7 72 1904 73 +3444 2 2 8 7 104 1905 105 +3445 2 2 8 7 1299 1643 528 +3446 2 2 8 7 620 1603 1422 +3447 2 2 8 7 1265 1499 523 +3448 2 2 8 7 267 1947 1247 +3449 2 2 8 7 44 1914 45 +3450 2 2 8 7 1324 1439 616 +3451 2 2 8 7 180 1704 1461 +3452 2 2 8 7 1221 1936 510 +3453 2 2 8 7 1192 1833 507 +3454 2 2 8 7 842 1664 1438 +3455 2 2 8 7 1461 1704 669 +3456 2 2 8 7 1438 1664 467 +3457 2 2 8 7 253 1775 1135 +3458 2 2 8 7 1136 1776 254 +3459 2 2 8 7 564 1844 1127 +3460 2 2 8 7 1125 1818 608 +3461 2 2 8 7 1127 1844 38 +3462 2 2 8 7 849 1946 1110 +3463 2 2 8 7 1159 1957 452 +3464 2 2 8 7 489 1755 1461 +3465 2 2 8 7 712 1802 1132 +3466 2 2 8 7 1189 1666 207 +3467 2 2 8 7 546 1666 1189 +3468 2 2 8 7 1601 2031 691 +3469 2 2 8 7 279 1629 1425 +3470 2 2 8 7 1216 1652 306 +3471 2 2 8 7 1242 1879 915 +3472 2 2 8 7 1910 1983 861 +3473 2 2 8 7 306 1924 1216 +3474 2 2 8 7 688 1659 1367 +3475 2 2 8 7 1116 1930 285 +3476 2 2 8 7 1426 1731 509 +3477 2 2 8 7 1558 1919 1227 +3478 2 2 8 7 1112 2006 631 +3479 2 2 8 7 526 2020 1505 +3480 2 2 8 7 1375 1964 584 +3481 2 2 8 7 511 1663 1188 +3482 2 2 8 7 1620 1674 703 +3483 2 2 8 7 553 1674 1620 +3484 2 2 8 7 202 1879 1797 +3485 2 2 8 7 1244 1653 586 +3486 2 2 8 7 162 1653 1244 +3487 2 2 8 7 1192 1659 289 +3488 2 2 8 7 1160 1751 316 +3489 2 2 8 7 276 1818 1499 +3490 2 2 8 7 585 1917 1730 +3491 2 2 8 7 1370 1745 635 +3492 2 2 8 7 634 1746 1369 +3493 2 2 8 7 79 1745 1370 +3494 2 2 8 7 1369 1746 98 +3495 2 2 8 7 596 2038 1117 +3496 2 2 8 7 756 1549 1385 +3497 2 2 8 7 689 2089 1200 +3498 2 2 8 7 1867 2073 602 +3499 2 2 8 7 988 2073 1867 +3500 2 2 8 7 1451 1740 523 +3501 2 2 8 7 1653 1997 861 +3502 2 2 8 7 162 1997 1653 +3503 2 2 8 7 1222 1665 545 +3504 2 2 8 7 951 2080 1418 +3505 2 2 8 7 728 2000 1639 +3506 2 2 8 7 1639 2000 843 +3507 2 2 8 7 1348 1468 500 +3508 2 2 8 7 551 1777 1175 +3509 2 2 8 7 527 1448 1447 +3510 2 2 8 7 1447 1448 655 +3511 2 2 8 7 1434 1994 1075 +3512 2 2 8 7 672 1874 1575 +3513 2 2 8 7 1576 1873 671 +3514 2 2 8 7 554 1652 1216 +3515 2 2 8 7 194 1635 1227 +3516 2 2 8 7 1674 1913 703 +3517 2 2 8 7 1550 2091 814 +3518 2 2 8 7 657 1955 1748 +3519 2 2 8 7 1538 1597 494 +3520 2 2 8 7 694 1845 1565 +3521 2 2 8 7 683 1597 1538 +3522 2 2 8 7 1384 1767 331 +3523 2 2 8 7 643 1767 1384 +3524 2 2 8 7 1156 1856 711 +3525 2 2 8 7 276 1909 1145 +3526 2 2 8 7 1352 2027 321 +3527 2 2 8 7 208 1665 1222 +3528 2 2 8 7 1433 1903 768 +3529 2 2 8 7 1175 1777 294 +3530 2 2 8 7 321 1526 1352 +3531 2 2 8 7 1352 1526 567 +3532 2 2 8 7 1230 1715 693 +3533 2 2 8 7 1172 1784 648 +3534 2 2 8 7 477 1778 1456 +3535 2 2 8 7 1216 1690 554 +3536 2 2 8 7 443 1690 1216 +3537 2 2 8 7 518 1590 1436 +3538 2 2 8 7 1435 1591 517 +3539 2 2 8 7 449 1987 1138 +3540 2 2 8 7 1229 1660 571 +3541 2 2 8 7 254 2053 1136 +3542 2 2 8 7 766 2036 1807 +3543 2 2 8 7 286 1643 1299 +3544 2 2 8 7 1779 1837 314 +3545 2 2 8 7 840 1837 1779 +3546 2 2 8 7 1181 1785 605 +3547 2 2 8 7 129 1785 1181 +3548 2 2 8 7 166 1757 1186 +3549 2 2 8 7 1232 1669 195 +3550 2 2 8 7 659 1754 1420 +3551 2 2 8 7 677 1716 1209 +3552 2 2 8 7 1420 1754 310 +3553 2 2 8 7 506 1525 1323 +3554 2 2 8 7 1224 1685 444 +3555 2 2 8 7 503 2088 1336 +3556 2 2 8 7 774 2033 1139 +3557 2 2 8 7 835 1883 1742 +3558 2 2 8 7 1742 1883 168 +3559 2 2 8 7 667 1888 1770 +3560 2 2 8 7 1522 1771 680 +3561 2 2 8 7 1176 1929 550 +3562 2 2 8 7 465 1866 1443 +3563 2 2 8 7 1140 2077 705 +3564 2 2 8 7 546 1717 1321 +3565 2 2 8 7 1219 1832 825 +3566 2 2 8 7 789 1677 1536 +3567 2 2 8 7 346 1983 1910 +3568 2 2 8 7 139 1611 1308 +3569 2 2 8 7 528 1566 1299 +3570 2 2 8 7 166 1651 1256 +3571 2 2 8 7 197 2036 1319 +3572 2 2 8 7 1347 2090 39 +3573 2 2 8 7 528 1643 1449 +3574 2 2 8 7 184 1787 1194 +3575 2 2 8 7 1256 1651 554 +3576 2 2 8 7 1200 2089 147 +3577 2 2 8 7 1676 1814 203 +3578 2 2 8 7 1221 1731 320 +3579 2 2 8 7 765 1814 1676 +3580 2 2 8 7 1681 1942 199 +3581 2 2 8 7 510 1782 1201 +3582 2 2 8 7 693 1715 1615 +3583 2 2 8 7 1615 1715 290 +3584 2 2 8 7 1495 2036 766 +3585 2 2 8 7 568 1584 1527 +3586 2 2 8 7 542 2036 1495 +3587 2 2 8 7 515 1893 1203 +3588 2 2 8 7 605 1892 1181 +3589 2 2 8 7 1527 1584 633 +3590 2 2 8 7 286 1783 1643 +3591 2 2 8 7 627 1824 1349 +3592 2 2 8 7 1350 1825 628 +3593 2 2 8 7 1349 1824 94 +3594 2 2 8 7 83 1825 1350 +3595 2 2 8 7 320 1936 1221 +3596 2 2 8 7 1271 1960 1105 +3597 2 2 8 7 606 1816 1220 +3598 2 2 8 7 236 1556 1364 +3599 2 2 8 7 1365 1557 237 +3600 2 2 8 7 1364 1556 590 +3601 2 2 8 7 591 1557 1365 +3602 2 2 8 7 1802 1876 559 +3603 2 2 8 7 620 1843 1564 +3604 2 2 8 7 1564 1843 721 +3605 2 2 8 7 1582 1895 305 +3606 2 2 8 7 304 1894 1583 +3607 2 2 8 7 253 1899 1346 +3608 2 2 8 7 273 2041 1718 +3609 2 2 8 7 1385 1549 532 +3610 2 2 8 7 1257 1688 271 +3611 2 2 8 7 680 1773 1522 +3612 2 2 8 7 238 2020 1240 +3613 2 2 8 7 1522 1773 624 +3614 2 2 8 7 735 1884 1775 +3615 2 2 8 7 1776 1885 736 +3616 2 2 8 7 1308 1611 552 +3617 2 2 8 7 632 1925 1811 +3618 2 2 8 7 490 1955 1337 +3619 2 2 8 7 1337 1955 657 +3620 2 2 8 7 1530 1765 568 +3621 2 2 8 7 273 1718 1248 +3622 2 2 8 7 383 1716 1569 +3623 2 2 8 7 1569 1716 677 +3624 2 2 8 7 1654 1656 681 +3625 2 2 8 7 560 1656 1654 +3626 2 2 8 7 1735 2034 330 +3627 2 2 8 7 1427 2032 629 +3628 2 2 8 7 1632 1958 580 +3629 2 2 8 7 249 1650 1335 +3630 2 2 8 7 1211 1871 473 +3631 2 2 8 7 514 1595 1341 +3632 2 2 8 7 1490 1491 836 +3633 2 2 8 7 1220 1816 48 +3634 2 2 8 7 1291 1787 184 +3635 2 2 8 7 404 2054 1259 +3636 2 2 8 7 562 1645 1307 +3637 2 2 8 7 505 1491 1490 +3638 2 2 8 7 584 1787 1291 +3639 2 2 8 7 1307 1645 325 +3640 2 2 8 7 1328 1698 556 +3641 2 2 8 7 557 1699 1329 +3642 2 2 8 7 279 1944 1191 +3643 2 2 8 7 1239 1755 489 +3644 2 2 8 7 748 1832 1219 +3645 2 2 8 7 680 1692 1309 +3646 2 2 8 7 344 2045 1177 +3647 2 2 8 7 517 1884 1435 +3648 2 2 8 7 1436 1885 518 +3649 2 2 8 7 1344 1757 822 +3650 2 2 8 7 968 1871 1275 +3651 2 2 8 7 1603 2018 687 +3652 2 2 8 7 1608 2015 524 +3653 2 2 8 7 687 1735 1603 +3654 2 2 8 7 1603 1735 330 +3655 2 2 8 7 1548 1783 626 +3656 2 2 8 7 684 1783 1548 +3657 2 2 8 7 1220 1881 606 +3658 2 2 8 7 1523 1758 569 +3659 2 2 8 7 1529 1724 616 +3660 2 2 8 7 1970 1992 351 +3661 2 2 8 7 955 1992 1970 +3662 2 2 8 7 667 1724 1529 +3663 2 2 8 7 568 2017 1584 +3664 2 2 8 7 200 1913 1674 +3665 2 2 8 7 1896 2064 732 +3666 2 2 8 7 241 2086 2083 +3667 2 2 8 7 2083 2086 1048 +3668 2 2 8 7 1286 1712 266 +3669 2 2 8 7 747 1586 1585 +3670 2 2 8 7 397 1620 1596 +3671 2 2 8 7 1265 1740 216 +3672 2 2 8 7 1398 1965 214 +3673 2 2 8 7 1596 1620 703 +3674 2 2 8 7 1585 1586 540 +3675 2 2 8 7 313 1994 1434 +3676 2 2 8 7 566 1712 1286 +3677 2 2 8 7 558 1875 1856 +3678 2 2 8 7 1301 1747 239 +3679 2 2 8 7 576 1747 1301 +3680 2 2 8 7 667 1770 1257 +3681 2 2 8 7 345 1766 1333 +3682 2 2 8 7 520 1579 1387 +3683 2 2 8 7 1285 1727 339 +3684 2 2 8 7 1333 1766 588 +3685 2 2 8 7 227 2008 1780 +3686 2 2 8 7 1296 1704 180 +3687 2 2 8 7 1643 1783 684 +3688 2 2 8 7 1354 1875 558 +3689 2 2 8 7 559 1876 1355 +3690 2 2 8 7 1741 2018 281 +3691 2 2 8 7 554 1799 1256 +3692 2 2 8 7 793 1751 1371 +3693 2 2 8 7 288 1813 1376 +3694 2 2 8 7 1226 1924 780 +3695 2 2 8 7 1577 1868 618 +3696 2 2 8 7 1227 1919 656 +3697 2 2 8 7 362 1948 1812 +3698 2 2 8 7 1812 1948 856 +3699 2 2 8 7 1289 2033 228 +3700 2 2 8 7 376 1968 1527 +3701 2 2 8 7 1346 1912 480 +3702 2 2 8 7 1265 1810 574 +3703 2 2 8 7 216 1810 1265 +3704 2 2 8 7 1025 1951 1262 +3705 2 2 8 7 1217 1973 377 +3706 2 2 8 7 1266 1790 53 +3707 2 2 8 7 124 1791 1267 +3708 2 2 8 7 1228 1923 470 +3709 2 2 8 7 550 1574 1422 +3710 2 2 8 7 158 1798 1339 +3711 2 2 8 7 573 1848 1454 +3712 2 2 8 7 1455 1849 572 +3713 2 2 8 7 1339 1798 593 +3714 2 2 8 7 1820 2049 1099 +3715 2 2 8 7 1100 2050 1821 +3716 2 2 8 7 585 1906 1264 +3717 2 2 8 7 1264 1906 454 +3718 2 2 8 7 1335 1867 602 +3719 2 2 8 7 506 1867 1335 +3720 2 2 8 7 1249 1854 96 +3721 2 2 8 7 81 1855 1250 +3722 2 2 8 7 1537 1588 404 +3723 2 2 8 7 722 1588 1537 +3724 2 2 8 7 621 1912 1346 +3725 2 2 8 7 862 1645 1405 +3726 2 2 8 7 286 2042 1783 +3727 2 2 8 7 1350 2048 878 +3728 2 2 8 7 274 1698 1328 +3729 2 2 8 7 1329 1699 275 +3730 2 2 8 7 529 1965 1398 +3731 2 2 8 7 1321 1717 282 +3732 2 2 8 7 1361 1826 598 +3733 2 2 8 7 597 1827 1360 +3734 2 2 8 7 122 1826 1361 +3735 2 2 8 7 1360 1827 55 +3736 2 2 8 7 472 2080 1307 +3737 2 2 8 7 542 1723 1319 +3738 2 2 8 7 765 2074 1213 +3739 2 2 8 7 1214 2051 450 +3740 2 2 8 7 575 1628 1404 +3741 2 2 8 7 1404 1628 286 +3742 2 2 8 7 622 1898 1254 +3743 2 2 8 7 539 2070 1431 +3744 2 2 8 7 324 1764 1507 +3745 2 2 8 7 1507 1764 654 +3746 2 2 8 7 358 1621 1531 +3747 2 2 8 7 1277 1835 868 +3748 2 2 8 7 1531 1621 611 +3749 2 2 8 7 1342 1998 587 +3750 2 2 8 7 220 1861 1282 +3751 2 2 8 7 856 2051 1358 +3752 2 2 8 7 1282 1861 579 +3753 2 2 8 7 1405 1645 562 +3754 2 2 8 7 1381 2062 535 +3755 2 2 8 7 820 1731 1426 +3756 2 2 8 7 1390 2015 593 +3757 2 2 8 7 2024 2069 810 +3758 2 2 8 7 206 2029 1606 +3759 2 2 8 7 798 1733 1369 +3760 2 2 8 7 1370 1734 799 +3761 2 2 8 7 1628 2042 286 +3762 2 2 8 7 1433 1671 577 +3763 2 2 8 7 1606 2029 777 +3764 2 2 8 7 580 1990 1632 +3765 2 2 8 7 1666 1667 782 +3766 2 2 8 7 546 1667 1666 +3767 2 2 8 7 507 1833 1462 +3768 2 2 8 7 596 1837 1543 +3769 2 2 8 7 1543 1837 840 +3770 2 2 8 7 1601 1828 660 +3771 2 2 8 7 806 1663 1424 +3772 2 2 8 7 691 1828 1601 +3773 2 2 8 7 1424 1663 511 +3774 2 2 8 7 409 2046 1631 +3775 2 2 8 7 1631 2046 793 +3776 2 2 8 7 1262 1934 399 +3777 2 2 8 7 1428 1648 532 +3778 2 2 8 7 712 1876 1802 +3779 2 2 8 7 1641 1941 804 +3780 2 2 8 7 1300 1817 446 +3781 2 2 8 7 319 1960 1271 +3782 2 2 8 7 1330 1778 477 +3783 2 2 8 7 1235 2044 239 +3784 2 2 8 7 669 1704 1378 +3785 2 2 8 7 219 1985 1732 +3786 2 2 8 7 1732 1985 808 +3787 2 2 8 7 680 1771 1692 +3788 2 2 8 7 581 1644 1444 +3789 2 2 8 7 1449 1643 684 +3790 2 2 8 7 1304 1986 482 +3791 2 2 8 7 999 2001 1457 +3792 2 2 8 7 1721 1722 721 +3793 2 2 8 7 570 1722 1721 +3794 2 2 8 7 571 2023 1489 +3795 2 2 8 7 1351 1759 855 +3796 2 2 8 7 741 1605 1581 +3797 2 2 8 7 224 1931 1834 +3798 2 2 8 7 295 1671 1433 +3799 2 2 8 7 1834 1931 829 +3800 2 2 8 7 1369 1733 634 +3801 2 2 8 7 635 1734 1370 +3802 2 2 8 7 697 2004 1534 +3803 2 2 8 7 1535 2003 696 +3804 2 2 8 7 1534 2004 802 +3805 2 2 8 7 801 2003 1535 +3806 2 2 8 7 628 2048 1350 +3807 2 2 8 7 1452 1662 540 +3808 2 2 8 7 1509 1965 529 +3809 2 2 8 7 1313 1845 694 +3810 2 2 8 7 792 1740 1451 +3811 2 2 8 7 894 1975 1963 +3812 2 2 8 7 1963 1975 689 +3813 2 2 8 7 1761 2011 676 +3814 2 2 8 7 675 2012 1760 +3815 2 2 8 7 831 2011 1761 +3816 2 2 8 7 1760 2012 830 +3817 2 2 8 7 277 1828 1633 +3818 2 2 8 7 1633 1828 691 +3819 2 2 8 7 1500 1738 541 +3820 2 2 8 7 190 1843 1574 +3821 2 2 8 7 1560 1967 893 +3822 2 2 8 7 287 1967 1560 +3823 2 2 8 7 260 2005 1334 +3824 2 2 8 7 861 1997 1471 +3825 2 2 8 7 458 1870 1332 +3826 2 2 8 7 1332 1870 587 +3827 2 2 8 7 1259 2054 555 +3828 2 2 8 7 1442 2024 810 +3829 2 2 8 7 235 2062 1381 +3830 2 2 8 7 857 1989 1526 +3831 2 2 8 7 1456 1778 583 +3832 2 2 8 7 85 1939 1292 +3833 2 2 8 7 1293 1940 92 +3834 2 2 8 7 1692 1771 211 +3835 2 2 8 7 845 1890 1492 +3836 2 2 8 7 1623 1777 995 +3837 2 2 8 7 708 2027 1273 +3838 2 2 8 7 294 1777 1623 +3839 2 2 8 7 1696 1882 724 +3840 2 2 8 7 1503 1972 844 +3841 2 2 8 7 1581 1605 547 +3842 2 2 8 7 814 1938 1393 +3843 2 2 8 7 1390 1796 327 +3844 2 2 8 7 593 1796 1390 +3845 2 2 8 7 1507 1744 324 +3846 2 2 8 7 480 1912 1314 +3847 2 2 8 7 615 1744 1507 +3848 2 2 8 7 898 2081 1863 +3849 2 2 8 7 1864 2082 899 +3850 2 2 8 7 1863 2081 649 +3851 2 2 8 7 650 2082 1864 +3852 2 2 8 7 1525 1650 603 +3853 2 2 8 7 1328 1894 609 +3854 2 2 8 7 610 1895 1329 +3855 2 2 8 7 558 1856 1636 +3856 2 2 8 7 1036 1866 1481 +3857 2 2 8 7 1637 1802 559 +3858 2 2 8 7 587 1872 1342 +3859 2 2 8 7 1342 1872 383 +3860 2 2 8 7 1418 2080 472 +3861 2 2 8 7 1347 1844 564 +3862 2 2 8 7 721 1843 1721 +3863 2 2 8 7 1721 1843 190 +3864 2 2 8 7 1856 1875 711 +3865 2 2 8 7 1981 2075 948 +3866 2 2 8 7 655 2075 1981 +3867 2 2 8 7 343 1819 1619 +3868 2 2 8 7 1305 1969 188 +3869 2 2 8 7 525 1845 1485 +3870 2 2 8 7 1619 1819 679 +3871 2 2 8 7 510 1936 1782 +3872 2 2 8 7 743 1617 1616 +3873 2 2 8 7 1616 1617 555 +3874 2 2 8 7 1808 1810 826 +3875 2 2 8 7 574 1810 1808 +3876 2 2 8 7 1437 1958 376 +3877 2 2 8 7 577 1671 1613 +3878 2 2 8 7 191 1875 1354 +3879 2 2 8 7 1355 1876 192 +3880 2 2 8 7 788 1817 1413 +3881 2 2 8 7 1376 1813 561 +3882 2 2 8 7 1427 1902 207 +3883 2 2 8 7 629 1902 1427 +3884 2 2 8 7 772 1652 1651 +3885 2 2 8 7 1651 1652 554 +3886 2 2 8 7 601 2022 1303 +3887 2 2 8 7 1303 2022 183 +3888 2 2 8 7 1303 1995 601 +3889 2 2 8 7 1346 1899 621 +3890 2 2 8 7 1324 1955 490 +3891 2 2 8 7 1545 1747 872 +3892 2 2 8 7 1705 1748 623 +3893 2 2 8 7 1536 1677 543 +3894 2 2 8 7 1661 1700 653 +3895 2 2 8 7 621 1700 1661 +3896 2 2 8 7 611 2055 1290 +3897 2 2 8 7 1701 1703 549 +3898 2 2 8 7 1354 2081 191 +3899 2 2 8 7 192 2082 1355 +3900 2 2 8 7 891 1703 1701 +3901 2 2 8 7 649 2081 1354 +3902 2 2 8 7 1355 2082 650 +3903 2 2 8 7 1345 1932 538 +3904 2 2 8 7 1708 1954 394 +3905 2 2 8 7 526 2002 1338 +3906 2 2 8 7 740 1954 1708 +3907 2 2 8 7 479 2076 1287 +3908 2 2 8 7 535 2062 1592 +3909 2 2 8 7 1613 1671 677 +3910 2 2 8 7 1852 1937 607 +3911 2 2 8 7 609 2025 1328 +3912 2 2 8 7 1329 2026 610 +3913 2 2 8 7 1328 2025 274 +3914 2 2 8 7 275 2026 1329 +3915 2 2 8 7 1360 1907 597 +3916 2 2 8 7 598 1908 1361 +3917 2 2 8 7 807 1937 1852 +3918 2 2 8 7 1431 2070 433 +3919 2 2 8 7 279 1971 1944 +3920 2 2 8 7 1682 1896 732 +3921 2 2 8 7 814 2091 1938 +3922 2 2 8 7 658 1896 1682 +3923 2 2 8 7 1414 2017 757 +3924 2 2 8 7 642 1831 1713 +3925 2 2 8 7 1713 1831 698 +3926 2 2 8 7 599 1926 1551 +3927 2 2 8 7 1552 1927 600 +3928 2 2 8 7 586 1983 1443 +3929 2 2 8 7 269 2017 1414 +3930 2 2 8 7 1349 1952 627 +3931 2 2 8 7 258 2024 1316 +3932 2 2 8 7 1443 1866 586 +3933 2 2 8 7 452 1957 1353 +3934 2 2 8 7 1392 1991 352 +3935 2 2 8 7 351 1992 1391 +3936 2 2 8 7 635 1991 1392 +3937 2 2 8 7 1391 1992 634 +3938 2 2 8 7 1636 1857 558 +3939 2 2 8 7 559 1858 1637 +3940 2 2 8 7 182 2057 1412 +3941 2 2 8 7 1499 1909 276 +3942 2 2 8 7 1307 2080 562 +3943 2 2 8 7 1319 2036 542 +3944 2 2 8 7 568 1968 1530 +3945 2 2 8 7 1447 1981 193 +3946 2 2 8 7 655 1981 1447 +3947 2 2 8 7 629 2032 1327 +3948 2 2 8 7 1467 1942 643 +3949 2 2 8 7 199 1942 1467 +3950 2 2 8 7 268 1964 1375 +3951 2 2 8 7 588 1766 1512 +3952 2 2 8 7 1599 1785 128 +3953 2 2 8 7 1512 1766 935 +3954 2 2 8 7 165 2064 1896 +3955 2 2 8 7 16 1758 1523 +3956 2 2 8 7 482 1986 1446 +3957 2 2 8 7 593 2037 1339 +3958 2 2 8 7 657 1748 1705 +3959 2 2 8 7 1804 1999 817 +3960 2 2 8 7 661 1999 1804 +3961 2 2 8 7 724 1974 1696 +3962 2 2 8 7 1696 1974 319 +3963 2 2 8 7 623 1748 1688 +3964 2 2 8 7 937 2083 1774 +3965 2 2 8 7 239 1747 1545 +3966 2 2 8 7 1393 1938 387 +3967 2 2 8 7 1498 1963 294 +3968 2 2 8 7 1462 1833 754 +3969 2 2 8 7 10 1765 1530 +3970 2 2 8 7 894 1963 1498 +3971 2 2 8 7 1363 2016 927 +3972 2 2 8 7 225 1836 1563 +3973 2 2 8 7 1563 1836 648 +3974 2 2 8 7 258 2069 2024 +3975 2 2 8 7 181 2007 1389 +3976 2 2 8 7 1389 2007 617 +3977 2 2 8 7 1767 1942 722 +3978 2 2 8 7 193 1889 1447 +3979 2 2 8 7 374 2035 1565 +3980 2 2 8 7 1565 2035 694 +3981 2 2 8 7 587 1998 1379 +3982 2 2 8 7 1609 2023 773 +3983 2 2 8 7 398 2023 1609 +3984 2 2 8 7 663 2090 1347 +3985 2 2 8 7 911 2044 1510 +3986 2 2 8 7 861 1983 1653 +3987 2 2 8 7 827 2009 1906 +3988 2 2 8 7 1906 2009 454 +3989 2 2 8 7 666 1865 1517 +3990 2 2 8 7 1517 1865 534 +3991 2 2 8 7 1786 1956 674 +3992 2 2 8 7 1481 1866 465 +3993 2 2 8 7 133 2047 1694 +3994 2 2 8 7 1946 2028 373 +3995 2 2 8 7 711 1875 1788 +3996 2 2 8 7 1789 1876 712 +3997 2 2 8 7 1600 1816 606 +3998 2 2 8 7 849 2028 1946 +3999 2 2 8 7 1788 1875 191 +4000 2 2 8 7 192 1876 1789 +4001 2 2 8 7 1445 2071 917 +4002 2 2 8 7 703 1913 1764 +4003 2 2 8 7 732 2064 1819 +4004 2 2 8 7 49 1816 1600 +4005 2 2 8 7 1567 1893 515 +4006 2 2 8 7 734 1966 1795 +4007 2 2 8 7 602 2073 1680 +4008 2 2 8 7 524 2015 1390 +4009 2 2 8 7 639 2034 1383 +4010 2 2 8 7 605 1785 1599 +4011 2 2 8 7 1393 2059 967 +4012 2 2 8 7 580 1958 1437 +4013 2 2 8 7 1384 2041 643 +4014 2 2 8 7 1466 1945 864 +4015 2 2 8 7 1938 2091 713 +4016 2 2 8 7 1472 1917 585 +4017 2 2 8 7 1653 1983 586 +4018 2 2 8 7 1412 2057 624 +4019 2 2 8 7 1688 1748 271 +4020 2 2 8 7 433 2070 1672 +4021 2 2 8 7 387 2059 1393 +4022 2 2 8 7 1443 1983 346 +4023 2 2 8 7 665 1754 1739 +4024 2 2 8 7 538 1932 1510 +4025 2 2 8 7 1446 1986 770 +4026 2 2 8 7 626 1891 1548 +4027 2 2 8 7 319 2060 1696 +4028 2 2 8 7 1711 2048 628 +4029 2 2 8 7 700 1956 1786 +4030 2 2 8 7 1548 1891 329 +4031 2 2 8 7 1556 2049 590 +4032 2 2 8 7 591 2050 1557 +4033 2 2 8 7 869 1872 1870 +4034 2 2 8 7 1870 1872 587 +4035 2 2 8 7 1457 2001 448 +4036 2 2 8 7 599 1873 1576 +4037 2 2 8 7 1575 1874 600 +4038 2 2 8 7 1739 1754 659 +4039 2 2 8 7 1564 2018 620 +4040 2 2 8 7 774 2067 1877 +4041 2 2 8 7 309 1919 1558 +4042 2 2 8 7 979 1893 1567 +4043 2 2 8 7 185 2016 1449 +4044 2 2 8 7 1521 1954 820 +4045 2 2 8 7 761 1965 1509 +4046 2 2 8 7 1507 1971 615 +4047 2 2 8 7 1813 1880 561 +4048 2 2 8 7 394 1954 1521 +4049 2 2 8 7 620 2018 1603 +4050 2 2 8 7 1476 2007 181 +4051 2 2 8 7 1527 1968 568 +4052 2 2 8 7 1505 2002 526 +4053 2 2 8 7 393 2071 1445 +4054 2 2 8 7 1809 1852 422 +4055 2 2 8 7 807 1852 1809 +4056 2 2 8 7 1489 2023 398 +4057 2 2 8 7 1505 2020 904 +4058 2 2 8 7 1796 1798 809 +4059 2 2 8 7 593 1798 1796 +4060 2 2 8 7 343 1982 1819 +4061 2 2 8 7 1819 1982 732 +4062 2 2 8 7 852 2061 1840 +4063 2 2 8 7 1840 2061 336 +4064 2 2 8 7 1543 2038 596 +4065 2 2 8 7 765 1891 1814 +4066 2 2 8 7 1877 2033 774 +4067 2 2 8 7 228 2033 1877 +4068 2 2 8 7 604 1882 1696 +4069 2 2 8 7 341 2030 1705 +4070 2 2 8 7 623 2072 1705 +4071 2 2 8 7 327 2065 1647 +4072 2 2 8 7 786 1902 1901 +4073 2 2 8 7 1901 1902 629 +4074 2 2 8 7 281 2018 1564 +4075 2 2 8 7 1587 2005 723 +4076 2 2 8 7 1760 1904 675 +4077 2 2 8 7 676 1905 1761 +4078 2 2 8 7 73 1904 1760 +4079 2 2 8 7 1761 1905 104 +4080 2 2 8 7 1697 2077 288 +4081 2 2 8 7 705 2077 1697 +4082 2 2 8 7 1584 2017 269 +4083 2 2 8 7 1632 1990 13 +4084 2 2 8 7 1783 2042 626 +4085 2 2 8 7 1814 1891 626 +4086 2 2 8 7 674 1956 1834 +4087 2 2 8 7 752 1880 1813 +4088 2 2 8 7 1764 1913 654 +4089 2 2 8 7 1696 2060 604 +4090 2 2 8 7 819 1984 1860 +4091 2 2 8 7 1705 2072 341 +4092 2 2 8 7 1592 2062 913 +4093 2 2 8 7 643 1942 1767 +4094 2 2 8 7 764 2042 1628 +4095 2 2 8 7 664 2066 1673 +4096 2 2 8 7 1782 1936 881 +4097 2 2 8 7 1621 2058 611 +4098 2 2 8 7 1883 2072 623 +4099 2 2 8 7 1922 2008 710 +4100 2 2 8 7 1647 2065 646 +4101 2 2 8 7 1673 2066 210 +4102 2 2 8 7 1795 1966 651 +4103 2 2 8 7 148 2089 1975 +4104 2 2 8 7 604 2060 1807 +4105 2 2 8 7 1985 2065 808 +4106 2 2 8 7 646 2065 1985 +4107 2 2 8 7 1705 2030 657 +4108 2 2 8 7 1672 2070 795 +4109 2 2 8 7 1834 1956 224 +4110 2 2 8 7 1694 2047 612 +4111 2 2 8 7 333 2048 1711 +4112 2 2 8 7 702 1943 1933 +4113 2 2 8 7 1933 1943 706 +4114 2 2 8 7 2086 2087 1048 +4115 2 2 8 7 625 2087 2086 +4116 2 2 8 7 1860 1984 386 +4117 2 2 8 7 2008 2085 710 +4118 2 2 8 7 1807 2060 766 +4119 2 2 8 7 590 2049 1820 +4120 2 2 8 7 1821 2050 591 +4121 2 2 8 7 707 2008 1922 +4122 2 2 8 7 1819 2064 679 +4123 2 2 8 7 1877 2067 673 +4124 2 2 8 7 835 2072 1883 +4125 2 2 8 7 2014 2066 664 +4126 2 2 8 7 902 2066 2014 +4127 2 2 8 7 1975 2089 689 +4128 2 2 8 7 227 2085 2008 +$EndElements diff --git a/examples/python/stiffness_matrix/stiffness_matrix.py b/examples/python/stiffness_matrix/stiffness_matrix.py new file mode 100644 index 000000000..573b7e75e --- /dev/null +++ b/examples/python/stiffness_matrix/stiffness_matrix.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +import akantu +import numpy as np + + + +def getStiffnessMatrix(material_file, mesh_file, traction): + akantu.parseInput(material_file) + spatial_dimension = 2 + + ################################################################ + # Initialization + ################################################################ + mesh = akantu.Mesh(spatial_dimension) + mesh.read(mesh_file) + + model = akantu.SolidMechanicsModel(mesh) + model.initFull(akantu.SolidMechanicsModelOptions(akantu._static)) + model.assembleStiffnessMatrix() + K = model.getMatrix('K') + stiff = akantu.AkantuSparseMatrix(K).toarray() + return stiff + +################################################################ +# main +################################################################ + + +def main(): + + import os + mesh_file = 'plate.msh' + # if mesh was not created the calls gmsh to generate it + if not os.path.isfile(mesh_file): + import subprocess + ret = subprocess.call( + 'gmsh -format msh2 -2 plate.geo {0}'.format(mesh_file), shell=True) + if not ret == 0: + raise Exception( + 'execution of GMSH failed: do you have it installed ?') + + material_file = 'material.dat' + + traction = 1. + mat = getStiffnessMatrix(material_file, mesh_file, traction) + print(mat) + +################################################################ +if __name__ == "__main__": + main() diff --git a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc index 99985a041..72530f60e 100644 --- a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc +++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc @@ -1,73 +1,76 @@ /** * @file boundary_functions.cc * * @author David Simon Kammer * * @date creation: Tue Dec 02 2014 * @date last modification: Fri Feb 23 2018 * * @brief * * @section LICENSE * * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "boundary_functions.hh" #include "communicator.hh" +#include "element_group.hh" +#include "node_group.hh" +#include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ Real integrateResidual(const std::string & sub_boundary_name, const SolidMechanicsModel & model, UInt dir) { Real int_res = 0.; const Mesh & mesh = model.getMesh(); const Array & residual = model.getInternalForce(); const ElementGroup & boundary = mesh.getElementGroup(sub_boundary_name); - for (auto & node : boundary.getNodes()) { + for (auto & node : boundary.getNodeGroup().getNodes()) { bool is_local_node = mesh.isLocalOrMasterNode(node); if (is_local_node) { int_res += residual(node, dir); } } mesh.getCommunicator().allReduce(int_res, SynchronizerOperation::_sum); return int_res; } /* -------------------------------------------------------------------------- */ void boundaryFix(Mesh & mesh, const std::vector & sub_boundary_names) { std::vector::const_iterator it = sub_boundary_names.begin(); std::vector::const_iterator end = sub_boundary_names.end(); for (; it != end; ++it) { if (mesh.element_group_find(*it) == mesh.element_group_end()) { - mesh.createElementGroup( - *it, mesh.getSpatialDimension() - 1); // empty element group + mesh.createElementGroup(*it, mesh.getSpatialDimension() - + 1); // empty element group } } } } // namespace akantu diff --git a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh index a16426a6c..f5413bdd9 100644 --- a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh +++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh @@ -1,45 +1,55 @@ /** * @file boundary_functions.hh * * @author David Simon Kammer * * @date creation: Fri Jan 04 2013 * @date last modification: Fri Feb 23 2018 * * @brief functions for boundaries * * @section LICENSE * * Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ -// akantu #include "aka_common.hh" -#include "solid_mechanics_model.hh" +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ + +#ifndef __AKANTU_BOUNDARY_FUNCTIONS_HH__ +#define __AKANTU_BOUNDARY_FUNCTIONS_HH__ + +namespace akantu { +class SolidMechanicsModel; +} namespace akantu { Real integrateResidual(const std::string & sub_boundary_name, const SolidMechanicsModel & model, UInt dir); /// this is a fix so that all subboundaries exist on all procs void boundaryFix(Mesh & mesh, const std::vector & sub_boundary_names); } // namespace akantu + +#endif /* __AKANTU_BOUNDARY_FUNCTIONS_HH__ */ diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc index a01620780..28e6d7f65 100644 --- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc +++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc @@ -1,554 +1,554 @@ /** * @file ntn_contact.cc * * @author David Simon Kammer * * @date creation: Tue Dec 02 2014 * @date last modification: Fri Feb 23 2018 * * @brief implementation of ntn_contact * * @section LICENSE * * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ // simtools #include "ntn_contact.hh" #include "dumper_nodal_field.hh" #include "dumper_text.hh" namespace akantu { /* -------------------------------------------------------------------------- */ NTNContact::NTNContact(SolidMechanicsModel & model, const ID & id, const MemoryID & memory_id) : NTNBaseContact(model, id, memory_id), masters(0, 1, 0, id + ":masters", std::numeric_limits::quiet_NaN(), "masters"), lumped_boundary_masters(0, 1, 0, id + ":lumped_boundary_masters", std::numeric_limits::quiet_NaN(), "lumped_boundary_masters"), master_elements("master_elements", id, memory_id) { AKANTU_DEBUG_IN(); const Mesh & mesh = this->model.getMesh(); UInt spatial_dimension = this->model.getSpatialDimension(); this->master_elements.initialize(mesh, _nb_component = 1, _spatial_dimension = spatial_dimension - 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::pairInterfaceNodes(const ElementGroup & slave_boundary, const ElementGroup & master_boundary, UInt surface_normal_dir, const Mesh & mesh, Array & pairs) { AKANTU_DEBUG_IN(); pairs.resize(0); AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2, "Array of node pairs should have nb_component = 2," << " but has nb_component = " << pairs.getNbComponent()); UInt dim = mesh.getSpatialDimension(); AKANTU_DEBUG_ASSERT(surface_normal_dir < dim, "Mesh is of " << dim << " dimensions" << " and cannot have direction " << surface_normal_dir << " for surface normal"); // offset for projection computation Vector offset(dim - 1); for (UInt i = 0, j = 0; i < dim; ++i) { if (surface_normal_dir != i) { offset(j) = i; ++j; } } // find projected node coordinates const Array & coordinates = mesh.getNodes(); // find slave nodes Array proj_slave_coord(slave_boundary.getNbNodes(), dim - 1, 0.); Array slave_nodes(slave_boundary.getNbNodes()); UInt n(0); - for (auto && slave_node : slave_boundary.getNodes()) { + for (auto && slave_node : slave_boundary.getNodeGroup().getNodes()) { for (UInt d = 0; d < dim - 1; ++d) { proj_slave_coord(n, d) = coordinates(slave_node, offset[d]); slave_nodes(n) = slave_node; } ++n; } // find master nodes Array proj_master_coord(master_boundary.getNbNodes(), dim - 1, 0.); Array master_nodes(master_boundary.getNbNodes()); n = 0; - for (auto && master_node : master_boundary.getNodes()) { + for (auto && master_node : master_boundary.getNodeGroup().getNodes()) { for (UInt d = 0; d < dim - 1; ++d) { proj_master_coord(n, d) = coordinates(master_node, offset[d]); master_nodes(n) = master_node; } ++n; } // find minimum distance between slave nodes to define tolerance Real min_dist = std::numeric_limits::max(); for (UInt i = 0; i < proj_slave_coord.size(); ++i) { for (UInt j = i + 1; j < proj_slave_coord.size(); ++j) { Real dist = 0.; for (UInt d = 0; d < dim - 1; ++d) { dist += (proj_slave_coord(i, d) - proj_slave_coord(j, d)) * (proj_slave_coord(i, d) - proj_slave_coord(j, d)); } if (dist < min_dist) { min_dist = dist; } } } min_dist = std::sqrt(min_dist); Real local_tol = 0.1 * min_dist; // find master slave node pairs for (UInt i = 0; i < proj_slave_coord.size(); ++i) { for (UInt j = 0; j < proj_master_coord.size(); ++j) { Real dist = 0.; for (UInt d = 0; d < dim - 1; ++d) { dist += (proj_slave_coord(i, d) - proj_master_coord(j, d)) * (proj_slave_coord(i, d) - proj_master_coord(j, d)); } dist = std::sqrt(dist); if (dist < local_tol) { // it is a pair Vector pair(2); pair[0] = slave_nodes(i); pair[1] = master_nodes(j); pairs.push_back(pair); continue; // found master do not need to search further for this slave } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::addSurfacePair(const ID & slave, const ID & master, UInt surface_normal_dir) { AKANTU_DEBUG_IN(); const Mesh & mesh = this->model.getMesh(); const ElementGroup & slave_boundary = mesh.getElementGroup(slave); const ElementGroup & master_boundary = mesh.getElementGroup(master); this->contact_surfaces.insert(&slave_boundary); this->contact_surfaces.insert(&master_boundary); Array pairs(0, 2); NTNContact::pairInterfaceNodes(slave_boundary, master_boundary, surface_normal_dir, this->model.getMesh(), pairs); // eliminate pairs which contain a pbc slave node Array pairs_no_PBC_slaves(0, 2); Array::const_vector_iterator it = pairs.begin(2); Array::const_vector_iterator end = pairs.end(2); for (; it != end; ++it) { const Vector & pair = *it; if (not mesh.isPeriodicSlave(pair(0)) and not mesh.isPeriodicSlave(pair(1))) { pairs_no_PBC_slaves.push_back(pair); } } this->addNodePairs(pairs_no_PBC_slaves); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::addNodePairs(const Array & pairs) { AKANTU_DEBUG_IN(); AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2, "Array of node pairs should have nb_component = 2," << " but has nb_component = " << pairs.getNbComponent()); UInt nb_pairs = pairs.size(); for (UInt n = 0; n < nb_pairs; ++n) { this->addSplitNode(pairs(n, 0), pairs(n, 1)); } // synchronize with depending nodes findBoundaryElements(this->slaves.getArray(), this->slave_elements); findBoundaryElements(this->masters.getArray(), this->master_elements); updateInternalData(); syncArrays(_added); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::getNodePairs(Array & pairs) const { AKANTU_DEBUG_IN(); pairs.resize(0); AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2, "Array of node pairs should have nb_component = 2," << " but has nb_component = " << pairs.getNbComponent()); UInt nb_pairs = this->getNbContactNodes(); for (UInt n = 0; n < nb_pairs; ++n) { Vector pair{this->slaves(n), this->masters(n)}; pairs.push_back(pair); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::addSplitNode(UInt slave, UInt master) { AKANTU_DEBUG_IN(); NTNBaseContact::addSplitNode(slave); this->masters.push_back(master); this->lumped_boundary_masters.push_back( std::numeric_limits::quiet_NaN()); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /* This function only works for surface elements with one quad point. For surface elements with more quad points, it computes still, but the result might not be what you are looking for. */ void NTNContact::updateNormals() { AKANTU_DEBUG_IN(); // set normals to zero this->normals.clear(); // contact information UInt dim = this->model.getSpatialDimension(); UInt nb_contact_nodes = this->getNbContactNodes(); this->synch_registry->synchronize(SynchronizationTag::_cf_nodal); // synchronize current pos const Array & cur_pos = this->model.getCurrentPosition(); FEEngine & boundary_fem = this->model.getFEEngineBoundary(); const Mesh & mesh = this->model.getMesh(); for (auto ghost_type: ghost_types) { for (auto & type : mesh.elementTypes(dim - 1, ghost_type)) { // compute the normals Array quad_normals(0, dim); boundary_fem.computeNormalsOnIntegrationPoints(cur_pos, quad_normals, type, ghost_type); UInt nb_quad_points = boundary_fem.getNbIntegrationPoints(type, ghost_type); // new version: compute normals only based on master elements (and not all // boundary elements) // ------------------------------------------------------------------------------------- UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type); const Array & connectivity = mesh.getConnectivity(type, ghost_type); // loop over contact nodes for (auto & element : (this->master_elements)(type, ghost_type)) { for (UInt q = 0; q < nb_nodes_per_element; ++q) { UInt node = connectivity(element, q); UInt node_index = this->masters.find(node); AKANTU_DEBUG_ASSERT(node_index != UInt(-1), "Could not find node " << node << " in the array!"); for (UInt q = 0; q < nb_quad_points; ++q) { // add quad normal to master normal for (UInt d = 0; d < dim; ++d) { this->normals(node_index, d) += quad_normals(element * nb_quad_points + q, d); } } } } } } Real * master_normals = this->normals.storage(); for (UInt n = 0; n < nb_contact_nodes; ++n) { if (dim == 2) Math::normalize2(&(master_normals[n * dim])); else if (dim == 3) Math::normalize3(&(master_normals[n * dim])); } // // normalize normals // auto nit = this->normals.begin(); // auto nend = this->normals.end(); // for (; nit != nend; ++nit) { // nit->normalize(); // } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::dumpRestart(const std::string & file_name) const { AKANTU_DEBUG_IN(); NTNBaseContact::dumpRestart(file_name); this->masters.dumpRestartFile(file_name); this->lumped_boundary_masters.dumpRestartFile(file_name); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::readRestart(const std::string & file_name) { AKANTU_DEBUG_IN(); NTNBaseContact::readRestart(file_name); this->masters.readRestartFile(file_name); this->lumped_boundary_masters.readRestartFile(file_name); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::updateImpedance() { AKANTU_DEBUG_IN(); UInt nb_contact_nodes = getNbContactNodes(); Real delta_t = this->model.getTimeStep(); AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?"); const Array & mass = this->model.getMass(); for (UInt n = 0; n < nb_contact_nodes; ++n) { UInt master = this->masters(n); UInt slave = this->slaves(n); Real imp = (this->lumped_boundary_masters(n) / mass(master)) + (this->lumped_boundary_slaves(n) / mass(slave)); imp = 2 / delta_t / imp; this->impedance(n) = imp; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::updateLumpedBoundary() { AKANTU_DEBUG_IN(); internalUpdateLumpedBoundary(this->slaves.getArray(), this->slave_elements, this->lumped_boundary_slaves); internalUpdateLumpedBoundary(this->masters.getArray(), this->master_elements, this->lumped_boundary_masters); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::applyContactPressure() { AKANTU_DEBUG_IN(); UInt nb_ntn_pairs = getNbContactNodes(); UInt dim = this->model.getSpatialDimension(); Array & residual = this->model.getInternalForce(); for (UInt n = 0; n < nb_ntn_pairs; ++n) { UInt master = this->masters(n); UInt slave = this->slaves(n); for (UInt d = 0; d < dim; ++d) { residual(master, d) += this->lumped_boundary_masters(n) * this->contact_pressure(n, d); residual(slave, d) -= this->lumped_boundary_slaves(n) * this->contact_pressure(n, d); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::computeRelativeTangentialField( const Array & field, Array & rel_tang_field) const { AKANTU_DEBUG_IN(); // resize arrays to zero rel_tang_field.resize(0); UInt dim = this->model.getSpatialDimension(); auto it_field = field.begin(dim); auto it_normal = this->normals.getArray().begin(dim); Vector rfv(dim); Vector np_rfv(dim); UInt nb_contact_nodes = this->slaves.size(); for (UInt n = 0; n < nb_contact_nodes; ++n) { // nodes UInt slave = this->slaves(n); UInt master = this->masters(n); // relative field vector (slave - master) rfv = Vector(it_field[slave]); rfv -= Vector(it_field[master]); // normal projection of relative field const Vector normal_v = it_normal[n]; np_rfv = normal_v; np_rfv *= rfv.dot(normal_v); // subract normal projection from relative field to get the tangential // projection rfv -= np_rfv; rel_tang_field.push_back(rfv); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::computeRelativeNormalField( const Array & field, Array & rel_normal_field) const { AKANTU_DEBUG_IN(); // resize arrays to zero rel_normal_field.resize(0); UInt dim = this->model.getSpatialDimension(); // Real * field_p = field.storage(); // Real * normals_p = this->normals.storage(); Array::const_iterator> it_field = field.begin(dim); Array::const_iterator> it_normal = this->normals.getArray().begin(dim); Vector rfv(dim); UInt nb_contact_nodes = this->getNbContactNodes(); for (UInt n = 0; n < nb_contact_nodes; ++n) { // nodes UInt slave = this->slaves(n); UInt master = this->masters(n); // relative field vector (slave - master) rfv = Vector(it_field[slave]); rfv -= Vector(it_field[master]); // length of normal projection of relative field const Vector normal_v = it_normal[n]; rel_normal_field.push_back(rfv.dot(normal_v)); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Int NTNContact::getNodeIndex(UInt node) const { AKANTU_DEBUG_IN(); Int slave_i = NTNBaseContact::getNodeIndex(node); Int master_i = this->masters.find(node); AKANTU_DEBUG_OUT(); return std::max(slave_i, master_i); } /* -------------------------------------------------------------------------- */ void NTNContact::printself(std::ostream & stream, int indent) const { AKANTU_DEBUG_IN(); std::string space; for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) ; stream << space << "NTNContact [" << std::endl; NTNBaseContact::printself(stream, indent); stream << space << " + masters : " << std::endl; this->masters.printself(stream, indent + 2); stream << space << " + lumped_boundary_mastres : " << std::endl; this->lumped_boundary_masters.printself(stream, indent + 2); stream << space << "]" << std::endl; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::syncArrays(SyncChoice sync_choice) { AKANTU_DEBUG_IN(); NTNBaseContact::syncArrays(sync_choice); this->masters.syncElements(sync_choice); this->lumped_boundary_masters.syncElements(sync_choice); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTNContact::addDumpFieldToDumper(const std::string & dumper_name, const std::string & field_id) { AKANTU_DEBUG_IN(); /* #ifdef AKANTU_USE_IOHELPER const Array & nodal_filter = this->slaves.getArray(); #define ADD_FIELD(field_id, field, type) \ internalAddDumpFieldToDumper(dumper_name, \ field_id, \ new DumperIOHelper::NodalField< type, true, \ Array, \ Array >(field, 0, 0, &nodal_filter)) */ if (field_id == "lumped_boundary_master") { internalAddDumpFieldToDumper( dumper_name, field_id, new dumper::NodalField(this->lumped_boundary_masters.getArray())); } else { NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id); } /* #undef ADD_FIELD #endif */ AKANTU_DEBUG_OUT(); } } // namespace akantu diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc index f0b0c5dea..c63898116 100644 --- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc +++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc @@ -1,322 +1,322 @@ /** * @file ntrf_contact.cc * * @author David Simon Kammer * * @date creation: Tue Dec 02 2014 * @date last modification: Fri Feb 23 2018 * * @brief * * @section LICENSE * * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ // simtools #include "ntrf_contact.hh" namespace akantu { /* -------------------------------------------------------------------------- */ NTRFContact::NTRFContact(SolidMechanicsModel & model, const ID & id, const MemoryID & memory_id) : NTNBaseContact(model, id, memory_id), reference_point(model.getSpatialDimension()), normal(model.getSpatialDimension()) { AKANTU_DEBUG_IN(); is_ntn_contact = false; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::setReferencePoint(Real x, Real y, Real z) { AKANTU_DEBUG_IN(); Real coord[3]; coord[0] = x; coord[1] = y; coord[2] = z; UInt dim = this->model.getSpatialDimension(); for (UInt d = 0; d < dim; ++d) this->reference_point(d) = coord[d]; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::setNormal(Real x, Real y, Real z) { AKANTU_DEBUG_IN(); UInt dim = this->model.getSpatialDimension(); Real coord[3]; coord[0] = x; coord[1] = y; coord[2] = z; for (UInt d = 0; d < dim; ++d) this->normal(d) = coord[d]; this->normal.normalize(); this->updateNormals(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::addSurface(const ID & surf) { AKANTU_DEBUG_IN(); const Mesh & mesh_ref = this->model.getMesh(); try { const ElementGroup & boundary = mesh_ref.getElementGroup(surf); this->contact_surfaces.insert(&boundary); // find slave nodes - for (auto && node : boundary.getNodes()) { + for (auto && node : boundary.getNodeGroup().getNodes()) { if (not mesh_ref.isPeriodicSlave(node)) { this->addSplitNode(node); } } } catch (debug::Exception & e) { AKANTU_DEBUG_INFO("NTRFContact addSurface did not found subboundary " << surf << " and ignored it. Other procs might have it :)"); } // synchronize with depending nodes findBoundaryElements(this->slaves.getArray(), this->slave_elements); updateInternalData(); syncArrays(_added); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::addNodes(Array & nodes) { AKANTU_DEBUG_IN(); UInt nb_nodes = nodes.size(); UInt nb_compo = nodes.getNbComponent(); for (UInt n = 0; n < nb_nodes; ++n) { for (UInt c = 0; c < nb_compo; ++c) { this->addSplitNode(nodes(n, c)); } } // synchronize with depending nodes findBoundaryElements(this->slaves.getArray(), this->slave_elements); updateInternalData(); syncArrays(_added); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::updateNormals() { AKANTU_DEBUG_IN(); // normal is the same for all slaves this->normals.set(this->normal); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::updateImpedance() { AKANTU_DEBUG_IN(); UInt nb_contact_nodes = getNbContactNodes(); Real delta_t = this->model.getTimeStep(); AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?"); const Array & mass = this->model.getMass(); for (UInt n = 0; n < nb_contact_nodes; ++n) { UInt slave = this->slaves(n); Real imp = this->lumped_boundary_slaves(n) / mass(slave); imp = 2 / delta_t / imp; this->impedance(n) = imp; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::computeRelativeTangentialField( const Array & field, Array & rel_tang_field) const { AKANTU_DEBUG_IN(); // resize arrays to zero rel_tang_field.resize(0); UInt dim = this->model.getSpatialDimension(); Array::const_iterator> it_field = field.begin(dim); Array::const_iterator> it_normal = this->normals.getArray().begin(dim); Vector rfv(dim); Vector np_rfv(dim); UInt nb_contact_nodes = this->slaves.size(); for (UInt n = 0; n < nb_contact_nodes; ++n) { // nodes UInt node = this->slaves(n); // relative field vector rfv = it_field[node]; ; // normal projection of relative field const Vector & normal_v = it_normal[n]; np_rfv = normal_v; np_rfv *= rfv.dot(normal_v); // subtract normal projection from relative field to get the tangential // projection rfv -= np_rfv; rel_tang_field.push_back(rfv); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::computeNormalGap(Array & gap) const { AKANTU_DEBUG_IN(); gap.resize(0); UInt dim = this->model.getSpatialDimension(); Array::const_iterator> it_cur_pos = this->model.getCurrentPosition().begin(dim); Array::const_iterator> it_normal = this->normals.getArray().begin(dim); Vector gap_v(dim); UInt nb_contact_nodes = this->getNbContactNodes(); for (UInt n = 0; n < nb_contact_nodes; ++n) { // nodes UInt node = this->slaves(n); // gap vector gap_v = it_cur_pos[node]; gap_v -= this->reference_point; // length of normal projection of gap vector const Vector & normal_v = it_normal[n]; gap.push_back(gap_v.dot(normal_v)); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::computeRelativeNormalField( const Array & field, Array & rel_normal_field) const { AKANTU_DEBUG_IN(); // resize arrays to zero rel_normal_field.resize(0); UInt dim = this->model.getSpatialDimension(); Array::const_iterator> it_field = field.begin(dim); Array::const_iterator> it_normal = this->normals.getArray().begin(dim); UInt nb_contact_nodes = this->getNbContactNodes(); for (UInt n = 0; n < nb_contact_nodes; ++n) { // nodes UInt node = this->slaves(n); const Vector & field_v = it_field[node]; const Vector & normal_v = it_normal[n]; rel_normal_field.push_back(field_v.dot(normal_v)); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::printself(std::ostream & stream, int indent) const { AKANTU_DEBUG_IN(); std::string space; for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) ; stream << space << "NTRFContact [" << std::endl; NTNBaseContact::printself(stream, indent); stream << space << "]" << std::endl; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void NTRFContact::addDumpFieldToDumper(const std::string & dumper_name, const std::string & field_id) { AKANTU_DEBUG_IN(); /* #ifdef AKANTU_USE_IOHELPER const Array & nodal_filter = this->slaves.getArray(); #define ADD_FIELD(field_id, field, type) \ internalAddDumpFieldToDumper(dumper_name, \ field_id, \ new DumperIOHelper::NodalField< type, true, \ Array, \ Array >(field, 0, 0, &nodal_filter)) */ /* if(field_id == "displacement") { ADD_FIELD(field_id, this->model.getDisplacement(), Real); } else if(field_id == "contact_pressure") { internalAddDumpFieldToDumper(dumper_name, field_id, new DumperIOHelper::NodalField(this->contact_pressure.getArray())); } else {*/ NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id); //} /* #undef ADD_FIELD #endif */ AKANTU_DEBUG_OUT(); } } // namespace akantu diff --git a/packages/cgal.cmake b/packages/cgal.cmake index eef6a0545..e876d907d 100644 --- a/packages/cgal.cmake +++ b/packages/cgal.cmake @@ -1,83 +1,86 @@ #=============================================================================== # @file cgal.cmake # # @author Lucas Frerot # @author Clement Roux # # @date creation: Thu Feb 19 2015 # @date last modification: Wed Jan 20 2016 # # @brief package description for CGAL # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== + +set(CGAL_DO_NOT_WARN_ABOUT_CMAKE_BUILD_TYPE ON + CACHE INTERNAL "Tells CGAL cmake to shut up" FORCE) + package_declare(CGAL EXTERNAL DESCRIPTION "Add CGAL support in akantu" COMPILE_FLAGS CXX -frounding-math BOOST_COMPONENTS system thread ) package_is_activated(CGAL _is_activated) if (_is_activated AND (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")) set(CGAL_DISABLE_ROUNDING_MATH_CHECK ON - CACHE INTERNAL - "Disable rounding math check in CGAL. This permits Valgrind to run." FORCE) + CACHE INTERNAL "Disable rounding math check in CGAL. This permits Valgrind to run." FORCE) endif() package_declare_sources(CGAL geometry/mesh_geom_common.hh geometry/mesh_geom_abstract.hh geometry/mesh_geom_factory.hh geometry/mesh_geom_factory_tmpl.hh geometry/mesh_abstract_intersector.hh geometry/mesh_abstract_intersector_tmpl.hh geometry/mesh_geom_intersector.hh geometry/mesh_geom_intersector_tmpl.hh geometry/mesh_segment_intersector.hh geometry/mesh_segment_intersector_tmpl.hh geometry/mesh_sphere_intersector.hh geometry/mesh_sphere_intersector_tmpl.hh geometry/tree_type_helper.hh geometry/geom_helper_functions.hh geometry/aabb_primitives/triangle.hh geometry/aabb_primitives/line_arc.hh geometry/aabb_primitives/tetrahedron.hh geometry/aabb_primitives/aabb_primitive.hh geometry/aabb_primitives/aabb_primitive.cc ) package_declare_documentation(CGAL "This package allows the use of CGAL's geometry algorithms in Akantu. Note that it needs a version of CGAL $\\geq$ 4.5 and needs activation of boost's system component." "" "CGAL checks with an assertion that the compilation flag \\shellcode{-frounding-math} is activated, which forbids the use of Valgrind on any code compilated with the package." ) package_set_package_system_dependency(CGAL deb-src "libcgal-dev >= 4.5") diff --git a/packages/solid_mechanics.cmake b/packages/solid_mechanics.cmake index f56de607e..9d51e1e4b 100644 --- a/packages/solid_mechanics.cmake +++ b/packages/solid_mechanics.cmake @@ -1,131 +1,131 @@ #=============================================================================== # @file solid_mechanics.cmake # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Nov 21 2011 # @date last modification: Mon Jan 18 2016 # # @brief package description for core # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== package_declare(solid_mechanics DEFAULT ON DESCRIPTION "Solid mechanics model" - DEPENDS core + DEPENDS core lapack ) package_declare_sources(solid_mechanics model/solid_mechanics/material.cc model/solid_mechanics/material.hh model/solid_mechanics/material_inline_impl.cc model/solid_mechanics/material_selector.hh model/solid_mechanics/material_selector_tmpl.hh model/solid_mechanics/materials/internal_field.hh model/solid_mechanics/materials/internal_field_tmpl.hh model/solid_mechanics/materials/random_internal_field.hh model/solid_mechanics/materials/random_internal_field_tmpl.hh model/solid_mechanics/solid_mechanics_model.cc model/solid_mechanics/solid_mechanics_model.hh model/solid_mechanics/solid_mechanics_model_inline_impl.cc model/solid_mechanics/solid_mechanics_model_io.cc model/solid_mechanics/solid_mechanics_model_mass.cc model/solid_mechanics/solid_mechanics_model_material.cc model/solid_mechanics/solid_mechanics_model_tmpl.hh model/solid_mechanics/solid_mechanics_model_event_handler.hh model/solid_mechanics/materials/plane_stress_toolbox.hh model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh model/solid_mechanics/materials/material_core_includes.hh model/solid_mechanics/materials/material_elastic.cc model/solid_mechanics/materials/material_elastic.hh model/solid_mechanics/materials/material_elastic_inline_impl.cc model/solid_mechanics/materials/material_thermal.cc model/solid_mechanics/materials/material_thermal.hh model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc model/solid_mechanics/materials/material_elastic_orthotropic.cc model/solid_mechanics/materials/material_elastic_orthotropic.hh model/solid_mechanics/materials/material_damage/material_damage.hh model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh model/solid_mechanics/materials/material_damage/material_marigo.cc model/solid_mechanics/materials/material_damage/material_marigo.hh model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc model/solid_mechanics/materials/material_damage/material_mazars.cc model/solid_mechanics/materials/material_damage/material_mazars.hh model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc model/solid_mechanics/materials/material_plastic/material_plastic.cc model/solid_mechanics/materials/material_plastic/material_plastic.hh model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.cc model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.hh model/solid_mechanics/materials/material_non_local.hh model/solid_mechanics/materials/material_non_local_tmpl.hh model/solid_mechanics/materials/material_non_local_includes.hh ) package_declare_material_infos(solid_mechanics LIST AKANTU_CORE_MATERIAL_LIST INCLUDE material_core_includes.hh ) package_declare_documentation_files(solid_mechanics manual-solidmechanicsmodel.tex manual-constitutive-laws.tex manual-lumping.tex manual-appendix-materials.tex figures/dynamic_analysis.png figures/explicit_dynamic.pdf figures/explicit_dynamic.svg figures/static.pdf figures/static.svg figures/hooke_law.pdf figures/implicit_dynamic.pdf figures/implicit_dynamic.svg figures/problemDomain.pdf_tex figures/problemDomain.pdf figures/static_analysis.png figures/stress_strain_el.pdf figures/tangent.pdf figures/tangent.svg figures/stress_strain_neo.pdf figures/visco_elastic_law.pdf figures/isotropic_hardening_plasticity.pdf figures/stress_strain_visco.pdf ) package_declare_extra_files_to_package(solid_mechanics SOURCES model/solid_mechanics/material_list.hh.in ) diff --git a/python/setup.py.in b/python/setup.py.in index f373e97c0..bd7f40535 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -1,28 +1,38 @@ from distutils.core import setup from distutils.core import setup, Extension import os import sys os.environ['CC'] = '@CMAKE_CXX_COMPILER@' os.environ['CXX'] = '@CMAKE_CXX_COMPILER@' def cmake_to_list(cmake_list): if cmake_list == '': return [] return cmake_list.split(';') +# https://stackoverflow.com/a/29634231 +# Remove the "-Wstrict-prototypes" compiler option, which isn't valid for C++. +import distutils.sysconfig +cfg_vars = distutils.sysconfig.get_config_vars() +for key, value in cfg_vars.items(): + if type(value) == str: + cfg_vars[key] = value.replace("-Wstrict-prototypes", "") +# ================================== + setup( name='akantu', license='LGPLv3', version='@AKANTU_VERSION@', py_modules=['akantu'], ext_modules=[Extension( '_akantu', cmake_to_list('@_ext_files@'), include_dirs=cmake_to_list('@_inc_dirs@'), language='c++', libraries=cmake_to_list('@_akantu_lib_name@'), library_dirs=cmake_to_list('@_lib_dirs@'), + runtime_library_dirs=cmake_to_list('@_lib_dirs@'), extra_compile_args=cmake_to_list('@_flags@') )] ) diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i index e533ce1bf..9152573a4 100644 --- a/python/swig/aka_array.i +++ b/python/swig/aka_array.i @@ -1,342 +1,342 @@ /** * @file aka_array.i * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Fri Dec 12 2014 * @date last modification: Wed Nov 11 2015 * * @brief wrapper for arrays * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ %{ #define SWIG_FILE_WITH_INIT #include "aka_array.hh" #include "aka_types.hh" %} %include "typemaps.i" namespace akantu { %ignore Array::operator=; %ignore Array::operator[]; %ignore Array::operator(); %ignore Array::set; %ignore Array::begin; %ignore Array::end; %ignore Array::begin_reinterpret; %ignore Array::end_reinterpret; %ignore ArrayBase::getSize; %ignore Array::operator*=; %ignore Array::operator*; }; %include "aka_array.hh" namespace akantu { %ignore TensorProxy::operator=; %ignore TensorProxy::operator[]; %ignore TensorProxy::operator(); %ignore Tensor3Proxy::operator=; %ignore Tensor3Proxy::operator[]; %ignore Tensor3Proxy::operator(); %ignore TensorStorage::operator=; %ignore TensorStorage::operator[]; %ignore TensorStorage::operator(); %ignore VectorProxy::operator=; %ignore VectorProxy::operator[]; %ignore VectorProxy::operator(); %ignore MatrixProxy::operator=; %ignore MatrixProxy::operator[]; %ignore MatrixProxy::operator(); %ignore Matrix::operator=; %ignore Matrix::operator[]; %ignore Matrix::operator(); %ignore Tensor3::operator=; %ignore Tensor3::operator[]; %ignore Tensor3::operator(); %ignore Vector::operator=; %ignore Vector::operator[]; %ignore Vector::operator(); %ignore Vector::solve; }; %include "aka_types.hh" // namespace akantu { // %template(RArray) Array; // %template(UArray) Array; // %template(BArray) Array; // %template(RVector) Vector; // }; %include "numpy.i" %init %{ import_array(); %} %inline %{ namespace akantu { template class ArrayForPython : public Array { protected: // deallocate the memory void deallocate() override final {} // allocate the memory void allocate(UInt size, UInt nb_component) override final {} // allocate and initialize the memory void allocate(UInt size, UInt nb_component, const T & value) override final {} public: ArrayForPython(T * data, UInt size, UInt nb_component, const ID & id) { this->id = id; this->values = data; this->size_ = size; this->nb_component = nb_component; } ArrayForPython(const Array & src) { this->values = src.storage(); this->size_ = src.size(); this->nb_component = src.getNbComponent(); } void resize(UInt size, const T & val) override final { if (size == this->size_) return; AKANTU_EXCEPTION("cannot resize a temporary array"); } void resize(UInt new_size) override final { if (new_size == this->size_) return; AKANTU_EXCEPTION("cannot resize a temporary array"); } - void reserve(UInt new_size) override final { - if (new_size == this->size_) return; + void reserve(UInt size, UInt new_size = UInt(-1)) override final { + if (size == this->size_) return; AKANTU_EXCEPTION("cannot resize a temporary array"); } }; } template int getPythonDataTypeCode() { AKANTU_EXCEPTION("undefined type"); } template <> int getPythonDataTypeCode() { int data_typecode = NPY_NOTYPE; size_t s = sizeof(bool); switch (s) { case 1: data_typecode = NPY_BOOL; break; case 2: data_typecode = NPY_UINT16; break; case 4: data_typecode = NPY_UINT32; break; case 8: data_typecode = NPY_UINT64; break; } return data_typecode; } template <> int getPythonDataTypeCode() { return NPY_DOUBLE; } template <> int getPythonDataTypeCode() { return NPY_LONGDOUBLE; } template <> int getPythonDataTypeCode() { return NPY_FLOAT; } template <> int getPythonDataTypeCode() { int data_typecode = NPY_NOTYPE; size_t s = sizeof(unsigned long); switch (s) { case 2: data_typecode = NPY_UINT16; break; case 4: data_typecode = NPY_UINT32; break; case 8: data_typecode = NPY_UINT64; break; } return data_typecode; } template <> int getPythonDataTypeCode() { int data_typecode = NPY_NOTYPE; size_t s = sizeof(akantu::UInt); switch (s) { case 2: data_typecode = NPY_UINT16; break; case 4: data_typecode = NPY_UINT32; break; case 8: data_typecode = NPY_UINT64; break; } return data_typecode; } template <> int getPythonDataTypeCode() { int data_typecode = NPY_NOTYPE; size_t s = sizeof(int); switch (s) { case 2: data_typecode = NPY_INT16; break; case 4: data_typecode = NPY_INT32; break; case 8: data_typecode = NPY_INT64; break; } return data_typecode; } int getSizeOfPythonType(int type_num) { switch (type_num) { case NPY_INT16: return 2; break; case NPY_UINT16: return 2; break; case NPY_INT32: return 4; break; case NPY_UINT32: return 4; break; case NPY_INT64: return 8; break; case NPY_UINT64: return 8; break; case NPY_FLOAT: return sizeof(float); break; case NPY_DOUBLE: return sizeof(double); break; case NPY_LONGDOUBLE: return sizeof(long double); break; } return 0; } std::string getPythonTypeName(int type_num) { switch (type_num) { case NPY_INT16: return "NPY_INT16"; break; case NPY_UINT16: return "NPY_UINT16"; break; case NPY_INT32: return "NPY_INT32"; break; case NPY_UINT32: return "NPY_UINT32"; break; case NPY_INT64: return "NPY_INT64"; break; case NPY_UINT64: return "NPY_UINT64"; break; case NPY_FLOAT: return "NPY_FLOAT"; break; case NPY_DOUBLE: return "NPY_DOUBLE"; break; case NPY_LONGDOUBLE: return "NPY_LONGDOUBLE"; break; } return 0; } template void checkDataType(int type_num) { AKANTU_DEBUG_ASSERT( type_num == getPythonDataTypeCode(), "incompatible types between numpy and input function: " << type_num << " != " << getPythonDataTypeCode() << std::endl << getSizeOfPythonType(type_num) << " != " << sizeof(T) << std::endl << "The numpy array is of type " << getPythonTypeName(type_num)); } %} %define %akantu_array_typemaps(DATA_TYPE) %typemap(out, fragment="NumPy_Fragments") (akantu::Array< DATA_TYPE > &) { int data_typecode = getPythonDataTypeCode(); npy_intp dims[2] = {npy_intp($1->size()), npy_intp($1->getNbComponent())}; PyObject * obj = PyArray_SimpleNewFromData(2, dims, data_typecode, $1->storage()); PyArrayObject * array = (PyArrayObject *)obj; if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result, obj); } %typemap(in) akantu::Array< DATA_TYPE > & { if (!PyArray_Check($input)) { AKANTU_EXCEPTION("incompatible input which is not a numpy"); } else { PyArray_Descr * numpy_type = (PyArray_Descr *)PyArray_DESCR((PyArrayObject *)$input); int type_num = numpy_type->type_num; checkDataType(type_num); UInt _n = PyArray_NDIM((PyArrayObject *)$input); if (_n != 2) AKANTU_EXCEPTION("incompatible numpy dimension " << _n); npy_intp * ndims = PyArray_DIMS((PyArrayObject *)$input); akantu::UInt sz = ndims[0]; akantu::UInt nb_components = ndims[1]; PyArrayIterObject * iter = (PyArrayIterObject *)PyArray_IterNew($input); if (iter == NULL) AKANTU_EXCEPTION("Python internal error"); $1 = new akantu::ArrayForPython((DATA_TYPE *)(iter->dataptr), sz, nb_components, "tmp_array_for_python"); } } %enddef %akantu_array_typemaps(double ) %akantu_array_typemaps(float ) %akantu_array_typemaps(unsigned int) %akantu_array_typemaps(unsigned long) %akantu_array_typemaps(int ) %akantu_array_typemaps(bool ) diff --git a/python/swig/mesh.i b/python/swig/mesh.i index 6c74b2d42..f294f8730 100644 --- a/python/swig/mesh.i +++ b/python/swig/mesh.i @@ -1,229 +1,230 @@ /** * @file mesh.i * * @author Guillaume Anciaux * @author Fabian Barras * @author Aurelia Isabel Cuba Ramos * @author Nicolas Richart * * @date creation: Fri Dec 12 2014 * @date last modification: Wed Jan 13 2016 * * @brief mesh wrapper * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ %{ #include "mesh.hh" #include "node_group.hh" #include "solid_mechanics_model.hh" #include "python_functor.hh" #include "mesh_utils.hh" #include "aka_bbox.hh" #include "mesh_accessor.hh" +#include "communicator.hh" using akantu::IntegrationPoint; using akantu::Vector; using akantu::ElementTypeMapArray; using akantu::MatrixProxy; using akantu::Matrix; using akantu::UInt; using akantu::Real; using akantu::Array; using akantu::BBox; +using akantu::Communicator; using akantu::SolidMechanicsModel; %} namespace akantu { %ignore NewNodesEvent; %ignore RemovedNodesEvent; %ignore NewElementsEvent; %ignore RemovedElementsEvent; %ignore MeshEventHandler; %ignore MeshEvent< UInt >; %ignore MeshEvent< Element >; %ignore Mesh::extractNodalCoordinatesFromPBCElement; %ignore Mesh::getGroupDumer; %ignore Mesh::getFacetLocalConnectivity; %ignore Mesh::getAllFacetTypes; %ignore Mesh::getCommunicator; %ignore Mesh::getConnectivities; %ignode Mesh::getBBox; %ignore GroupManager::getElementGroups; %ignore Dumpable::addDumpFieldExternalReal; } print_self(Mesh) // Swig considers enums to be ints, and it creates a conflict with two versions of getNbElement() %rename(getNbElementByDimension) akantu::Mesh::getNbElement(const UInt spatial_dimension = _all_dimensions, const GhostType& ghost_type = _not_ghost, const ElementKind& kind = _ek_not_defined) const; %extend akantu::Mesh { - - PyObject * getElementGroups(){ - return akantu::PythonFunctor::convertToPython($self->getElementGroups()); - } + // PyObject * getElementGroups(){ + // return akantu::PythonFunctor::convertToPython($self->getElementGroups()); + // } PyObject * getAllConnectivities(){ return akantu::PythonFunctor::convertToPython($self->getConnectivities()); } void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) { Array & nodes = const_cast &>($self->getNodes()); nodes.resize(nb_nodes); $self->addConnectivityType(type); Array & connectivity = const_cast &>($self->getConnectivity(type)); connectivity.resize(nb_element); } Array & getNodalDataReal(const ID & name, UInt nb_components = 1) { auto && data = $self->getNodalData(name, nb_components); data.resize($self->getNbNodes()); return data; } bool hasDataReal(const ID & name, const ElementType & type) { return $self->hasData(name, type); } Array & getElementalDataReal(const ID & name, const ElementType & type, UInt nb_components = 1) { auto && data = $self->getElementalDataArrayAlloc(name, type, akantu::_not_ghost, nb_components); data.resize($self->getNbElement(type, akantu::_not_ghost)); return data; } Array & getElementalDataUInt(const ID & name, const ElementType & type, UInt nb_components = 1) { auto && data = $self->getElementalDataArrayAlloc(name, type, akantu::_not_ghost, nb_components); data.resize($self->getNbElement(type, akantu::_not_ghost)); return data; } Array & computeBarycenters(const ElementType & type) { auto dim = $self->getSpatialDimension(); auto && data = $self->getElementalDataArrayAlloc("barycenters", type, akantu::_not_ghost, dim); auto nb_el = data.size(); auto total_nb_el = $self->getNbElement(type, akantu::_not_ghost); data.resize(total_nb_el); auto bary_it = make_view(data, dim).begin() + nb_el; for (auto el = nb_el; el < total_nb_el; ++el) { $self->getBarycenter(akantu::Element{type, el, akantu::_not_ghost}, *bary_it); ++bary_it; } return data; } void ready() { akantu::MeshAccessor ma(* $self); ma.makeReady(); } } %extend akantu::GroupManager { void createGroupsFromStringMeshData(const std::string & dataset_name) { if (dataset_name == "physical_names"){ AKANTU_EXCEPTION("Deprecated behavior: no need to call 'createGroupsFromStringMeshData' for physical names"); } $self->createGroupsFromMeshData(dataset_name); } void createGroupsFromUIntMeshData(const std::string & dataset_name) { $self->createGroupsFromMeshData(dataset_name); } } %extend akantu::NodeGroup { akantu::Array & getGroupedNodes(akantu::Array & surface_array, Mesh & mesh) { auto && group_node = $self->getNodes(); auto && full_array = mesh.getNodes(); surface_array.resize(group_node.size()); for (UInt i = 0; i < group_node.size(); ++i) { for (UInt cmp = 0; cmp < full_array.getNbComponent(); ++cmp) { surface_array(i, cmp) = full_array(group_node(i), cmp); } } akantu::Array & res(surface_array); return res; } akantu::Array & getGroupedArray(akantu::Array & surface_array, akantu::SolidMechanicsModel & model, int type) { akantu::Array * full_array; switch (type) { case 0 : full_array = new akantu::Array(model.getDisplacement()); break; case 1 : full_array = new akantu::Array(model.getVelocity()); break; - case 2 : full_array = new akantu::Array(model.getForce()); + case 2 : full_array = new akantu::Array(model.getExternalForce()); break; } akantu::Array group_node = $self->getNodes(); surface_array.resize(group_node.size()); for (UInt i = 0; i < group_node.size(); ++i) { for (UInt cmp = 0; cmp < full_array->getNbComponent(); ++cmp) { surface_array(i,cmp) = (*full_array)(group_node(i),cmp); } } akantu::Array & res(surface_array); return res; } } %include "group_manager.hh" %include "node_group.hh" %include "dumper_iohelper.hh" %include "dumpable_iohelper.hh" %include "element_group.hh" %include "mesh.hh" %include "mesh_utils.hh" %include "aka_bbox.hh" namespace akantu{ %extend Dumpable { void addDumpFieldExternalReal(const std::string & field_id, const Array & field){ $self->addDumpFieldExternal(field_id,field); } } } diff --git a/python/swig/model.i b/python/swig/model.i index 4cb6acdba..5fbdc89df 100644 --- a/python/swig/model.i +++ b/python/swig/model.i @@ -1,116 +1,121 @@ /** * @file model.i * * @author Guillaume Anciaux * @author Aurelia Isabel Cuba Ramos * @author Nicolas Richart * * @date creation: Fri Dec 12 2014 * @date last modification: Wed Nov 11 2015 * * @brief model wrapper * * @section LICENSE * * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory * (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ %{ #include "boundary_condition_python_functor.hh" #include "model_solver.hh" #include "non_linear_solver.hh" + #include "sparse_matrix_aij.hh" %} namespace akantu { %ignore Model::createSynchronizerRegistry; %ignore Model::getSynchronizerRegistry; %ignore Model::createParallelSynch; %ignore Model::getDOFSynchronizer; %ignore Model::registerFEEngineObject; %ignore Model::unregisterFEEngineObject; // %ignore Model::getFEEngineBoundary; // %ignore Model::getFEEngine; %ignore Model::getFEEngineClass; %ignore Model::getFEEngineClassBoundary; %ignore Model::setParser; %ignore Model::updateDataForNonLocalCriterion; %ignore IntegrationPoint::operator=; } %include "sparse_matrix.i" %include "fe_engine.hh" %rename(FreeBoundaryDirichlet) akantu::BC::Dirichlet::FreeBoundary; %rename(FreeBoundaryNeumann) akantu::BC::Neumann::FreeBoundary; %rename(PythonBoundary) akantu::BC::Dirichlet::PythonFunctor; %include "boundary_condition_functor.hh" %include "boundary_condition.hh" %include "boundary_condition_python_functor.hh" %include "communication_buffer.hh" %include "data_accessor.hh" //%include "synchronizer.hh" //%include "synchronizer_registry.hh" %include "model.hh" %include "non_linear_solver.hh" %include "model_options.hh" %extend akantu::Model { void initFullImpl( const akantu::ModelOptions & options = akantu::ModelOptions()){ $self->initFull(options); }; + akantu::SparseMatrixAIJ & getMatrix(const std::string & name){ + return dynamic_cast($self->getDOFManager().getMatrix(name)); + }; + %insert("python") %{ def initFull(self, *args, **kwargs): if len(args) == 0: import importlib as __aka_importlib _module = __aka_importlib.import_module(self.__module__) _cls = getattr(_module, "{0}Options".format(self.__class__.__name__)) options = _cls() if len(kwargs) > 0: for key, val in kwargs.items(): if key[0] == '_': key = key[1:] setattr(options, key, val) else: options = args[0] self.initFullImpl(options) %} void solveStep(const akantu::ID & id=""){ $self->solveStep(id); } akantu::NonLinearSolver & getNonLinearSolver(const akantu::ID & id=""){ return $self->getNonLinearSolver(id); } } %extend akantu::NonLinearSolver { void set(const std::string & id, akantu::Real val){ if (id == "max_iterations") $self->set(id, int(val)); else if (id == "convergence_type") $self->set(id, akantu::SolveConvergenceCriteria(UInt(val))); else $self->set(id, val); } } diff --git a/python/swig/sparse_matrix.i b/python/swig/sparse_matrix.i index f3c2dc6b0..24785d7a1 100644 --- a/python/swig/sparse_matrix.i +++ b/python/swig/sparse_matrix.i @@ -1,34 +1,36 @@ %include "sparse_matrix.hh" +%include "sparse_matrix_aij.hh" + %pythoncode %{ import scipy.sparse import numpy as _np class AkantuSparseMatrix (scipy.sparse.coo_matrix) : def __init__(self,aka_sparse): self.aka_sparse = aka_sparse - matrix_type = self.aka_sparse.getSparseMatrixType() + matrix_type = self.aka_sparse.getMatrixType() sz = self.aka_sparse.size() row = self.aka_sparse.getIRN()[:,0] -1 col = self.aka_sparse.getJCN()[:,0] -1 data = self.aka_sparse.getA()[:,0] row = row.copy() col = col.copy() data = data.copy() if matrix_type == _symmetric: non_diags = (row != col) row_sup = col[non_diags] col_sup = row[non_diags] data_sup = data[non_diags] col = _np.concatenate((col,col_sup)) row = _np.concatenate((row,row_sup)) data = _np.concatenate((data,data_sup)) scipy.sparse.coo_matrix.__init__(self,(data, (row,col)),shape=(sz,sz)) %} diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh index 89d88b4b2..001d5e6ba 100644 --- a/src/common/aka_common.hh +++ b/src/common/aka_common.hh @@ -1,621 +1,623 @@ /** * @file aka_common.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Mon Jun 14 2010 * @date last modification: Mon Feb 12 2018 * * @brief common type descriptions for akantu * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * * @section DESCRIPTION * * All common things to be included in the projects files * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_COMMON_HH__ #define __AKANTU_COMMON_HH__ #include "aka_compatibilty_with_cpp_standard.hh" /* -------------------------------------------------------------------------- */ #define __BEGIN_AKANTU_DUMPER__ namespace dumper { #define __END_AKANTU_DUMPER__ } /* -------------------------------------------------------------------------- */ #if defined(WIN32) #define __attribute__(x) #endif /* -------------------------------------------------------------------------- */ #include "aka_config.hh" #include "aka_error.hh" #include "aka_safe_enum.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include #include #include /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ /* Constants */ /* -------------------------------------------------------------------------- */ namespace { __attribute__((unused)) constexpr UInt _all_dimensions{ std::numeric_limits::max()}; #ifdef AKANTU_NDEBUG __attribute__((unused)) constexpr Real REAL_INIT_VALUE{0.}; #else __attribute__((unused)) constexpr Real REAL_INIT_VALUE{ std::numeric_limits::quiet_NaN()}; #endif } // namespace /* -------------------------------------------------------------------------- */ /* Common types */ /* -------------------------------------------------------------------------- */ using ID = std::string; using MemoryID = UInt; } // namespace akantu /* -------------------------------------------------------------------------- */ #ifndef SWIG #include "aka_enum_macros.hh" #endif /* -------------------------------------------------------------------------- */ #include "aka_element_classes_info.hh" namespace akantu { /* -------------------------------------------------------------------------- */ /* Mesh/FEM/Model types */ /* -------------------------------------------------------------------------- */ /// small help to use names for directions enum SpatialDirection { _x = 0, _y = 1, _z = 2 }; /// enum MeshIOType type of mesh reader/writer enum MeshIOType { _miot_auto, ///< Auto guess of the reader to use based on the extension _miot_gmsh, ///< Gmsh files _miot_gmsh_struct, ///< Gsmh reader with reintpretation of elements has /// structures elements _miot_diana, ///< TNO Diana mesh format _miot_abaqus ///< Abaqus mesh format }; /// enum MeshEventHandlerPriority defines relative order of execution of /// events enum EventHandlerPriority { _ehp_highest = 0, _ehp_mesh = 5, _ehp_fe_engine = 9, _ehp_synchronizer = 10, _ehp_dof_manager = 20, _ehp_model = 94, _ehp_non_local_manager = 100, _ehp_lowest = 100 }; #ifndef SWIG // clang-format off #define AKANTU_MODEL_TYPES \ (model) \ (solid_mechanics_model) \ (solid_mechanics_model_cohesive) \ (heat_transfer_model) \ (structural_mechanics_model) \ (embedded_model) // clang-format on AKANTU_CLASS_ENUM_DECLARE(ModelType, AKANTU_MODEL_TYPES) AKANTU_CLASS_ENUM_OUTPUT_STREAM(ModelType, AKANTU_MODEL_TYPES) AKANTU_CLASS_ENUM_INPUT_STREAM(ModelType, AKANTU_MODEL_TYPES) #else /// enum ModelType defines which type of physics is solved enum class ModelType { _model, _solid_mechanics_model, _solid_mechanics_model_cohesive, _heat_transfer_model, _structural_mechanics_model, _embedded_model }; #endif /// enum AnalysisMethod type of solving method used to solve the equation of /// motion enum AnalysisMethod { _static = 0, _implicit_dynamic = 1, _explicit_lumped_mass = 2, _explicit_lumped_capacity = 2, _explicit_consistent_mass = 3 }; /// enum DOFSupportType defines which kind of dof that can exists enum DOFSupportType { _dst_nodal, _dst_generic }; #if !defined(SWIG) && !defined(DOXYGEN) // clang-format off #define AKANTU_NON_LINEAR_SOLVER_TYPES \ (linear) \ (newton_raphson) \ (newton_raphson_modified) \ (lumped) \ (gmres) \ (bfgs) \ (cg) \ (auto) // clang-format on AKANTU_CLASS_ENUM_DECLARE(NonLinearSolverType, AKANTU_NON_LINEAR_SOLVER_TYPES) AKANTU_CLASS_ENUM_OUTPUT_STREAM(NonLinearSolverType, AKANTU_NON_LINEAR_SOLVER_TYPES) AKANTU_CLASS_ENUM_INPUT_STREAM(NonLinearSolverType, AKANTU_NON_LINEAR_SOLVER_TYPES) #else /// Type of non linear resolution available in akantu enum class NonLinearSolverType { _linear, ///< No non linear convergence loop _newton_raphson, ///< Regular Newton-Raphson _newton_raphson_modified, ///< Newton-Raphson with initial tangent _lumped, ///< Case of lumped mass or equivalent matrix _gmres, _bfgs, _cg, _auto ///< This will take a default value that make sense in case of /// model::getNewSolver }; #endif #if !defined(SWIG) && !defined(DOXYGEN) // clang-format off #define AKANTU_TIME_STEP_SOLVER_TYPE \ (static) \ (dynamic) \ (dynamic_lumped) \ (not_defined) // clang-format on AKANTU_CLASS_ENUM_DECLARE(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE) AKANTU_CLASS_ENUM_OUTPUT_STREAM(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE) AKANTU_CLASS_ENUM_INPUT_STREAM(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE) #else /// Type of time stepping solver enum class TimeStepSolverType { _static, ///< Static solution _dynamic, ///< Dynamic solver _dynamic_lumped, ///< Dynamic solver with lumped mass _not_defined, ///< For not defined cases }; #endif #if !defined(SWIG) && !defined(DOXYGEN) // clang-format off #define AKANTU_INTEGRATION_SCHEME_TYPE \ (pseudo_time) \ (forward_euler) \ (trapezoidal_rule_1) \ (backward_euler) \ (central_difference) \ (fox_goodwin) \ (trapezoidal_rule_2) \ (linear_acceleration) \ (newmark_beta) \ (generalized_trapezoidal) // clang-format on AKANTU_CLASS_ENUM_DECLARE(IntegrationSchemeType, AKANTU_INTEGRATION_SCHEME_TYPE) AKANTU_CLASS_ENUM_OUTPUT_STREAM(IntegrationSchemeType, AKANTU_INTEGRATION_SCHEME_TYPE) AKANTU_CLASS_ENUM_INPUT_STREAM(IntegrationSchemeType, AKANTU_INTEGRATION_SCHEME_TYPE) #else /// Type of integration scheme enum class IntegrationSchemeType { _pseudo_time, ///< Pseudo Time _forward_euler, ///< GeneralizedTrapezoidal(0) _trapezoidal_rule_1, ///< GeneralizedTrapezoidal(1/2) _backward_euler, ///< GeneralizedTrapezoidal(1) _central_difference, ///< NewmarkBeta(0, 1/2) _fox_goodwin, ///< NewmarkBeta(1/6, 1/2) _trapezoidal_rule_2, ///< NewmarkBeta(1/2, 1/2) _linear_acceleration, ///< NewmarkBeta(1/3, 1/2) _newmark_beta, ///< generic NewmarkBeta with user defined /// alpha and beta _generalized_trapezoidal ///< generic GeneralizedTrapezoidal with user /// defined alpha }; #endif #if !defined(SWIG) && !defined(DOXYGEN) // clang-format off #define AKANTU_SOLVE_CONVERGENCE_CRITERIA \ (residual) \ (solution) \ (residual_mass_wgh) // clang-format on AKANTU_CLASS_ENUM_DECLARE(SolveConvergenceCriteria, AKANTU_SOLVE_CONVERGENCE_CRITERIA) AKANTU_CLASS_ENUM_OUTPUT_STREAM(SolveConvergenceCriteria, AKANTU_SOLVE_CONVERGENCE_CRITERIA) AKANTU_CLASS_ENUM_INPUT_STREAM(SolveConvergenceCriteria, AKANTU_SOLVE_CONVERGENCE_CRITERIA) #else /// enum SolveConvergenceCriteria different convergence criteria enum class SolveConvergenceCriteria { _residual, ///< Use residual to test the convergence _solution, ///< Use solution to test the convergence _residual_mass_wgh ///< Use residual weighted by inv. nodal mass to ///< testb }; #endif /// enum CohesiveMethod type of insertion of cohesive elements enum CohesiveMethod { _intrinsic, _extrinsic }; /// @enum SparseMatrixType type of sparse matrix used enum MatrixType { _unsymmetric, _symmetric, _mt_not_defined }; /* -------------------------------------------------------------------------- */ /* Ghosts handling */ /* -------------------------------------------------------------------------- */ /// @enum CommunicatorType type of communication method to use enum CommunicatorType { _communicator_mpi, _communicator_dummy }; #if !defined(SWIG) && !defined(DOXYGEN) // clang-format off #define AKANTU_SYNCHRONIZATION_TAG \ (whatever) \ (update) \ (ask_nodes) \ (size) \ (smm_mass) \ (smm_for_gradu) \ (smm_boundary) \ (smm_uv) \ (smm_res) \ (smm_init_mat) \ (smm_stress) \ (smmc_facets) \ (smmc_facets_conn) \ (smmc_facets_stress) \ (smmc_damage) \ (giu_global_conn) \ (ce_groups) \ (gm_clusters) \ (htm_temperature) \ (htm_gradient_temperature) \ (htm_phi) \ (htm_gradient_phi) \ (mnl_for_average) \ (mnl_weight) \ (nh_criterion) \ (test) \ (user_1) \ (user_2) \ (material_id) \ (for_dump) \ (cf_nodal) \ (cf_incr) \ (solver_solution) // clang-format on AKANTU_CLASS_ENUM_DECLARE(SynchronizationTag, AKANTU_SYNCHRONIZATION_TAG) AKANTU_CLASS_ENUM_OUTPUT_STREAM(SynchronizationTag, AKANTU_SYNCHRONIZATION_TAG) #else /// @enum SynchronizationTag type of synchronizations enum class SynchronizationTag { //--- Generic tags --- _whatever, _update, _ask_nodes, _size, //--- SolidMechanicsModel tags --- _smm_mass, ///< synchronization of the SolidMechanicsModel.mass _smm_for_gradu, ///< synchronization of the /// SolidMechanicsModel.displacement _smm_boundary, ///< synchronization of the boundary, forces, velocities /// and displacement _smm_uv, ///< synchronization of the nodal velocities and displacement _smm_res, ///< synchronization of the nodal residual _smm_init_mat, ///< synchronization of the data to initialize materials _smm_stress, ///< synchronization of the stresses to compute the ///< internal /// forces _smmc_facets, ///< synchronization of facet data to setup facet synch _smmc_facets_conn, ///< synchronization of facet global connectivity _smmc_facets_stress, ///< synchronization of facets' stress to setup ///< facet /// synch _smmc_damage, ///< synchronization of damage // --- GlobalIdsUpdater tags --- _giu_global_conn, ///< synchronization of global connectivities // --- CohesiveElementInserter tags --- _ce_groups, ///< synchronization of cohesive element insertion depending /// on facet groups // --- GroupManager tags --- _gm_clusters, ///< synchronization of clusters // --- HeatTransfer tags --- _htm_temperature, ///< synchronization of the nodal temperature _htm_gradient_temperature, ///< synchronization of the element gradient /// temperature // --- LevelSet tags --- _htm_phi, ///< synchronization of the nodal level set value phi _htm_gradient_phi, ///< synchronization of the element gradient phi //--- Material non local --- _mnl_for_average, ///< synchronization of data to average in non local /// material _mnl_weight, ///< synchronization of data for the weight computations // --- NeighborhoodSynchronization tags --- _nh_criterion, // --- General tags --- _test, ///< Test tag _user_1, ///< tag for user simulations _user_2, ///< tag for user simulations _material_id, ///< synchronization of the material ids _for_dump, ///< everything that needs to be synch before dump // --- Contact & Friction --- _cf_nodal, ///< synchronization of disp, velo, and current position _cf_incr, ///< synchronization of increment // --- Solver tags --- _solver_solution ///< synchronization of the solution obained with the /// PETSc solver }; #endif /// @enum GhostType type of ghost enum GhostType { _not_ghost = 0, _ghost = 1, _casper // not used but a real cute ghost }; /// Define the flag that can be set to a node enum class NodeFlag : std::uint8_t { _normal = 0x00, _distributed = 0x01, _master = 0x03, _slave = 0x05, _pure_ghost = 0x09, _shared_mask = 0x0F, _periodic = 0x10, _periodic_master = 0x30, _periodic_slave = 0x50, _periodic_mask = 0xF0, _local_master_mask = 0xCC, // ~(_master & _periodic_mask) }; inline NodeFlag operator&(const NodeFlag & a, const NodeFlag & b) { using under = std::underlying_type_t; return NodeFlag(under(a) & under(b)); } inline NodeFlag operator|(const NodeFlag & a, const NodeFlag & b) { using under = std::underlying_type_t; return NodeFlag(under(a) | under(b)); } inline NodeFlag & operator|=(NodeFlag & a, const NodeFlag & b) { a = a | b; return a; } inline NodeFlag & operator&=(NodeFlag & a, const NodeFlag & b) { a = a & b; return a; } inline NodeFlag operator~(const NodeFlag & a) { using under = std::underlying_type_t; return NodeFlag(~under(a)); } inline std::ostream & operator<<(std::ostream & stream, const NodeFlag & flag) { using under = std::underlying_type_t; stream << under(flag); return stream; } } // namespace akantu #ifndef SWIG AKANTU_ENUM_HASH(GhostType) #endif namespace akantu { /* -------------------------------------------------------------------------- */ struct GhostType_def { using type = GhostType; static const type _begin_ = _not_ghost; static const type _end_ = _casper; }; using ghost_type_t = safe_enum; extern ghost_type_t ghost_types; /// standard output stream operator for GhostType inline std::ostream & operator<<(std::ostream & stream, GhostType type); /* -------------------------------------------------------------------------- */ /* Global defines */ /* -------------------------------------------------------------------------- */ #define AKANTU_MIN_ALLOCATION 2000 #define AKANTU_INDENT ' ' #define AKANTU_INCLUDE_INLINE_IMPL /* -------------------------------------------------------------------------- */ #define AKANTU_SET_MACRO(name, variable, type) \ inline void set##name(type variable) { this->variable = variable; } #define AKANTU_GET_MACRO(name, variable, type) \ inline type get##name() const { return variable; } #define AKANTU_GET_MACRO_NOT_CONST(name, variable, type) \ inline type get##name() { return variable; } #define AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, support, con) \ inline con Array & get##name( \ const support & el_type, const GhostType & ghost_type = _not_ghost) \ con { \ return variable(el_type, ghost_type); \ } #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, ) #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, const) #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, ) #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE_CONST(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, const) /* -------------------------------------------------------------------------- */ /// initialize the static part of akantu void initialize(int & argc, char **& argv); /// initialize the static part of akantu and read the global input_file void initialize(const std::string & input_file, int & argc, char **& argv); /* -------------------------------------------------------------------------- */ /// finilize correctly akantu and clean the memory void finalize(); /* -------------------------------------------------------------------------- */ /// Read an new input file void readInputFile(const std::string & input_file); /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* string manipulation */ /* -------------------------------------------------------------------------- */ inline std::string to_lower(const std::string & str); /* -------------------------------------------------------------------------- */ inline std::string trim(const std::string & to_trim); inline std::string trim(const std::string & to_trim, char c); /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /// give a string representation of the a human readable size in bit template std::string printMemorySize(UInt size); /* -------------------------------------------------------------------------- */ struct TensorTrait {}; } // namespace akantu /* -------------------------------------------------------------------------- */ /* Type traits */ /* -------------------------------------------------------------------------- */ namespace aka { /* ------------------------------------------------------------------------ */ template using is_tensor = std::is_base_of; /* ------------------------------------------------------------------------ */ template using is_scalar = std::is_arithmetic; /* ------------------------------------------------------------------------ */ +#if not defined(SWIG) template ::value> * = nullptr> bool is_of_type(T && t) { return ( dynamic_cast>::value, std::add_const_t, R>>>(&t) != nullptr); } /* ------------------------------------------------------------------------ */ template ::value> * = nullptr> decltype(auto) as_type(T && t) { static_assert( disjunction< std::is_base_of, std::decay_t>, // down-cast std::is_base_of, std::decay_t> // up-cast >::value, "Type T and R are not valid for a as_type conversion"); return dynamic_cast>::value, std::add_const_t, R>>>(t); } +#endif } // namespace aka #include "aka_fwd.hh" namespace akantu { /// get access to the internal argument parser cppargparse::ArgumentParser & getStaticArgumentParser(); /// get access to the internal input file parser Parser & getStaticParser(); /// get access to the user part of the internal input file parser const ParserSection & getUserParser(); } // namespace akantu #include "aka_common_inline_impl.cc" /* -------------------------------------------------------------------------- */ #if AKANTU_INTEGER_SIZE == 4 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b9 #elif AKANTU_INTEGER_SIZE == 8 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b97f4a7c13LL #endif namespace std { /** * Hashing function for pairs based on hash_combine from boost The magic * number is coming from the golden number @f[\phi = \frac{1 + \sqrt5}{2}@f] * @f[\frac{2^32}{\phi} = 0x9e3779b9@f] * http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine * http://burtleburtle.net/bob/hash/doobs.html */ template struct hash> { hash() = default; size_t operator()(const std::pair & p) const { size_t seed = ah(p.first); return bh(p.second) + AKANTU_HASH_COMBINE_MAGIC_NUMBER + (seed << 6) + (seed >> 2); } private: const hash ah{}; const hash bh{}; }; } // namespace std #endif /* __AKANTU_COMMON_HH__ */ diff --git a/src/common/aka_types.hh b/src/common/aka_types.hh index 5e3c4b7e7..08dc7ca15 100644 --- a/src/common/aka_types.hh +++ b/src/common/aka_types.hh @@ -1,1418 +1,1492 @@ /** * @file aka_types.hh * * @author Nicolas Richart * * @date creation: Thu Feb 17 2011 * @date last modification: Tue Feb 20 2018 * * @brief description of the "simple" types * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_error.hh" #include "aka_fwd.hh" #include "aka_math.hh" /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_AKA_TYPES_HH__ #define __AKANTU_AKA_TYPES_HH__ namespace akantu { enum NormType { L_1 = 1, L_2 = 2, L_inf = UInt(-1) }; /** * DimHelper is a class to generalize the setup of a dim array from 3 * values. This gives a common interface in the TensorStorage class * independently of its derived inheritance (Vector, Matrix, Tensor3) * @tparam dim */ template struct DimHelper { static inline void setDims(UInt m, UInt n, UInt p, UInt dims[dim]); }; /* -------------------------------------------------------------------------- */ template <> struct DimHelper<1> { static inline void setDims(UInt m, __attribute__((unused)) UInt n, __attribute__((unused)) UInt p, UInt dims[1]) { dims[0] = m; } }; /* -------------------------------------------------------------------------- */ template <> struct DimHelper<2> { static inline void setDims(UInt m, UInt n, __attribute__((unused)) UInt p, UInt dims[2]) { dims[0] = m; dims[1] = n; } }; /* -------------------------------------------------------------------------- */ template <> struct DimHelper<3> { static inline void setDims(UInt m, UInt n, UInt p, UInt dims[3]) { dims[0] = m; dims[1] = n; dims[2] = p; } }; /* -------------------------------------------------------------------------- */ template class TensorStorage; /* -------------------------------------------------------------------------- */ /* Proxy classes */ /* -------------------------------------------------------------------------- */ namespace tensors { template struct is_copyable { enum : bool { value = false }; }; template struct is_copyable { enum : bool { value = true }; }; template struct is_copyable { enum : bool { value = true }; }; template struct is_copyable { enum : bool { value = true }; }; } // namespace tensors /** * @class TensorProxy aka_types.hh * @desc The TensorProxy class is a proxy class to the TensorStorage it handles * the * wrapped case. That is to say if an accessor should give access to a Tensor * wrapped on some data, like the Array::iterator they can return a * TensorProxy that will be automatically transformed as a TensorStorage wrapped * on the same data * @tparam T stored type * @tparam ndim order of the tensor * @tparam RetType real derived type */ template class TensorProxy { protected: using RetTypeProxy = typename _RetType::proxy; constexpr TensorProxy(T * data, UInt m, UInt n, UInt p) { DimHelper::setDims(m, n, p, this->n); this->values = data; } #ifndef SWIG - template ::value>> + template ::value>> explicit TensorProxy(const Other & other) { this->values = other.storage(); for (UInt i = 0; i < ndim; ++i) this->n[i] = other.size(i); } #endif public: using RetType = _RetType; UInt size(UInt i) const { - AKANTU_DEBUG_ASSERT(i < ndim, - "This tensor has only " << ndim << " dimensions, not " - << (i + 1)); + AKANTU_DEBUG_ASSERT(i < ndim, "This tensor has only " << ndim + << " dimensions, not " + << (i + 1)); return n[i]; } inline UInt size() const { UInt _size = 1; for (UInt d = 0; d < ndim; ++d) _size *= this->n[d]; return _size; } T * storage() const { return values; } #ifndef SWIG - template ::value>> + template ::value>> inline TensorProxy & operator=(const Other & other) { AKANTU_DEBUG_ASSERT( other.size() == this->size(), "You are trying to copy two tensors with different sizes"); memcpy(this->values, other.storage(), this->size() * sizeof(T)); return *this; } #endif // template ::value>> // inline TensorProxy & operator=(const Other && other) { // AKANTU_DEBUG_ASSERT( // other.size() == this->size(), // "You are trying to copy two tensors with different sizes"); // memcpy(this->values, other.storage(), this->size() * sizeof(T)); // return *this; // } template inline RetTypeProxy & operator*=(const O & o) { RetType(*this) *= o; return static_cast(*this); } template inline RetTypeProxy & operator/=(const O & o) { RetType(*this) /= o; return static_cast(*this); } protected: T * values; UInt n[ndim]; }; /* -------------------------------------------------------------------------- */ template class VectorProxy : public TensorProxy> { using parent = TensorProxy>; using type = Vector; public: constexpr VectorProxy(T * data, UInt n) : parent(data, n, 0, 0) {} template explicit VectorProxy(Other & src) : parent(src) {} /* ---------------------------------------------------------------------- */ template inline VectorProxy & operator=(const Other & other) { parent::operator=(other); return *this; } // inline VectorProxy & operator=(const VectorProxy && other) { // parent::operator=(other); // return *this; // } /* ------------------------------------------------------------------------ */ T & operator()(UInt index) { return this->values[index]; }; const T & operator()(UInt index) const { return this->values[index]; }; }; template class MatrixProxy : public TensorProxy> { using parent = TensorProxy>; using type = Matrix; public: MatrixProxy(T * data, UInt m, UInt n) : parent(data, m, n, 0) {} template explicit MatrixProxy(Other & src) : parent(src) {} /* ---------------------------------------------------------------------- */ template inline MatrixProxy & operator=(const Other & other) { parent::operator=(other); return *this; } }; template class Tensor3Proxy : public TensorProxy> { using parent = TensorProxy>; using type = Tensor3; public: Tensor3Proxy(const T * data, UInt m, UInt n, UInt k) : parent(data, m, n, k) {} Tensor3Proxy(const Tensor3Proxy & src) : parent(src) {} Tensor3Proxy(const Tensor3 & src) : parent(src) {} /* ---------------------------------------------------------------------- */ template inline Tensor3Proxy & operator=(const Other & other) { parent::operator=(other); return *this; } }; /* -------------------------------------------------------------------------- */ /* Tensor base class */ /* -------------------------------------------------------------------------- */ template class TensorStorage : public TensorTrait { public: using value_type = T; friend class Array; protected: template void copySize(const TensorType & src) { for (UInt d = 0; d < ndim; ++d) this->n[d] = src.size(d); this->_size = src.size(); } TensorStorage() : values(nullptr) { for (UInt d = 0; d < ndim; ++d) this->n[d] = 0; _size = 0; } TensorStorage(const TensorProxy & proxy) { this->copySize(proxy); this->values = proxy.storage(); this->wrapped = true; } public: TensorStorage(const TensorStorage & src) = delete; TensorStorage(const TensorStorage & src, bool deep_copy) : values(nullptr) { if (deep_copy) this->deepCopy(src); else this->shallowCopy(src); } protected: TensorStorage(UInt m, UInt n, UInt p, const T & def) { static_assert(std::is_trivially_constructible{}, "Cannot create a tensor on non trivial types"); DimHelper::setDims(m, n, p, this->n); this->computeSize(); this->values = new T[this->_size]; this->set(def); this->wrapped = false; } TensorStorage(T * data, UInt m, UInt n, UInt p) { DimHelper::setDims(m, n, p, this->n); this->computeSize(); this->values = data; this->wrapped = true; } public: /* ------------------------------------------------------------------------ */ template inline void shallowCopy(const TensorType & src) { this->copySize(src); if (!this->wrapped) delete[] this->values; this->values = src.storage(); this->wrapped = true; } /* ------------------------------------------------------------------------ */ template inline void deepCopy(const TensorType & src) { this->copySize(src); if (!this->wrapped) delete[] this->values; static_assert(std::is_trivially_constructible{}, "Cannot create a tensor on non trivial types"); this->values = new T[this->_size]; static_assert(std::is_trivially_copyable{}, "Cannot copy a tensor on non trivial types"); memcpy((void *)this->values, (void *)src.storage(), this->_size * sizeof(T)); this->wrapped = false; } virtual ~TensorStorage() { if (!this->wrapped) delete[] this->values; } /* ------------------------------------------------------------------------ */ inline TensorStorage & operator=(const TensorStorage & src) { return this->operator=(aka::as_type(src)); } /* ------------------------------------------------------------------------ */ inline TensorStorage & operator=(const RetType & src) { if (this != &src) { if (this->wrapped) { static_assert(std::is_trivially_copyable{}, "Cannot copy a tensor on non trivial types"); // this test is not sufficient for Tensor of order higher than 1 AKANTU_DEBUG_ASSERT(this->_size == src.size(), "Tensors of different size"); memcpy((void *)this->values, (void *)src.storage(), this->_size * sizeof(T)); } else { deepCopy(src); } } return *this; } /* ------------------------------------------------------------------------ */ template inline RetType & operator+=(const TensorStorage & other) { T * a = this->storage(); T * b = other.storage(); AKANTU_DEBUG_ASSERT( _size == other.size(), "The two tensors do not have the same size, they cannot be subtracted"); for (UInt i = 0; i < _size; ++i) *(a++) += *(b++); return *(static_cast(this)); } /* ------------------------------------------------------------------------ */ template inline RetType & operator-=(const TensorStorage & other) { T * a = this->storage(); T * b = other.storage(); AKANTU_DEBUG_ASSERT( _size == other.size(), "The two tensors do not have the same size, they cannot be subtracted"); for (UInt i = 0; i < _size; ++i) *(a++) -= *(b++); return *(static_cast(this)); } /* ------------------------------------------------------------------------ */ inline RetType & operator+=(const T & x) { T * a = this->values; for (UInt i = 0; i < _size; ++i) *(a++) += x; return *(static_cast(this)); } /* ------------------------------------------------------------------------ */ inline RetType & operator-=(const T & x) { T * a = this->values; for (UInt i = 0; i < _size; ++i) *(a++) -= x; return *(static_cast(this)); } /* ------------------------------------------------------------------------ */ inline RetType & operator*=(const T & x) { T * a = this->storage(); for (UInt i = 0; i < _size; ++i) *(a++) *= x; return *(static_cast(this)); } /* ---------------------------------------------------------------------- */ inline RetType & operator/=(const T & x) { T * a = this->values; for (UInt i = 0; i < _size; ++i) *(a++) /= x; return *(static_cast(this)); } /// Y = \alpha X + Y inline RetType & aXplusY(const TensorStorage & other, const T & alpha = 1.) { AKANTU_DEBUG_ASSERT( _size == other.size(), "The two tensors do not have the same size, they cannot be subtracted"); Math::aXplusY(this->_size, alpha, other.storage(), this->storage()); return *(static_cast(this)); } /* ------------------------------------------------------------------------ */ T * storage() const { return values; } UInt size() const { return _size; } UInt size(UInt i) const { - AKANTU_DEBUG_ASSERT(i < ndim, - "This tensor has only " << ndim << " dimensions, not " - << (i + 1)); + AKANTU_DEBUG_ASSERT(i < ndim, "This tensor has only " << ndim + << " dimensions, not " + << (i + 1)); return n[i]; }; /* ------------------------------------------------------------------------ */ inline void clear() { memset(values, 0, _size * sizeof(T)); }; inline void set(const T & t) { std::fill_n(values, _size, t); }; template inline void copy(const TensorType & other) { AKANTU_DEBUG_ASSERT( _size == other.size(), "The two tensors do not have the same size, they cannot be copied"); memcpy(values, other.storage(), _size * sizeof(T)); } bool isWrapped() const { return this->wrapped; } protected: inline void computeSize() { _size = 1; for (UInt d = 0; d < ndim; ++d) _size *= this->n[d]; } protected: template struct NormHelper { template static R norm(const Ten & ten) { R _norm = 0.; R * it = ten.storage(); R * end = ten.storage() + ten.size(); for (; it < end; ++it) _norm += std::pow(std::abs(*it), norm_type); return std::pow(_norm, 1. / norm_type); } }; template struct NormHelper { template static R norm(const Ten & ten) { R _norm = 0.; R * it = ten.storage(); R * end = ten.storage() + ten.size(); for (; it < end; ++it) _norm += std::abs(*it); return _norm; } }; template struct NormHelper { template static R norm(const Ten & ten) { R _norm = 0.; R * it = ten.storage(); R * end = ten.storage() + ten.size(); for (; it < end; ++it) _norm += *it * *it; return sqrt(_norm); } }; template struct NormHelper { template static R norm(const Ten & ten) { R _norm = 0.; R * it = ten.storage(); R * end = ten.storage() + ten.size(); for (; it < end; ++it) _norm = std::max(std::abs(*it), _norm); return _norm; } }; public: /*----------------------------------------------------------------------- */ /// "Entrywise" norm norm @f[ \|\boldsymbol{T}\|_p = \left( /// \sum_i^{n[0]}\sum_j^{n[1]}\sum_k^{n[2]} |T_{ijk}|^p \right)^{\frac{1}{p}} /// @f] template inline T norm() const { return NormHelper::norm(*this); } protected: UInt n[ndim]; UInt _size; T * values; bool wrapped{false}; }; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ namespace types { namespace details { template class vector_iterator { public: using difference_type = std::ptrdiff_t; using value_type = std::decay_t; using pointer = value_type *; using reference = reference_; using iterator_category = std::input_iterator_tag; vector_iterator(pointer ptr) : ptr(ptr) {} // input iterator ++it vector_iterator & operator++() { ++ptr; return *this; } // input iterator it++ vector_iterator operator++(int) { auto cpy = *this; ++ptr; return cpy; } vector_iterator & operator+=(int n) { ptr += n; return *this; } vector_iterator operator+(int n) { vector_iterator cpy(*this); cpy += n; return cpy; } // input iterator it != other_it bool operator!=(const vector_iterator & other) const { return ptr != other.ptr; } bool operator==(const vector_iterator & other) const { return ptr == other.ptr; } difference_type operator-(const vector_iterator & other) const { return this->ptr - other.ptr; } // input iterator dereference *it reference operator*() { return *ptr; } pointer operator->() { return ptr; } private: pointer ptr; }; } // namespace details } // namespace types /* -------------------------------------------------------------------------- */ /* Vector */ /* -------------------------------------------------------------------------- */ template class Vector : public TensorStorage> { using parent = TensorStorage>; public: using value_type = typename parent::value_type; using proxy = VectorProxy; public: Vector() : parent() {} explicit Vector(UInt n, const T & def = T()) : parent(n, 0, 0, def) {} Vector(T * data, UInt n) : parent(data, n, 0, 0) {} Vector(const Vector & src, bool deep_copy = true) : parent(src, deep_copy) {} Vector(const TensorProxy & src) : parent(src) {} Vector(std::initializer_list list) : parent(list.size(), 0, 0, T()) { UInt i = 0; for (auto val : list) { operator()(i++) = val; } } public: using iterator = types::details::vector_iterator; using const_iterator = types::details::vector_iterator; iterator begin() { return iterator(this->storage()); } iterator end() { return iterator(this->storage() + this->size()); } const_iterator begin() const { return const_iterator(this->storage()); } const_iterator end() const { return const_iterator(this->storage() + this->size()); } public: ~Vector() override = default; /* ------------------------------------------------------------------------ */ inline Vector & operator=(const Vector & src) { parent::operator=(src); return *this; } /* ------------------------------------------------------------------------ */ inline T & operator()(UInt i) { AKANTU_DEBUG_ASSERT((i < this->n[0]), "Access out of the vector! " << "Index (" << i << ") is out of the vector of size (" << this->n[0] << ")"); return *(this->values + i); } inline const T & operator()(UInt i) const { AKANTU_DEBUG_ASSERT((i < this->n[0]), "Access out of the vector! " << "Index (" << i << ") is out of the vector of size (" << this->n[0] << ")"); return *(this->values + i); } inline T & operator[](UInt i) { return this->operator()(i); } inline const T & operator[](UInt i) const { return this->operator()(i); } /* ------------------------------------------------------------------------ */ inline Vector & operator*=(Real x) { return parent::operator*=(x); } inline Vector & operator/=(Real x) { return parent::operator/=(x); } /* ------------------------------------------------------------------------ */ inline Vector & operator*=(const Vector & vect) { - AKANTU_DEBUG_ASSERT(this->_size == vect._size, "The vectors have non matching sizes"); + AKANTU_DEBUG_ASSERT(this->_size == vect._size, + "The vectors have non matching sizes"); T * a = this->storage(); T * b = vect.storage(); for (UInt i = 0; i < this->_size; ++i) *(a++) *= *(b++); return *this; } /* ------------------------------------------------------------------------ */ inline Real dot(const Vector & vect) const { return Math::vectorDot(this->values, vect.storage(), this->_size); } /* ------------------------------------------------------------------------ */ inline Real mean() const { Real mean = 0; T * a = this->storage(); for (UInt i = 0; i < this->_size; ++i) mean += *(a++); return mean / this->_size; } /* ------------------------------------------------------------------------ */ inline Vector & crossProduct(const Vector & v1, const Vector & v2) { AKANTU_DEBUG_ASSERT(this->size() == 3, "crossProduct is only defined in 3D (n=" << this->size() << ")"); AKANTU_DEBUG_ASSERT( this->size() == v1.size() && this->size() == v2.size(), "crossProduct is not a valid operation non matching size vectors"); Math::vectorProduct3(v1.storage(), v2.storage(), this->values); return *this; } inline Vector crossProduct(const Vector & v) { Vector tmp(this->size()); tmp.crossProduct(*this, v); return tmp; } /* ------------------------------------------------------------------------ */ inline void solve(const Matrix & A, const Vector & b) { AKANTU_DEBUG_ASSERT( this->size() == A.rows() && this->_size == A.cols(), "The size of the solution vector mismatches the size of the matrix"); AKANTU_DEBUG_ASSERT( this->_size == b._size, "The rhs vector has a mismatch in size with the matrix"); Math::solve(this->_size, A.storage(), this->values, b.storage()); } /* ------------------------------------------------------------------------ */ template inline void mul(const Matrix & A, const Vector & x, Real alpha = 1.0); /* ------------------------------------------------------------------------ */ inline Real norm() const { return parent::template norm(); } template inline Real norm() const { return parent::template norm(); } /* ------------------------------------------------------------------------ */ inline Vector & normalize() { Real n = norm(); operator/=(n); return *this; } /* ------------------------------------------------------------------------ */ /// norm of (*this - x) inline Real distance(const Vector & y) const { Real * vx = this->values; Real * vy = y.storage(); Real sum_2 = 0; for (UInt i = 0; i < this->_size; ++i, ++vx, ++vy) sum_2 += (*vx - *vy) * (*vx - *vy); return sqrt(sum_2); } /* ------------------------------------------------------------------------ */ inline bool equal(const Vector & v, Real tolerance = Math::getTolerance()) const { T * a = this->storage(); T * b = v.storage(); UInt i = 0; while (i < this->_size && (std::abs(*(a++) - *(b++)) < tolerance)) ++i; return i == this->_size; } /* ------------------------------------------------------------------------ */ inline short compare(const Vector & v, Real tolerance = Math::getTolerance()) const { T * a = this->storage(); T * b = v.storage(); for (UInt i(0); i < this->_size; ++i, ++a, ++b) { if (std::abs(*a - *b) > tolerance) return (((*a - *b) > tolerance) ? 1 : -1); } return 0; } /* ------------------------------------------------------------------------ */ inline bool operator==(const Vector & v) const { return equal(v); } inline bool operator!=(const Vector & v) const { return !operator==(v); } inline bool operator<(const Vector & v) const { return compare(v) == -1; } inline bool operator>(const Vector & v) const { return compare(v) == 1; } #ifndef SWIG template decltype(auto) accumulate(const Vector & v, Acc && accumulator, Func && func) const { T * a = this->storage(); T * b = v.storage(); for (UInt i(0); i < this->_size; ++i, ++a, ++b) { accumulator = func(*a, *b, std::forward(accumulator)); } return accumulator; } inline bool operator<=(const Vector & v) const { bool res = true; return accumulate(v, res, [](auto && a, auto && b, auto && accumulator) { return accumulator & (a <= b); }); } inline bool operator>=(const Vector & v) const { bool res = true; return accumulate(v, res, [](auto && a, auto && b, auto && accumulator) { return accumulator & (a >= b); }); } #endif /* ------------------------------------------------------------------------ */ /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const { std::string space; for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) ; stream << "["; for (UInt i = 0; i < this->_size; ++i) { if (i != 0) stream << ", "; stream << this->values[i]; } stream << "]"; } /* ---------------------------------------------------------------------- */ static inline Vector zeros(UInt n) { Vector tmp(n); tmp.set(T()); return tmp; } }; using RVector = Vector; /* ------------------------------------------------------------------------ */ template <> inline bool Vector::equal(const Vector & v, __attribute__((unused)) Real tolerance) const { UInt * a = this->storage(); UInt * b = v.storage(); UInt i = 0; while (i < this->_size && (*(a++) == *(b++))) ++i; return i == this->_size; } +/* -------------------------------------------------------------------------- */ +#ifndef SWIG +namespace types { + namespace details { + template class column_iterator { + public: + using difference_type = std::ptrdiff_t; + using value_type = decltype(std::declval().operator()(0)); + using pointer = value_type *; + using reference = value_type &; + using iterator_category = std::input_iterator_tag; + + + column_iterator(Mat & mat, UInt col) : mat(mat), col(col) {} + decltype(auto) operator*() { return mat(col); } + decltype(auto) operator++() { + ++col; + AKANTU_DEBUG_ASSERT(col <= mat.cols(), "The iterator is out of bound"); + return *this; + } + decltype(auto) operator++(int) { + auto tmp = *this; + ++col; + AKANTU_DEBUG_ASSERT(col <= mat.cols(), "The iterator is out of bound"); + return tmp; + } + bool operator!=(const column_iterator & other) const { + return col != other.col; + } + + bool operator==(const column_iterator & other) const { + return not operator!=(other); + } + + private: + Mat & mat; + UInt col; + }; + } // namespace details +} // namespace types +#endif + /* ------------------------------------------------------------------------ */ /* Matrix */ /* ------------------------------------------------------------------------ */ template class Matrix : public TensorStorage> { using parent = TensorStorage>; public: using value_type = typename parent::value_type; using proxy = MatrixProxy; public: Matrix() : parent() {} Matrix(UInt m, UInt n, const T & def = T()) : parent(m, n, 0, def) {} Matrix(T * data, UInt m, UInt n) : parent(data, m, n, 0) {} Matrix(const Matrix & src, bool deep_copy = true) : parent(src, deep_copy) {} Matrix(const MatrixProxy & src) : parent(src) {} Matrix(std::initializer_list> list) { static_assert(std::is_trivially_copyable{}, "Cannot create a tensor on non trivial types"); std::size_t n = 0; std::size_t m = list.size(); for (auto row : list) { n = std::max(n, row.size()); } DimHelper<2>::setDims(m, n, 0, this->n); this->computeSize(); this->values = new T[this->_size]; this->set(0); UInt i = 0, j = 0; for (auto & row : list) { for (auto & val : row) { at(i, j++) = val; } ++i; j = 0; } } ~Matrix() override = default; /* ------------------------------------------------------------------------ */ inline Matrix & operator=(const Matrix & src) { parent::operator=(src); return *this; } public: /* ---------------------------------------------------------------------- */ UInt rows() const { return this->n[0]; } UInt cols() const { return this->n[1]; } /* ---------------------------------------------------------------------- */ inline T & at(UInt i, UInt j) { AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])), "Access out of the matrix! " << "Index (" << i << ", " << j << ") is out of the matrix of size (" << this->n[0] << ", " << this->n[1] << ")"); return *(this->values + i + j * this->n[0]); } inline const T & at(UInt i, UInt j) const { AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])), "Access out of the matrix! " << "Index (" << i << ", " << j << ") is out of the matrix of size (" << this->n[0] << ", " << this->n[1] << ")"); return *(this->values + i + j * this->n[0]); } /* ------------------------------------------------------------------------ */ inline T & operator()(UInt i, UInt j) { return this->at(i, j); } inline const T & operator()(UInt i, UInt j) const { return this->at(i, j); } /// give a line vector wrapped on the column i inline VectorProxy operator()(UInt j) { AKANTU_DEBUG_ASSERT(j < this->n[1], "Access out of the matrix! " << "You are trying to access the column vector " << j << " in a matrix of size (" << this->n[0] << ", " << this->n[1] << ")"); return VectorProxy(this->values + j * this->n[0], this->n[0]); } inline const VectorProxy operator()(UInt j) const { AKANTU_DEBUG_ASSERT(j < this->n[1], "Access out of the matrix! " << "You are trying to access the column vector " << j << " in a matrix of size (" << this->n[0] << ", " << this->n[1] << ")"); return VectorProxy(this->values + j * this->n[0], this->n[0]); } +#ifndef SWIG +public: + decltype(auto) begin() { + return types::details::column_iterator>(*this, 0); + } + decltype(auto) begin() const { + return types::details::column_iterator>(*this, 0); + } + + decltype(auto) end() { + return types::details::column_iterator>(*this, this->cols()); + } + decltype(auto) end() const { + return types::details::column_iterator>(*this, + this->cols()); + } +#endif + + /* ------------------------------------------------------------------------ */ inline void block(const Matrix & block, UInt pos_i, UInt pos_j) { AKANTU_DEBUG_ASSERT(pos_i + block.rows() <= rows(), "The block size or position are not correct"); AKANTU_DEBUG_ASSERT(pos_i + block.cols() <= cols(), "The block size or position are not correct"); for (UInt i = 0; i < block.rows(); ++i) for (UInt j = 0; j < block.cols(); ++j) this->at(i + pos_i, j + pos_j) = block(i, j); } inline Matrix block(UInt pos_i, UInt pos_j, UInt block_rows, UInt block_cols) const { AKANTU_DEBUG_ASSERT(pos_i + block_rows <= rows(), "The block size or position are not correct"); AKANTU_DEBUG_ASSERT(pos_i + block_cols <= cols(), "The block size or position are not correct"); Matrix block(block_rows, block_cols); for (UInt i = 0; i < block_rows; ++i) for (UInt j = 0; j < block_cols; ++j) block(i, j) = this->at(i + pos_i, j + pos_j); return block; } inline T & operator[](UInt idx) { return *(this->values + idx); }; inline const T & operator[](UInt idx) const { return *(this->values + idx); }; /* ---------------------------------------------------------------------- */ inline Matrix operator*(const Matrix & B) { Matrix C(this->rows(), B.cols()); C.mul(*this, B); return C; } /* ----------------------------------------------------------------------- */ inline Matrix & operator*=(const T & x) { return parent::operator*=(x); } inline Matrix & operator*=(const Matrix & B) { Matrix C(*this); this->mul(C, B); return *this; } /* ---------------------------------------------------------------------- */ template inline void mul(const Matrix & A, const Matrix & B, T alpha = 1.0) { UInt k = A.cols(); if (tr_A) k = A.rows(); #ifndef AKANTU_NDEBUG if (tr_B) { AKANTU_DEBUG_ASSERT(k == B.cols(), "matrices to multiply have no fit dimensions"); AKANTU_DEBUG_ASSERT(this->cols() == B.rows(), "matrices to multiply have no fit dimensions"); } else { AKANTU_DEBUG_ASSERT(k == B.rows(), "matrices to multiply have no fit dimensions"); AKANTU_DEBUG_ASSERT(this->cols() == B.cols(), "matrices to multiply have no fit dimensions"); } if (tr_A) { AKANTU_DEBUG_ASSERT(this->rows() == A.cols(), "matrices to multiply have no fit dimensions"); } else { AKANTU_DEBUG_ASSERT(this->rows() == A.rows(), "matrices to multiply have no fit dimensions"); } #endif // AKANTU_NDEBUG Math::matMul(this->rows(), this->cols(), k, alpha, A.storage(), B.storage(), 0., this->storage()); } /* ---------------------------------------------------------------------- */ inline void outerProduct(const Vector & A, const Vector & B) { AKANTU_DEBUG_ASSERT( A.size() == this->rows() && B.size() == this->cols(), "A and B are not compatible with the size of the matrix"); for (UInt i = 0; i < this->rows(); ++i) { for (UInt j = 0; j < this->cols(); ++j) { this->values[i + j * this->rows()] += A[i] * B[j]; } } } private: class EigenSorter { public: EigenSorter(const Vector & eigs) : eigs(eigs) {} bool operator()(const UInt & a, const UInt & b) const { return (eigs(a) > eigs(b)); } private: const Vector & eigs; }; public: /* ---------------------------------------------------------------------- */ inline void eig(Vector & eigenvalues, Matrix & eigenvectors) const { AKANTU_DEBUG_ASSERT(this->cols() == this->rows(), "eig is not a valid operation on a rectangular matrix"); AKANTU_DEBUG_ASSERT(eigenvalues.size() == this->cols(), "eigenvalues should be of size " << this->cols() << "."); #ifndef AKANTU_NDEBUG if (eigenvectors.storage() != nullptr) AKANTU_DEBUG_ASSERT((eigenvectors.rows() == eigenvectors.cols()) && (eigenvectors.rows() == this->cols()), "Eigenvectors needs to be a square matrix of size " << this->cols() << " x " << this->cols() << "."); #endif Matrix tmp = *this; Vector tmp_eigs(eigenvalues.size()); Matrix tmp_eig_vects(eigenvectors.rows(), eigenvectors.cols()); if (tmp_eig_vects.rows() == 0 || tmp_eig_vects.cols() == 0) Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage()); else Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage(), tmp_eig_vects.storage()); Vector perm(eigenvalues.size()); for (UInt i = 0; i < perm.size(); ++i) perm(i) = i; std::sort(perm.storage(), perm.storage() + perm.size(), EigenSorter(tmp_eigs)); for (UInt i = 0; i < perm.size(); ++i) eigenvalues(i) = tmp_eigs(perm(i)); if (tmp_eig_vects.rows() != 0 && tmp_eig_vects.cols() != 0) for (UInt i = 0; i < perm.size(); ++i) { for (UInt j = 0; j < eigenvectors.rows(); ++j) { eigenvectors(j, i) = tmp_eig_vects(j, perm(i)); } } } /* ---------------------------------------------------------------------- */ inline void eig(Vector & eigenvalues) const { Matrix empty; eig(eigenvalues, empty); } /* ---------------------------------------------------------------------- */ inline void eye(T alpha = 1.) { AKANTU_DEBUG_ASSERT(this->cols() == this->rows(), "eye is not a valid operation on a rectangular matrix"); this->clear(); for (UInt i = 0; i < this->cols(); ++i) { this->values[i + i * this->rows()] = alpha; } } /* ---------------------------------------------------------------------- */ static inline Matrix eye(UInt m, T alpha = 1.) { Matrix tmp(m, m); tmp.eye(alpha); return tmp; } /* ---------------------------------------------------------------------- */ inline T trace() const { AKANTU_DEBUG_ASSERT( this->cols() == this->rows(), "trace is not a valid operation on a rectangular matrix"); T trace = 0.; for (UInt i = 0; i < this->rows(); ++i) { trace += this->values[i + i * this->rows()]; } return trace; } /* ---------------------------------------------------------------------- */ inline Matrix transpose() const { Matrix tmp(this->cols(), this->rows()); for (UInt i = 0; i < this->rows(); ++i) { for (UInt j = 0; j < this->cols(); ++j) { tmp(j, i) = operator()(i, j); } } return tmp; } /* ---------------------------------------------------------------------- */ inline void inverse(const Matrix & A) { AKANTU_DEBUG_ASSERT(A.cols() == A.rows(), "inv is not a valid operation on a rectangular matrix"); AKANTU_DEBUG_ASSERT(this->cols() == A.cols(), "the matrix should have the same size as its inverse"); if (this->cols() == 1) *this->values = 1. / *A.storage(); else if (this->cols() == 2) Math::inv2(A.storage(), this->values); else if (this->cols() == 3) Math::inv3(A.storage(), this->values); else Math::inv(this->cols(), A.storage(), this->values); } inline Matrix inverse() { Matrix inv(this->rows(), this->cols()); inv.inverse(*this); return inv; } /* --------------------------------------------------------------------- */ inline T det() const { AKANTU_DEBUG_ASSERT(this->cols() == this->rows(), "inv is not a valid operation on a rectangular matrix"); if (this->cols() == 1) return *(this->values); else if (this->cols() == 2) return Math::det2(this->values); else if (this->cols() == 3) return Math::det3(this->values); else return Math::det(this->cols(), this->values); } /* --------------------------------------------------------------------- */ inline T doubleDot(const Matrix & other) const { AKANTU_DEBUG_ASSERT( this->cols() == this->rows(), "doubleDot is not a valid operation on a rectangular matrix"); if (this->cols() == 1) return *(this->values) * *(other.storage()); else if (this->cols() == 2) return Math::matrixDoubleDot22(this->values, other.storage()); else if (this->cols() == 3) return Math::matrixDoubleDot33(this->values, other.storage()); else AKANTU_ERROR("doubleDot is not defined for other spatial dimensions" << " than 1, 2 or 3."); return T(); } /* ---------------------------------------------------------------------- */ /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const { std::string space; for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) ; stream << "["; for (UInt i = 0; i < this->n[0]; ++i) { if (i != 0) stream << ", "; stream << "["; for (UInt j = 0; j < this->n[1]; ++j) { if (j != 0) stream << ", "; stream << operator()(i, j); } stream << "]"; } stream << "]"; }; }; /* ------------------------------------------------------------------------ */ template template inline void Vector::mul(const Matrix & A, const Vector & x, Real alpha) { #ifndef AKANTU_NDEBUG UInt n = x.size(); if (tr_A) { AKANTU_DEBUG_ASSERT(n == A.rows(), "matrix and vector to multiply have no fit dimensions"); AKANTU_DEBUG_ASSERT(this->size() == A.cols(), "matrix and vector to multiply have no fit dimensions"); } else { AKANTU_DEBUG_ASSERT(n == A.cols(), "matrix and vector to multiply have no fit dimensions"); AKANTU_DEBUG_ASSERT(this->size() == A.rows(), "matrix and vector to multiply have no fit dimensions"); } #endif Math::matVectMul(A.rows(), A.cols(), alpha, A.storage(), x.storage(), 0., this->storage()); } /* -------------------------------------------------------------------------- */ template inline std::ostream & operator<<(std::ostream & stream, const Matrix & _this) { _this.printself(stream); return stream; } /* -------------------------------------------------------------------------- */ template inline std::ostream & operator<<(std::ostream & stream, const Vector & _this) { _this.printself(stream); return stream; } /* ------------------------------------------------------------------------ */ /* Tensor3 */ /* ------------------------------------------------------------------------ */ template class Tensor3 : public TensorStorage> { using parent = TensorStorage>; public: using value_type = typename parent::value_type; using proxy = Tensor3Proxy; public: Tensor3() : parent(){}; Tensor3(UInt m, UInt n, UInt p, const T & def = T()) : parent(m, n, p, def) {} Tensor3(T * data, UInt m, UInt n, UInt p) : parent(data, m, n, p) {} Tensor3(const Tensor3 & src, bool deep_copy = true) : parent(src, deep_copy) {} Tensor3(const proxy & src) : parent(src) {} public: /* ------------------------------------------------------------------------ */ inline Tensor3 & operator=(const Tensor3 & src) { parent::operator=(src); return *this; } /* ---------------------------------------------------------------------- */ inline T & operator()(UInt i, UInt j, UInt k) { AKANTU_DEBUG_ASSERT( (i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]), "Access out of the tensor3! " << "You are trying to access the element " << "(" << i << ", " << j << ", " << k << ") in a tensor of size (" << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")"); return *(this->values + (k * this->n[0] + i) * this->n[1] + j); } inline const T & operator()(UInt i, UInt j, UInt k) const { AKANTU_DEBUG_ASSERT( (i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]), "Access out of the tensor3! " << "You are trying to access the element " << "(" << i << ", " << j << ", " << k << ") in a tensor of size (" << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")"); return *(this->values + (k * this->n[0] + i) * this->n[1] + j); } inline MatrixProxy operator()(UInt k) { AKANTU_DEBUG_ASSERT((k < this->n[2]), "Access out of the tensor3! " << "You are trying to access the slice " << k << " in a tensor3 of size (" << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")"); return MatrixProxy(this->values + k * this->n[0] * this->n[1], this->n[0], this->n[1]); } inline const MatrixProxy operator()(UInt k) const { AKANTU_DEBUG_ASSERT((k < this->n[2]), "Access out of the tensor3! " << "You are trying to access the slice " << k << " in a tensor3 of size (" << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")"); return MatrixProxy(this->values + k * this->n[0] * this->n[1], this->n[0], this->n[1]); } inline MatrixProxy operator[](UInt k) { return MatrixProxy(this->values + k * this->n[0] * this->n[1], this->n[0], this->n[1]); } inline const MatrixProxy operator[](UInt k) const { return MatrixProxy(this->values + k * this->n[0] * this->n[1], this->n[0], this->n[1]); } }; /* -------------------------------------------------------------------------- */ // support operations for the creation of other vectors /* -------------------------------------------------------------------------- */ template Vector operator*(const T & scalar, const Vector & a) { Vector r(a); r *= scalar; return r; } template Vector operator*(const Vector & a, const T & scalar) { Vector r(a); r *= scalar; return r; } template Vector operator/(const Vector & a, const T & scalar) { Vector r(a); r /= scalar; return r; } template Vector operator*(const Vector & a, const Vector & b) { Vector r(a); r *= b; return r; } template Vector operator+(const Vector & a, const Vector & b) { Vector r(a); r += b; return r; } template Vector operator-(const Vector & a, const Vector & b) { Vector r(a); r -= b; return r; } template Vector operator*(const Matrix & A, const Vector & b) { Vector r(b.size()); r.template mul(A, b); return r; } /* -------------------------------------------------------------------------- */ template Matrix operator*(const T & scalar, const Matrix & a) { Matrix r(a); r *= scalar; return r; } template Matrix operator*(const Matrix & a, const T & scalar) { Matrix r(a); r *= scalar; return r; } template Matrix operator/(const Matrix & a, const T & scalar) { Matrix r(a); r /= scalar; return r; } template Matrix operator+(const Matrix & a, const Matrix & b) { Matrix r(a); r += b; return r; } template Matrix operator-(const Matrix & a, const Matrix & b) { Matrix r(a); r -= b; return r; } } // namespace akantu #include namespace std { template struct iterator_traits<::akantu::types::details::vector_iterator> { protected: using iterator = ::akantu::types::details::vector_iterator; public: using iterator_category = typename iterator::iterator_category; using value_type = typename iterator::value_type; using difference_type = typename iterator::difference_type; using pointer = typename iterator::pointer; using reference = typename iterator::reference; }; + +template +struct iterator_traits<::akantu::types::details::column_iterator> { +protected: + using iterator = ::akantu::types::details::column_iterator; + +public: + using iterator_category = typename iterator::iterator_category; + using value_type = typename iterator::value_type; + using difference_type = typename iterator::difference_type; + using pointer = typename iterator::pointer; + using reference = typename iterator::reference; +}; + } // namespace std #endif /* __AKANTU_AKA_TYPES_HH__ */ diff --git a/src/fe_engine/fe_engine_template.hh b/src/fe_engine/fe_engine_template.hh index 6a7d648a6..1da5b81c4 100644 --- a/src/fe_engine/fe_engine_template.hh +++ b/src/fe_engine/fe_engine_template.hh @@ -1,414 +1,413 @@ /** * @file fe_engine_template.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Mon Jan 29 2018 * * @brief templated class that calls integration and shape objects * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ - /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_FE_ENGINE_TEMPLATE_HH__ #define __AKANTU_FE_ENGINE_TEMPLATE_HH__ /* -------------------------------------------------------------------------- */ #include "fe_engine.hh" #include "integrator.hh" #include "shape_functions.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ namespace akantu { class DOFManager; namespace fe_engine { namespace details { template struct AssembleLumpedTemplateHelper; template struct AssembleFieldMatrixHelper; } // namespace details } // namespace fe_engine template struct AssembleFieldMatrixStructHelper; struct DefaultIntegrationOrderFunctor { template static inline constexpr int getOrder() { return ElementClassProperty::polynomial_degree; } }; /* -------------------------------------------------------------------------- */ template