diff --git a/Project.toml b/Project.toml index 181ec13..c14bea2 100644 --- a/Project.toml +++ b/Project.toml @@ -50,7 +50,6 @@ SparseArrays = "1" StaticArrays = "1" Tensors = "1" Test = "1" -TestSetExtensions = "2" TimerOutputs = "0.5" julia = "1" @@ -62,7 +61,6 @@ CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" Exodus = "f57ae99e-f805-4780-bdca-96e224be1e5a" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04" [targets] -test = ["AMDGPU", "Aqua", "CUDA", "Exodus", "MPI", "Test", "TestSetExtensions"] +test = ["AMDGPU", "Aqua", "CUDA", "Exodus", "MPI", "Test"] diff --git a/examples/electromechanics/cube.g b/examples/electromechanics/cube.g new file mode 100644 index 0000000..0df6606 Binary files /dev/null and b/examples/electromechanics/cube.g differ diff --git a/examples/electromechanics/script.jl b/examples/electromechanics/script.jl new file mode 100644 index 0000000..9ab3838 --- /dev/null +++ b/examples/electromechanics/script.jl @@ -0,0 +1,119 @@ +using Exodus +using FiniteElementContainers +using ForwardDiff +using StaticArrays +using Tensors + +struct ElectroMechanics <: FiniteElementContainers.AbstractPhysics{4, 4, 0} +end + +function FiniteElementContainers.create_properties(physics, props_dict) + return SVector{4, Float64}( + props_dict["shear modulus"], + props_dict["bulk modulus"], + props_dict["Jm"], + props_dict["permitivity"] + ) +end + +@inline function FiniteElementContainers.energy( + physics::ElectroMechanics, interps, x_el, t, dt, u_el, u_el_old, state_old_q, props_el + ) + G, K, Jm, ϵ = props_el + + interps = map_interpolants(interps, x_el) + (; X_q, N, ∇N_X, JxW) = interps + U_q, ∇U_q = interpolate_field_values_and_gradients(physics, interps, u_el) + + ∇u_q = Tensor{2, 3, eltype(u_el), 9}(∇U_q[1:3, :]) + F_q = ∇u_q + one(∇u_q) + J_q = det(F_q) + C_q = tdot(F_q) + C_inv_q = inv(C_q) + E_R_q = Vec{3, eltype(u_el)}(∇U_q[4, :]) + D_R_q = ϵ * J_q * dot(C_inv_q, E_R_q) + + # kinematics + I_1_bar = tr(J_q^(-2. / 3.) * C_q) + + # constitutive + ψ_vol = 0.5 * K * (0.5 * (J_q^2 - 1) - log(J_q)) + ψ_dev = -G * Jm / 2. * log(1. - (I_1_bar - 3.) / Jm) + ψ_mech = ψ_vol + ψ_dev + ψ_elec = (1. / (2 * ϵ * J_q)) * dot(D_R_q, C_q, D_R_q) + ψ_q = ψ_mech + ψ_elec + state_new_q = copy(state_old_q) + return JxW * ψ_q, state_new_q +end + +@inline function FiniteElementContainers.residual( + physics::ElectroMechanics, interps, x_el, t, dt, u_el, u_el_old, state_old_q, props_el +) + state_new_q = copy(state_old_q) + return ForwardDiff.gradient( + z -> energy(physics, interps, x_el, t, dt, z, u_el_old, state_old_q, props_el)[1], u_el + ), state_new_q +end + +@inline function FiniteElementContainers.stiffness( + physics::ElectroMechanics, interps, x_el, t, dt, u_el, u_el_old, state_old_q, props_el +) + state_new_q = copy(state_old_q) + return ForwardDiff.hessian( + z -> energy(physics, interps, x_el, t, dt, z, u_el_old, state_old_q, props_el)[1], u_el + ), state_new_q +end + +function run_electromechanics() + mesh_file = Base.source_dir() * "/cube.g" + output_file = Base.source_dir() * "/output.e" + + zero_func(_, _) = 0. + potential_func(_, t) = 0.8 * t + + mesh = UnstructuredMesh(mesh_file) + V = FunctionSpace(mesh, H1Field, Lagrange) + displ = VectorFunction(V, :displ) + φ = ScalarFunction(V, :phi) + u = FiniteElementContainers.GeneralFunction(displ, φ) + asm = SparseMatrixAssembler(u; use_condensed=true) + times = TimeStepper(0., 1., 11) + + dbcs = DirichletBC[ + DirichletBC("displ_x", "ssx-", zero_func) + DirichletBC("displ_y", "ssy-", zero_func) + DirichletBC("displ_z", "ssz-", zero_func) + DirichletBC("phi", "ssz-", zero_func) + DirichletBC("phi", "ssz+", potential_func) + ] + + physics = ElectroMechanics() + props = Dict( + "shear modulus" => 1.0, + "bulk modulus" => 100.0, + "Jm" => 7., + "permitivity" => 1. + ) + props = create_properties(physics, props) + p = create_parameters(mesh, asm, physics, props; dirichlet_bcs=dbcs, times=times) + + # setup solver and integrator + # linear_solver = IterativeLinearSolver(asm, :CgSolver) + linear_solver = DirectLinearSolver(asm) + solver = NewtonSolver(linear_solver) + # solver = nsolver(lsolver(asm)) + integrator = QuasiStaticIntegrator(solver) + + pp = PostProcessor(mesh, output_file, u) + write_times(pp, 1, 0.0) + + for n in 1:11 + evolve!(integrator, p) + write_times(pp, n + 1, FiniteElementContainers.current_time(p.times)) + write_field(pp, n + 1, ("displ_x", "displ_y", "displ_z", "phi"), p.h1_field) + end + + close(pp) +end + +run_electromechanics() diff --git a/src/FiniteElementContainers.jl b/src/FiniteElementContainers.jl index 9241bb7..680fe90 100644 --- a/src/FiniteElementContainers.jl +++ b/src/FiniteElementContainers.jl @@ -182,6 +182,7 @@ include("PostProcessors.jl") # include("TimeSteppers.jl") include("Parameters.jl") +include("integrals/Integrals.jl") include("solvers/Solvers.jl") include("integrators/Integrators.jl") diff --git a/src/Functions.jl b/src/Functions.jl index b0283b9..6a8f25e 100644 --- a/src/Functions.jl +++ b/src/Functions.jl @@ -178,6 +178,28 @@ function Base.show(io::IO, ::SymmetricTensorFunction{S, F}) where {S, F} println(io, " names: $S") end +struct GeneralFunction{S, F} <: AbstractFunction{S, F} + fspace::F +end + +function GeneralFunction(args...) + fspace = args[1].fspace + for arg in args + @assert typeof(arg.fspace) == typeof(fspace) + end + # syms = mapreduce(names, vcat, args) + syms = () + for arg in args + syms = (syms..., names(arg)...) + end + # @show syms + return GeneralFunction{syms, typeof(fspace)}(fspace) +end + +function Base.show(io::IO, ::GeneralFunction{S, F}) where {S, F} + println(io, "GeneralFunction:") + println(io, " names: $S") +end # struct StateFunction{S, F, NS, NQ} <: AbstractFunction{S, F} # fspace::F diff --git a/src/assemblers/SparseMatrixAssembler.jl b/src/assemblers/SparseMatrixAssembler.jl index e58ecfb..5c20bdf 100644 --- a/src/assemblers/SparseMatrixAssembler.jl +++ b/src/assemblers/SparseMatrixAssembler.jl @@ -8,7 +8,6 @@ struct SparseMatrixAssembler{ Condensed, NumArrDims, NumFields, - # BlockPattern <: NamedTuple, IV <: AbstractArray{Int, 1}, RV <: AbstractArray{Float64, 1}, Var <: AbstractFunction, @@ -16,7 +15,6 @@ struct SparseMatrixAssembler{ QuadratureStorage <: NamedTuple } <: AbstractAssembler{DofManager{Condensed, Int, IV, Var}} dof::DofManager{Condensed, Int, IV, Var} - # matrix_pattern::SparseMatrixPattern{IV, BlockPattern, RV} matrix_pattern::SparseMatrixPattern{IV, RV} vector_pattern::SparseVectorPattern{IV} constraint_storage::RV diff --git a/src/assemblers/SparseMatrixAssemblerNew.jl b/src/assemblers/SparseMatrixAssemblerNew.jl new file mode 100644 index 0000000..1b7f660 --- /dev/null +++ b/src/assemblers/SparseMatrixAssemblerNew.jl @@ -0,0 +1,11 @@ +struct SparseMatrixAssembler{ + Condensed, + IV <: AbstractArray{Int, 1}, + RV <: AbstractArray{Float64, 1}, + Var <: AbstractFunction +} <: AbstractAssembler{DofManager{Condensed, Int, IV, Var}} + constraint_storage::RV + dof::DofManager{Condensed, Int, IV, Var} + matrix_pattern::SparseMatrixPattern{IV, BlockPattern, RV} + vector_pattern::SparseVectorPattern{IV} +end \ No newline at end of file diff --git a/src/integrals/Integrals.jl b/src/integrals/Integrals.jl new file mode 100644 index 0000000..2338eb8 --- /dev/null +++ b/src/integrals/Integrals.jl @@ -0,0 +1,59 @@ +abstract type AbstractIntegral{ + A <: AbstractAssembler, + Integrand <: Function +} end + +function integrate end + +struct ScalarIntegral{A, I, C <: NamedTuple} <: AbstractIntegral{A, I} + assembler::A + cache::C + integrand::I +end + +function ScalarIntegral(asm, integrand) + fspace = function_space(asm.dof) + cache = Matrix{Float64}[] + for (key, val) in pairs(fspace.ref_fes) + NQ = ReferenceFiniteElements.num_quadrature_points(val) + NE = size(getfield(fspace.elem_conns, key), 2) + field = L2ElementField(zeros(Float64, NQ, NE)) + push!(cache, field) + end + cache = NamedTuple{keys(fspace.ref_fes)}(tuple(scalar_quadarature_storage...)) + return ScalarIntegral(asm, cache, integrand) +end + +# function gradient(integral::ScalarIntegral) +# # func(physics, interps, x, t, dt, u, u_n, state_old, props) = ForwardDiff.gradient( +# # z -> integral.integrand(physics, interps, x, t, dt, z, u_n, state_old, props)[1], +# # ) +# function integrand_grad(physics, interps, x, t, dt, u, u_n, state_old, props) +# return ForwardDiff.gradient() +# # return VectorIntegral +# end + +function integrate(integral::ScalarIntegral, U, p) + cache, dof = integral.cache, integral.assembler.dof + func = integral.integrand + assemble_quadrature_quantity!(cache, dof, func, U, p) + return mapreduce(sum, sum, values(cache)) +end + +struct VectorIntegral{A, I, C <: AbstractField} <: AbstractIntegral{A, I} + assembler::A + cache::C + integrand::I +end + +function VectorIntegral(asm, integrand) + cache = create_field(asm) + return VectorIntegral(asm, cache, integrand) +end + +function integrate(integral::VectorIntegral, U, p) + cache, dof = integral.cache, integral.assembler.dof + func = integral.integrand + assemble_vector!(cache, dof, func, U, p) + return cache +end diff --git a/test/TestAssemblers.jl b/test/TestAssemblers.jl index f35abd6..6f66342 100644 --- a/test/TestAssemblers.jl +++ b/test/TestAssemblers.jl @@ -1,16 +1,11 @@ -f(X, _) = 2. * π^2 * sin(π * X[1]) * sin(π * X[2]) -bc_func(_, _) = 0. -# TODO this creates a warning during testing due to -# reinclude -include("poisson/TestPoissonCommon.jl") - - -@testset ExtendedTestSet "Sparse matrix assembler" begin +function test_sparse_matrix_assembler() # create very simple poisson problem mesh_file = "./poisson/poisson.g" mesh = UnstructuredMesh(mesh_file) V = FunctionSpace(mesh, H1Field, Lagrange) - physics = Poisson() + f(X, _) = 2. * π^2 * sin(π * X[1]) * sin(π * X[2]) + bc_func(_, _) = 0. + physics = Poisson(f) props = SVector{0, Float64}() u = ScalarFunction(V, :u) @show asm = SparseMatrixAssembler(u) @@ -54,3 +49,7 @@ include("poisson/TestPoissonCommon.jl") # mainly just to test the show method for parameters @show p end + +@testset "Sparse matrix assembler" begin + test_sparse_matrix_assembler() +end diff --git a/test/TestBCs.jl b/test/TestBCs.jl index 14e985e..fe7e998 100644 --- a/test/TestBCs.jl +++ b/test/TestBCs.jl @@ -43,7 +43,7 @@ function test_neumann_bc_container_init() @show bc end -@testset ExtendedTestSet "BoundaryConditions" begin +@testset "BoundaryConditions" begin test_dirichlet_bc_input() test_dirichlet_bc_container_init() test_neumann_bc_input() diff --git a/test/TestConnectivities.jl b/test/TestConnectivities.jl index 38cdb12..83f91cd 100644 --- a/test/TestConnectivities.jl +++ b/test/TestConnectivities.jl @@ -1,4 +1,4 @@ -@testset ExtendedTestSet "Connectivities" begin +function test_connectivities() conn_in = [ 1 5 9; 2 6 10; @@ -42,3 +42,7 @@ # conn_temp = connectivity(conn, 1) # @test SVector{4, Int64}(conn_temp[:, 1]) ≈ conn_in[:, 1] end + +@testset "Connectivities" begin + test_connectivities() +end diff --git a/test/TestDofManagers.jl b/test/TestDofManagers.jl index 7026014..e07f9c1 100644 --- a/test/TestDofManagers.jl +++ b/test/TestDofManagers.jl @@ -61,7 +61,7 @@ end # @test FiniteElementContainers.num_bcs(dof) == 5 # end -@testset ExtendedTestSet "DofManager" begin +@testset "DofManager" begin # mesh = FileMesh(FiniteElementContainers.ExodusMesh, "./poisson/poisson.g") mesh = UnstructuredMesh("./poisson/poisson.g") fspace = FunctionSpace(mesh, H1Field, Lagrange) diff --git a/test/TestFields.jl b/test/TestFields.jl index 6dcf3cc..7006ced 100644 --- a/test/TestFields.jl +++ b/test/TestFields.jl @@ -1,4 +1,4 @@ -@testset ExtendedTestSet "L2 Element Field" begin +function test_l2_element_field() data = rand(2, 20) field = L2ElementField(data) @@ -31,7 +31,7 @@ end end -@testset ExtendedTestSet "H1 Field" begin +function test_h1_field() data = rand(2, 20) field = H1Field(data) @@ -63,7 +63,7 @@ end end end -@testset ExtendedTestSet "Quadrature Field" begin +function test_l2_quadrature_field() data = rand(Float64, 2, 3, 100) field = L2QuadratureField(data) @@ -94,3 +94,9 @@ end @test size(field) == (0, 3, 0) @test axes(field) == (Base.OneTo(0), Base.OneTo(3), Base.OneTo(0)) end + +@testset "Fields" begin + test_h1_field() + test_l2_element_field() + test_l2_quadrature_field() +end diff --git a/test/TestFormulations.jl b/test/TestFormulations.jl index 1a36543..60d7332 100644 --- a/test/TestFormulations.jl +++ b/test/TestFormulations.jl @@ -369,7 +369,7 @@ function test_three_dimensional(∇N_X, ∇u_q, A_q) end # TODO test formulations on various element types -@testset ExtendedTestSet "Formulations" begin +function test_formulations() X = [ 0.0 0.0; 1.0 0.0; @@ -397,3 +397,7 @@ end ∇u_q = SMatrix{3, 3, Float64, 9}((1., 2., 3., 4., 5., 6., 7., 8., 9.)) test_three_dimensional(∇N_X, ∇u_q, A_q) end + +@testset "Formulations" begin + test_formulations() +end diff --git a/test/TestFunctionSpaces.jl b/test/TestFunctionSpaces.jl index f049ca8..ad0883c 100644 --- a/test/TestFunctionSpaces.jl +++ b/test/TestFunctionSpaces.jl @@ -60,45 +60,60 @@ function test_linear_reproducing(coords, elem_id_map, conns, dof, ref_fe, target end end -@testset ExtendedTestSet "FunctionSpaces" begin - coords, conns = FiniteElementContainers.create_structured_mesh_data(7, 7, [0., 1.], [0., 1.]) - target_disp_grad = [ - 0.1 0.4; - -0.2 -0.1 - ] - coords = H1Field(coords) +# @testset "FunctionSpaces" begin +# coords, conns = FiniteElementContainers.create_structured_mesh_data(7, 7, [0., 1.], [0., 1.]) +# target_disp_grad = [ +# 0.1 0.4; +# -0.2 -0.1 +# ] +# coords = H1Field(coords) - # coords = NodalField{size(coords)}(coords) - # elem_id_map = Dict{Int, Int}(zip(1:size(conns, 2), 1:size(conns, 2))) - # conns = Connectivity{size(conns)}(conns) - # dof = DofManager{Vector{Float64}}(size(coords, 1), size(coords, 2)) - # ref_fe = ReferenceFiniteElements.Tri3 - # expected_vol = 1.0 - # expected_element_vol = 0.5 / (6 * 6) - # # test_element_level_field_methods( - # # coords, elem_id_map, conns, dof, ref_fe - # # ) - # test_non_allocated_function_space_volume( - # coords, elem_id_map, conns, dof, ref_fe, - # expected_element_vol, expected_vol - # ) - # # test_linear_reproducing( - # # coords, elem_id_map, conns, dof, ref_fe, - # # target_disp_grad - # # ) -end +# # coords = NodalField{size(coords)}(coords) +# # elem_id_map = Dict{Int, Int}(zip(1:size(conns, 2), 1:size(conns, 2))) +# # conns = Connectivity{size(conns)}(conns) +# # dof = DofManager{Vector{Float64}}(size(coords, 1), size(coords, 2)) +# # ref_fe = ReferenceFiniteElements.Tri3 +# # expected_vol = 1.0 +# # expected_element_vol = 0.5 / (6 * 6) +# # # test_element_level_field_methods( +# # # coords, elem_id_map, conns, dof, ref_fe +# # # ) +# # test_non_allocated_function_space_volume( +# # coords, elem_id_map, conns, dof, ref_fe, +# # expected_element_vol, expected_vol +# # ) +# # # test_linear_reproducing( +# # # coords, elem_id_map, conns, dof, ref_fe, +# # # target_disp_grad +# # # ) +# end -@testset ExtendedTestSet "FunctionSpaces - H1Field" begin - mesh = UnstructuredMesh("mechanics/mechanics.g") +function test_fspace_h1_field(mesh) @show fspace = FunctionSpace(mesh, H1Field, Lagrange) end -@testset ExtendedTestSet "FunctionSpaces - L2ElementField" begin - mesh = UnstructuredMesh("mechanics/mechanics.g") +function test_fspace_l2_element_field(mesh) @show fspace = FunctionSpace(mesh, L2ElementField, Lagrange) end -@testset ExtendedTestSet "FunctionSpaces - L2QuadratureField" begin - mesh = UnstructuredMesh("mechanics/mechanics.g") +function test_fspace_l2_quadrature_field(mesh) @show fspace = FunctionSpace(mesh, L2QuadratureField, Lagrange) end + +function test_function_spaces() + # coords, conns = FiniteElementContainers.create_structured_mesh_data(7, 7, [0., 1.], [0., 1.]) + # target_disp_grad = [ + # 0.1 0.4; + # -0.2 -0.1 + # ] + # coords = H1Field(coords) + + mesh = UnstructuredMesh("mechanics/mechanics.g") + test_fspace_h1_field(mesh) + test_fspace_l2_element_field(mesh) + test_fspace_l2_quadrature_field(mesh) +end + +@testset "Function spaces" begin + test_function_spaces() +end diff --git a/test/TestFunctions.jl b/test/TestFunctions.jl index afc735e..7d29cf6 100644 --- a/test/TestFunctions.jl +++ b/test/TestFunctions.jl @@ -1,4 +1,4 @@ -@testset ExtendedTestSet "Functions" begin +function test_functions() mesh = UnstructuredMesh("poisson/poisson.g") fspace = FunctionSpace(mesh, H1Field, Lagrange) @@ -32,3 +32,7 @@ @test length(u) == 3 @test names(u) == (:u_xx, :u_yy, :u_xy) end + +@testset "Functions" begin + test_functions() +end diff --git a/test/TestICs.jl b/test/TestICs.jl index 0eaafb9..961522d 100644 --- a/test/TestICs.jl +++ b/test/TestICs.jl @@ -29,7 +29,7 @@ function test_ic_update_field_ics(ics, U) @test all(U[2, :] .== 0.) end -@testset ExtendedTestSet "InitialConditions" begin +@testset "InitialConditions" begin test_ic_input() ics, X, U = ic_container_init() test_ic_update_values(ics, X) diff --git a/test/TestIntegrals.jl b/test/TestIntegrals.jl new file mode 100644 index 0000000..e69de29 diff --git a/test/TestMesh.jl b/test/TestMesh.jl index 4f71ea5..110f23a 100644 --- a/test/TestMesh.jl +++ b/test/TestMesh.jl @@ -11,14 +11,15 @@ function test_structured_mesh() ] end -@testset ExtendedTestSet "Mesh" begin - test_structured_mesh() -end +# @testset ExtendedTestSet "Mesh" begin +# test_structured_mesh() +# end struct DummyMesh <: FiniteElementContainers.AbstractMesh end # @test ExtendedTestSet "Mesh definition" begin +function test_bad_mesh_methods() mesh = DummyMesh() @test_throws AssertionError coordinates(mesh) @test_throws AssertionError element_block_id_map(mesh, 1) @@ -36,11 +37,17 @@ end @test_throws AssertionError sidesets(mesh) @test_throws AssertionError sideset_ids(mesh) @test_throws AssertionError sideset_names(mesh) -# end +end function test_bad_mesh_file_type() file_name = "some_file.badext" @test_throws ErrorException UnstructuredMesh(file_name) end -test_bad_mesh_file_type() +# test_bad_mesh_file_type() + +@testset "Mesh" begin + test_bad_mesh_file_type() + test_bad_mesh_methods() + test_structured_mesh() +end diff --git a/test/TestPhysics.jl b/test/TestPhysics.jl index e5d7233..377004f 100644 --- a/test/TestPhysics.jl +++ b/test/TestPhysics.jl @@ -1,9 +1,13 @@ -@testset ExtendedTestSet "Physics" begin - struct MyPhysics <: AbstractPhysics{1, 2, 3} - end - +struct MyPhysics <: AbstractPhysics{1, 2, 3} +end + +function test_physics() physics = MyPhysics() @test num_fields(physics) == 1 @test num_properties(physics) == 2 @test num_states(physics) == 3 end + +@testset "Physics" begin + test_physics() +end diff --git a/test/poisson/TestPoisson.jl b/test/poisson/TestPoisson.jl index 2771cb5..483df83 100644 --- a/test/poisson/TestPoisson.jl +++ b/test/poisson/TestPoisson.jl @@ -16,7 +16,7 @@ f(X, _) = 2. * π^2 * sin(π * X[1]) * sin(π * X[2]) bc_func(_, _) = 0. bc_func_neumann(_, _) = SVector{1, Float64}(1.) -include("TestPoissonCommon.jl") +# include("TestPoissonCommon.jl") # read mesh and relevant quantities @@ -26,7 +26,7 @@ function test_poisson_dirichlet( ) mesh = UnstructuredMesh(mesh_file) V = FunctionSpace(mesh, H1Field, Lagrange) - physics = Poisson() + physics = Poisson(f) props = create_properties(physics) u = ScalarFunction(V, :u) asm = SparseMatrixAssembler(u; use_condensed=use_condensed) @@ -76,7 +76,7 @@ function test_poisson_neumann( ) mesh = UnstructuredMesh(mesh_file) V = FunctionSpace(mesh, H1Field, Lagrange) - physics = Poisson() + physics = Poisson(f) props = create_properties(physics) u = ScalarFunction(V, :u) asm = SparseMatrixAssembler(u; use_condensed=use_condensed) @@ -135,7 +135,7 @@ function test_poisson_dirichlet_multi_block_quad4_quad4( ) mesh = UnstructuredMesh(Base.source_dir() * "/poisson/multi_block_mesh_quad4_quad4.g") V = FunctionSpace(mesh, H1Field, Lagrange) - physics = Poisson() + physics = Poisson(f) props = create_properties(physics) u = ScalarFunction(V, :u) asm = SparseMatrixAssembler(u; use_condensed=use_condensed) @@ -182,7 +182,7 @@ function test_poisson_dirichlet_multi_block_quad4_tri3( ) mesh = UnstructuredMesh(Base.source_dir() * "/poisson/multi_block_mesh_quad4_tri3.g") V = FunctionSpace(mesh, H1Field, Lagrange) - physics = Poisson() + physics = Poisson(f) props = create_properties(physics) u = ScalarFunction(V, :u) asm = SparseMatrixAssembler(u; use_condensed=use_condensed) diff --git a/test/poisson/TestPoissonCommon.jl b/test/poisson/TestPoissonCommon.jl index 5a5d502..7b8ec06 100644 --- a/test/poisson/TestPoissonCommon.jl +++ b/test/poisson/TestPoissonCommon.jl @@ -1,7 +1,8 @@ # since this type of physics has no state # just return the old state which will be empty -struct Poisson <: AbstractPhysics{1, 0, 0} +struct Poisson{F <: Function} <: AbstractPhysics{1, 0, 0} + func::F end @inline function FiniteElementContainers.energy( @@ -10,7 +11,7 @@ end interps = map_interpolants(interps, x_el) (; X_q, N, ∇N_X, JxW) = interps u_q, ∇u_q = interpolate_field_values_and_gradients(physics, interps, u_el) - e_q = 0.5 * dot(∇u_q, ∇u_q) - dot(u_q, f(X_q, 0.0)) + e_q = 0.5 * dot(∇u_q, ∇u_q) - dot(u_q, physics.func(X_q, 0.0)) return JxW * e_q, state_old_q end @@ -30,7 +31,7 @@ end interps = map_interpolants(interps, x_el) (; X_q, N, ∇N_X, JxW) = interps ∇u_q = interpolate_field_gradients(physics, interps, u_el) - R_q = ∇u_q * ∇N_X' - N' * f(X_q, 0.0) + R_q = ∇u_q * ∇N_X' - N' * physics.func(X_q, 0.0) return JxW * R_q[:], state_old_q end diff --git a/test/runtests.jl b/test/runtests.jl index 6a8c027..af0976b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,7 +11,12 @@ using ReferenceFiniteElements using StaticArrays using Tensors using Test -using TestSetExtensions +# using TestSetExtensions + +# put these first so we can use these +# physics in other tests +include("mechanics/TestMechanicsCommon.jl") +include("poisson/TestPoissonCommon.jl") include("TestAssemblers.jl") include("TestBCs.jl") @@ -22,17 +27,14 @@ include("TestFormulations.jl") include("TestFunctions.jl") include("TestFunctionSpaces.jl") include("TestICs.jl") +include("TestIntegrals.jl") include("TestMesh.jl") include("TestPhysics.jl") -# @testset ExtendedTestSet "Eigen problem" begin -# include("eigen/TestEigen.jl") -# end - # "Regression" tests below - -@testset ExtendedTestSet "Poisson problem" begin - include("poisson/TestPoisson.jl") +function test_poisson() +# @testset "Poisson problem" begin + # include("poisson/TestPoisson.jl") cg_solver = x -> IterativeLinearSolver(x, :CgSolver) condensed = [false, true] @@ -66,9 +68,9 @@ include("TestPhysics.jl") end end -@testset ExtendedTestSet "Mechanics Problem" begin - include("mechanics/TestMechanicsCommon.jl") - include("mechanics/TestMechanics.jl") +# @testset "Mechanics Problem" begin +function test_mechanics() + # include("mechanics/TestMechanics.jl") cg_solver = x -> IterativeLinearSolver(x, :CgSolver) @@ -88,12 +90,13 @@ end end end -@testset ExtendedTestSet "Aqua" begin - Aqua.test_all(FiniteElementContainers; ambiguities=false) +@testset "Regression tests" begin + include("poisson/TestPoisson.jl") + @testset "Poisson" test_poisson() + include("mechanics/TestMechanics.jl") + @testset "Mechanics" test_mechanics() end -# getting an error from FileMesh.num_nodes for some reason. No method -# @testset ExtendedTestSet "JET" begin -# JET.test_package(FiniteElementContainers; target_defined_modules=true) -# # JET.test_package(FiniteElementContainers) -# end +@testset "Aqua" begin + Aqua.test_all(FiniteElementContainers; ambiguities=false) +end