Skip to content

Commit 2ad119a

Browse files
committed
Add inversion using MadNLP
1 parent fe797f6 commit 2ad119a

File tree

5 files changed

+46
-29
lines changed

5 files changed

+46
-29
lines changed

data/PIG_testopt_small.mat

258 KB
Binary file not shown.

src/core/control.jl

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,52 @@ using Enzyme
22
using ManualNLPModels
33
using MadNLP
44

5-
function Control_Core(md::model, femmodel::FemModel)
5+
function Control_Core(md::model, femmodel::FemModel, solutionstring::Symbol)#{{{
66
#independent variable
77
α = md.inversion.independent
88
#initialize derivative as 0
9-
∂J_∂α = zero(α)
9+
∂J_∂α = make_zero(α)
1010
if md.inversion.onlygrad
1111
# only compute the gradient
12-
ComputeGradient(∂J_∂α, α, femmodel)
12+
ComputeGradient!(∂J_∂α, α, femmodel)
1313
#Put gradient in results
1414
InputUpdateFromVectorx(femmodel, ∂J_∂α, GradientEnum, VertexSIdEnum)
1515
RequestedOutputsx(femmodel, [GradientEnum])
1616
else
1717
# optimization
18-
# use user defined grad, errors!
19-
# optprob = OptimizationFunction(costfunction, Optimization.AutoEnzyme())
20-
# prob = Optimization.OptimizationProblem(optprob, α, femmodel, lb=md.inversion.min_parameters, ub=md.inversion.max_parameters)
21-
# sol = Optimization.solve(prob, Optim.LBFGS())
18+
# define cost function and gradient
19+
# need to build connection between md and x
20+
f(x) = begin
21+
fem=DJUICE.ModelProcessor(md, solutionstring)
22+
DJUICE.CostFunction(x, fem)
23+
end
24+
25+
g!(gx, x) = begin
26+
fem=DJUICE.ModelProcessor(md, solutionstring)
27+
DJUICE.ComputeGradient!(gx, x, fem)
28+
end
29+
nlp = NLPModel(
30+
α,
31+
f,
32+
grad = g!,
33+
lvar = md.inversion.min_parameters,
34+
uvar = md.inversion.max_parameters,
35+
)
36+
37+
results_qn = madnlp(
38+
nlp;
39+
linear_solver=LapackCPUSolver,
40+
hessian_approximation=MadNLP.CompactLBFGS,
41+
tol=md.inversion.tol,
42+
max_iter=md.inversion.maxiter,
43+
)
44+
2245
independent_enum = StringToEnum(md.inversion.independent_string)
23-
InputUpdateFromVectorx(femmodel, sol.u, independent_enum, VertexSIdEnum)
46+
InputUpdateFromVectorx(femmodel, results_qn.solution, independent_enum, VertexSIdEnum)
2447
RequestedOutputsx(femmodel, [independent_enum])
2548
end
2649
end#}}}
27-
28-
function ComputeGradient(∂J_∂α::Vector{Float64}, α::Vector{Float64}, femmodel::FemModel) #{{{
50+
function ComputeGradient!(∂J_∂α::Vector{Float64}, α::Vector{Float64}, femmodel::FemModel) #{{{
2951
# zero ALL depth of the model, make sure we get correct gradient
3052
dfemmodel = make_zero(Base.Core.Typeof(femmodel), IdDict(), femmodel)
3153
# zero the gradient
@@ -54,6 +76,7 @@ function CostFunction(α::Vector{Float64}, femmodel::FemModel) #{{{
5476
# compute cost function
5577
# TODO: loop through all controls with respect to all the components in the cost function
5678
solutionstring = FindParam(Symbol, femmodel.parameters, SolutionTypeEnum)
79+
# return J
5780
CostFunctionx(femmodel, α, controlvar_enum, VertexSIdEnum, cost_enum_list, Val(solutionstring))
5881
end#}}}
5982
function CostFunctionx(femmodel::FemModel, α::Vector{Float64}, controlvar_enum::IssmEnum, SId_enum::IssmEnum, cost_enum_list::Vector{IssmEnum}, ::Val{solutionstring}) where solutionstring #{{{

