Skip to content

Commit

Permalink
Implement no flow conditions (#23)
Browse files Browse the repository at this point in the history
* Implement no flow conditions

* Fix tests
  • Loading branch information
marcbasquensmunoz authored Oct 31, 2024
1 parent ea03858 commit 038fd7f
Showing 10 changed files with 497 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/modular/boreholes/SingleUPipeBorehole.jl
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ function uniform_Tb_coeffs(borehole::SingleUPipeBorehole, λ, mass_flow, Tref, f
@unpack λg, λp, rb, rp, rpo, dpw, H, R_cache, A, method, exp_cache = borehole

if mass_flow == 0.
return 1., -1., 0.
return 1., 0., -1.
end

hp = heat_transfer_coefficient(mass_flow, Tref, borehole, fluid)
27 changes: 20 additions & 7 deletions src/modular/constraints/HeatLoadConstraint.jl
Original file line number Diff line number Diff line change
@@ -47,17 +47,30 @@ function constraints_coeffs!(M, ::HeatLoadConstraint, borefield::Borefield, netw

Nb = n_boreholes(network)
for (i, first_bh) in enumerate(first_bhs_in_branch(network))
for bh in neighborhood(network.graph, first_bh, Nb)
if bh == source(network) || bh == sink(network)
continue
end
M[i, 3Nb + bh] = one(eltype(M)) * get_H(borefield, bh)
bhs_in_branch = neighborhood(network.graph, first_bh, Nb)
for bh in bhs_in_branch
if mass_flows[bh] == 0.
M[i, 2bh - 1] = 1.
M[i, 2bh] = -1.
break
else
if bh == source(network) || bh == sink(network)
continue
end
M[i, 3Nb + bh] = one(eltype(M)) * get_H(borefield, bh)
end
end
end
end

function constraints_b!(b, constraint::HeatLoadConstraint, operation, step)
b .= @view constraint.Q_tot[:, step]
function constraints_b!(b, constraint::HeatLoadConstraint, network, mass_flows, step)
for (i, borehole) in enumerate(first_bhs_in_branch(network))
if mass_flows[borehole] == 0.
b[i] = 0.
else
b[i] = constraint.Q_tot[i, step]
end
end
end

function branch_of_borehole(network, borehole)
13 changes: 11 additions & 2 deletions src/modular/constraints/InletTempConstraint.jl
Original file line number Diff line number Diff line change
@@ -46,9 +46,18 @@ function constraints_coeffs!(M, ::InletTempConstraint, borefield::Borefield, net

for (i, borehole) in enumerate(first_bhs_in_branch(network))
M[i, 2*borehole - 1] = one(eltype(M))
if mass_flows[borehole] == zero(eltype(M))
M[i, 2*borehole ] = -one(eltype(M))
end
end
end

function constraints_b!(b, constraint::InletTempConstraint, operation, step)
b .= @view constraint.T_in[:, step]
function constraints_b!(b, constraint::InletTempConstraint, network, mass_flows, step)
for (i, borehole) in enumerate(first_bhs_in_branch(network))
if mass_flows[borehole] == zero(eltype(b))
b[i] = zero(eltype(b))
else
b[i] = constraint.T_in[i, step]
end
end
end
38 changes: 22 additions & 16 deletions src/modular/constraints/TotalHeatLoadConstraint.jl
Original file line number Diff line number Diff line change
@@ -12,29 +12,35 @@ end

function constraints_coeffs!(M, ::TotalHeatLoadConstraint, borefield::Borefield, network, mass_flows)
M .= zero(eltype(M))

Nb = n_boreholes(network)
j = 1

first_bhs = first_bhs_in_branch(network)
first_bh = first_bhs[1]
for i in 2:n_branches(network)
M[i, 2*first_bh-1] = -1.
bh_in = 2*first_bhs[i]-1
M[i, bh_in] = 1.
end

if sum(mass_flows) == 0
M[1, 2*first_bh-1] = 1.
M[1, 2Nb+first_bh] = -1.
return
first_bh = findfirst(i-> mass_flows[i] != 0., first_bhs)

for bh in first_bhs
if mass_flows[bh] == 0.
M[j, 2*bh] = -1.
else
if bh == first_bh
continue
end
M[j, 2*first_bh-1] = -1.
end
M[j, 2*bh-1] = 1.
j += 1
end

for i in 1:Nb
M[1, 3Nb+i] = get_H(borefield, i)
if sum(mass_flows) != 0
for i in 1:Nb
M[end, 3Nb+i] = get_H(borefield, i)
end
end
end

function constraints_b!(b, constraint::TotalHeatLoadConstraint, operation, step)
function constraints_b!(b, constraint::TotalHeatLoadConstraint, network, mass_flows, step)
b .= zero(eltype(b))
b[1] = constraint.Q_tot[step]
if sum(mass_flows) != 0.
b[end] = constraint.Q_tot[step]
end
end
7 changes: 6 additions & 1 deletion src/modular/core/topology.jl
Original file line number Diff line number Diff line change
@@ -10,12 +10,17 @@ function topology_coeffs!(M, network::BoreholeNetwork, mass_flows)
end
parents = inneighbors(network.graph, bh_in)
filter!(i -> i source(network), parents)

for bh_out in parents
if bh_out == source(network)
continue
end
M[j, 2*bh_in-1] = 1.
M[j, 2*bh_out] = - mass_flows[bh_out] / mass_flows[bh_in]
if mass_flows[bh_in] == 0.
M[j, 2*bh_in] = -1.
else
M[j, 2*bh_out] = - mass_flows[bh_out] / mass_flows[bh_in]
end
end
if !isempty(parents)
j += 1
2 changes: 1 addition & 1 deletion src/modular/interfaces/Constraint.jl
Original file line number Diff line number Diff line change
@@ -17,5 +17,5 @@ abstract type Constraint end

@required Constraint begin
constraints_coeffs!(M, ::Constraint, ::Borefield, network, mass_flows)
constraints_b!(b, ::Constraint, operation, step)
constraints_b!(b, ::Constraint, network, mass_flows, step)
end
2 changes: 1 addition & 1 deletion src/modular/simulate.jl
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ function simulate!(;operator, options::SimulationOptions, containers::Simulation
# Update b
@views internal_model_b!(b[internal_model_eqs], borefield)
@views topology_b!(b[topology_eqs], operation)
@views constraints_b!(b[constraints_eqs], constraint, operation, i)
@views constraints_b!(b[constraints_eqs], constraint, network, mass_flows, i)
@views method_b!(b[method_eqs], method, borefield, medium, i)
@views heat_balance_b!(b[balance_eqs], borefield)

149 changes: 148 additions & 1 deletion test/constraints/test_HeatLoadConstraint.jl
Original file line number Diff line number Diff line change
@@ -25,6 +25,66 @@ import BoreholeNetworksSimulator: constraints_coeffs!, constraints_b!
@test test_sparse_matrix(M, expected)
end


@testset "test_HeatLoadConstraint_M_parallel_no_flow" begin
Nbr = 3
Nb = 3
Nt = 1

H = 23.

Q_tot = ones(Nbr, Nt)
constraint = HeatLoadConstraint(Q_tot)

M = zeros(Nbr, 4*Nb)

network = all_parallel_network(Nb)
mass_flows = initialize_mass_flows(network)
operation = BoreholeOperation(network=network, mass_flows=zeros(Nbr))
compute_mass_flows!(mass_flows, network, operation)

borefield = BorefieldMock(H = H * ones(3))

constraints_coeffs!(M, constraint, borefield, network, mass_flows)

expected = [
(1, 1, 1.), (1, 2, -1.),
(2, 3, 1.), (2, 4, -1.),
(3, 5, 1.), (3, 6, -1.),
]
@test test_sparse_matrix(M, expected)
end


@testset "test_HeatLoadConstraint_M_parallel_no_flow_partial" begin
Nbr = 3
Nb = 3
Nt = 1

H = 23.

Q_tot = ones(Nbr, Nt)
constraint = HeatLoadConstraint(Q_tot)

M = zeros(Nbr, 4*Nb)

network = all_parallel_network(Nb)
mass_flows = initialize_mass_flows(network)
operation = BoreholeOperation(network=network, mass_flows=vcat(zeros(1), ones(1), zeros(1)))
compute_mass_flows!(mass_flows, network, operation)

borefield = BorefieldMock(H = H * ones(3))

constraints_coeffs!(M, constraint, borefield, network, mass_flows)

expected = [
(1, 1, 1.), (1, 2, -1.),
(2, 3Nb+2, H),
(3, 5, 1.), (3, 6, -1.),
]
@test test_sparse_matrix(M, expected)
end

@testset "test_HeatLoadConstraint_M_series" begin
Nbr = 1
Nb = 3
@@ -50,6 +110,31 @@ end
@test test_sparse_matrix(M, expected)
end

@testset "test_HeatLoadConstraint_M_series_no_flow" begin
Nbr = 1
Nb = 3
Nt = 1

H = 32.

Q_tot = ones(Nbr, Nt)
constraint = HeatLoadConstraint(Q_tot)

M = zeros(Nbr, 4*Nb)

borefield = BorefieldMock(H = H * ones(3))

network = all_series_network(Nb)
mass_flows = initialize_mass_flows(network)
operation = BoreholeOperation(network=network, mass_flows=zeros(Nbr))
compute_mass_flows!(mass_flows, network, operation)

constraints_coeffs!(M, constraint, borefield, network, mass_flows)

expected = [(1, 1, 1.), (1, 2, -1.)]
@test test_sparse_matrix(M, expected)
end

@testset "test_HeatLoadConstraint_M_mixed" begin
Nbr = 3
Nb = 5
@@ -79,6 +164,39 @@ end
@test test_sparse_matrix(M, expected)
end

@testset "test_HeatLoadConstraint_M_mixed_no_flow" begin
Nbr = 3
Nb = 5
Nt = 1

H = 51.

Q_tot = ones(Nbr, Nt)
constraint = HeatLoadConstraint(Q_tot)

M = zeros(Nbr, 4*Nb)

network = BoreholeNetwork(5)
connect_to_source!(network, [1, 3, 5])
connect!(network, 1, 2)
connect!(network, 3, 4)
connect_to_sink!(network, [2, 4, 5])
operation = BoreholeOperation(network=network, mass_flows=zeros(Nbr))
mass_flows = initialize_mass_flows(network)
compute_mass_flows!(mass_flows, network, operation)

borefield = BorefieldMock(H = H * ones(5))

constraints_coeffs!(M, constraint, borefield, network, mass_flows)

expected = [
(1, 1, 1.), (1, 2, -1.),
(2, 5, 1.), (2, 6, -1.),
(3, 9, 1.), (3, 10, -1.)
]
@test test_sparse_matrix(M, expected)
end

@testset "test_HeatLoadConstraint_b" begin
Nbr = 3
Nb = 3
@@ -94,12 +212,41 @@ end

network = all_parallel_network(Nb)
operation = BoreholeOperation(network=network, mass_flows=ones(Nbr))
mass_flows = initialize_mass_flows(network)
compute_mass_flows!(mass_flows, network, operation)

b_time = zeros(Nbr, Nt)
for step in 1:Nt
constraints_b!(b, constraint, operation, step)
constraints_b!(b, constraint, network, mass_flows, step)
b_time[:, step] .= b
end

@test b_time == Q_tot
end

@testset "test_HeatLoadConstraint_b_no_flow" begin
Nbr = 3
Nb = 3
Nt = 10

Q_tot = ones(Nbr, Nt)
for i in axes(Q_tot, 2)
Q_tot[:, i] .= Float64(i)
end
constraint = HeatLoadConstraint(Q_tot)

b = zeros(Nbr)

network = all_parallel_network(Nb)
operation = BoreholeOperation(network=network, mass_flows=zeros(Nbr))
mass_flows = initialize_mass_flows(network)
compute_mass_flows!(mass_flows, network, operation)

b_time = zeros(Nbr, Nt)
for step in 1:Nt
constraints_b!(b, constraint, network, mass_flows, step)
b_time[:, step] .= b
end

@test b_time == zeros(Nbr, Nt)
end
Loading

0 comments on commit 038fd7f

Please sign in to comment.