From 4b471ac9ba13f0be798c582fecd49dc9b79e8888 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Thu, 20 Sep 2018 19:59:45 +0300 Subject: [PATCH 01/14] Store Xdmf results in Mixed format Store element connectivity as "Mixed" format to Xdmf file. It's a long list where first number is element code and then there is connectivity data (starting from 0). Xdmf format does not support several Topology-elements in Xml file format, so before it was not possible to store e.g. both Tri3 and Quad4 elements in same problem. After this commit this should now be possible. Paraview Xdmf3 reader is needed to use. --- src/io.jl | 86 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/src/io.jl b/src/io.jl index 1316a41..cc519e4 100644 --- a/src/io.jl +++ b/src/io.jl @@ -328,6 +328,29 @@ global const xdmf_element_mapping = Dict( "Wedge15" => "Wedge_15", "Hex20" => "Hex_20") +get_xdmf_element_code(::Element{Poi1}) = 1 +get_xdmf_element_code(::Element{Seg2}) = 2 +# get_xdmf_element_code(::Element{Polygon}) = 3 +get_xdmf_element_code(::Element{Tri3}) = 4 +get_xdmf_element_code(::Element{Quad4}) = 5 +get_xdmf_element_code(::Element{Tet4}) = 6 +get_xdmf_element_code(::Element{Pyr5}) = 7 +get_xdmf_element_code(::Element{Wedge6}) = 8 +get_xdmf_element_code(::Element{Hex8}) = 9 +# get_xdmf_element_code(::Element{Polyhedron}) = 16 + +get_xdmf_element_code(::Element{Seg3}) = 34 +get_xdmf_element_code(::Element{Quad9}) = 35 +get_xdmf_element_code(::Element{Tri6}) = 36 +get_xdmf_element_code(::Element{Quad8}) = 37 +get_xdmf_element_code(::Element{Tet10}) = 38 +# get_xdmf_element_code(::Element{Pyr13}) = 39 +get_xdmf_element_code(::Element{Wedge15}) = 40 +# get_xdmf_element_code(::Element{Wedge18}) = 41 +get_xdmf_element_code(::Element{Hex20}) = 48 +# get_xdmf_element_code(::Element{Hex24}) = 49 +get_xdmf_element_code(::Element{Hex27}) = 50 + """ get_spatial_collection() @@ -416,27 +439,48 @@ function update_xdmf!(xdmf::Xdmf, problem::Problem, time::Float64, fields::Vecto add_child(geometry, X_dataitem) # 5. save topology - all_elements = get_elements(problem) - nelements = length(all_elements) - element_types = unique(map(get_element_type, all_elements)) - nelement_types = length(element_types) - @debug("Xdmf: Saving topology of $nelements elements total, $nelement_types different element types.") - - for element_type in element_types - elements = collect(filter_by_element_type(element_type, all_elements)) - nelements = length(elements) - @debug("Xdmf: $nelements elements of type $element_type") - sort!(elements, by=get_element_id) - element_ids = map(get_element_id, elements) - element_conn = map(element -> [node_mapping[j]-1 for j in get_connectivity(element)], elements) - element_conn = hcat(element_conn...) - element_code = split(string(element_type), ".")[end] + mesh_type = "unstructured" + if mesh_type == "unstructured" + element_conn = Int64[] + for element in get_elements(problem) + xdmf_element_code = get_xdmf_element_code(element) + xdmf_element_code > 0 || continue + push!(element_conn, xdmf_element_code) + if xdmf_element_code == 2 + push!(element_conn, length(element)) + end + for j in get_connectivity(element) + push!(element_conn, node_mapping[j]-1) + end + end topology_dataitem = new_dataitem(xdmf, element_conn) - topology = new_child(frame, "Topology") - set_attribute(topology, "TopologyType", xdmf_element_mapping[element_code]) - set_attribute(topology, "NumberOfElements", length(elements)) + set_attribute(topology, "TopologyType", "Mixed") add_child(topology, topology_dataitem) + else + all_elements = get_elements(problem) + nelements = length(all_elements) + element_types = unique(map(get_element_type, all_elements)) + nelement_types = length(element_types) + @debug("Xdmf: Saving topology of $nelements elements total, $nelement_types different element types.") + if nelement_types != 1 + error("Xdmf: only single type of element supported by structured grid type!") + end + for element_type in element_types + elements = collect(filter_by_element_type(element_type, all_elements)) + nelements = length(elements) + @debug("Xdmf: $nelements elements of type $element_type") + sort!(elements, by=get_element_id) + element_ids = map(get_element_id, elements) + element_conn = map(element -> [node_mapping[j]-1 for j in get_connectivity(element)], elements) + element_conn = hcat(element_conn...) + element_code = split(string(element_type), ".")[end] + topology_dataitem = new_dataitem(xdmf, element_conn) + topology = new_child(frame, "Topology") + set_attribute(topology, "TopologyType", xdmf_element_mapping[element_code]) + set_attribute(topology, "NumberOfElements", length(elements)) + add_child(topology, topology_dataitem) + end end # 6. save requested fields @@ -444,7 +488,11 @@ function update_xdmf!(xdmf::Xdmf, problem::Problem, time::Float64, fields::Vecto field_dict = problem(field_name, time) field_center = "Node" field_node_ids = sort(collect(keys(field_dict))) - @assert node_ids == field_node_ids + if node_ids != field_node_ids + @error("geom node ids = $node_ids") + @error("field node ids = $field_node_ids") + error("!=, geometry does not match with field.") + end field_dim = length(field_dict[first(field_node_ids)]) if field_dim == 2 @debug("Xdmf: Field dimension = 2, extending to 3") From 69be547d9d519bd4228f23933b738c49c09ff5c6 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sat, 27 Oct 2018 19:23:57 +0300 Subject: [PATCH 02/14] Add upper bound to Julia v2.0 to REQUIRE --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 5cbec28..ac9dc79 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,4 @@ -julia 0.7 +julia 0.7 2.0 FEMBase FEMBasis FEMQuad From 5714f4aa0cde6fe89dcc4a48220f7c1bb939bc6e Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sat, 27 Oct 2018 19:55:26 +0300 Subject: [PATCH 03/14] Fix example of 2d hertz contact Example was not Julia 1.0 compatible. Fixed. Closes issue #221. --- examples/2d_hertz_contact.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/2d_hertz_contact.jl b/examples/2d_hertz_contact.jl index 8ad1ad8..62daf37 100644 --- a/examples/2d_hertz_contact.jl +++ b/examples/2d_hertz_contact.jl @@ -23,7 +23,7 @@ # Substituting values, one gets accurate solution to be ``p_0 = 3585 \;\mathrm{MPa}`` and # ``a = 6.21 \;\mathrm{mm}``. -using JuliaFEM +using JuliaFEM, LinearAlgebra # Simulation starts by reading the mesh. Model is constructed and meshed using # SALOME, thus mesh format is .med. Mesh type is quite simple structure, @@ -33,7 +33,7 @@ using JuliaFEM # need to use `Mesh` in simulation anyway if we figure some other way to define # the geometry for elements. -datadir = Pkg.dir("JuliaFEM", "examples", "2d_hertz_contact") +datadir = abspath(joinpath(pathof(JuliaFEM), "..", "..", "examples", "2d_hertz_contact")) meshfile = joinpath(datadir, "hertz_2d_full.med") mesh = aster_read_mesh(meshfile) for (elset_name, element_ids) in mesh.element_sets @@ -153,6 +153,7 @@ Rt = 0.0 time = 0.0 for sel in contact_slave_elements for ip in get_integration_points(sel) + global Rn, Rt w = ip.weight*sel(ip, time, Val{:detJ}) n = sel("normal", ip, time) t = sel("tangent", ip, time) @@ -181,10 +182,11 @@ p0_acc = 3585.0 for (nid, n) in normal lan = dot(n, lambda[nid]) println("$nid => $lan") + global p0 p0 = max(p0, lan) end -p0 = round(p0, 2) -rtol = round(norm(p0-p0_acc)/max(p0,p0_acc)*100, 2) +p0 = round(p0, digits=2) +rtol = round(norm(p0-p0_acc)/max(p0,p0_acc)*100, digits=2) println("Maximum contact pressure p0 = $p0, p0_acc = $p0_acc, rtol = $rtol %") # To get rough approximation where does the contact open, we can find the element @@ -202,6 +204,7 @@ for element in contact_slave_elements println("Contact opening element lambda: la1 = $la1, la2 = $la2") x11, y11 = X1 x12, y12 = X2 + global a_rad a_rad = 1/2*abs(x11+x12) break end From 64c6ff8ad5cc0e60b46b9a457ed66b0a886e004c Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Fri, 2 Nov 2018 13:38:15 -0400 Subject: [PATCH 04/14] improve performance in elasticity --- src/problems_elasticity.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/problems_elasticity.jl b/src/problems_elasticity.jl index faff70b..3d6aa75 100644 --- a/src/problems_elasticity.jl +++ b/src/problems_elasticity.jl @@ -202,8 +202,8 @@ function assemble!(assembly::Assembly, # calculate stress fill!(D, 0.0) - E = element("youngs modulus", ip, time) - nu = element("poissons ratio", ip, time) + E = element("youngs modulus", ip, time)::Float64 + nu = element("poissons ratio", ip, time)::Float64 la = E*nu/((1.0+nu)*(1.0-2.0*nu)) mu = E/(2.0*(1.0+nu)) D[1,1] = D[2,2] = D[3,3] = 2*mu + la From 58f9fb05bea32a9787a263d5b183aa1f1a309a1d Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Fri, 2 Nov 2018 13:47:57 -0400 Subject: [PATCH 05/14] improve performance in elasticity by moving out computation of X from intergration point loop --- src/problems_elasticity.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/problems_elasticity.jl b/src/problems_elasticity.jl index faff70b..fc7f6a6 100644 --- a/src/problems_elasticity.jl +++ b/src/problems_elasticity.jl @@ -130,13 +130,14 @@ function assemble!(assembly::Assembly, for element in elements u = element("displacement", time) + X = element("geometry", time) + fill!(Km, 0.0) fill!(Kg, 0.0) fill!(f_int, 0.0) fill!(f_ext, 0.0) for ip in get_integration_points(element) - X = element("geometry", time) eval_basis!(bi, X, ip) w = ip.weight*bi.detJ N = bi.N From 190644ffa9466901c095a239e2160377fa9679d1 Mon Sep 17 00:00:00 2001 From: Reza Rastak Date: Wed, 27 Feb 2019 21:35:50 -0800 Subject: [PATCH 06/14] fixed deprecated warning for format = html --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 1ac2a68..9a955cf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -254,7 +254,7 @@ PAGES = [ @info("Pages in documentation", PAGES) makedocs(modules=[JuliaFEM], - format = :html, + format = Documenter.HTML(), checkdocs = :all, sitename = "JuliaFEM", analytics = "UA-83590644-1", From ab222b04e325100effc4d49621c35d674f00a57c Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Mon, 8 Apr 2019 18:36:47 +0300 Subject: [PATCH 07/14] Update README.md (#216) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7df45f4..979fd8a 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Errors should never pass silently. If you like using our package, please consider citing our [article](https://rakenteidenmekaniikka.journal.fi/article/view/64224/26397) ``` @article{frondelius2017juliafem, - title={JuliaFEM - open source solver for both industrial and academia usage}, + title={Julia{FEM} - open source solver for both industrial and academia usage}, volume={50}, url={https://rakenteidenmekaniikka.journal.fi/article/view/64224}, DOI={10.23998/rm.64224}, From e462fa28625b50496fab02de312a66ba25e79b9f Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Mon, 8 Apr 2019 21:35:13 +0300 Subject: [PATCH 08/14] Documentation deployment fix (#230) Similar work done in FEMQuad.jl and FEMBase.jl --- .travis.yml | 11 +++++++++++ docs/deploy.jl | 1 - docs/make.jl | 7 ++++--- test/runtests.jl | 4 ---- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 49f5582..c470e92 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,5 +17,16 @@ matrix: allow_failures: - julia: nightly +jobs: + include: + - stage: "Documentation" + julia: 1.0 + os: linux + script: + - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); + Pkg.instantiate()' + - julia --project=docs/ -e 'import Pkg; Pkg.add("Documenter"); include("docs/make.jl")' + after_success: skip + after_success: - julia -e 'cd(Pkg.dir("JuliaFEM")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())' diff --git a/docs/deploy.jl b/docs/deploy.jl index 2d5c1d6..df9a90d 100644 --- a/docs/deploy.jl +++ b/docs/deploy.jl @@ -5,7 +5,6 @@ using Documenter deploydocs( repo = "github.com/JuliaFEM/JuliaFEM.jl.git", - julia = "1.0", target = "build", deps = nothing, make = nothing) diff --git a/docs/make.jl b/docs/make.jl index 9a955cf..79abe05 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -254,8 +254,9 @@ PAGES = [ @info("Pages in documentation", PAGES) makedocs(modules=[JuliaFEM], - format = Documenter.HTML(), + format = Documenter.HTML(analytics="UA-83590644-1"), checkdocs = :all, - sitename = "JuliaFEM", - analytics = "UA-83590644-1", + sitename = "JuliaFEM.jl", pages = PAGES) + +include("deploy.jl") diff --git a/test/runtests.jl b/test/runtests.jl index 7d4ff3e..eb7a173 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,8 +3,6 @@ using JuliaFEM, Test -include("../docs/make.jl") - @testset "JuliaFEM.jl" begin @testset "test_dirichlet.jl" begin include("test_dirichlet.jl") @@ -163,5 +161,3 @@ include("../docs/make.jl") include("test_von_mises_material.jl") end end - -include("../docs/deploy.jl") From ae64e8a3fe186f51828ccd717da83faa41fa63f1 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Fri, 13 Sep 2019 13:21:03 +0300 Subject: [PATCH 09/14] Update travis.yml to test with newest versions 0.7, 1.0 and nightly --> 1.2, 1.3, nightly --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c470e92..dbe3598 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ os: - linux julia: - - 0.7 - - 1.0 + - 1.2 + - 1.3 - nightly addons: From 824920c433ba36319ce82b6feb2e035877f4d5c5 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Fri, 13 Sep 2019 12:45:50 +0300 Subject: [PATCH 10/14] Fix broken test The order of the calculated eigenvalues has been changed in the newest Julia versions. Fixed by sorting the lists before comparison. Closes issue #232. --- test/test_elasticity_tet10_stiffness_matrix.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_elasticity_tet10_stiffness_matrix.jl b/test/test_elasticity_tet10_stiffness_matrix.jl index d85cf3b..e0de522 100644 --- a/test/test_elasticity_tet10_stiffness_matrix.jl +++ b/test/test_elasticity_tet10_stiffness_matrix.jl @@ -34,4 +34,4 @@ eigs_expected = [8809.45, 4936.01, 2880.56, 2491.66, 2004.85, 195.832, 104.008, 72.7562, 64.4376, 53.8515, 23.8417, 16.6354, 9.54682, 6.93361, 2.22099, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] -@test isapprox(eigs, eigs_expected; atol=1.0e-2) +@test isapprox(sort(eigs), sort(eigs_expected); atol=1.0e-2) From a0808f18fdea60234ff702207e1141196c950183 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Fri, 13 Sep 2019 14:09:40 +0300 Subject: [PATCH 11/14] Update automatic document generation It looks document generation proceduce has slightly changed. docs/Project.toml is defining dependencies for document generation and they are not explicitly given in `travis.yml`. --- .travis.yml | 6 ++---- docs/Project.toml | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 docs/Project.toml diff --git a/.travis.yml b/.travis.yml index dbe3598..9af7731 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,12 +20,10 @@ matrix: jobs: include: - stage: "Documentation" - julia: 1.0 os: linux script: - - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); - Pkg.instantiate()' - - julia --project=docs/ -e 'import Pkg; Pkg.add("Documenter"); include("docs/make.jl")' + - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' + - julia --project=docs/ docs/make.jl after_success: skip after_success: diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..cf645b5 --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,3 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" From b62ddac26a8a7b6553d6029a2dcc15c546a8daa2 Mon Sep 17 00:00:00 2001 From: Matt Campbell Date: Wed, 25 Sep 2019 10:15:05 -0700 Subject: [PATCH 12/14] change in old function name ucfirst to uppercasefirst, which was preventing the beam examples from running --- src/solvers_modal.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvers_modal.jl b/src/solvers_modal.jl index 4ac9038..ca30cc4 100644 --- a/src/solvers_modal.jl +++ b/src/solvers_modal.jl @@ -289,7 +289,7 @@ function update_xdmf!(solver::Solver{Modal}) # save modes temporal_collection = get_temporal_collection(xdmf) - unknown_field_name = ucfirst(get_unknown_field_name(solver)) + unknown_field_name = uppercasefirst(get_unknown_field_name(solver)) frames = [] @timeit "save modes" for (j, eigval) in enumerate(real(solver.properties.eigvals)) From 0d30a8f516a6bc1d1acedd785b7b798877e03b3a Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Fri, 11 Oct 2019 17:34:11 +0300 Subject: [PATCH 13/14] Create Project.toml file and remove REQUIRE files --- Project.toml | 39 +++++++++++++++++++++++++++++++++++++++ REQUIRE | 16 ---------------- test/REQUIRE | 2 -- 3 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 Project.toml delete mode 100644 REQUIRE delete mode 100644 test/REQUIRE diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..a9c3cd3 --- /dev/null +++ b/Project.toml @@ -0,0 +1,39 @@ +name = "JuliaFEM" +uuid = "f80590ac-b429-510a-8a99-e7c46989f22d" +author = ["Jukka Aho ", "Tero Frondelius ", "Olli Väinölä"] +version = "0.5.1" + +[deps] +AbaqusReader = "bc6b9049-e460-56d6-94b4-a597b2c0390d" +Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +AsterReader = "cb1a753d-6b7b-52e3-9bfe-57d99d445c39" +FEMBase = "fbcbbc08-f1bf-5204-9233-b69f5d396135" +FEMBasis = "353fb843-c566-51e6-ba49-78b3e3d5ebb5" +FEMBeam = "962f5c4a-ca9e-56d3-a659-14f0d9baaf78" +FEMQuad = "be8e8821-3f6f-54c2-987c-d2773c3a52cb" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" +HeatTransfer = "4030f512-cedb-5907-ac7f-4ab05ad75ee7" +LightXML = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MortarContact2D = "048d6160-1a0b-53cd-a5b3-316946cc8d80" +MortarContact2DAD = "c1673bdb-6aff-560b-99da-c78ea6da9af3" +REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +Reexport = "189a3867-3050-52da-a836-e630ba90ab69" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" + +[compat] +HDF5 = "≥ 0.7.0" +LightXML = "≥ 0.4.0" +julia = "≥ 1.0" + +[extras] +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/REQUIRE b/REQUIRE deleted file mode 100644 index ac9dc79..0000000 --- a/REQUIRE +++ /dev/null @@ -1,16 +0,0 @@ -julia 0.7 2.0 -FEMBase -FEMBasis -FEMQuad -ForwardDiff -LightXML 0.4 -HDF5 0.7 -TimerOutputs -Reexport -Arpack -AbaqusReader -AsterReader -HeatTransfer -MortarContact2D -MortarContact2DAD -FEMBeam diff --git a/test/REQUIRE b/test/REQUIRE deleted file mode 100644 index b340ebe..0000000 --- a/test/REQUIRE +++ /dev/null @@ -1,2 +0,0 @@ -Documenter -Literate From e821e07723cbad7afebe49bcebbefc1ee8085ccb Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sun, 13 Oct 2019 11:40:16 +0300 Subject: [PATCH 14/14] Remove imports not available anymore in Base Closes issue #234. --- src/JuliaFEM.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JuliaFEM.jl b/src/JuliaFEM.jl index b4a4812..ddaecc0 100644 --- a/src/JuliaFEM.jl +++ b/src/JuliaFEM.jl @@ -117,7 +117,7 @@ using TimerOutputs export @timeit, print_timer import Base: getindex, setindex!, convert, length, size, isapprox, - similar, start, first, next, done, last, endof, vec, + similar, first, last, vec, ==, +, -, *, /, haskey, copy, push!, isempty, empty!, append!, read, copy