src/core/solve.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ function solve(md::model, solution::Symbol) #{{{
4444
#Construct FemModel from md
4545
femmodel=ModelProcessor(md, solutionkey)
4646

47-
#Solve (FIXME: to be improved later...)
47+
#Solve
4848
if (md.inversion.iscontrol) # solve inverse problem
49-
Control_Core(md, femmodel)
49+
Control_Core(md, femmodel, solutionkey)
5050
else # otherwise forward problem
5151
if(solutionkey===:StressbalanceSolution)
5252
analysis = StressbalanceAnalysis()

src/usr/classes.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,12 @@ mutable struct Inversion
272272
max_parameters::Vector{Float64}
273273
independent::Vector{Float64}
274274
maxiter::Int64
275+
tol::Float64
275276
independent_string::String
276277
dependent_string::Vector{String}
277278
end
278279
function Inversion() #{{{
279-
return Inversion( false, true, Vector{Float64}(undef,0), Vector{Float64}(undef,0), Vector{Float64}(undef,0), Vector{Float64}(undef,0), Vector{Float64}(undef,0), 0, "Friction", Vector{String}(undef,0))
280+
return Inversion( false, true, Vector{Float64}(undef,0), Vector{Float64}(undef,0), Vector{Float64}(undef,0), Vector{Float64}(undef,0), Vector{Float64}(undef,0), 0, 0., "Friction", Vector{String}(undef,0))
280281
end# }}}
281282
function Base.show(io::IO, this::Inversion)# {{{
282283
IssmStructDisp(io, this)

test/testoptimization.jl renamed to test/test4020.jl

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ md.inversion.min_parameters = ones(md.mesh.numberofvertices)*(1.0)
2626
md.inversion.max_parameters = ones(md.mesh.numberofvertices)*(200)
2727
md.inversion.independent_string = "FrictionCoefficient"
2828
md.inversion.dependent_string = ["SurfaceAbsVelMisfit"]
29+
md.inversion.maxiter = 40
30+
md.inversion.tol = 1e-5
2931

3032
md.verbose.convergence = false
3133

32-
if onlygrad == 1
33-
md = solve(md, :sb)
34-
end
34+
#md = solve(md, :sb);
35+
3536
α = md.inversion.independent
3637
∂J_∂α = zero(α)
3738

@@ -44,20 +45,11 @@ end
4445
# Enzyme gradient g
4546
g!(gx, x) = begin
4647
femmodel=DJUICE.ModelProcessor(md, :StressbalanceSolution)
47-
dfemmodel = Enzyme.Compiler.make_zero(Base.Core.Typeof(femmodel), IdDict(), femmodel)
48-
dx = zero(x)
49-
Enzyme.autodiff(set_runtime_activity(Enzyme.Reverse), DJUICE.CostFunction, Active, Duplicated(x, gx), Duplicated(femmodel,dfemmodel))
50-
@assert typeof(dx) == typeof(gx)
51-
gx .= dx
48+
DJUICE.ComputeGradient!(gx, x, femmodel)
5249
end
5350

54-
#g!(gx, x) = begin
55-
# femmodel=DJUICE.ModelProcessor(md, :StressbalanceSolution)
56-
# DJUICE.ComputeGradient(gx, x, femmodel)
57-
#end
58-
5951
nlp = NLPModel(
60-
α,
52+
md.inversion.independent,
6153
f,
6254
grad = g!,
6355
lvar = md.inversion.min_parameters,
@@ -68,7 +60,8 @@ results_qn = madnlp(
6860
nlp;
6961
linear_solver=LapackCPUSolver,
7062
hessian_approximation=MadNLP.CompactLBFGS,
71-
tol=1e-5,
72-
max_iter=40,
63+
tol=md.inversion.tol,
64+
max_iter=md.inversion.maxiter,
7365
)
7466

67+

0 commit comments

Comments
 (0)