|
1 |
| -using AlgebraicMultigrid |
2 |
| -import AlgebraicMultigrid as AMG |
3 |
| -using Test |
4 |
| -using SparseArrays, LinearAlgebra |
5 |
| -using Ferrite, FerriteGmsh, SparseArrays |
6 |
| -using Downloads: download |
7 |
| - |
8 | 1 | ## Test QR factorization
|
9 | 2 | @testset "fit_candidates unit test cases" begin
|
10 | 3 | cases = Vector{Tuple{SparseMatrixCSC{Float64,Int},Matrix{Float64}}}()
|
@@ -69,138 +62,6 @@ using Downloads: download
|
69 | 62 | end
|
70 | 63 | end
|
71 | 64 |
|
72 |
| -## Test Convergance of AMG for linear elasticity & bending beam |
73 |
| -function assemble_external_forces!(f_ext, dh, facetset, facetvalues, prescribed_traction) |
74 |
| - # Create a temporary array for the facet's local contributions to the external force vector |
75 |
| - fe_ext = zeros(getnbasefunctions(facetvalues)) |
76 |
| - for facet in FacetIterator(dh, facetset) |
77 |
| - # Update the facetvalues to the correct facet number |
78 |
| - reinit!(facetvalues, facet) |
79 |
| - # Reset the temporary array for the next facet |
80 |
| - fill!(fe_ext, 0.0) |
81 |
| - # Access the cell's coordinates |
82 |
| - cell_coordinates = getcoordinates(facet) |
83 |
| - for qp in 1:getnquadpoints(facetvalues) |
84 |
| - # Calculate the global coordinate of the quadrature point. |
85 |
| - x = spatial_coordinate(facetvalues, qp, cell_coordinates) |
86 |
| - tₚ = prescribed_traction(x) |
87 |
| - # Get the integration weight for the current quadrature point. |
88 |
| - dΓ = getdetJdV(facetvalues, qp) |
89 |
| - for i in 1:getnbasefunctions(facetvalues) |
90 |
| - Nᵢ = shape_value(facetvalues, qp, i) |
91 |
| - fe_ext[i] += tₚ ⋅ Nᵢ * dΓ |
92 |
| - end |
93 |
| - end |
94 |
| - # Add the local contributions to the correct indices in the global external force vector |
95 |
| - assemble!(f_ext, celldofs(facet), fe_ext) |
96 |
| - end |
97 |
| - return f_ext |
98 |
| -end |
99 |
| - |
100 |
| -function assemble_cell!(ke, cellvalues, C) |
101 |
| - for q_point in 1:getnquadpoints(cellvalues) |
102 |
| - # Get the integration weight for the quadrature point |
103 |
| - dΩ = getdetJdV(cellvalues, q_point) |
104 |
| - for i in 1:getnbasefunctions(cellvalues) |
105 |
| - # Gradient of the test function |
106 |
| - ∇Nᵢ = shape_gradient(cellvalues, q_point, i) |
107 |
| - for j in 1:getnbasefunctions(cellvalues) |
108 |
| - # Symmetric gradient of the trial function |
109 |
| - ∇ˢʸᵐNⱼ = shape_symmetric_gradient(cellvalues, q_point, j) |
110 |
| - ke[i, j] += (∇Nᵢ ⊡ C ⊡ ∇ˢʸᵐNⱼ) * dΩ |
111 |
| - end |
112 |
| - end |
113 |
| - end |
114 |
| - return ke |
115 |
| -end |
116 |
| - |
117 |
| -function assemble_global!(K, dh, cellvalues, C) |
118 |
| - # Allocate the element stiffness matrix |
119 |
| - n_basefuncs = getnbasefunctions(cellvalues) |
120 |
| - ke = zeros(n_basefuncs, n_basefuncs) |
121 |
| - # Create an assembler |
122 |
| - assembler = start_assemble(K) |
123 |
| - # Loop over all cells |
124 |
| - for cell in CellIterator(dh) |
125 |
| - # Update the shape function gradients based on the cell coordinates |
126 |
| - reinit!(cellvalues, cell) |
127 |
| - # Reset the element stiffness matrix |
128 |
| - fill!(ke, 0.0) |
129 |
| - # Compute element contribution |
130 |
| - assemble_cell!(ke, cellvalues, C) |
131 |
| - # Assemble ke into K |
132 |
| - assemble!(assembler, celldofs(cell), ke) |
133 |
| - end |
134 |
| - return K |
135 |
| -end |
136 |
| - |
137 |
| -function create_nns(dh) |
138 |
| - Ndof = ndofs(dh) |
139 |
| - grid = dh.grid |
140 |
| - B = zeros(Float64, Ndof, 3) |
141 |
| - B[1:2:end, 1] .= 1 # x - translation |
142 |
| - B[2:2:end, 2] .= 1 # y - translation |
143 |
| - |
144 |
| - # in-plane rotation (x,y) → (-y,x) |
145 |
| - coords = reduce(hcat, grid.nodes .|> (n -> n.x |> collect))' # convert nodes to 2d array |
146 |
| - y = coords[:, 2] |
147 |
| - x = coords[:, 1] |
148 |
| - B[1:2:end, 3] .= -y |
149 |
| - B[2:2:end, 3] .= x |
150 |
| - return B |
151 |
| -end |
152 |
| - |
153 |
| -function linear_elasticity_2d() |
154 |
| - # Example test: https://ferrite-fem.github.io/Ferrite.jl/stable/tutorials/linear_elasticity/ |
155 |
| - logo_mesh = "logo.geo" |
156 |
| - asset_url = "https://raw.githubusercontent.com/Ferrite-FEM/Ferrite.jl/gh-pages/assets/" |
157 |
| - isfile(logo_mesh) || download(string(asset_url, logo_mesh), logo_mesh) |
158 |
| - |
159 |
| - grid = togrid(logo_mesh) |
160 |
| - addfacetset!(grid, "top", x -> x[2] ≈ 1.0) # facets for which x[2] ≈ 1.0 for all nodes |
161 |
| - addfacetset!(grid, "left", x -> abs(x[1]) < 1.0e-6) |
162 |
| - addfacetset!(grid, "bottom", x -> abs(x[2]) < 1.0e-6) |
163 |
| - |
164 |
| - dim = 2 |
165 |
| - order = 1 # linear interpolation |
166 |
| - ip = Lagrange{RefTriangle,order}()^dim # vector valued interpolation |
167 |
| - |
168 |
| - qr = QuadratureRule{RefTriangle}(1) # 1 quadrature point |
169 |
| - qr_face = FacetQuadratureRule{RefTriangle}(1) |
170 |
| - |
171 |
| - cellvalues = CellValues(qr, ip) |
172 |
| - facetvalues = FacetValues(qr_face, ip) |
173 |
| - |
174 |
| - dh = DofHandler(grid) |
175 |
| - add!(dh, :u, ip) |
176 |
| - close!(dh) |
177 |
| - |
178 |
| - ch = ConstraintHandler(dh) |
179 |
| - add!(ch, Dirichlet(:u, getfacetset(grid, "bottom"), (x, t) -> 0.0, 2)) |
180 |
| - add!(ch, Dirichlet(:u, getfacetset(grid, "left"), (x, t) -> 0.0, 1)) |
181 |
| - close!(ch) |
182 |
| - |
183 |
| - traction(x) = Vec(0.0, 20.0e3 * x[1]) |
184 |
| - Emod = 200.0e3 # Young's modulus [MPa] |
185 |
| - ν = 0.3 # Poisson's ratio [-] |
186 |
| - |
187 |
| - Gmod = Emod / (2(1 + ν)) # Shear modulus |
188 |
| - Kmod = Emod / (3(1 - 2ν)) # Bulk modulus |
189 |
| - |
190 |
| - C = gradient(ϵ -> 2 * Gmod * dev(ϵ) + 3 * Kmod * vol(ϵ), zero(SymmetricTensor{2,2})) |
191 |
| - A = allocate_matrix(dh) |
192 |
| - assemble_global!(A, dh, cellvalues, C) |
193 |
| - |
194 |
| - b = zeros(ndofs(dh)) |
195 |
| - B = create_nns(dh) |
196 |
| - assemble_external_forces!(b, dh, getfacetset(grid, "top"), facetvalues, traction) |
197 |
| - |
198 |
| - apply!(A, b, ch) |
199 |
| - |
200 |
| - return A, b, B # return the assembled matrix, force vector, and NNS matrix |
201 |
| -end |
202 |
| - |
203 |
| - |
204 | 65 | ## Helper functions for cantilever frame beam ##
|
205 | 66 |
|
206 | 67 | # Element stiffness matrix
|
@@ -307,16 +168,18 @@ end
|
307 | 168 |
|
308 | 169 | @testset "Mechanics test cases" begin
|
309 | 170 | @testset "Linear elasticity 2D" begin
|
310 |
| - A, b, B = linear_elasticity_2d() |
| 171 | + # load linear elasticity test data |
| 172 | + @load "lin_elastic_2d.jld2" A b B |
| 173 | + A = SparseMatrixCSC(A.m, A.n, A.colptr, A.rowval, A.nzval) |
311 | 174 |
|
312 | 175 | x_nns, residuals_nns = solve(A, b, SmoothedAggregationAMG(B); log=true, reltol=1e-10)
|
313 | 176 | x_wonns, residuals_wonns = solve(A, b, SmoothedAggregationAMG(); log=true, reltol=1e-10)
|
314 | 177 |
|
315 | 178 | ml = smoothed_aggregation(A, B)
|
316 | 179 | @show ml
|
317 | 180 |
|
318 |
| - println("No NNS: final residual at iteration ", length(residuals_wonns), ": ", residuals_nns[end]) |
319 |
| - println("With NNS: final residual at iteration ", length(residuals_nns), ": ", residuals_wonns[end]) |
| 181 | + println("No NNS: final residual at iteration ", length(residuals_wonns), ": ", residuals_wonns[end]) |
| 182 | + println("With NNS: final residual at iteration ", length(residuals_nns), ": ", residuals_nns[end]) |
320 | 183 |
|
321 | 184 |
|
322 | 185 | #test QR factorization on linear elasticity
|
|
351 | 214 | x_nns, residuals_nns = solve(A, b, SmoothedAggregationAMG(B); log=true, reltol=1e-10)
|
352 | 215 | x_wonns, residuals_wonns = solve(A, b, SmoothedAggregationAMG(); log=true, reltol=1e-10)
|
353 | 216 |
|
354 |
| - println("No NNS: final residual at iteration ", length(residuals_wonns), ": ", residuals_nns[end]) |
355 |
| - println("With NNS: final residual at iteration ", length(residuals_nns), ": ", residuals_wonns[end]) |
| 217 | + println("No NNS: final residual at iteration ", length(residuals_wonns), ": ", residuals_wonns[end]) |
| 218 | + println("With NNS: final residual at iteration ", length(residuals_nns), ": ", residuals_nns[end]) |
356 | 219 |
|
357 | 220 |
|
358 | 221 | # test QR factorization on bending beam
|
|
0 commit comments