Skip to content

Commit 3664d03

Browse files
committed
Nonlin solve for jacobian
1 parent a173557 commit 3664d03

File tree

5 files changed

+43
-19
lines changed

5 files changed

+43
-19
lines changed

examples/bench.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ body_aero = BodyAerodynamics([wing])
6464
vsm_solver = Solver(
6565
body_aero;
6666
aerodynamic_model_type=VSM,
67-
is_with_artificial_damping=false
67+
is_with_artificial_damping=false,
68+
solver_type=NONLIN,
6869
)
6970

7071
# Setting velocity conditions
@@ -82,8 +83,8 @@ set_va!(body_aero, vel_app)
8283

8384
# Solving and plotting distributions
8485
results = solve(vsm_solver, body_aero)
85-
results_base = solve_base!(vsm_solver, body_aero)
86+
solve_base!(vsm_solver, body_aero)
8687
println("RAM-air kite:")
87-
@time results_base = solve_base!(vsm_solver, body_aero)
88+
@time solve_base!(vsm_solver, body_aero)
8889

8990
nothing

examples/ram_air_kite.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ end
2525
vsm_solver = Solver(body_aero;
2626
aerodynamic_model_type=VSM,
2727
is_with_artificial_damping=false,
28-
rtol=1e-8,
28+
rtol=1e-5,
2929
solver_type=NONLIN
3030
)
3131

@@ -44,6 +44,15 @@ set_va!(body_aero, vel_app)
4444

