Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flash bypass and improved performance for many components #37

Merged
merged 38 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
97696fc
Compositional equilibriation improvements
moyner Apr 5, 2024
7240a3c
Add volume shift
moyner Apr 5, 2024
49cad41
Update utils.jl
moyner Apr 5, 2024
d0889de
Set default well solver to only apply for first iteration
moyner Apr 6, 2024
8a91265
Update flux.jl
moyner Apr 6, 2024
6b20661
Speed up generic CPR weights
moyner Apr 6, 2024
7e34bc4
Put some bypass parts in place
moyner Apr 8, 2024
e3bed2a
Update flash.jl
moyner Apr 8, 2024
369130a
Pass previous phase state onto flash
moyner Apr 8, 2024
720648b
Put in place some of the stability bypass features
moyner Apr 8, 2024
f20074f
Update flash.jl
moyner Apr 8, 2024
ec898ea
Update flash.jl
moyner Apr 8, 2024
189b294
Update flash.jl
moyner Apr 8, 2024
c4f6f2c
Update to flash changes
moyner Apr 9, 2024
d8d2a8c
Split into functions
moyner Apr 9, 2024
d6fbc05
Update flash.jl
moyner Apr 9, 2024
5eb9108
Fix argument order
moyner Apr 9, 2024
80a77b3
Update to flash
moyner Apr 9, 2024
7a8fea6
Update flash.jl
moyner Apr 10, 2024
9f87def
Clean up flash code
moyner Apr 10, 2024
29b99fd
Improve reuse of flash results
moyner Apr 10, 2024
dc74b24
Wrap flash reuse in exception handler
moyner Apr 10, 2024
f0aa2c7
Add a closure to flash loop
moyner Apr 10, 2024
afb2fd1
Fix flash reuse code by normalization
moyner Apr 10, 2024
6b1be13
Add flash codes as possible output
moyner Apr 10, 2024
121caf9
Improve a warning message
moyner Apr 10, 2024
dee4158
co2props: Fix calling for fixed temperature tables
moyner Apr 10, 2024
e4e0706
Update flash.jl
moyner Apr 10, 2024
77a64f2
Add more safeguards to flash reuse
moyner Apr 10, 2024
5be49de
Update wells.jl
moyner Apr 10, 2024
1eb2421
Fix flash Newton failure criterion
moyner Apr 11, 2024
07592bd
NLDD: Fix wrong solve flag for zero solves
moyner Apr 11, 2024
f697c23
NLDD: Make subdomain solver information configurable
moyner Apr 11, 2024
725e871
Allow interrupts in subdomain solver
moyner Apr 11, 2024
9484747
Bump compat
moyner Apr 12, 2024
ab9388d
Documentation
moyner Apr 12, 2024
b86652c
Add fast flash to tests
moyner Apr 12, 2024
4a67e37
Bump compat
moyner Apr 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Krylov = "0.9.1"
LinearAlgebra = "1"
LoopVectorization = "0.12.115"
MAT = "0.10.3"
MultiComponentFlash = "1.1.10"
MultiComponentFlash = "1.1.13"
OrderedCollections = "1.6.2"
PartitionedArrays = "0.3.2"
Polyester = "0.6.11, 0.7.3"
Expand Down
12 changes: 6 additions & 6 deletions src/CO2Properties/setup.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
function setup_reservoir_model_co2_brine(reservoir::DataDomain,
T = missing;
thermal = false,
composite = thermal,
kwarg...
function setup_reservoir_model_co2_brine(reservoir::DataDomain;
temperature = missing,
thermal = false,
composite = thermal,
kwarg...
)
tables = co2_brine_property_tables(T)
tables = co2_brine_property_tables(temperature)
rho = JutulDarcy.BrineCO2MixingDensities(tables[:density])
mu = JutulDarcy.PTViscosities(tables[:viscosity])
if thermal
Expand Down
10 changes: 9 additions & 1 deletion src/NLDD/simulator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,11 @@ function get_solve_status(rep, ok)
if length(rep) > 1
status = local_solved_in_multiple_steps
else
if length(only(rep)[:steps]) == 0
rep = only(rep)
nstep = length(rep[:steps])
if nstep == 0
status = local_already_converged
elseif nstep == 1 && !haskey(rep[:steps][1], :linear_solver)
status = local_already_converged
else
status = local_solved_in_single_step
Expand Down Expand Up @@ -673,6 +677,10 @@ function solve_subdomain(sim, i, dt, forces, cfg)
ok, report = Jutul.solve_timestep!(sim, dt, f, max_iter, cfg,
finalize = true, prepare = true, update_explicit = false)
catch e
if e isa InterruptException
# Don't leave the user trapped...
rethrow(e)
end
@warn "Subdomain $i threw exception: $e"
end
return (ok, report)
Expand Down
6 changes: 5 additions & 1 deletion src/NLDD/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import JutulDarcy: set_default_cnv_mb!

function simulator_config(sim::NLDDSimulator;
method = :nldd,
subdomain_info_level = -1,
inner_tol_mul = 1.0,
inner_tol_final = 10.0,
inner_max_timestep_cuts = 2,
Expand All @@ -19,6 +20,9 @@ function simulator_config(sim::NLDDSimulator;
inc_tol_dz = Inf,
kwarg...
)
if subdomain_info_level isa Real
subdomain_info_level = i -> i == subdomain_info_level
end
check_before_solve = isinf(inc_tol_dp_abs) && isinf(inc_tol_dp_rel) && isinf(inc_tol_dz)
cfg = simulator_config(sim.simulator)
set_default_cnv_mb!(cfg, sim.simulator.model,
Expand Down Expand Up @@ -68,7 +72,7 @@ function simulator_config(sim::NLDDSimulator;
min_nonlinear_iterations = inner_min_nonlinear_iterations,
tol_factor_final_iteration = inner_tol_final,
check_before_solve = check_before_solve,
info_level = -1
info_level = Int(subdomain_info_level(i))
)
# Small hack for reservoir stuff
set_default_cnv_mb!(subconfigs[i], subsims[i].model, tol_cnv = inner_tol_mul*tol_cnv,
Expand Down
9 changes: 5 additions & 4 deletions src/cpr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ function true_impes!(w, acc, r, n, bz, arg...)
elseif bz == 8
true_impes_8!(w, acc, r, n, bz, arg...)
else
true_impes_gen!(w, acc, r, n, bz, arg...)
true_impes_gen!(w, acc, r, n, Val(bz), arg...)
end
end

Expand Down Expand Up @@ -447,9 +447,10 @@ function true_impes_8!(w, acc, r, n, bz, s, scaling)
end
end

function true_impes_gen!(w, acc, r, n, bz, p_scale, scaling)
function true_impes_gen!(w, acc, r, n, ::Val{bz}, p_scale, scaling) where bz
r_p = SVector{bz}(r)
A = MMatrix{bz, bz, eltype(r)}(zeros(bz, bz))
r_T = eltype(r)
A = MMatrix{bz, bz, r_T}(undef)
for cell in 1:n
@inbounds for i = 1:bz
v = acc[i, cell]
Expand All @@ -458,7 +459,7 @@ function true_impes_gen!(w, acc, r, n, bz, p_scale, scaling)
A[j, i] = v.partials[j]
end
end
invert_w!(w, A, r_p, cell, bz, scaling)
invert_w!(w, SMatrix{bz, bz, r_T}(A), r_p, cell, bz, scaling)
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/facility/well_presolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ end

function Jutul.simulator_config!(cfg, sim, ::PrepareStepWellSolver, storage)
add_option!(cfg, :well_iterations, 25, "Well iterations to be performed before step.", types = Int, values = 0:10000)
add_option!(cfg, :well_outer_iterations_limit, Inf, "Number of outer iterations for each solve where wells are to be solved.", types = Union{Int, Float64})
add_option!(cfg, :well_outer_iterations_limit, 1, "Number of outer iterations for each solve where wells are to be solved.", types = Union{Int, Float64})
add_option!(cfg, :well_acceptance_factor, 10.0, "Accept well pre-solve results at this relaxed factor.", types = Float64)
add_option!(cfg, :well_info_level, -1, "Info level for well solver.", types = Int)
end
Expand Down
3 changes: 2 additions & 1 deletion src/flux.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ function face_average_density(model::Union{CompositionalModel, ThermalCompositio
elseif s_r_tiny
ρ_avg = ρ_l
else
ρ_avg = (s_l*ρ_r + s_r*ρ_l)/(s_l + s_r)
# alt def: (s_l*ρ_r + s_r*ρ_l)/(s_l + s_r)
ρ_avg = 0.5*(ρ_r + ρ_l)
end
end
return ρ_avg
Expand Down
108 changes: 88 additions & 20 deletions src/init/init.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ function equilibriate_state(model, contacts,
cells = missing,
rs = missing,
rv = missing,
composition = missing,
kwarg...
)
model = reservoir_model(model)
Expand All @@ -25,7 +26,7 @@ function equilibriate_state(model, contacts,

init = Dict{Symbol, Any}()
init = equilibriate_state!(init, pts, model, sys, contacts, datum_depth, datum_pressure;
cells = cells, rv = rv, rs = rs, kwarg...
cells = cells, rv = rv, rs = rs, composition = composition, kwarg...
)

is_blackoil = sys isa StandardBlackOilSystem
Expand All @@ -51,13 +52,29 @@ function equilibriate_state(model, contacts,
init[:Rv] = Rv
end
end
is_compositional = sys isa CompositionalSystem
if is_compositional
@assert !ismissing(composition)
has_wat = has_other_phase(sys)
nc = length(init[:Pressure])
ncomp = number_of_components(sys) - has_wat
zmf = zeros(ncomp, nc)
for i in 1:nc
zmf[:, i] = composition(pts[i])
end
init[:OverallMoleFractions] = zmf
if has_wat
init[:ImmiscibleSaturation] = init[:Saturations][1, :]
end
end
return init
end

function equilibriate_state!(init, depths, model, sys, contacts, depth, datum_pressure;
cells = 1:length(depths),
rs = missing,
rv = missing,
composition = missing,
T_z = missing,
s_min = missing,
contacts_pc = missing,
Expand Down Expand Up @@ -95,24 +112,43 @@ function equilibriate_state!(init, depths, model, sys, contacts, depth, datum_pr
relperm = last(relperm)
end

pvt = rho.pvt
reg = Int[pvtnum]
function density_f(p, z, ph)
pvt_i = pvt[ph]
if phases[ph] == LiquidPhase() && disgas
rs_max = table_by_region(sys.rs_max, pvtnum)
Rs = min(rs(z), rs_max(p))
b = JutulDarcy.shrinkage(pvt_i, reg, p, Rs, 1)
rho = b*(rhoOS + Rs*rhoGS)
elseif phases[ph] == VaporPhase() && vapoil
rv_max = table_by_region(sys.rv_max, pvtnum)
Rv = min(rv(z), rv_max(p))
b = JutulDarcy.shrinkage(pvt_i, reg, p, Rv, 1)
rho = b*(rhoGS + Rv*rhoOS)
if rho isa ThreePhaseCompositionalDensitiesLV || rho isa TwoPhaseCompositionalDensities
if phases[ph] == AqueousPhase()
phase_density = rho_s[ph]*JutulDarcy.shrinkage(rho.immiscible_pvt, p)
else
@assert !ismissing(composition) "Composition must be present for equilibrium."
@assert !ismissing(T_z) "Temperature must be present for equilibrium."
z_i = Vector{Float64}(composition(z))
T = T_z(z)
eos = model.system.equation_of_state
f = MultiComponentFlash.flashed_mixture_2ph(eos, (p = p, T = T, z = z_i))
rho_l, rho_v = mass_densities(eos, p, T, f)
if phases[ph] == VaporPhase() || rho_l == 0
phase_density = rho_v
else
phase_density = rho_l
end
end
else
rho = rho_s[ph]*JutulDarcy.shrinkage(pvt_i, reg, p, 1)
pvt = rho.pvt
pvt_i = pvt[ph]
if phases[ph] == LiquidPhase() && disgas
rs_max = table_by_region(sys.rs_max, pvtnum)
Rs = min(rs(z), rs_max(p))
b = JutulDarcy.shrinkage(pvt_i, reg, p, Rs, 1)
phase_density = b*(rhoOS + Rs*rhoGS)
elseif phases[ph] == VaporPhase() && vapoil
rv_max = table_by_region(sys.rv_max, pvtnum)
Rv = min(rv(z), rv_max(p))
b = JutulDarcy.shrinkage(pvt_i, reg, p, Rv, 1)
phase_density = b*(rhoGS + Rv*rhoOS)
else
phase_density = rho_s[ph]*JutulDarcy.shrinkage(pvt_i, reg, p, 1)
end
end
return rho
return phase_density
end
pressures = determine_hydrostatic_pressures(depths, depth, zmin, zmax, contacts, datum_pressure, density_f, contacts_pc)
if nph > 1
Expand Down Expand Up @@ -207,6 +243,8 @@ function parse_state0_equil(model, datafile)

init = Dict{Symbol, Any}()
sol = datafile["SOLUTION"]
props = datafile["PROPS"]

G = physical_representation(model.data_domain)
nc = number_of_cells(G)
nph = number_of_phases(model.system)
Expand All @@ -220,12 +258,17 @@ function parse_state0_equil(model, datafile)
npvt = GeoEnergyIO.InputParser.number_of_tables(datafile, :pvtnum)
nsat = GeoEnergyIO.InputParser.number_of_tables(datafile, :satnum)

if haskey(sol, "RTEMP")
Ti = convert_to_si(only(sol["RTEMP"]), :Celsius)
if haskey(sol, "RTEMP") || haskey(props, "RTEMP")
if haskey(props, "RTEMP")
rtmp = only(props["RTEMP"])
else
rtmp = only(sol["RTEMP"])
end
Ti = convert_to_si(rtmp, :Celsius)
T_z = z -> Ti
elseif haskey(sol, "TEMPVD")
z = vec(sol["TEMPVD"][:, 1])
Tvd = vec(sol["TEMPVD"][:, 2] + 273.15)
elseif haskey(props, "TEMPVD")
z = vec(props["TEMPVD"][:, 1])
Tvd = vec(props["TEMPVD"][:, 2] + 273.15)
T_z = get_1d_interpolator(z, Tvd)
else
T_z = missing
Expand Down Expand Up @@ -359,9 +402,34 @@ function parse_state0_equil(model, datafile)
else
rv = missing
end
if haskey(props, "ZMFVD")
ztab = props["ZMFVD"][ereg]
N = size(ztab, 2) - 1
Sz = SVector{N, Float64}
ztab_z = Float64[]
ztab_static = Sz[]
for row in size(ztab, 1)
mf_i = Sz(ztab[row, 2:end])
z_i = ztab[row, 1]
push!(ztab_z, z_i)
push!(ztab_static, mf_i)
if row == 1
push!(ztab_z, z_i-1.0)
push!(ztab_static, mf_i)
end
if row == size(ztab, 1)
push!(ztab_z, z_i+1.0)
push!(ztab_static, mf_i)
end
end
composition = get_1d_interpolator(ztab_z, ztab_static)
else
composition = missing
end

subinit = equilibriate_state(
model, contacts, datum_depth, datum_pressure,
composition = composition,
cells = cells,
pvtnum = preg,
contacts_pc = contacts_pc,
Expand Down
14 changes: 10 additions & 4 deletions src/input_simulation/data_input.jl
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ function filter_inactive_completions!(completions_vector, g)
if !haskey(tuple_active, k)
ix = cell_index(g, tupl, throw = false)
if isnothing(ix)
jutul_message("Removing well",
"Well $well completion $tupl was declared using COMPDAT, but that cell is not active in model. Skipped.",
jutul_message("$well completion",
"Removed COMPDAT as $tupl is not active in processed mesh.",
color = :yellow
)
tuple_active[k] = false
Expand Down Expand Up @@ -824,7 +824,7 @@ function parse_physics_types(datafile; pvt_region = missing)
push!(phases, VaporPhase())
push!(rhoS, rhoGS)

cnames = props["CNAMES"]
cnames = copy(props["CNAMES"])
acf = props["ACF"]
mw = props["MW"]
p_c = props["PCRIT"]
Expand All @@ -837,6 +837,7 @@ function parse_physics_types(datafile; pvt_region = missing)
A_ij = nothing
end
mp = MolecularProperty.(mw, p_c, T_c, V_c, acf)
@assert length(cnames) == length(mp)
mixture = MultiComponentMixture(mp, A_ij = A_ij, names = cnames)
if haskey(props, "EOS")
eos_str = uppercase(props["EOS"])
Expand All @@ -853,7 +854,12 @@ function parse_physics_types(datafile; pvt_region = missing)
else
eos_type = PengRobinson()
end
eos = GenericCubicEOS(mixture, eos_type)
if haskey(props, "SSHIFT")
vshift = Tuple(props["SSHIFT"])
else
vshift = nothing
end
eos = GenericCubicEOS(mixture, eos_type, volume_shift = vshift)
sys = MultiPhaseCompositionalSystemLV(eos, phases, reference_densities = rhoS)
else
if has_oil
Expand Down
Loading
Loading