diff --git a/test/test_gpu_elasticity.jl b/test/test_gpu_elasticity.jl new file mode 100644 index 0000000..1c29a5c --- /dev/null +++ b/test/test_gpu_elasticity.jl @@ -0,0 +1,141 @@ +""" +Test GPU elasticity solver with cantilever beam + +Geometry: 10×1×1 beam, fixed at X=0, pressure on top +""" + +using Test +using LinearAlgebra + +# Load solver +include(joinpath(@__DIR__, "..", "src", "gpu_elasticity.jl")) +using .GPUElasticity + +@testset "GPU Elasticity - Cantilever Beam" begin + println("\n" * "="^70) + println("TEST: Cantilever Beam with GPU Solver") + println("="^70) + + # Check if mesh exists, if not generate it + mesh_file = joinpath(@__DIR__, "testdata", "cantilever_beam.msh") + + if !isfile(mesh_file) + println("\n⚠️ Mesh file not found: $mesh_file") + println("Generating mesh...") + + # Create testdata directory if needed + mkpath(dirname(mesh_file)) + + # Generate mesh + include(joinpath(@__DIR__, "..", "scripts", "generate_cantilever_mesh.jl")) + Base.invokelatest(generate_cantilever_mesh, + length=10.0, + width=1.0, + height=1.0, + mesh_size=0.5, + output_file=mesh_file + ) + end + + # Read mesh + println("\nReading mesh...") + mesh = read_gmsh_mesh(mesh_file) + + @test size(mesh.nodes, 2) > 0 + @test size(mesh.elements, 2) > 0 + + # Find boundary nodes + fixed_nodes = get_surface_nodes(mesh, "FixedEnd") + pressure_nodes = get_surface_nodes(mesh, "PressureSurface") + + println("\nBoundary nodes:") + println(" Fixed: $(length(fixed_nodes))") + println(" Pressure: $(length(pressure_nodes))") + + @test length(fixed_nodes) > 0 + @test length(pressure_nodes) > 0 + + # Material (steel) + material = ElasticMaterial( + 210e9, # E = 210 GPa + 0.3 # ν = 0.3 + ) + + # Applied pressure (1 MPa) + pressure = 1e6 # Pa + + # Define physics + physics = ElasticityPhysics( + mesh, + material, + fixed_nodes, + pressure_nodes, + pressure + ) + + # Solve on GPU + println("\n" * "="^70) + println("Solving on GPU...") + println("="^70) + + u = solve_elasticity_gpu(physics, tol=1e-6, max_iter=1000) + + # Check solution + @test length(u) == 3 * size(mesh.nodes, 2) + @test maximum(abs.(u)) > 0.0 # Non-trivial solution + + # Fixed nodes should have zero displacement + for node in fixed_nodes + ux = u[3*node-2] + uy = u[3*node-1] + uz = u[3*node] + @test abs(ux) < 1e-10 + @test abs(uy) < 1e-10 + @test abs(uz) < 1e-10 + end + println("✅ Fixed boundary condition satisfied") + + # Free end should have maximum displacement + x_max = maximum(mesh.nodes[1, :]) + free_end_nodes = findall(abs.(mesh.nodes[1, :] .- x_max) .< 1e-6) + + max_disp_free_end = maximum(abs.(u[3*n] for n in free_end_nodes)) + max_disp_overall = maximum(abs.(u)) + + println("\nDisplacement analysis:") + println(" Max displacement at free end: $(max_disp_free_end) m") + println(" Max displacement overall: $(max_disp_overall) m") + + # Free end should have largest displacement (cantilever behavior) + @test max_disp_free_end > 0.5 * max_disp_overall + println("✅ Cantilever deflection pattern correct") + + # Analytical comparison (Euler-Bernoulli beam theory) + # For uniform load q on beam of length L: + # w_max = q*L^4 / (8*E*I) + + L = 10.0 # Length + width = 1.0 + height = 1.0 + I = width * height^3 / 12 # Second moment of area + + # Convert pressure to line load (approximate) + q = pressure * width # N/m + + w_analytical = q * L^4 / (8 * material.E * I) + + println("\nAnalytical comparison:") + println(" Analytical max deflection: $(w_analytical) m") + println(" FEM max deflection: $(max_disp_free_end) m") + println(" Relative error: $(abs(w_analytical - max_disp_free_end) / w_analytical * 100)%") + + # Should be within reasonable range (mesh dependent) + # Note: This is approximate due to discretization + @test max_disp_free_end > 0.1 * w_analytical + @test max_disp_free_end < 10.0 * w_analytical + println("✅ Solution within reasonable range of analytical") + + println("\n" * "="^70) + println("✅ All tests passed!") + println("="^70) +end diff --git a/test/testdata/cantilever_beam.msh b/test/testdata/cantilever_beam.msh new file mode 100644 index 0000000..e46d778 --- /dev/null +++ b/test/testdata/cantilever_beam.msh @@ -0,0 +1,989 @@ +$MeshFormat +4.1 0 8 +$EndMeshFormat +$PhysicalNames +3 +2 1 "FixedEnd" +2 6 "PressureSurface" +3 1 "Bulk" +$EndPhysicalNames +$Entities +8 12 6 1 +1 0 0 1 0 +2 0 0 0 0 +3 0 1 1 0 +4 0 1 0 0 +5 10 0 1 0 +6 10 0 0 0 +7 10 1 1 0 +8 10 1 0 0 +1 -1e-07 -1e-07 -9.999999994736442e-08 1e-07 1e-07 1.0000001 0 2 2 -1 +2 -1e-07 -9.999999994736442e-08 0.9999999000000001 1e-07 1.0000001 1.0000001 0 2 1 -3 +3 -1e-07 0.9999999000000001 -9.999999994736442e-08 1e-07 1.0000001 1.0000001 0 2 4 -3 +4 -1e-07 -9.999999994736442e-08 -1e-07 1e-07 1.0000001 1e-07 0 2 2 -4 +5 9.999999900000001 -1e-07 -9.999999994736442e-08 10.0000001 1e-07 1.0000001 0 2 6 -5 +6 9.999999900000001 -9.999999994736442e-08 0.9999999000000001 10.0000001 1.0000001 1.0000001 0 2 5 -7 +7 9.999999900000001 0.9999999000000001 -9.999999994736442e-08 10.0000001 1.0000001 1.0000001 0 2 8 -7 +8 9.999999900000001 -9.999999994736442e-08 -1e-07 10.0000001 1.0000001 1e-07 0 2 6 -8 +9 -1.000000002804313e-07 -1e-07 -1e-07 10.0000001 1e-07 1e-07 0 2 2 -6 +10 -1.000000002804313e-07 -1e-07 0.9999999000000001 10.0000001 1e-07 1.0000001 0 2 1 -5 +11 -1.000000002804313e-07 0.9999999000000001 -1e-07 10.0000001 1.0000001 1e-07 0 2 4 -8 +12 -1.000000002804313e-07 0.9999999000000001 0.9999999000000001 10.0000001 1.0000001 1.0000001 0 2 3 -7 +1 -1e-07 -9.999999994736442e-08 -9.999999994736442e-08 1e-07 1.0000001 1.0000001 1 1 4 -1 4 3 -2 +2 9.999999900000001 -9.999999994736442e-08 -9.999999994736442e-08 10.0000001 1.0000001 1.0000001 0 4 -5 8 7 -6 +3 -1.000000002804313e-07 -1e-07 -9.999999994736442e-08 10.0000001 1e-07 1.0000001 0 4 -9 1 10 -5 +4 -1.000000002804313e-07 0.9999999000000001 -9.999999994736442e-08 10.0000001 1.0000001 1.0000001 0 4 -11 3 12 -7 +5 -1.000000002804313e-07 -9.999999994736442e-08 -1e-07 10.0000001 1.0000001 1e-07 0 4 -4 9 8 -11 +6 -1.000000002804313e-07 -9.999999994736442e-08 0.9999999000000001 10.0000001 1.0000001 1.0000001 1 2 4 -2 10 6 -12 +1 -1.000000002804313e-07 -9.999999994736442e-08 -9.999999994736442e-08 10.0000001 1.0000001 1.0000001 1 3 6 -1 2 -3 4 -5 6 +$EndEntities +$Nodes +27 190 1 190 +0 1 0 1 +1 +0 0 1 +0 2 0 1 +2 +0 0 0 +0 3 0 1 +3 +0 1 1 +0 4 0 1 +4 +0 1 0 +0 5 0 1 +5 +10 0 1 +0 6 0 1 +6 +10 0 0 +0 7 0 1 +7 +10 1 1 +0 8 0 1 +8 +10 1 0 +1 1 0 1 +9 +0 0 0.5 +1 2 0 1 +10 +0 0.5 1 +1 3 0 1 +11 +0 1 0.5 +1 4 0 1 +12 +0 0.5 0 +1 5 0 1 +13 +10 0 0.5 +1 6 0 1 +14 +10 0.5 1 +1 7 0 1 +15 +10 1 0.5 +1 8 0 1 +16 +10 0.5 0 +1 9 0 19 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +0.5 0 0 +1 0 0 +1.5 0 0 +2 0 0 +2.5 0 0 +3 0 0 +3.5 0 0 +4 0 0 +4.5 0 0 +5 0 0 +5.5 0 0 +6 0 0 +6.5 0 0 +7 0 0 +7.5 0 0 +8 0 0 +8.5 0 0 +9 0 0 +9.5 0 0 +1 10 0 19 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +0.5 0 1 +1 0 1 +1.5 0 1 +2 0 1 +2.5 0 1 +3 0 1 +3.5 0 1 +4 0 1 +4.5 0 1 +5 0 1 +5.5 0 1 +6 0 1 +6.5 0 1 +7 0 1 +7.5 0 1 +8 0 1 +8.5 0 1 +9 0 1 +9.5 0 1 +1 11 0 19 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +0.5 1 0 +1 1 0 +1.5 1 0 +2 1 0 +2.5 1 0 +3 1 0 +3.5 1 0 +4 1 0 +4.5 1 0 +5 1 0 +5.5 1 0 +6 1 0 +6.5 1 0 +7 1 0 +7.5 1 0 +8 1 0 +8.5 1 0 +9 1 0 +9.5 1 0 +1 12 0 19 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +0.5 1 1 +1 1 1 +1.5 1 1 +2 1 1 +2.5 1 1 +3 1 1 +3.5 1 1 +4 1 1 +4.5 1 1 +5 1 1 +5.5 1 1 +6 1 1 +6.5 1 1 +7 1 1 +7.5 1 1 +8 1 1 +8.5 1 1 +9 1 1 +9.5 1 1 +2 1 0 4 +93 +94 +95 +96 +0 0.75 0.75 +0 0.625 0.3749999999999999 +0 0.28125 0.2812500000000001 +0 0.3457031249999999 0.6542968750000001 +2 2 0 4 +97 +98 +99 +100 +10 0.75 0.75 +10 0.625 0.3749999999999999 +10 0.28125 0.2812500000000001 +10 0.3457031249999999 0.6542968750000001 +2 3 0 22 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +1.75 0 0.5069585776743641 +0.75 0 0.5669872981077807 +2.749380588907528 0 0.5238365255897386 +3.749132824470539 0 0.4823627640453123 +4.750867175529461 0 0.4823627640453123 +7.251506891338066 0 0.4995938179975555 +9.25 0 0.4330127018922193 +5.750619411092472 0 0.5238365255897386 +8.251734351058921 0 0.5191392280307945 +1.25 0 0.48123057673124 +2.249926260584229 0 0.4890493032942006 +6.25020208203005 0 0.4813856891854416 +4.25 0 0.4941209213484373 +6.750284828894686 0 0.4968299178638328 +8.75371528672418 0 0.5225617672120302 +5.250247764436988 0 0.5010332149391751 +7.750540207066164 0 0.5031221743380583 +3.249752235563011 0 0.5010332149391751 +0.3287258330795123 0 0.3668411415816576 +9.671274166920488 0 0.6331588584183425 +0.289906066861805 0 0.7110089675965732 +9.710093933138193 0 0.2889910324034273 +2 4 0 22 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +1.25 1 0.5227636741068051 +2.249380588907528 1 0.5238365255897386 +3.249132824470539 1 0.4823627640453123 +4.25 1 0.47858229244173 +5.250867175529461 1 0.4823627640453123 +6.250619411092472 1 0.5224905590412035 +7.25 1 0.52141770755827 +8.25 1 0.52141770755827 +9.25 1 0.5669872981077807 +0.75 1 0.4330127018922193 +1.749926260584229 1 0.4909308623933007 +6.75007373941577 1 0.4860879465643809 +7.75 1 0.485960226149746 +8.75 1 0.4747073272589484 +3.74985547074509 1 0.4934908427478403 +4.75014452925491 1 0.4934908427478403 +5.750247764436988 1 0.5008088871810858 +2.749752235563011 1 0.5010332149391751 +0.3287258330795123 1 0.6331588584183424 +9.671274166920488 1 0.3668411415816575 +9.710093933138195 1 0.7110089675965732 +0.2899060668618049 1 0.2889910324034266 +2 5 0 22 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +2.249132824470539 0.5176372359546877 0 +3.750619411092472 0.5238365255897387 0 +4.751214045741245 0.5005353055285795 0 +6.751734351058921 0.5191392280307945 0 +0.75 0.5669872981077807 0 +5.751734351058921 0.4808607719692055 0 +7.750619411092472 0.4761634744102614 0 +8.75 0.4930414223256358 0 +1.249380588907528 0.4775094409587964 0 +2.751069516486335 0.4938777785477007 0 +4.250218268670681 0.4882846280387501 0 +8.25007373941577 0.5109506967057993 0 +9.25 0.5511587314970074 0 +1.749752235563011 0.499191112818914 0 +5.250491399466694 0.4968993462496308 0 +7.250392293691899 0.4992171170735092 0 +3.250281487929801 0.5029523840229065 0 +6.25057811701964 0.5 0 +0.3287258330795123 0.3668411415816576 0 +9.672020287404903 0.363394611684695 0 +9.703490779236464 0.7027288461524623 0 +0.289906066861805 0.7110089675965734 0 +2 6 0 22 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +2.25 0.518123521556161 1 +0.75 0.5669872981077807 1 +3.250619411092472 0.4761634744102612 1 +4.25 0.4930414223256358 1 +5.25 0.4930414223256358 1 +6.25 0.4930414223256358 1 +7.25 0.4772363258931948 1 +8.25 0.4772363258931948 1 +9.25 0.4330127018922193 1 +1.249380588907528 0.4775094409587964 1 +3.75007373941577 0.5109506967057993 1 +4.75 0.4976804741085452 1 +5.75 0.4976804741085452 1 +6.75 0.5110784171204343 1 +7.75 0.5137193056244123 1 +8.75 0.5174254524836885 1 +1.749896764817921 0.4992721604191595 1 +2.750103235182078 0.4990478326610704 1 +9.671274166920488 0.6331588584183425 1 +0.3287258330795123 0.3668411415816576 1 +9.710093933138195 0.2889910324034269 1 +0.289906066861805 0.7110089675965734 1 +3 1 0 2 +189 +190 +9.510944495345575 0.4892527009302248 0.5185495759302249 +0.4890555046544248 0.4814504240697751 0.510747299069775 +$EndNodes +$Elements +3 534 1 534 +2 1 2 14 +1 9 1 96 +2 1 10 96 +3 2 9 95 +4 12 2 95 +5 10 3 93 +6 3 11 93 +7 11 4 94 +8 4 12 94 +9 95 9 96 +10 10 93 96 +11 93 11 94 +12 94 12 95 +13 93 94 96 +14 94 95 96 +2 6 2 86 +15 1 186 10 +16 36 186 1 +17 10 188 3 +18 3 188 74 +19 14 187 5 +20 5 187 54 +21 7 185 14 +22 92 185 7 +23 186 188 10 +24 185 187 14 +25 37 168 36 +26 168 186 36 +27 38 176 37 +28 37 176 168 +29 39 183 38 +30 38 183 176 +31 40 167 39 +32 167 183 39 +33 41 184 40 +34 40 184 167 +35 42 169 41 +36 169 184 41 +37 43 177 42 +38 42 177 169 +39 44 170 43 +40 170 177 43 +41 45 178 44 +42 44 178 170 +43 46 171 45 +44 171 178 45 +45 47 179 46 +46 46 179 171 +47 48 172 47 +48 172 179 47 +49 49 180 48 +50 48 180 172 +51 50 173 49 +52 173 180 49 +53 51 181 50 +54 50 181 173 +55 52 174 51 +56 174 181 51 +57 53 182 52 +58 52 182 174 +59 54 175 53 +60 175 182 53 +61 54 187 175 +62 74 168 75 +63 74 188 168 +64 75 176 76 +65 168 176 75 +66 76 183 77 +67 176 183 76 +68 77 167 78 +69 77 183 167 +70 78 184 79 +71 167 184 78 +72 79 169 80 +73 79 184 169 +74 80 177 81 +75 169 177 80 +76 81 170 82 +77 81 177 170 +78 82 178 83 +79 170 178 82 +80 83 171 84 +81 83 178 171 +82 84 179 85 +83 171 179 84 +84 85 172 86 +85 85 179 172 +86 86 180 87 +87 172 180 86 +88 87 173 88 +89 87 180 173 +90 88 181 89 +91 173 181 88 +92 89 174 90 +93 89 181 174 +94 90 182 91 +95 174 182 90 +96 91 175 92 +97 91 182 175 +98 175 185 92 +99 168 188 186 +100 175 187 185 +3 1 4 434 +101 147 138 178 171 +102 155 113 147 178 +103 140 118 125 184 +104 138 155 147 178 +105 162 180 172 114 +106 127 116 147 159 +107 127 139 179 159 +108 127 179 116 159 +109 183 158 145 101 +110 155 113 178 170 +111 140 118 154 125 +112 140 103 118 184 +113 113 105 147 178 +114 178 138 155 170 +115 116 127 147 171 +116 114 160 173 106 +117 158 183 145 133 +118 171 179 116 127 +119 112 162 172 114 +120 154 161 125 118 +121 167 111 140 184 +122 108 179 139 159 +123 179 108 116 159 +124 134 180 172 162 +125 123 158 133 183 +126 103 140 118 154 +127 135 117 181 106 +128 147 138 171 127 +129 155 177 113 170 +130 148 180 162 114 +131 111 154 145 140 +132 183 145 111 101 +133 103 140 111 184 +134 118 125 104 161 +135 111 154 140 103 +136 172 128 134 162 +137 125 104 161 137 +138 180 148 162 134 +139 155 177 104 113 +140 125 118 169 184 +141 177 155 104 137 +142 160 173 148 114 +143 126 155 138 170 +144 159 139 108 150 +145 177 126 155 137 +146 126 177 155 170 +147 130 117 181 135 +148 124 133 145 183 +149 111 124 183 167 +150 124 111 183 145 +151 140 145 111 124 +152 146 161 104 137 +153 111 140 124 167 +154 115 152 136 189 +155 148 173 180 114 +156 104 137 155 146 +157 130 109 156 152 +158 177 137 104 169 +159 125 118 104 169 +160 181 174 117 130 +161 110 176 123 190 +162 123 153 110 190 +163 110 158 153 123 +164 125 104 137 169 +165 136 182 115 189 +166 109 130 117 174 +167 109 130 136 152 +168 136 115 109 152 +169 109 174 182 130 +170 130 182 109 136 +171 115 136 109 182 +172 157 136 152 189 +173 123 132 153 190 +174 152 115 107 189 +175 136 131 182 189 +176 123 176 168 190 +177 110 102 176 190 +178 182 175 115 189 +179 132 149 153 190 +180 152 107 157 189 +181 110 153 102 190 +182 136 157 131 189 +183 132 123 168 190 +184 175 182 131 189 +185 149 102 153 190 +186 168 176 102 190 +187 175 107 115 189 +188 171 138 178 83 +189 113 177 43 170 +190 178 82 138 170 +191 79 140 125 184 +192 39 183 111 101 +193 177 113 43 104 +194 178 113 44 170 +195 83 171 138 127 +196 114 30 160 106 +197 111 167 183 39 +198 178 171 45 116 +199 82 126 138 170 +200 139 127 65 159 +201 65 139 159 150 +202 105 113 44 178 +203 169 79 125 184 +204 162 139 66 150 +205 45 105 178 116 +206 137 126 81 177 +207 177 126 81 170 +208 66 128 139 162 +209 180 48 172 114 +210 161 154 22 118 +211 109 156 152 33 +212 112 29 162 114 +213 30 160 148 114 +214 148 162 29 114 +215 167 140 78 184 +216 125 60 154 140 +217 112 172 48 114 +218 64 127 147 159 +219 154 161 60 125 +220 127 147 138 64 +221 115 109 152 33 +222 139 85 179 128 +223 158 110 19 101 +224 103 22 154 118 +225 151 160 31 106 +226 85 172 179 128 +227 114 173 49 106 +228 151 109 117 32 +229 23 104 161 118 +230 31 117 151 106 +231 104 118 42 169 +232 59 145 154 140 +233 140 167 78 124 +234 148 68 134 160 +235 129 134 68 160 +236 173 49 180 114 +237 151 156 109 32 +238 133 124 77 183 +239 134 67 148 162 +240 42 177 104 169 +241 19 110 158 153 +242 67 134 128 162 +243 69 135 129 160 +244 154 21 111 145 +245 135 69 151 160 +246 153 18 110 102 +247 76 123 133 183 +248 167 77 124 183 +249 154 111 21 103 +250 59 145 140 124 +251 117 51 174 181 +252 176 183 38 101 +253 104 23 161 146 +254 158 145 58 133 +255 51 109 117 174 +256 47 179 172 108 +257 104 113 24 155 +258 123 76 176 183 +259 38 110 176 101 +260 108 172 47 112 +261 133 145 58 124 +262 155 24 104 146 +263 130 181 89 135 +264 18 153 149 102 +265 174 181 89 130 +266 144 166 55 190 +267 90 182 174 130 +268 90 182 130 136 +269 153 56 132 123 +270 56 149 153 132 +271 107 115 152 34 +272 157 136 72 152 +273 157 165 142 189 +274 152 157 107 34 +275 131 182 91 136 +276 37 176 110 102 +277 168 123 75 176 +278 175 115 53 182 +279 144 55 132 190 +280 149 55 166 190 +281 131 136 72 157 +282 122 164 35 189 +283 175 182 91 131 +284 142 131 157 189 +285 188 96 93 190 +286 132 123 75 168 +287 168 176 37 102 +288 149 17 102 190 +289 141 74 188 190 +290 175 53 115 107 +291 120 99 122 189 +292 100 99 120 189 +293 164 122 99 189 +294 149 163 17 190 +295 141 188 93 190 +296 185 92 143 189 +297 163 119 17 190 +298 143 98 97 189 +299 92 185 175 189 +300 119 102 17 190 +301 163 95 119 190 +302 185 143 97 189 +303 97 100 185 189 +304 142 73 165 157 +305 95 96 119 190 +306 120 107 54 189 +307 36 186 168 190 +308 164 99 98 189 +309 141 93 94 190 +310 186 96 188 190 +311 187 120 54 189 +312 186 36 121 190 +313 163 94 95 190 +314 149 17 18 102 +315 149 132 55 190 +316 122 35 107 189 +317 56 153 57 123 +318 73 142 131 157 +319 80 79 125 169 +320 39 111 167 40 +321 43 177 104 42 +322 98 143 142 189 +323 171 83 84 127 +324 74 168 188 190 +325 126 82 81 170 +326 144 94 166 190 +327 33 109 156 32 +328 180 49 48 114 +329 98 142 165 189 +330 66 67 128 162 +331 68 69 129 160 +332 158 19 20 101 +333 139 65 66 150 +334 77 76 133 183 +335 51 117 50 181 +336 178 44 105 45 +337 59 154 60 140 +338 84 85 179 139 +339 29 30 148 114 +340 30 31 160 106 +341 79 78 140 184 +342 138 82 178 83 +343 116 159 27 26 +344 98 165 164 189 +345 172 48 47 112 +346 154 21 22 103 +347 147 63 138 64 +348 93 96 94 190 +349 92 131 143 189 +350 94 144 141 190 +351 171 46 45 116 +352 161 22 23 118 +353 92 175 131 189 +354 43 44 113 170 +355 70 71 130 156 +356 21 20 111 145 +357 97 98 100 189 +358 163 166 94 190 +359 180 86 87 134 +360 105 25 147 26 +361 69 70 135 151 +362 183 39 38 101 +363 36 168 102 190 +364 175 54 107 189 +365 100 187 185 189 +366 121 119 96 190 +367 188 10 93 96 +368 161 61 60 125 +369 33 152 115 34 +370 181 88 89 135 +371 81 80 137 177 +372 100 120 187 189 +373 121 96 186 190 +374 24 23 104 146 +375 145 59 58 124 +376 58 57 158 133 +377 64 65 127 159 +378 63 62 155 126 +379 28 108 150 27 +380 113 25 24 155 +381 173 87 88 129 +382 172 85 86 128 +383 90 174 89 130 +384 36 102 121 190 +385 187 54 175 189 +386 31 151 117 32 +387 41 42 118 169 +388 103 40 41 184 +389 50 49 173 106 +390 179 47 46 108 +391 28 29 162 112 +392 98 99 100 189 +393 146 62 61 137 +394 157 164 165 189 +395 182 90 91 136 +396 94 96 95 190 +397 120 100 13 99 +398 132 141 144 190 +399 76 75 123 176 +400 38 176 110 37 +401 52 53 115 182 +402 95 119 2 163 +403 13 120 99 122 +404 97 143 15 98 +405 163 149 166 190 +406 78 77 124 167 +407 67 68 134 148 +408 71 72 136 152 +409 131 142 143 189 +410 10 188 186 96 +411 51 52 109 174 +412 72 73 131 157 +413 9 119 95 96 +414 185 14 100 97 +415 107 120 122 189 +416 168 186 188 190 +417 110 19 18 153 +418 35 107 157 34 +419 143 15 98 142 +420 168 37 36 102 +421 75 74 132 168 +422 91 92 175 131 +423 175 54 53 107 +424 16 98 164 99 +425 175 185 187 189 +426 119 121 102 190 +427 163 12 95 94 +428 8 98 142 165 +429 93 94 11 141 +430 120 5 100 187 +431 1 186 121 96 +432 99 164 6 122 +433 119 9 121 96 +434 187 14 100 185 +435 15 8 98 142 +436 16 98 165 164 +437 100 13 5 120 +438 186 1 10 96 +439 94 144 11 141 +440 12 163 166 94 +441 95 2 12 163 +442 119 2 9 95 +443 6 16 164 99 +444 3 93 141 188 +445 7 185 143 97 +446 4 166 144 94 +447 11 3 93 141 +448 185 7 14 97 +449 56 55 149 132 +450 98 8 16 165 +451 17 2 119 163 +452 144 11 4 94 +453 166 4 12 94 +454 5 14 100 187 +455 121 9 1 96 +456 99 6 13 122 +457 93 3 10 188 +458 143 15 7 97 +459 122 164 6 35 +460 5 120 54 187 +461 1 186 36 121 +462 7 185 92 143 +463 74 3 141 188 +464 8 142 73 165 +465 4 166 55 144 +466 129 135 173 160 +467 106 173 135 160 +468 106 135 173 181 +469 151 106 135 160 +470 135 106 151 117 +471 147 113 25 105 +472 147 25 113 155 +473 101 145 20 158 +474 101 20 145 111 +475 134 172 86 128 +476 134 86 172 180 +477 178 116 147 171 +478 147 116 178 105 +479 127 179 84 171 +480 127 84 179 139 +481 152 130 71 156 +482 152 71 130 136 +483 108 159 27 116 +484 27 159 108 150 +485 101 158 123 183 +486 123 158 101 110 +487 123 176 101 183 +488 101 176 123 110 +489 155 137 62 146 +490 155 62 137 126 +491 116 147 26 105 +492 26 147 116 159 +493 184 111 40 167 +494 184 40 111 103 +495 179 128 108 139 +496 108 128 179 172 +497 138 155 63 147 +498 63 155 138 126 +499 106 181 50 117 +500 106 50 181 173 +501 179 116 46 171 +502 46 116 179 108 +503 137 169 80 125 +504 80 169 137 177 +505 160 134 173 129 +506 160 173 134 148 +507 180 134 173 148 +508 118 184 41 169 +509 41 184 118 103 +510 123 158 57 133 +511 123 57 158 153 +512 137 161 61 146 +513 137 61 161 125 +514 130 135 151 117 +515 130 109 151 156 +516 151 109 130 117 +517 109 182 52 115 +518 52 182 109 174 +519 35 189 157 107 +520 157 189 35 164 +521 190 74 132 141 +522 190 132 74 168 +523 135 173 88 129 +524 135 88 173 181 +525 162 128 108 172 +526 108 112 162 172 +527 162 139 108 128 +528 108 139 162 150 +529 134 173 87 180 +530 134 87 173 129 +531 151 130 70 135 +532 70 130 151 156 +533 162 108 28 112 +534 28 108 162 150 +$EndElements