4545
if LINEARIZE
4646
println("Linearize")
47+
jac, res = VortexStepMethod.linearize(
48+
vsm_solver,
49+
body_aero,
50+
wing,
51+
[zeros(4); vel_app; zeros(3)];
52+
alpha_idxs=1:4,
53+
va_idxs=5:7,
54+
omega_idxs=8:10,
55+
moment_frac=0.1)
4756
@time jac, res = VortexStepMethod.linearize(
4857
vsm_solver,
4958
body_aero,
@@ -72,7 +81,7 @@ PLOT && plot_geometry(
7281
)
7382

7483
# Solving and plotting distributions
75-
results = solve(vsm_solver, body_aero; log=true)
84+
results = VortexStepMethod.solve(vsm_solver, body_aero; log=true)
7685
@time results = solve(vsm_solver, body_aero; log=true)
7786

7887
body_y_coordinates = [panel.aero_center[2] for panel in body_aero.panels]

src/solver.jl

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ sol::VSMSolution = VSMSolution(): The result of calling [solve!](@ref)
102102

103103
# Nonlin solver fields
104104
prob::Union{NonlinearProblem, Nothing} = nothing
105+
cache::Union{NonlinearSolve.AbstractNonlinearSolveCache, Nothing} = nothing
105106
atol::Float64 = 1e-5
106107

107108
# Damping settings
@@ -153,7 +154,7 @@ a dictionary.
153154
The solution of type [VSMSolution](@ref)
154155
"""
155156
function solve!(solver::Solver, body_aero::BodyAerodynamics, gamma_distribution=solver.sol.gamma_distribution;
156-
log=false, reference_point=zeros(MVec3), moment_frac=0.1)
157+
log=false, reference_point=zeros(MVec3), moment_frac=0.1)
157158

158159
# calculate intermediate result
159160
solve_base!(solver, body_aero, gamma_distribution; log, reference_point)
@@ -446,18 +447,20 @@ function gamma_loop!(
446447
relative_velocity_array = cache[5][va_array]
447448
relative_velocity_crossz = cache[6][va_array]
448449
v_acrossz_array = cache[7][va_array]
449-
cl_array = cache[8][gamma]
450-
damp = cache[9][cl_array]
451-
v_normal_array = cache[10][cl_array]
452-
v_tangential_array = cache[11][cl_array]
450+
cl_array = cache[8][solver.lr.gamma_new]
451+
damp = cache[9][solver.lr.gamma_new]
452+
v_normal_array = cache[10][solver.lr.gamma_new]
453+
v_tangential_array = cache[11][solver.lr.gamma_new]
453454

454455
AIC_x, AIC_y, AIC_z = body_aero.AIC[1, :, :], body_aero.AIC[2, :, :], body_aero.AIC[3, :, :]
455456

456457
velocity_view_x = @view induced_velocity_all[:, 1]
457458
velocity_view_y = @view induced_velocity_all[:, 2]
458459
velocity_view_z = @view induced_velocity_all[:, 3]
459460

460-
function calc_gamma_new!(gamma_new, gamma)
461+
function calc_gamma_new!(gamma_new, gamma, p)
462+
# (AIC_x, AIC_y, AIC_z, va_array, induced_velocity_all,
463+
# x_airf_array, y_airf_array, z_airf_array, panels, chord_array) = p
461464
# Calculate induced velocities
462465
mul!(velocity_view_x, AIC_x, gamma)
463466
mul!(velocity_view_y, AIC_y, gamma)
@@ -466,9 +469,9 @@ function gamma_loop!(
466469
relative_velocity_array .= va_array .+ induced_velocity_all
467470
for i in 1:n_panels
468471
relative_velocity_crossz[i, :] .= MVec3(view(relative_velocity_array, i, :)) ×
469-
MVec3(view(y_airf_array, i, :))
472+
MVec3(view(y_airf_array, i, :))
470473
v_acrossz_array[i, :] .= MVec3(view(va_array, i, :)) ×
471-
MVec3(view(y_airf_array, i, :))
474+
MVec3(view(y_airf_array, i, :))
472475
end
473476

474477
for i in 1:n_panels
@@ -492,14 +495,15 @@ function gamma_loop!(
492495
if solver.solver_type == NONLIN
493496
if isnothing(solver.prob)
494497
function f_nonlin!(d_gamma, gamma, p)
495-
calc_gamma_new!(solver.lr.gamma_new, gamma)
498+
calc_gamma_new!(solver.lr.gamma_new, gamma, p)
496499
d_gamma .= solver.lr.gamma_new .- gamma
497500
nothing
498501
end
499502
solver.prob = NonlinearProblem(f_nonlin!, solver.lr.gamma_new, nothing)
503+
solver.cache = init(solver.prob, NewtonRaphson(autodiff=AutoFiniteDiff()); abstol=solver.atol, reltol=solver.rtol)
500504
end
501505

502-
sol = NonlinearSolve.solve(solver.prob, NewtonRaphson(autodiff=AutoFiniteDiff()); abstol=solver.atol, reltol=solver.rtol)
506+
sol = NonlinearSolve.solve!(solver.cache)
503507
gamma .= sol.u
504508
solver.lr.gamma_new .= sol.u
505509
solver.lr.converged = SciMLBase.successful_retcode(sol)
@@ -509,7 +513,7 @@ function gamma_loop!(
509513
if solver.solver_type == LOOP
510514
function f_loop!(gamma_new, gamma, damp)
511515
gamma .= gamma_new
512-
calc_gamma_new!(gamma_new, gamma)
516+
calc_gamma_new!(gamma_new, gamma, nothing)
513517
# Update gamma with relaxation and damping
514518
@. gamma_new = (1 - relaxation_factor) * gamma +
515519
relaxation_factor * gamma_new + damp
@@ -640,7 +644,7 @@ function linearize(solver::Solver, body_aero::BodyAerodynamics, wing::RamAirWing
640644

641645
if !isnothing(va_idxs) && isnothing(omega_idxs)
642646
set_va!(body_aero, y[va_idxs])
643-
elseif !isnothing(va_idxs) && isnothing(omega_idxs)
647+
elseif !isnothing(va_idxs) && !isnothing(omega_idxs)
644648
set_va!(body_aero, y[va_idxs], y[omega_idxs])
645649
elseif isnothing(va_idxs) && isnothing(omega_idxs)
646650
set_va!(body_aero, init_va)
@@ -657,7 +661,7 @@ function linearize(solver::Solver, body_aero::BodyAerodynamics, wing::RamAirWing
657661
jac = zeros(length(results), length(y))
658662
backend = AutoFiniteDiff(absstep=1e-3, relstep=1e-3)
659663
prep = prepare_jacobian(calc_results!, results, backend, y)
660-
@time jacobian!(calc_results!, results, jac, prep, backend, y)
664+
jacobian!(calc_results!, results, jac, prep, backend, y)
661665

662666
calc_results!(results, y)
663667
return jac, results

src/wing_geometry.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ Represents a wing section with leading edge, trailing edge, and aerodynamic prop
1717
aero_data::AeroData = nothing
1818
end
1919

20+
function Section(LE_point, TE_point, aero_model)
21+
return Section(LE_point, TE_point, aero_model, nothing)
22+
end
23+
2024
"""
2125
init!(section::Section, LE_point, TE_point, aero_model=nothing, aero_data=nothing)
2226

test/bench.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ using LinearAlgebra
5656
# Initialize solvers for both LLT and VSM methods
5757
P = length(body_aero.panels)
5858
solver = Solver{P}()
59+
nonlin_solver = Solver{P}(; solver_type=NONLIN)
5960

6061
# Pre-allocate arrays
6162
gamma = rand(n_panels)
@@ -196,13 +197,18 @@ using LinearAlgebra
196197
end
197198

198199
@testset "Allocation Tests for solve() and solve!()" begin
199-
# Step 5: Solve using both methods
200200
result = @benchmark solve_base!($solver, $body_aero, nothing) samples=1 evals=1 # 51 allocations
201201
@test result.allocs <= 55
202202
# time Python: 32.0 ms Ryzen 7950x
203203
# time Julia: 0.45 ms Ryzen 7950x
204204
result = @benchmark sol = solve!($solver, $body_aero, nothing) samples=1 evals=1 # 85 allocations
205205
@test result.allocs <= 89
206+
207+
# Step 5: Solve using both methods
208+
result = @benchmark solve_base!($nonlin_solver, $body_aero, nothing) samples=1 evals=1 # 51 allocations
209+
@test result.allocs <= 55
210+
result = @benchmark sol = solve!($nonlin_solver, $body_aero, nothing) samples=1 evals=1 # 85 allocations
211+
@test result.allocs <= 89
206212
end
207213
end
208214

0 commit comments

Comments
 (0)