From b3ca5d34ad9df5dcbd7ef245fcd3d874133eee1a Mon Sep 17 00:00:00 2001 From: Cheng Gong Date: Sat, 22 Jun 2024 12:05:01 -0800 Subject: [PATCH 1/3] make test101 works with ISSM Archive data --- test/runtests.jl | 34 +++++++++++++++++++++++++++++++++- test/test101.jl | 15 +++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 7402bec..16941e1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,14 +5,46 @@ function searchdir(path,key) filter(x->occursin(key,x), readdir(path)) end +function compareArchive(id, procedure::Symbol) + archive_name = "Archive"*string(id) + archive_path = issmdir()*"/test/Archives/"*archive_name*".arch" + if procedure===:update + # update Archive + else + # check Archive + if isempty(archive_path) + @warn "$archive_name does not exist! Skip the comparison of the results" + else + for k=1:length(field_names) + # Get field and tolerance + field=field_values[k]; + fieldname=field_names[k]; + tolerance=field_tolerances[k]; + + # Compare to archive + # Our output is in the correct order (n,1) or (1,1), so we do not need to transpose again + archive = archread(archive_path, archive_name*"_field"*string(k)) + error_diff = (maximum(abs.(archive-field))/(maximum(abs.(archive))+eps(Float64))) + + @test isnan(error_diff) == false + @test error_diff < tolerance + end + end + end +end + @time begin @time @testset "Model Struct Tests" begin include("modelstructtests.jl") end # test each individual cases, name with test[0-9]*.jl - testsolutions = searchdir("./", r"test[0-9]*.jl") + testsolutions = searchdir("./", r"test\d+.jl") @time @testset "Model Solution Tests" begin for tf in testsolutions + # run the test include(tf) + # check the results vs. saved archive + testid = match(r"test(\d+).jl", tf).captures[1] + compareArchive(testid, :test) end end diff --git a/test/test101.jl b/test/test101.jl index 070e21c..e64bdac 100755 --- a/test/test101.jl +++ b/test/test101.jl @@ -22,12 +22,12 @@ y = archread(issmdir()*"/test/Data/SquareShelfConstrained.arch","y") vx = archread(issmdir()*"/test/Data/SquareShelfConstrained.arch","vx") vy = archread(issmdir()*"/test/Data/SquareShelfConstrained.arch","vy") index = Int.(archread(issmdir()*"/test/Data/SquareShelfConstrained.arch","index")) -md.initialization.vx=0 .*InterpFromMeshToMesh2d(index,x,y,vx,md.mesh.x,md.mesh.y,0.0) -md.initialization.vy=0 .*InterpFromMeshToMesh2d(index,x,y,vy,md.mesh.x,md.mesh.y,0.0) +md.initialization.vx=InterpFromMeshToMesh2d(index,x,y,vx,md.mesh.x,md.mesh.y,0.0) +md.initialization.vy=InterpFromMeshToMesh2d(index,x,y,vy,md.mesh.x,md.mesh.y,0.0) -md.materials.rheology_B=1.815730284801701e+08*ones(md.mesh.numberofvertices) +md.materials.rheology_B=1.815730284801701e08*ones(md.mesh.numberofvertices) md.materials.rheology_n=3*ones(md.mesh.numberofelements) -md.friction.coefficient=20*ones(md.mesh.numberofvertices) +md.friction.coefficient=0.0*ones(md.mesh.numberofvertices) md.friction.p=ones(md.mesh.numberofvertices) md.friction.q=ones(md.mesh.numberofvertices) @@ -43,3 +43,10 @@ md.stressbalance.spcvx[pos] .= 0.0 md.stressbalance.spcvy[pos] .= 0.0 md=solve(md,:Stressbalance) + +# Fields and tolerances to track changes +field_names =["Vx","Vy","Vel"] +field_tolerances=[4e-13,4e-13,4e-13] +field_values= [(md.results["StressbalanceSolution"]["Vx"]), + (md.results["StressbalanceSolution"]["Vy"]), + (md.results["StressbalanceSolution"]["Vel"]) ] From 2dbc2ad6e2272e235143d6d3be50e16355a21c3b Mon Sep 17 00:00:00 2001 From: Cheng Gong Date: Sat, 22 Jun 2024 12:14:07 -0800 Subject: [PATCH 2/3] ignore thoes without Archive data --- test/runtests.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 16941e1..48c6edb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -12,9 +12,7 @@ function compareArchive(id, procedure::Symbol) # update Archive else # check Archive - if isempty(archive_path) - @warn "$archive_name does not exist! Skip the comparison of the results" - else + if isfile(archive_path) for k=1:length(field_names) # Get field and tolerance field=field_values[k]; @@ -29,6 +27,8 @@ function compareArchive(id, procedure::Symbol) @test isnan(error_diff) == false @test error_diff < tolerance end + else + @warn "$archive_name does not exist! Skip the comparison of the results" end end end From c4aa1c3b7e70b27bec6a1340b8121d99ab50bfe1 Mon Sep 17 00:00:00 2001 From: Cheng Gong Date: Sat, 22 Jun 2024 17:30:50 -0400 Subject: [PATCH 3/3] add arch data --- test/Archives/Archive101.arch | Bin 0 -> 19629 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/Archives/Archive101.arch diff --git a/test/Archives/Archive101.arch b/test/Archives/Archive101.arch new file mode 100644 index 0000000000000000000000000000000000000000..a17d99e347e320519305dc077587232b7d26173d GIT binary patch literal 19629 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