Skip to content

Commit

Permalink
Added Embedded tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JordiManyer committed Nov 11, 2024
1 parent 572a6a7 commit d321890
Showing 1 changed file with 121 additions and 0 deletions.
121 changes: 121 additions & 0 deletions test/seq/EmbeddedTests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
module EmbeddedTests
using Test

using GridapTopOpt
using Gridap, Gridap.Geometry, Gridap.Adaptivity
using GridapEmbedded, GridapEmbedded.LevelSetCutters

using Gridap.Arrays: Operation
using GridapTopOpt: get_conormal_vector

function generate_model(D,n)
domain = (D==2) ? (0,1,0,1) : (0,1,0,1,0,1)
cell_partition = (D==2) ? (n,n) : (n,n,n)
base_model = UnstructuredDiscreteModel((CartesianDiscreteModel(domain,cell_partition)))
ref_model = refine(base_model, refinement_method = "barycentric")
model = ref_model.model
return model
end

function level_set(shape::Symbol)
if shape == :square
x -> max(abs(x[1]-0.5),abs(x[2]-0.5))-0.25 # Square
elseif shape == :corner_2d
x -> ((x[1]-0.5)^N+(x[2]-0.5)^N)^(1/N)-0.25 # Curved corner
elseif shape == :diamond
x -> abs(x[1]-0.5)+abs(x[2]-0.5)-0.25-0/n/10 # Diamond
elseif shape == :circle
x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2)-0.5223 # Circle
elseif shape == :square_prism
x -> max(abs(x[1]-0.5),abs(x[2]-0.5),abs(x[3]-0.5))-0.25 # Square prism
elseif shape == :corner_3d
x -> ((x[1]-0.5)^N+(x[2]-0.5)^N+(x[3]-0.5)^N)^(1/N)-0.25 # Curved corner
elseif shape == :diamond_prism
x -> abs(x[1]-0.5)+abs(x[2]-0.5)+abs(x[3]-0.5)-0.25-0/n/10 # Diamond prism
elseif shape == :sphere
x -> sqrt((x[1]-0.5)^2+(x[2]-0.5)^2+(x[3]-0.5)^2)-0.53 # Sphere
elseif shape == :regular_2d
x -> cos(2π*x[1])*cos(2π*x[2])-0.11 # "Regular" LSF
elseif shape == :regular_3d
x -> cos(2π*x[1])*cos(2π*x[2])*cos(2π*x[3])-0.11 # "Regular" LSF
end
end

function main(model,φ::Function,f::Function)

order = 1
reffe = ReferenceFE(lagrangian,Float64,order)
V_φ = TestFESpace(model,reffe)

φh = interpolate(φ,V_φ)
fh = interpolate(f,V_φ)

# Correction if level set is on top of a node
x_φ = get_free_dof_values(φh)
idx = findall(isapprox(0.0;atol=10^-10),x_φ)
!isempty(idx) && @info "Correcting level values!"
x_φ[idx] .+= 10*eps(eltype(x_φ))

geo = DiscreteGeometry(φh,model)
cutgeo = cut(model,geo)

# A) Volume integral

Ω = Triangulation(cutgeo,PHYSICAL_IN)
Ω_AD = DifferentiableTriangulation(Ω)
= Measure(Ω_AD,2*order)

Γ = EmbeddedBoundary(cutgeo)
= Measure(Γ,2*order)

J_bulk(φ) = (fh)dΩ
dJ_bulk_AD = gradient(J_bulk,φh)
dJ_bulk_AD_vec = assemble_vector(dJ_bulk_AD,V_φ)

dJ_bulk_exact(q) = (-fh*q/(norm ((φh))))dΓ
dJ_bulk_exact_vec = assemble_vector(dJ_bulk_exact,V_φ)

@test norm(dJ_bulk_AD_vec - dJ_bulk_exact_vec) < 1e-10

# B) Facet integral

Γ = EmbeddedBoundary(cutgeo)
Γ_AD = DifferentiableTriangulation(Γ)
Λ = Skeleton(Γ)
Σ = Boundary(Γ)

= Measure(Γ,2*order)
= Measure(Λ,2*order)
= Measure(Σ,2*order)

n_Γ = get_normal_vector(Γ)

n_S_Λ = get_normal_vector(Λ)
m_k_Λ = get_conormal_vector(Λ)
∇ˢφ_Λ = Operation(abs)(n_S_Λ (φh).plus)

n_S_Σ = get_normal_vector(Σ)
m_k_Σ = get_conormal_vector(Σ)
∇ˢφ_Σ = Operation(abs)(n_S_Σ (φh))

dΓ_AD = Measure(Γ_AD,2*order)
J_int(φ) = (fh)dΓ_AD
dJ_int_AD = gradient(J_int,φh)
dJ_int_AD_vec = assemble_vector(dJ_int_AD,V_φ)

dJ_int_exact(w) = ((-n_Γ(fh))*w/(norm ((φh))))dΓ +
(-n_S_Λ (jump(fh*m_k_Λ) * mean(w) / ∇ˢφ_Λ))dΛ +
(-n_S_Σ (fh*m_k_Σ * w / ∇ˢφ_Σ))dΣ
dJ_int_exact_vec = assemble_vector(dJ_int_exact,V_φ)

@test norm(dJ_int_AD_vec - dJ_int_exact_vec) < 1e-10
end

D = 2
n = 10
model = generate_model(D,n)
φ = level_set(:circle)
f = x -> 1.0
main(model,φ,f)

end

0 comments on commit d321890

Please sign in to comment.