diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5e9df30..427336f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,8 +18,7 @@ jobs: fail-fast: false matrix: version: - - '1.6' - - 'nightly' + - '1.10' os: - ubuntu-latest arch: @@ -33,10 +32,4 @@ jobs: - uses: julia-actions/cache@v1 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v2 - with: - files: lcov.info - - uses: julia-actions/julia-uploadcoveralls@v1 - env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + diff --git a/Examples/XLSX_interface/ClassicHENSProblem/Gundersen_4_stream/Gundersen_4_stream.jl b/Examples/XLSX_interface/ClassicHENSProblem/Gundersen_4_stream/Gundersen_4_stream.jl index a9b92dd..bfcdbd8 100644 --- a/Examples/XLSX_interface/ClassicHENSProblem/Gundersen_4_stream/Gundersen_4_stream.jl +++ b/Examples/XLSX_interface/ClassicHENSProblem/Gundersen_4_stream/Gundersen_4_stream.jl @@ -6,7 +6,7 @@ using Plots using JuMP using Test -using BARON +#using BARON #exportall(CompHENS) @@ -43,13 +43,13 @@ obj_func = CostScaledPaterson() base_cost, cost_coeff, scaling_coeff = 4000, 500, 0.83 # 7.i. Commercial using BARON: -optimizer = optimizer_with_attributes(BARON.Optimizer, "MaxTime" => 20.0, "AbsConFeasTol" => 1) +#= optimizer = optimizer_with_attributes(BARON.Optimizer, "MaxTime" => 20.0, "AbsConFeasTol" => 1) results_df = generate_network!(prob, EMAT; optimizer = optimizer, obj_func = obj_func, verbose = true, cost_coeff = cost_coeff, scaling_coeff = scaling_coeff, base_cost = base_cost, save_model = true) model = prob.results_dict[:network_gen_model] file_name = "/home/avinash/Desktop/COMPHENS/CompHENS.jl/Examples/XLSX_interface/ClassicHENSProblem/Gundersen_4_stream/Gundersen_4_stream.pdf" -plot_HEN_streamwise(prob, model, overall_network, file_name; digits = 1) +plot_HEN_streamwise(prob, model, overall_network, file_name; digits = 1) =# #=Trials #CompHENS. diff --git a/Project.toml b/Project.toml index d48dc18..875becb 100644 --- a/Project.toml +++ b/Project.toml @@ -4,7 +4,6 @@ authors = ["Avinash Subramanian"] version = "0.1.4" [deps] -BARON = "2e2ca445-9e14-5b13-8677-4410f177f82b" Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" @@ -15,11 +14,16 @@ Kwonly = "18d08c8c-0732-55ee-a446-91a51d7b4206" MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" NamedArrays = "86f7a689-2022-50b4-a561-43c23ac3c673" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" XLSX = "fdbf4ff8-1666-58a4-91e7-1b58723a45e0" +[weakdeps] +PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" + +[extensions] +CompHENSNetworkXPlotsExt = "PyCall" + [compat] -BARON = "0.8" +Conda = "1" DataFrames = "1" DocStringExtensions = "0.9" HiGHS = "1" @@ -29,10 +33,9 @@ Kwonly = "0.1" MathOptInterface = "1" NamedArrays = "0.9" Plots = "1" -XLSX = "0.8, 0.9" -julia = "1.6" PyCall = "1" -Conda = "1" +XLSX = "0.8, 0.9" +julia = "1.10" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/ext/CompHENSNetworkXPlotsExt.jl b/ext/CompHENSNetworkXPlotsExt.jl new file mode 100644 index 0000000..49a9108 --- /dev/null +++ b/ext/CompHENSNetworkXPlotsExt.jl @@ -0,0 +1,156 @@ +module CompHENSNetworkXPlotsExt + + using CompHENS + using PyCall + using Conda + + const nx = PyNULL() + const plt = PyNULL() + const back_pdf = PyNULL() + + + function __init__() + copy!(nx, pyimport_conda("networkx", "networkx")) + copy!(plt, pyimport_conda("matplotlib.pyplot", "matplotlib")) + copy!(back_pdf, pyimport_conda("matplotlib.backends.backend_pdf", "matplotlib")) + end + + """ + $(TYPEDSIGNATURES) + The visualization tools for the HEN uses the Python `NetworkX` and `MatPlotlib` packages. + By default, OS-X and Windows users should PyCall configured to use the Miniconda environment installed at `.julia/conda/` (this can be attained by calling `Conda.ROOTENV`). + For Linux users: By default the default system installation is used, and it is necessary to over-ride this as follows: + - Set + ``` + ENV["PYTHON"]="" + using Pkg + Pkg.build("PyCall") + ``` + Then **restart** the Julia process. + """ + function CompHENS.plot_HEN_streamwise(prob::ClassicHENSProblem, model::AbstractModel, overall_network::Dict{String, AbstractSuperstructure}, file_name; digits = 1) + __init__() + pdf = CompHENS.back_pdf.PdfPages(file_name) + for stream in prob.all_names + plt.close() + (g, edge_labels, node_labels, position, node_size) = get_stream_graph(prob.all_dict[stream], prob, model, overall_network[stream]; digits = digits) + nx.draw_networkx(g, position, node_size = node_size, with_labels=false, arrowstyle="->", node_shape = "s") + nx.draw_networkx_labels(g, position, labels = node_labels, font_size = 3, horizontalalignment = "left", verticalalignment = "top") + nx.draw_networkx_edge_labels(g, position, edge_labels = edge_labels, horizontalalignment = "center", verticalalignment = "center", font_size = 2, rotate=false) + pdf.savefig() + end + pdf.close() + end + + """ + + + Gets a NetworkX Digraph for each stream + Returns: (g, edge_labels, node_labels, position, node_size) + """ + function CompHENS.get_stream_graph(stream::AbstractStream, prob::ClassicHENSProblem, model::AbstractModel, superstructure::AbstractSplitSuperstructure; digits = 1) + g = nx.DiGraph() + edge_labels = Dict() + node_labels = Dict() + + # Add nodes to NetworkX graph + for node in superstructure.nodes + g.add_node(node.name) + if node isa HX + match = node.match + if stream isa HotStream + node_labels[node.name] = "match: $(match), Q = $(round((prob.results_dict[:Q][match, stream.name]), digits = digits))" + elseif stream isa ColdStream + node_labels[node.name] = "match: $(match), Q = $(round((prob.results_dict[:Q][stream.name, match]), digits = digits))" + end + end + end + + # Only add edges if f_edge is greater than 0 + for edge in superstructure.edges + if value(model[:f][(stream.name, edge)]) > 0.0 + g.add_edge(edge.in.name, edge.out.name) + edge_labels[(edge.in.name, edge.out.name)] = "m: $(round(value(model[:f][(stream.name, edge)]); digits = digits)) T: $(round(value(model[:t][(stream.name, edge)]); digits = digits))" + end + end + + num_matches = length(prob.results_dict[:HLD_list][stream.name]) + # Copied from SeqHENS.jl + # Setting the coordinates of the nodes + position = Dict() + coordinates = [] # Array to keep pushing paired coordinates to, will then go through and assign to dictionary + bfix = 0.4 # Determines the vertical spacing + + push!(coordinates, (0,0)) + push!(coordinates, (1,0)) + for e in 1:num_matches + push!(coordinates,(2,0-(bfix*(e-1)))) + push!(coordinates,(5,0-(bfix*(e-1)))) + push!(coordinates,(9,0-(bfix*(e-1)))) + end + push!(coordinates,(10,0)) + push!(coordinates,(11,0)) + + i = 0 # hack for now + for node in superstructure.nodes + i += 1 + position[node.name] = coordinates[i] + end + + node_size = fill(1.0, length(superstructure.nodes)) + return(g, edge_labels, node_labels, position, node_size) + end + + function CompHENS.get_stream_graph(stream::AbstractUtility, prob::ClassicHENSProblem, model::AbstractModel, superstructure::AbstractSplitSuperstructure; digits = 1) + g = nx.DiGraph() + edge_labels = Dict() + node_labels = Dict() + + # Add nodes to NetworkX graph + for node in superstructure.nodes + g.add_node(node.name) + if node isa HX + match = node.match + if stream isa HotStream + node_labels[node.name] = "o: $(match), Q = $(round((prob.results_dict[:Q][match, stream.name]), digits = digits))" + elseif stream isa ColdStream + node_labels[node.name] = "o: $(match), Q = $(round((prob.results_dict[:Q][stream.name, match]), digits = digits))" + end + end + end + + # Only add edges if f_edge is greater than 0 + for edge in superstructure.edges + if edge.in isa HX || edge.out isa HX # Only care about edges attached to HX + g.add_edge(edge.in.name, edge.out.name) + edge_labels[(edge.in.name, edge.out.name)] = "T: $(round(value(model[:t][(stream.name, edge)]); digits = digits))" + end + end + + num_matches = length(prob.results_dict[:HLD_list][stream.name]) + # Copied from SeqHENS.jl + # Setting the coordinates of the nodes + position = Dict() + coordinates = [] # Array to keep pushing paired coordinates to, will then go through and assign to dictionary + bfix = 0.4 # Determines the vertical spacing + + push!(coordinates, (0,0)) + push!(coordinates, (1,0)) + for e in 1:num_matches + push!(coordinates,(2,0-(bfix*(e-1)))) + push!(coordinates,(5,0-(bfix*(e-1)))) + push!(coordinates,(9,0-(bfix*(e-1)))) + end + push!(coordinates,(10,0)) + push!(coordinates,(11,0)) + + i = 0 # hack for now + for node in superstructure.nodes + i += 1 + position[node.name] = coordinates[i] + end + + node_size = fill(1.0, length(superstructure.nodes)) + return(g, edge_labels, node_labels, position, node_size) + end +end \ No newline at end of file diff --git a/src/CompHENS.jl b/src/CompHENS.jl index 3527442..2364cdd 100644 --- a/src/CompHENS.jl +++ b/src/CompHENS.jl @@ -103,7 +103,7 @@ include("Superstructures/ParallelSplit.jl") export generate_network!, postprocess_network!, plot_HEN_streamwise, print_stream_results, get_design_area, AreaArithmeticMean, AreaPaterson, CostScaledPaterson, get_stream_graph include("SubProblems/Network_generation/network_generator_JuMP.jl") include("SubProblems/Network_generation/network_postprocess.jl") -include("SubProblems/Network_generation/conda_networkx_plots.jl") +#include("SubProblems/Network_generation/conda_networkx_plots.jl") diff --git a/src/Streams/streams.jl b/src/Streams/streams.jl index 705875f..4ef20e5 100644 --- a/src/Streams/streams.jl +++ b/src/Streams/streams.jl @@ -44,6 +44,7 @@ mutable struct ColdStream <: AbstractStream T_in <= T_out || error("Supply and Target temperature don't match stream type") mcp >= 0.0 || error("mcp values negative") # Can be zero if stream doesn't exist in one period. h > smallest_value || error("values infeasible") + push!(add_user_data, "Working Terminal T" => T_out) new(name, Float64(T_in), Float64(T_out), Float64(mcp), Float64(h), add_user_data, calc) end end diff --git a/src/SubProblems/Network_generation/conda_networkx_plots.jl b/src/SubProblems/Network_generation/conda_networkx_plots.jl index 26e395f..85bae41 100644 --- a/src/SubProblems/Network_generation/conda_networkx_plots.jl +++ b/src/SubProblems/Network_generation/conda_networkx_plots.jl @@ -1,16 +1,3 @@ -using Conda, PyCall - -const nx = PyNULL() -const plt = PyNULL() -const back_pdf = PyNULL() - - -function __init__() - copy!(nx, pyimport_conda("networkx", "networkx")) - copy!(plt, pyimport_conda("matplotlib.pyplot", "matplotlib")) - copy!(back_pdf, pyimport_conda("matplotlib.backends.backend_pdf", "matplotlib")) -end - """ $(TYPEDSIGNATURES) The visualization tools for the HEN uses the Python `NetworkX` and `MatPlotlib` packages. @@ -24,18 +11,7 @@ Pkg.build("PyCall") ``` Then **restart** the Julia process. """ -function plot_HEN_streamwise(prob::ClassicHENSProblem, model::AbstractModel, overall_network::Dict{String, AbstractSuperstructure}, file_name; digits = 1) - __init__() - pdf = CompHENS.back_pdf.PdfPages(file_name) - for stream in prob.all_names - plt.close() - (g, edge_labels, node_labels, position, node_size) = get_stream_graph(prob.all_dict[stream], prob, model, overall_network[stream]; digits = digits) - nx.draw_networkx(g, position, node_size = node_size, with_labels=false, arrowstyle="->", node_shape = "s") - nx.draw_networkx_labels(g, position, labels = node_labels, font_size = 3, horizontalalignment = "left", verticalalignment = "top") - nx.draw_networkx_edge_labels(g, position, edge_labels = edge_labels, horizontalalignment = "center", verticalalignment = "center", font_size = 2, rotate=false) - pdf.savefig() - end - pdf.close() +function plot_HEN_streamwise() end """ @@ -44,108 +20,5 @@ end Gets a NetworkX Digraph for each stream Returns: (g, edge_labels, node_labels, position, node_size) """ -function get_stream_graph(stream::AbstractStream, prob::ClassicHENSProblem, model::AbstractModel, superstructure::AbstractSplitSuperstructure; digits = 1) - g = nx.DiGraph() - edge_labels = Dict() - node_labels = Dict() - - # Add nodes to NetworkX graph - for node in superstructure.nodes - g.add_node(node.name) - if node isa HX - match = node.match - if stream isa HotStream - node_labels[node.name] = "match: $(match), Q = $(round((prob.results_dict[:Q][match, stream.name]), digits = digits))" - elseif stream isa ColdStream - node_labels[node.name] = "match: $(match), Q = $(round((prob.results_dict[:Q][stream.name, match]), digits = digits))" - end - end - end - - # Only add edges if f_edge is greater than 0 - for edge in superstructure.edges - if value(model[:f][(stream.name, edge)]) > 0.0 - g.add_edge(edge.in.name, edge.out.name) - edge_labels[(edge.in.name, edge.out.name)] = "m: $(round(value(model[:f][(stream.name, edge)]); digits = digits)) T: $(round(value(model[:t][(stream.name, edge)]); digits = digits))" - end - end - - num_matches = length(prob.results_dict[:HLD_list][stream.name]) - # Copied from SeqHENS.jl - # Setting the coordinates of the nodes - position = Dict() - coordinates = [] # Array to keep pushing paired coordinates to, will then go through and assign to dictionary - bfix = 0.4 # Determines the vertical spacing - - push!(coordinates, (0,0)) - push!(coordinates, (1,0)) - for e in 1:num_matches - push!(coordinates,(2,0-(bfix*(e-1)))) - push!(coordinates,(5,0-(bfix*(e-1)))) - push!(coordinates,(9,0-(bfix*(e-1)))) - end - push!(coordinates,(10,0)) - push!(coordinates,(11,0)) - - i = 0 # hack for now - for node in superstructure.nodes - i += 1 - position[node.name] = coordinates[i] - end - - node_size = fill(1.0, length(superstructure.nodes)) - return(g, edge_labels, node_labels, position, node_size) -end - -function get_stream_graph(stream::AbstractUtility, prob::ClassicHENSProblem, model::AbstractModel, superstructure::AbstractSplitSuperstructure; digits = 1) - g = nx.DiGraph() - edge_labels = Dict() - node_labels = Dict() - - # Add nodes to NetworkX graph - for node in superstructure.nodes - g.add_node(node.name) - if node isa HX - match = node.match - if stream isa HotStream - node_labels[node.name] = "o: $(match), Q = $(round((prob.results_dict[:Q][match, stream.name]), digits = digits))" - elseif stream isa ColdStream - node_labels[node.name] = "o: $(match), Q = $(round((prob.results_dict[:Q][stream.name, match]), digits = digits))" - end - end - end - - # Only add edges if f_edge is greater than 0 - for edge in superstructure.edges - if edge.in isa HX || edge.out isa HX # Only care about edges attached to HX - g.add_edge(edge.in.name, edge.out.name) - edge_labels[(edge.in.name, edge.out.name)] = "T: $(round(value(model[:t][(stream.name, edge)]); digits = digits))" - end - end - - num_matches = length(prob.results_dict[:HLD_list][stream.name]) - # Copied from SeqHENS.jl - # Setting the coordinates of the nodes - position = Dict() - coordinates = [] # Array to keep pushing paired coordinates to, will then go through and assign to dictionary - bfix = 0.4 # Determines the vertical spacing - - push!(coordinates, (0,0)) - push!(coordinates, (1,0)) - for e in 1:num_matches - push!(coordinates,(2,0-(bfix*(e-1)))) - push!(coordinates,(5,0-(bfix*(e-1)))) - push!(coordinates,(9,0-(bfix*(e-1)))) - end - push!(coordinates,(10,0)) - push!(coordinates,(11,0)) - - i = 0 # hack for now - for node in superstructure.nodes - i += 1 - position[node.name] = coordinates[i] - end - - node_size = fill(1.0, length(superstructure.nodes)) - return(g, edge_labels, node_labels, position, node_size) +function get_stream_graph() end diff --git a/src/SubProblems/Network_generation/starting_point_generator.jl b/src/SubProblems/Network_generation/starting_point_generator.jl index d4f0c0e..2d6d965 100644 --- a/src/SubProblems/Network_generation/starting_point_generator.jl +++ b/src/SubProblems/Network_generation/starting_point_generator.jl @@ -1,13 +1,15 @@ #[WIP] -#= +using CompHENS +pk_dir = pkgdir(CompHENS) +include(joinpath(pk_dir, "Examples", "XLSX_interface", "ClassicHENSProblem", "Gundersen_4_stream", "Gundersen_4_stream.jl")) exportall(CompHENS) -verbose && @info "Solving the Network Generation subproblem" +#verbose && @info "Solving the Network Generation subproblem" haskey(prob.results_dict, :y) || error("Stream match data not available. Solve corresponding subproblem first.") haskey(prob.results_dict, :Q) || error("HLD data not available. Solve corresponding subproblem first.") haskey(prob.results_dict, :HLD_list) || error("Match list data not available. Solve corresponding subproblem first.") -haskey(prob.results_dict, :T_bounds) || generate_temperature_bounds!(prob) +haskey(prob.results_dict, :T_bounds) || CompHENS.generate_temperature_bounds!(prob) #y, Q = prob.results_dict[:y], prob.results_dict[:Q] @@ -33,6 +35,164 @@ end @variable(model, 0.0 <= t[all_e_tuple_vec]) @variable(model, 0.0 <= f[stream_e_tuple_vec]) + + +#TODO: + +function test_terminal_match(hot_T_out, hot_T_in, cold_T_out, cold_T_in, EMAT) + terminal_feasible = false + if (hot_T_out >= cold_T_in + EMAT) && (hot_T_in >= cold_T_out + EMAT) + terminal_feasible = true + end + return (; terminal_feasible, hot_T_out, hot_T_in, cold_T_out, cold_T_in) +end + +""" +Test if the `matching_stream` can be feasibly placed as the terminal serial heat exchanger of the `stream` +""" +function test_terminal_match(stream_name::String, matching_stream_name::String, EMAT, overall_network) + test_terminal_match(prob.all_dict[stream_name], prob.all_dict[matching_stream_name], EMAT, overall_network) +end + +stream_name = "C2" +matching_stream_name = "ST" + +cold_stream = prob.all_dict[stream_name] +hot_matching_stream = prob.all_dict[matching_stream_name] + +function test_terminal_match(cold_stream::Union{ColdStream}, hot_matching_stream::Union{HotStream, SimpleHotUtility}, EMAT, overall_network) + + Q = prob.results_dict[:Q][cold_stream.name, hot_matching_stream.name] + + hot_T_out = overall_network[hot_matching_stream.name].metadata["Working Terminal T"] + if hot_matching_stream isa SimpleHotUtility + hot_T_in = hot_matching_stream.T_in + else + hot_T_in = hot_T_out + Q/hot_matching_stream.mcp + end + + cold_T_out = overall_network[cold_stream.name].metadata["Working Terminal T"] + cold_T_in = cold_T_out - Q/cold_stream.mcp + + test_terminal_match(hot_T_out, hot_T_in, cold_T_out, cold_T_in, EMAT) +end + +stream_name = "H2" +matching_stream_name = "CW" + +hot_stream = prob.all_dict[stream_name] +cold_matching_stream = prob.all_dict[matching_stream_name] + +function test_terminal_match(hot_stream::Union{HotStream}, cold_matching_stream::Union{ColdStream, SimpleColdUtility}, EMAT, overall_network) + Q = prob.results_dict[:Q][cold_matching_stream.name, hot_stream.name] + + hot_T_out = overall_network[hot_stream.name].metadata["Working Terminal T"] + hot_T_in = hot_T_out + Q/hot_stream.mcp + + cold_T_out = overall_network[cold_matching_stream.name].metadata["Working Terminal T"] + if cold_matching_stream isa SimpleColdUtility + cold_T_in = cold_matching_stream.T_in + else + cold_T_in = cold_T_out - Q/cold_matching_stream.mcp + end + + test_terminal_match(hot_T_out, hot_T_in, cold_T_out, cold_T_in, EMAT) +end + +## Main while loop for attaining feasible initial values. +# This will be mutated in the initialization loop +working_HX_list = deepcopy(prob.results_dict[:HX_list]) + +# Initialize all the Working Terminal Temperatures to T_out: +# Also +for (k,v) in overall_network + push!(v.metadata, "Working Terminal Node" => only(v.major_mixer)) + push!(v.metadata, "Working Terminal T" => prob.all_dict[k].T_out) + + # Set the temperatures of the source -> BS edge and the BM -> Sink edge + superstructure = overall_network[k] + SO_BS_edge = only(out_edges(superstructure.source[1], superstructure)) + set_start_value(model[:t][(k, SO_BS_edge)], prob.all_dict[k].T_in) + + BM_SK_edge = only(in_edges(superstructure.sink[1], superstructure)) + set_start_value(model[:t][(k, BM_SK_edge)], prob.all_dict[k].T_out) + + if prob.all_dict[k] isa Union{HotStream, ColdStream} # Utilities don't have f streams + set_start_value(model[:f][(k, SO_BS_edge)], prob.all_dict[k].mcp) + set_start_value(model[:f][(k, BM_SK_edge)], prob.all_dict[k].mcp) + end +end + +only(overall_network["C2"].metadata["Working Terminal Node"] ) + +# 1. Place utilies at edges +# 1.A Hot utilities: +hot_utilities = filter(working_HX_list) do (k,v) + prob.all_dict[k] isa SimpleHotUtility +end + +hot_util = only(keys(hot_utilities)) +cold_stream = only(working_HX_list[hot_util]) # Not gen. +#for hot_util in hot_utilities + for cold_stream in working_HX_list[hot_util] + @show cold_stream + end + + (; terminal_feasible, hot_T_out, hot_T_in, cold_T_out, cold_T_in) = test_terminal_match(cold_stream,hot_util, EMAT, overall_network) + if terminal_feasible + set_serial_terminal_starting_points!(model, hot_T_out, hot_T_in, cold_T_out, cold_T_in) + end + + + +superstructure = overall_network["C2"] + +# TODO: 0: Set these inits. Also push all inits to a dict for plotting. +k = "C2" +prob.all_dict[k].T_in + +stream = prob.all_dict[k] +superstructure = overall_network[k] +matching_stream = "ST" +terminal_match_HX = only(filter(k -> k.match == matching_stream, superstructure.hxs)) +new_terminal_node = only(get_source_nodes(terminal_match_HX, superstructure)) + +""" +This function is to be called if a HX is chosen to be placed (by setting starting points) as the last serial HX of the `stream` OR prior to another HX which has also been previously placed as a serial terminal HX. +This function sets starting points such a strictly serial connection is made between the `new_terminal_node` and the `stream`'s current terminal node which can be queried by `superstructure.metadata["Working Terminal Node"]`. +Lastly, the `superstructure.metadata["Working Terminal Node"]` is set to the `new_terminal_node` and the `superstructure.metadata["Working Terminal T"]` is set to the new temperature. +""" +function set_serial_terminal_starting_points!(model, new_terminal_node::Node, stream::ColdStream, superstructure::AbstractSplitSuperstructure; hot_T_out, hot_T_in, cold_T_out, cold_T_in) +end + +@assert new_terminal_node isa MinorMixer || error("The new terminal node must be a MinorMixer") +# 1. Set the starting points for the edge from MinorMixer to HX +MM_HX_edge = only(out_edges(new_terminal_node, superstructure)) + +function set_serial_terminal_starting_points!(model, new_terminal_node::Node, stream::HotStream, superstructure::AbstractSplitSuperstructure; hot_T_out, hot_T_in, cold_T_out, cold_T_in) +end + + + + + +#BM_SK_edge = only(in_edges(superstructure.sink[1], superstructure)) +#@constraint(model, model[:f][(stream.name, BM_SK_edge)] == stream.mcp) +#@constraint(model, model[:t][(stream.name, BM_SK_edge)] == stream.T_out) + + +function get_utility_match_start_vals() +end + utils_dict = merge(prob.cold_utilities_dict, prob.hot_utilities_dict) + for (k,v) in utils_dict + @show k + end + (k,v) = first(utils_dict) + matched_streams = prob.results_dict[:HX_list][k] + for stream in matched_streams + @show stream + end + #function set_start_values!(prob, EMAT, overall_network; verbose = verbose) # 1. Initialize the required dictionaries for book-keeping: prob.results_dict[:unflagged_matches] = deepcopy(filter(prob.results_dict[:HX_list]) do (k,v) @@ -55,8 +215,11 @@ Initially, the `working_terminal_node` of a stream is its `MajorMixer`. If a `HX The, `working_terminal_temp` is changed from `T_out` and calculated for each added terminal match. """ #function set_terminal_match!(model::AbstractModel, prob, stream::ColdStream, superstructure::AbstractSplitSuperstructure, match ; verbose = true) - # A. Set starting values for the flows: + # A. Set starting values for the temperatures: set_start_value(model[:t][(stream.name, only(out_edges(only(superstructure.source), superstructure)))], 69.0) -=# + + # B. Set starting values for the temperatures: + set_start_value(model[:t][(stream.name, only(out_edges(only(superstructure.source), superstructure)))], 69.0) + diff --git a/src/Superstructures/FloudasCiricGrossmann.jl b/src/Superstructures/FloudasCiricGrossmann.jl index 5c9aa5b..d5d57a2 100644 --- a/src/Superstructures/FloudasCiricGrossmann.jl +++ b/src/Superstructures/FloudasCiricGrossmann.jl @@ -26,12 +26,13 @@ Naming convention for `nodes`. Type of the node (see below) `_ edge.in == mixer, edges)) == 1 || error("Each mixer only has a single outgoing edge") end - return FloudasCiricGrossmann(nodes, edges) + return FloudasCiricGrossmann(nodes, edges, Dict{Symbol, Any}()) end function construct_superstructure(stream::String, superstructure::FloudasCiricGrossmann, prob::ClassicHENSProblem; verbose = true)