gridap / gridap/Gridap.jl

Issues with the gradient of the elastic energy

Open
#1,099 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
879
Forks
119
Avg merge
6d 3h
Merged PRs (30d)
4

Description

I’m working on a simple linear elasticity problem using Gridap.jl. I'm trying to compute the elastic energy in two ways:
Using the global expression: 0.5u'Ku
Using the local expression: sum(∫((0.5(ε(uh_Disp) ⊙ (σfun∘(ε(uh_Disp))))))*fem_params.dΩ)
Both expressions yield the same energy values, which is expected.
However, when I compute the derivative of these energy expressions with respect to the nodal displacements:
For the global case: K * u
For the local case: EngCont_DispFn(v) = ∫(1.0 * (ε(v) ⊙ (σfun ∘ ε(uh_Disp)))) * dΩ; grad_force_dis = assemble_vector(EngCont_DispFn, U0_Disp)
I notice a mismatch between the two resulting vectors.
Could you please help me identify what might be going wrong in the way I'm assembling the vector from the local energy derivative? I’ve attached the relevant part of the code for reference. The given problem is under force loading

```
function ElasFourthOrderConstTensor(E,ν)
C1111 = (E*(1-ν*ν))/((1+ν)*(1-ν-2*ν*ν))
C1122 = (ν*E)/(1-ν-2*ν*ν)
C1112 = 0.0
C2222 = (E*(1-ν))/(1-ν-2*ν*ν)
C2212 = 0.0
C1212 =E/(2*(1+ν))
C_ten = SymFourthOrderTensorValue(C1111 ,C1112 ,C1122 ,C1112 ,C1212 ,C2212 ,C1122 ,C2212 ,C2222)
return C_ten
end

const C_mat = ElasFourthOrderConstTensor(E_mat ,ν_mat);

function σfun(ε)
σ = C_mat⊙ε
return σ
end

order = 1
f = VectorValue(0.0,-1.0)

reffe_Disp = ReferenceFE(lagrangian ,VectorValue{2,Float64},order)
V0_Disp = TestFESpace(model,reffe_Disp;conformity =:H1,
dirichlet_tags = ["LeftSupport"],
dirichlet_masks =[(true,true)])
uApp1(x) = VectorValue(0.0,0.0)
U0_Disp = TrialFESpace(V0_Disp ,[uApp1])

degree = 2*order
Ω= Triangulation(model)
dΩ= Measure(Ω,degree)

labels = get_face_labeling(model)
LoadTagId = get_tag_from_name(labels ,"LoadLine")
Γ_Load = BoundaryTriangulation(model ;tags = LoadTagId)
dΓ_Load = Measure(Γ_Load ,degree)
n_Γ_Load = get_normal_vector(Γ_Load)

fem_params = (;V0_Disp, U0_Disp, Ω, dΩ)

function stepForceLoading(fem_params)
a_Disp(u,v) = ∫(ε(v) ⊙ (σfun∘(ε(u))))fem_params.dΩ
b_Disp(v) = ∫(v ⋅ f)dΓ_Load
op_Disp = AffineFEOperator(a_Disp ,b_Disp ,fem_params.U0_Disp ,fem_params.V0_Disp)
uh_out = solve(op_Disp)
return get_free_dof_values(uh_out)
end

function KMatForce(fem_params)

return assemble_matrix(fem_params.U0_Disp, fem_params.V0_Disp) do u, v
∫((∇(u))' ⊙ (C_mat ⊙ ∇(v)))fem_params.dΩ
end
end;

u_vecDisp = stepForceLoading(fem_params)
uh_Disp = FEFunction(fem_params.U0_Disp, u_vecDisp)

KMatD = KMatForce(fem_params)
EngDisc_Disp = 0.5*u_vecDisp'*KMatD*u_vecDisp

EngCont_Disp = sum(∫((0.5*(ε(uh_Disp) ⊙ (σfun∘(ε(uh_Disp))))))*fem_params.dΩ)
EngDisc_Disp, EngCont_Disp

EngCont_DispFn(v) = ∫(((ε(v) ⊙ (σfun∘(ε(uh_Disp))))))*dΩ
grad_force_dis = assemble_vector(EngCont_DispFn,U0_Disp)
[KMatD*u_vecDisp grad_force_dis]
```

Contributor guide

Open the contributing guide

Research direction

Start with the KMatForce, stepForceLoading, and EngCont_DispFn entry points, comparing their use of gradients, strains, measures, and the U0_Disp/V0_Disp spaces. Reproduce the mismatch and trace how assemble_vector handles the local derivative; done when the assembled derivative agrees with KMatD*u_vecDisp for the supplied force-loading example.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.