From ecaf8cb7fcb1bbc8adb34ebdface6e37aa7ce312 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sat, 19 Aug 2017 12:05:32 +0300 Subject: [PATCH] Use global timer to measure performance This makes syntax a little bit easier. Also, measure more accurately performance of modal solver under investigation. --- src/JuliaFEM.jl | 7 +-- src/solvers.jl | 56 +++++++++---------- src/solvers_modal.jl | 45 +++++++-------- ..._elasticity_2d_linear_with_surface_load.jl | 2 - 4 files changed, 49 insertions(+), 61 deletions(-) diff --git a/src/JuliaFEM.jl b/src/JuliaFEM.jl index 5c925b2..c24f838 100644 --- a/src/JuliaFEM.jl +++ b/src/JuliaFEM.jl @@ -9,12 +9,7 @@ This is JuliaFEM -- Finite Element Package module JuliaFEM using TimerOutputs -const to = TimerOutput() -function print_statistics() - println(to) -end - -export print_statistics, @timeit, to +export @timeit, print_timer import Base: getindex, setindex!, convert, length, size, isapprox, similar, start, first, next, done, last, endof, vec, ==, +, -, *, /, haskey, copy, diff --git a/src/solvers.jl b/src/solvers.jl index fdd61e0..f9bf1c7 100644 --- a/src/solvers.jl +++ b/src/solvers.jl @@ -363,24 +363,33 @@ function solve!(solver::Solver; empty_assemblies_before_solution=true, symmetric return end -""" Default assembler for solver. """ -function assemble!(solver::Solver; timing=true, with_mass_matrix=false) +""" + assemble!(solver; with_mass_matrix=false) + +Default assembler for solver. + +This function loops over all problems defined in problem and launches +standard assembler for them. As a result, each problem.assembly is +populated with global stiffness matrix, force vector, and, optionally, +mass matrix. +""" +function assemble!(solver::Solver; with_mass_matrix=false) info("Assembling problems ...") - function do_assemble(problem) - t00 = Base.time() - empty!(problem.assembly) - assemble!(problem, solver.time) - if with_mass_matrix && is_field_problem(problem) - assemble!(problem, solver.time, Val{:mass_matrix}) + for problem in get_problems(solver) + timeit("assemble $(problem.name)") do + empty!(problem.assembly) + assemble!(problem, solver.time) end - t11 = Base.time() - return t11-t00 end - t0 = Base.time() - assembly_times = map(do_assemble, solver.problems) - nproblems = length(assembly_times) + if with_mass_matrix + for problem in get_field_problems(solver) + timeit("assemble $(problem.name) mass matrix") do + assemble!(problem, solver.time, Val{:mass_matrix}) + end + end + end ndofs = 0 for problem in solver.problems @@ -388,18 +397,9 @@ function assemble!(solver::Solver; timing=true, with_mass_matrix=false) Cs = size(problem.assembly.C1, 2) ndofs = max(ndofs, Ks, Cs) end - solver.ndofs = ndofs - t1 = round(Base.time()-t0, 2) - info("Assembled $nproblems problems in $t1 seconds. ndofs = $ndofs.") - if timing - info("Assembly times:") - for (i, problem) in enumerate(solver.problems) - pn = problem.name - pt = round(assembly_times[i], 2) - info("$i $pn $pt") - end - end + + info("Assembly done!") end function get_unknown_fields(solver::Solver) @@ -688,10 +688,10 @@ function (solver::Solver{Linear})() info("Starting linear solver") info("Increment time t=$(round(solver.time, 3))") info(repeat("-", 80)) - @timeit to "initialize solver" initialize!(solver) - @timeit to "assemble problems" assemble!(solver) - @timeit to "solve linear system" solve!(solver) - @timeit to "update problems" update!(solver) + @timeit "initialize solver" initialize!(solver) + @timeit "assemble problems" assemble!(solver) + @timeit "solve linear system" solve!(solver) + @timeit "update problems" update!(solver) t1 = round(Base.time()-t0, 2) info("Linear solver ready in $t1 seconds.") end diff --git a/src/solvers_modal.jl b/src/solvers_modal.jl index c9c085d..6ab4c48 100644 --- a/src/solvers_modal.jl +++ b/src/solvers_modal.jl @@ -217,12 +217,13 @@ function (solver::Solver{Modal})(; bc_invertible=false, P=nothing, symmetric=tru info("Increment time t=$(round(solver.time, 3))") info(repeat("-", 80)) initialize!(solver) - @timeit to "assemble matrices" begin + + @timeit "assemble matrices" begin assemble!(solver; with_mass_matrix=true) - end - M, K, Kg, f = get_field_assembly(solver) - if solver.properties.geometric_stiffness - K += Kg + M, K, Kg, f = get_field_assembly(solver) + if solver.properties.geometric_stiffness + K += Kg + end end dim = size(K, 1) @@ -232,23 +233,19 @@ function (solver::Solver{Modal})(; bc_invertible=false, P=nothing, symmetric=tru K_red = K M_red = M - if !(P == nothing) - tic() - info("Using custom P to make transform K_red = P'*K*P and M_red = P'*M*P") - K_red = P'*K_red*P - M_red = P'*M_red*P - t1 = round(toq(), 2) - info("Transform ready in $t1 seconds.") - elseif nboundary_problems != 0 - tic() - info("Eliminate boundary conditions from system.") - for boundary_problem in get_boundary_problems(solver) - eliminate_boundary_conditions!(K_red, M_red, boundary_problem, dim) + @timeit "eliminate boundary conditions" begin + if !(P == nothing) + info("Using custom P to make transform K_red = P'*K*P and M_red = P'*M*P") + K_red = P'*K_red*P + M_red = P'*M_red*P + elseif nboundary_problems != 0 + info("Eliminate boundary conditions from system.") + for boundary_problem in get_boundary_problems(solver) + eliminate_boundary_conditions!(K_red, M_red, boundary_problem, dim) + end + else + info("No boundary Dirichlet boundary conditions found for system.") end - t1 = round(toq(), 2) - info("Eliminated boundary conditions in $t1 seconds.") - else - info("No boundary Dirichlet boundary conditions found for system.") end # free up some memory before solution @@ -299,7 +296,7 @@ function (solver::Solver{Modal})(; bc_invertible=false, P=nothing, symmetric=tru passed = false try - @timeit to "solve eigenvalue problem using `eigs`" begin + @timeit "solve eigenvalue problem using `eigs`" begin om2, X = eigs(K_red + sigma*I, M_red; nev=props.nev, which=props.which) end passed = true @@ -354,9 +351,7 @@ function (solver::Solver{Modal})(; bc_invertible=false, P=nothing, symmetric=tru end end - @timeit to "save results to Xdmf" begin - update_xdmf!(solver) - end + @timeit "save results to Xdmf" update_xdmf!(solver) return true diff --git a/test/test_elasticity_2d_linear_with_surface_load.jl b/test/test_elasticity_2d_linear_with_surface_load.jl index 0f56ece..6cd4cce 100644 --- a/test/test_elasticity_2d_linear_with_surface_load.jl +++ b/test/test_elasticity_2d_linear_with_surface_load.jl @@ -49,5 +49,3 @@ using JuliaFEM u3_expected = f/E*[-nu, 1] + g/(2*E)*[-nu, 1] @test isapprox(u3, u3_expected) end - -print_statistics()