From 740664f051e989c10cf15be58c035611d9b4cfb8 Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Mon, 11 Sep 2023 10:05:30 -0500 Subject: [PATCH 01/15] updated input data lists to include wellpressure, elevation, and initialpipelinediameters --- backend/app/internal/get_data.py | 3 +++ electron/ui/src/assets/CategoryNames.json | 3 +++ electron/ui/src/assets/Subcategories.json | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/app/internal/get_data.py b/backend/app/internal/get_data.py index 141d7301..f822c9c0 100644 --- a/backend/app/internal/get_data.py +++ b/backend/app/internal/get_data.py @@ -642,6 +642,7 @@ def get_input_lists(): "CST", "CCT", "CKT", + "Elevation", "CompletionsPadOutsideSystem", "DesalinationTechnologies", "DesalinationSites", @@ -649,8 +650,10 @@ def get_input_lists(): "CompletionsDemand", "PadRates", "FlowbackRates", + "WellPressure", "NodeCapacities", "InitialPipelineCapacity", + "InitialPipelineDiameters", "InitialDisposalCapacity", "InitialTreatmentCapacity", "FreshwaterSourcingAvailability", diff --git a/electron/ui/src/assets/CategoryNames.json b/electron/ui/src/assets/CategoryNames.json index e281986c..c96d134f 100644 --- a/electron/ui/src/assets/CategoryNames.json +++ b/electron/ui/src/assets/CategoryNames.json @@ -10,6 +10,7 @@ "FlowbackRates":"Flowback Rates", "NodeCapacities":"Node Capacities", "InitialPipelineCapacity":"Initial Pipeline Capacity", + "InitialPipelineDiameters":"Initial Pipeline Diameters", "InitialDisposalCapacity":"Initial Disposal Capacity", "InitialTreatmentCapacity":"Initial Treatment Capacity", "FreshwaterSourcingAvailability":"Freshwater Sourcing Availability", @@ -39,6 +40,8 @@ "PadStorageInitialWaterQuality":"Pad Storage Initial Water Quality", "DisposalOperatingCapacity":"Disposal Operating Capacity", "RemovalEfficiency": "Removal Efficiency", + "WellPressure": "Well Pressure", + "Elevation": "Elevation", "PNA":"PNA", "CNA":"CNA", "CCA":"CCA", diff --git a/electron/ui/src/assets/Subcategories.json b/electron/ui/src/assets/Subcategories.json index 3581ca77..a1636c00 100644 --- a/electron/ui/src/assets/Subcategories.json +++ b/electron/ui/src/assets/Subcategories.json @@ -2,12 +2,12 @@ "Dynamic": [ "CompletionsDemand","DisposalOperationalCost","TreatmentOperationalCost","CompletionsPadOutsideSystem", "DesalinationTechnologies","DesalinationSites","TruckingTime","PadRates","FlowbackRates","NodeCapacities", - "InitialPipelineCapacity","InitialDisposalCapacity","InitialTreatmentCapacity","FreshwaterSourcingAvailability", + "InitialPipelineCapacity","InitialPipelineDiameters", "InitialDisposalCapacity","InitialTreatmentCapacity","FreshwaterSourcingAvailability", "PadOffloadingCapacity","CompletionsPadStorage","ReuseOperationalCost","PipelineOperationalCost", "FreshSourcingCost","TruckingHourlyCost","PipelineDiameterValues","DisposalCapacityIncrements", "InitialStorageCapacity","StorageCapacityIncrements","TreatmentCapacityIncrements","TreatmentEfficiency", "DisposalExpansionCost","StorageExpansionCost","TreatmentExpansionCost","PipelineCapexDistanceBased", - "PipelineCapexCapacityBased","PipelineCapacityIncrements","PipelineExpansionDistance","Hydraulics", + "PipelineCapexCapacityBased","PipelineCapacityIncrements","PipelineExpansionDistance","WellPressure", "Hydraulics","Elevation", "Economics","PadWaterQuality","StorageInitialWaterQuality","PadStorageInitialWaterQuality","DisposalOperatingCapacity", "RemovalEfficiency" ], "Static": [ From 31bb03883e3e9584cd3f0b4991c2a619f10dbff7 Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Mon, 11 Sep 2023 10:19:49 -0500 Subject: [PATCH 02/15] added hydraulics option to optimization settings; hooked it up to backend --- backend/app/internal/pareto_stategic_model.py | 2 ++ backend/app/internal/scenario_handler.py | 1 + backend/app/routers/scenarios.py | 4 +-- .../ui/src/views/Optimization/Optimization.js | 28 +++++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/backend/app/internal/pareto_stategic_model.py b/backend/app/internal/pareto_stategic_model.py index 09cd6396..42260341 100644 --- a/backend/app/internal/pareto_stategic_model.py +++ b/backend/app/internal/pareto_stategic_model.py @@ -9,6 +9,7 @@ solve_model, PipelineCost, PipelineCapacity, + Hydraulics, WaterQuality ) from pyomo.opt import TerminationCondition @@ -76,6 +77,7 @@ def run_strategic_model(input_file, output_file, id, modelParameters, overrideVa "pipeline_capacity": PipelineCapacity.input, "node_capacity": True, "water_quality": WaterQuality[modelParameters["waterQuality"]], + "hydraulics": Hydraulics[modelParameters["hydraulics"]], # "build_units": BuildUnits[modelParameters["build_units"]] }, ) diff --git a/backend/app/internal/scenario_handler.py b/backend/app/internal/scenario_handler.py index 93dc03fb..cad627f8 100644 --- a/backend/app/internal/scenario_handler.py +++ b/backend/app/internal/scenario_handler.py @@ -214,6 +214,7 @@ def upload_excelsheet(self, output_path, scenarioName, filename): "runtime": 900, "pipelineCostCalculation": "distance_based", "waterQuality": "false", + "hydraulics": "false", "solver": "cbc", "build_units": "scaled_units", "optimalityGap": 0, diff --git a/backend/app/routers/scenarios.py b/backend/app/routers/scenarios.py index e639e0ef..5206da9f 100644 --- a/backend/app/routers/scenarios.py +++ b/backend/app/routers/scenarios.py @@ -107,8 +107,8 @@ async def run_model(request: Request, background_tasks: BackgroundTasks): "pipelineCost": data['scenario']['optimization']['pipelineCostCalculation'], "waterQuality": data['scenario']['optimization']['waterQuality'] } - defaultParams = {'solver': None, 'build_units': 'user_units', 'optimalityGap': 5, 'scale_model': True} - for param in ['solver', 'build_units', 'optimalityGap', 'scale_model']: + defaultParams = {'solver': None, 'build_units': 'user_units', 'optimalityGap': 5, 'scale_model': True, 'hydraulics': 'false'} + for param in ['solver', 'build_units', 'optimalityGap', 'scale_model', 'hydraulics']: try: modelParameters[param]=data['scenario']['optimization'][param] except: diff --git a/electron/ui/src/views/Optimization/Optimization.js b/electron/ui/src/views/Optimization/Optimization.js index 452b79d8..ce06b971 100644 --- a/electron/ui/src/views/Optimization/Optimization.js +++ b/electron/ui/src/views/Optimization/Optimization.js @@ -37,6 +37,12 @@ export default function Optimization(props) { -Post Process: Calculates the water quality after optimization. The model cannot impose quality restrictions.
-Discrete: Utilize a discrete model to incorporate water quality into decisions. This model can impose quality restrictions. For example, a maximum TDS allowed at a treatment facility. , + hydraulics:
+ PARETO's hydraulics module allows the user to determine pumping needs and compute pressures at every node in the network while considering maximum allowable operating pressure (MAOP) constraints. Select how you would like to include it in the model:
+ -False: This option allows the user to skip the hydraulics computations in the PARETO model.
+ -Post Process: PARETO first solves for optimal flows and network design. Afterwards, the hydraulics block containing constraints for pressure balances and losses is solved.
+ -Co-Optimize: In this method, the hydraulics model block is solved together with the produced water flow and network design. Note: The co-optimize model as currently implemented requires the following MINLP solvers: SCIP and BARON.. +
, solver:
Select the solver you would like to use. Note: Gurobi requires a license. If you do not have a Gurobi licence, select "CBC", an open source solver. @@ -254,6 +260,28 @@ export default function Optimization(props) { + + +

Hydraulics + +

+
+
+ + + + + +

From 46440f9e2a0a5d38fbfd9333f0af3cd135a6976d Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 12 Sep 2023 09:37:47 -0500 Subject: [PATCH 03/15] added water quality chart; need data for hydraulics chart --- .../ui/src/components/AreaChart/AreaChart.js | 18 ++++-- electron/ui/src/views/DataInput/DataInput.js | 2 + .../ui/src/views/ModelResults/KPIDashboard.js | 61 ++++++++++++++++++- .../ui/src/views/ModelResults/ModelResults.js | 2 + .../ui/src/views/Optimization/Optimization.js | 4 +- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/electron/ui/src/components/AreaChart/AreaChart.js b/electron/ui/src/components/AreaChart/AreaChart.js index 3965f5c2..405b83a3 100644 --- a/electron/ui/src/components/AreaChart/AreaChart.js +++ b/electron/ui/src/components/AreaChart/AreaChart.js @@ -3,7 +3,7 @@ import {useEffect, useState} from 'react'; import Plot from 'react-plotly.js'; -export default function KPIDashboard(props) { +export default function AreaChart(props) { const [ areaChartData, setAreaChartData ] = useState(null) useEffect(()=>{ @@ -48,9 +48,14 @@ export default function KPIDashboard(props) { // organize area chart data for (var index = 1; index < props.data.length; index++) { let item = props.data[index] - let key = item[1] - let x = item[2] - let y = item[3] + let key = item[props.labelIndex] + // if(key.length > 4) { + // key=key.substring(0,4) + // console.log(key) + // } + key = key.replace('PostTreatmentTreatedWaterNode',"PTTWN").replace("PostTreatmentResidualNode","PTRN").replace('intermediate','I') + let x = item[props.xindex] + let y = item[props.yindex] if (key in tempData){ tempData[key].x.push(parseInt(x.substring(1))) tempData[key].y.push(y) @@ -63,10 +68,11 @@ export default function KPIDashboard(props) { // tempAreaChartData.push({x: value.x, y: value.y, stackgroup: 'one', name: key}) // }) - let keys = Object.keys(tempData).sort().reverse() + // let keys = Object.keys(tempData).sort().reverse() + let keys = Object.keys(tempData).sort() keys.map((key, ind) => { let value = tempData[key] - tempAreaChartData.push({x: value.x, y: value.y, stackgroup: 'one', name: key}) + tempAreaChartData.push({x: value.x, y: value.y, stackgroup: props.stackgroup, name: key}) return 1 }) setAreaChartData(tempAreaChartData) diff --git a/electron/ui/src/views/DataInput/DataInput.js b/electron/ui/src/views/DataInput/DataInput.js index e08509c1..88064a1c 100644 --- a/electron/ui/src/views/DataInput/DataInput.js +++ b/electron/ui/src/views/DataInput/DataInput.js @@ -275,6 +275,8 @@ const handleRowFilter = (row) => { width={750} height={500} showlegend={true} + chartType={'area'} + stackgroup={"one"} /> ) diff --git a/electron/ui/src/views/ModelResults/KPIDashboard.js b/electron/ui/src/views/ModelResults/KPIDashboard.js index 0c106c1c..8bf3f796 100644 --- a/electron/ui/src/views/ModelResults/KPIDashboard.js +++ b/electron/ui/src/views/ModelResults/KPIDashboard.js @@ -1,9 +1,10 @@ import React from 'react'; import {useEffect, useState} from 'react'; -import { Box, Grid, IconButton } from '@mui/material'; +import { Box, Grid, IconButton, Tooltip } from '@mui/material'; import ChangeCircleIcon from '@mui/icons-material/ChangeCircle'; import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import WaterIcon from '@mui/icons-material/Water'; +import InfoIcon from '@mui/icons-material/Info'; import Plot from 'react-plotly.js'; import AreaChart from '../../components/AreaChart/AreaChart' @@ -233,7 +234,7 @@ export default function KPIDashboard(props) { - + @@ -242,9 +243,14 @@ export default function KPIDashboard(props) { title="Trucked Water Deliveries By Destination" xaxis={{titletext: "Planning Horizon (weeks)"}} yaxis={{titletext: "Amount of Water (bbl/week)"}} + labelIndex={1} + xindex={2} + yindex={3} width={600} height={500} showlegend={true} + chartType={'area'} + stackgroup={"one"} /> @@ -255,9 +261,14 @@ export default function KPIDashboard(props) { title="Piped Water Deliveries By Destination" xaxis={{titletext: "Planning Horizon (weeks)"}} yaxis={{titletext: "Amount of Water (bbl/week)"}} + labelIndex={1} + xindex={2} + yindex={3} width={600} height={500} showlegend={true} + chartType={'area'} + stackgroup={"one"} /> @@ -265,6 +276,52 @@ export default function KPIDashboard(props) { + + + + + + + + + + + + + {/* */} + + + + {/* */} + + + } diff --git a/electron/ui/src/views/ModelResults/ModelResults.js b/electron/ui/src/views/ModelResults/ModelResults.js index a1022c38..87e28e4a 100644 --- a/electron/ui/src/views/ModelResults/ModelResults.js +++ b/electron/ui/src/views/ModelResults/ModelResults.js @@ -276,6 +276,8 @@ const handleNewInfrastructureOverride = () => { overviewData={props.scenario.results.data['v_F_Overview_dict']} truckedData={props.scenario.results.data['v_F_Trucked_dict']} pipedData={props.scenario.results.data['v_F_Piped_dict']} + waterQualityData={props.scenario.results.data["quality.v_Q_dict"]} + /> } /* diff --git a/electron/ui/src/views/Optimization/Optimization.js b/electron/ui/src/views/Optimization/Optimization.js index ce06b971..0b73a548 100644 --- a/electron/ui/src/views/Optimization/Optimization.js +++ b/electron/ui/src/views/Optimization/Optimization.js @@ -1,5 +1,5 @@ import React from 'react'; -import {useEffect, useState} from 'react'; +import { useState } from 'react'; import { Box, Grid, InputAdornment, Checkbox, FormControlLabel, FormControl, Button } from '@mui/material'; import { MenuItem, Radio, RadioGroup, Select, IconButton, Tooltip, Collapse, OutlinedInput } from '@mui/material'; import InfoIcon from '@mui/icons-material/Info'; @@ -41,7 +41,7 @@ export default function Optimization(props) { PARETO's hydraulics module allows the user to determine pumping needs and compute pressures at every node in the network while considering maximum allowable operating pressure (MAOP) constraints. Select how you would like to include it in the model:
-False: This option allows the user to skip the hydraulics computations in the PARETO model.
-Post Process: PARETO first solves for optimal flows and network design. Afterwards, the hydraulics block containing constraints for pressure balances and losses is solved.
- -Co-Optimize: In this method, the hydraulics model block is solved together with the produced water flow and network design. Note: The co-optimize model as currently implemented requires the following MINLP solvers: SCIP and BARON.. + -Co-Optimize: In this method, the hydraulics model block is solved together with the produced water flow and network design. Note: The co-optimize model as currently implemented requires the following MINLP solvers: SCIP and BARON.

, solver:
Select the solver you would like to use. Note: Gurobi requires a license. From 893b0ca831f7a34b0a7ca4115bc24124c9313ce0 Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 12 Sep 2023 09:40:23 -0500 Subject: [PATCH 04/15] renamed areachart -> customchart --- .../AreaChart.js => CustomChart/CustomChart.js} | 0 .../tests/{areachart.test.js => customchart.test.js} | 6 +++--- electron/ui/src/views/DataInput/DataInput.js | 4 ++-- electron/ui/src/views/ModelResults/KPIDashboard.js | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) rename electron/ui/src/components/{AreaChart/AreaChart.js => CustomChart/CustomChart.js} (100%) rename electron/ui/src/tests/{areachart.test.js => customchart.test.js} (89%) diff --git a/electron/ui/src/components/AreaChart/AreaChart.js b/electron/ui/src/components/CustomChart/CustomChart.js similarity index 100% rename from electron/ui/src/components/AreaChart/AreaChart.js rename to electron/ui/src/components/CustomChart/CustomChart.js diff --git a/electron/ui/src/tests/areachart.test.js b/electron/ui/src/tests/customchart.test.js similarity index 89% rename from electron/ui/src/tests/areachart.test.js rename to electron/ui/src/tests/customchart.test.js index 4ebadb0c..127866d9 100644 --- a/electron/ui/src/tests/areachart.test.js +++ b/electron/ui/src/tests/customchart.test.js @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react'; -import AreaChart from "../components/AreaChart/AreaChart" +import CustomChart from "../components/CustomChart/CustomChart" import mockScenario from './data/mockScenario.json' import * as React from 'react' @@ -8,7 +8,7 @@ const mockCategory1 = "CompletionsDemand"; const mockCategory2 = "v_F_Piped_dict"; test('test data input area chart', () => { - render( { }) test('test model results area chart', () => { - render( { - - - - - {/* Date: Tue, 12 Sep 2023 09:52:00 -0500 Subject: [PATCH 05/15] updated component test --- electron/ui/src/tests/customchart.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/electron/ui/src/tests/customchart.test.js b/electron/ui/src/tests/customchart.test.js index 127866d9..0a0b4e34 100644 --- a/electron/ui/src/tests/customchart.test.js +++ b/electron/ui/src/tests/customchart.test.js @@ -31,6 +31,11 @@ test('test model results area chart', () => { width={600} height={500} showlegend={true} + labelIndex={1} + xindex={2} + yindex={3} + chartType={'area'} + stackgroup={"one"} /> ) }) \ No newline at end of file From 3d4b4a56c11bbcbcf5d4836a26d81f551640573d Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 12 Sep 2023 09:56:50 -0500 Subject: [PATCH 06/15] updated component test --- electron/ui/src/tests/customchart.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/ui/src/tests/customchart.test.js b/electron/ui/src/tests/customchart.test.js index 0a0b4e34..29a01095 100644 --- a/electron/ui/src/tests/customchart.test.js +++ b/electron/ui/src/tests/customchart.test.js @@ -31,7 +31,7 @@ test('test model results area chart', () => { width={600} height={500} showlegend={true} - labelIndex={1} + labelIndex={0} xindex={2} yindex={3} chartType={'area'} From ef7b8b65f2be513c286bfe0babae107fc88bb2ce Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Fri, 15 Sep 2023 12:54:26 -0500 Subject: [PATCH 07/15] add hydraulics stuff to category names dictionary --- electron/ui/src/assets/CategoryNames.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/electron/ui/src/assets/CategoryNames.json b/electron/ui/src/assets/CategoryNames.json index c96d134f..b53c9320 100644 --- a/electron/ui/src/assets/CategoryNames.json +++ b/electron/ui/src/assets/CategoryNames.json @@ -97,6 +97,11 @@ "v_S_DisposalCapacity_dict":"Slack Disposal Capacity", "v_S_TreatmentCapacity_dict":"Slack reatment Capacity", "v_S_ReuseCapacity_dict":"Slack Reuse Capacity", + "hydraulics.v_PumpHead_dict": "Hydraulics Pump Head", + "hydraulics.vb_Y_Pump_dict": "Hydraulics New Pump", + "hydraulics.v_ValveHead_dict": "Hydraulics Valve Head", + "hydraulics.v_PumpCost_dict": "Hydraulics Pump Cost", + "hydraulics.v_Pressure_dict": "Hydraulics Pressure", "v_Z": "Objective", "v_R_TotalStorage": "Credit Total Storage", From d9ae5abe7f8038e4ebf0dacfdb86634a1fa58cee Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Fri, 15 Sep 2023 13:01:59 -0500 Subject: [PATCH 08/15] added hydraulics pressure visualization --- .../ui/src/views/ModelResults/KPIDashboard.js | 90 ++++++++++--------- .../ui/src/views/ModelResults/ModelResults.js | 1 + 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/electron/ui/src/views/ModelResults/KPIDashboard.js b/electron/ui/src/views/ModelResults/KPIDashboard.js index 00b2de00..3fc3dbd8 100644 --- a/electron/ui/src/views/ModelResults/KPIDashboard.js +++ b/electron/ui/src/views/ModelResults/KPIDashboard.js @@ -277,49 +277,57 @@ export default function KPIDashboard(props) { - - - - - - + {props.waterQualityData && props.waterQualityData.length>1 && + + + + + + + + + {/* */} - - - - - {/* */} + } + + {props.hydraulicsData && + + + + + + + + + {/* */} - - - {/* */} - + } diff --git a/electron/ui/src/views/ModelResults/ModelResults.js b/electron/ui/src/views/ModelResults/ModelResults.js index 87e28e4a..52df2f47 100644 --- a/electron/ui/src/views/ModelResults/ModelResults.js +++ b/electron/ui/src/views/ModelResults/ModelResults.js @@ -277,6 +277,7 @@ const handleNewInfrastructureOverride = () => { truckedData={props.scenario.results.data['v_F_Trucked_dict']} pipedData={props.scenario.results.data['v_F_Piped_dict']} waterQualityData={props.scenario.results.data["quality.v_Q_dict"]} + hydraulicsData={props.scenario.results.data["hydraulics.v_Pressure_dict"]} /> } From 51e20e4f33ac9fbd14cf5c9d03b8c1dadbf8b70a Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Fri, 15 Sep 2023 13:02:30 -0500 Subject: [PATCH 09/15] added check to ensure hydraulics visualization only displays if ther is data --- electron/ui/src/views/ModelResults/KPIDashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/ui/src/views/ModelResults/KPIDashboard.js b/electron/ui/src/views/ModelResults/KPIDashboard.js index 3fc3dbd8..9741dd24 100644 --- a/electron/ui/src/views/ModelResults/KPIDashboard.js +++ b/electron/ui/src/views/ModelResults/KPIDashboard.js @@ -303,7 +303,7 @@ export default function KPIDashboard(props) { } - {props.hydraulicsData && + {props.hydraulicsData && props.hydraulicsData.length>1 && From d1f1138523fc84af6e6217688462b32aa7c51a5d Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 19 Sep 2023 08:52:22 -0500 Subject: [PATCH 10/15] update workflow to reflect branch name --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41f019fb..7bb12cbd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: App build on: push: branches: - - "update-workflow-new-cert" + - "september-updates" defaults: run: From e80dce27964a3a650f403b7df49d94c46155c8ae Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 19 Sep 2023 17:16:25 -0500 Subject: [PATCH 11/15] remove commented out code --- electron/ui/src/views/Optimization/Optimization.js | 1 - 1 file changed, 1 deletion(-) diff --git a/electron/ui/src/views/Optimization/Optimization.js b/electron/ui/src/views/Optimization/Optimization.js index 0b73a548..5f225737 100644 --- a/electron/ui/src/views/Optimization/Optimization.js +++ b/electron/ui/src/views/Optimization/Optimization.js @@ -187,7 +187,6 @@ export default function Optimization(props) { > CBC (Free) Gurobi (Commercial) - {/* Gurobi Direct (Commercial) */} From f91b886705491484e86327d5137fc26a6fce6e73 Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Mon, 25 Sep 2023 13:05:26 -0500 Subject: [PATCH 12/15] update comparison table to include water quality/hydraulics values in results table --- electron/ui/src/assets/CategoryNames.json | 3 +- .../ComparisonTable/ComparisonTable.js | 54 +++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/electron/ui/src/assets/CategoryNames.json b/electron/ui/src/assets/CategoryNames.json index b53c9320..5c953836 100644 --- a/electron/ui/src/assets/CategoryNames.json +++ b/electron/ui/src/assets/CategoryNames.json @@ -102,7 +102,8 @@ "hydraulics.v_ValveHead_dict": "Hydraulics Valve Head", "hydraulics.v_PumpCost_dict": "Hydraulics Pump Cost", "hydraulics.v_Pressure_dict": "Hydraulics Pressure", - + "quality.v_X": "Water Quality", + "hydraulics.v_Z_HydrualicsCost": "Hydraulics Cost", "v_Z": "Objective", "v_R_TotalStorage": "Credit Total Storage", "reuse_WaterKPI": "Produced Water Recycle Rate", diff --git a/electron/ui/src/components/ComparisonTable/ComparisonTable.js b/electron/ui/src/components/ComparisonTable/ComparisonTable.js index 09e83839..0740cc43 100644 --- a/electron/ui/src/components/ComparisonTable/ComparisonTable.js +++ b/electron/ui/src/components/ComparisonTable/ComparisonTable.js @@ -27,20 +27,42 @@ export default function ComparisonTable(props) { setIndices([scenarioIndex, secondaryScenarioIndex]) }, [scenarioIndex, secondaryScenarioIndex]) + const getValue = (index) => { + try { + return scenarios[indices[1]].results.data[category][index+1][3].toLocaleString('en-US', {maximumFractionDigits:0}) + }catch(e) { + return "" + } + + } - const getPercentDifference = (value1, value2) => { - let result = ((value1 - value2) / value2) * 100 - if (isNaN(result)) return 0 - else if(value1 > value2) return "+" + (Math.round(result * 10) / 10) - else return Math.round(result * 10) / 10 + const getPercentDifference = (index) => { + try { + let value1 = scenarios[indices[0]].results.data[category][index+1][3] + let value2 = scenarios[indices[1]].results.data[category][index+1][3] + + let result = ((value1 - value2) / value2) * 100 + if (isNaN(result)) return 0 + else if(value1 > value2) return "+" + (Math.round(result * 10) / 10) + else return Math.round(result * 10) / 10 + } catch(e) { + return "" + } + } - const getDifferenceStyling = (value1, value2) => { - let style = {} - if (value1 > value2) style.color = "green" - else if (value2 > value1) style.color = "red" - return style + const getDifferenceStyling = (index) => { + try { + let value1 = scenarios[indices[0]].results.data[category][index+1][3] + let value2 = scenarios[indices[1]].results.data[category][index+1][3] + let style = {} + if (value1 > value2) style.color = "green" + else if (value2 > value1) style.color = "red" + return style + } catch (e) { + return {} + } } const renderOutputTable = () => { @@ -57,8 +79,7 @@ export default function ComparisonTable(props) { Units {scenarios[indices[0]].name} {scenarios[indices[1]].name} - Percent Difference - {/* {renderConfigurationSelect(1)} */} + Percent Difference @@ -74,6 +95,7 @@ export default function ComparisonTable(props) { cellValue.toLocaleString('en-US', {maximumFractionDigits:0}) : cellValue ? CategoryNames[cellValue] ? CategoryNames[cellValue] : cellValue.replace('v_F_','').replace('v_C_','Cost ').replace(/([A-Z])/g, ' $1').replace('Cap Ex', 'CapEx').trim() + // cellValue : null } @@ -83,15 +105,15 @@ export default function ComparisonTable(props) { align="right" style={styles.other} > - {scenarios[indices[1]].results.data[category][index+1][3].toLocaleString('en-US', {maximumFractionDigits:0})} + {getValue(index)} - + > + { - getPercentDifference(scenarios[indices[0]].results.data[category][index+1][3], scenarios[indices[1]].results.data[category][index+1][3]) + getPercentDifference(index) } % From c4ea5e708287cfe4dc909a296360bbc05a501356 Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Mon, 25 Sep 2023 16:50:55 -0500 Subject: [PATCH 13/15] try using toy case study for e2e tests --- electron/ui/cypress/e2e/ScenarioTests.cy.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/electron/ui/cypress/e2e/ScenarioTests.cy.js b/electron/ui/cypress/e2e/ScenarioTests.cy.js index d1532f91..2996e4c0 100644 --- a/electron/ui/cypress/e2e/ScenarioTests.cy.js +++ b/electron/ui/cypress/e2e/ScenarioTests.cy.js @@ -3,7 +3,8 @@ describe('scenario testing', () => { use sc_count for screenshot names to ensure they are saved in chronological order start with 10 because starting with 0 would stop working when it hits 10 */ - let strategic_small_case_study_url = "https://github.com/project-pareto/project-pareto/raw/main/pareto/case_studies/strategic_small_case_study.xlsx" + // let strategic_small_case_study_url = "https://github.com/project-pareto/project-pareto/raw/main/pareto/case_studies/strategic_small_case_study.xlsx" + let strategic_toy_case_study_url = "https://github.com/project-pareto/project-pareto/raw/main/pareto/case_studies/strategic_toy_case_study.xlsx" let sc_count = 10 it('test that scenario list loads properly', () => { //load webpage @@ -28,8 +29,8 @@ describe('scenario testing', () => { sc_count+=1 }) - it('download strategic small case study', () => { - cy.downloadFile(strategic_small_case_study_url,'cypress/downloads','strategic_small_case_study.xlsx') + it('download strategic toy case study', () => { + cy.downloadFile(strategic_toy_case_study_url,'cypress/downloads','strategic_toy_case_study.xlsx') }) it('creates a new scenario by uploading excel sheet', () => { @@ -59,7 +60,7 @@ describe('scenario testing', () => { cy.screenshot(`${sc_count}_clicked create new scenario`) sc_count+=1 cy.findByRole('textbox').type('cypress test') - cy.get('input[type=file]').selectFile('./cypress/downloads/strategic_small_case_study.xlsx', { + cy.get('input[type=file]').selectFile('./cypress/downloads/strategic_toy_case_study.xlsx', { action: 'drag-drop', force: true }) From 0ecf1b5560934cf1c6a83cb504159f86569e6abd Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 26 Sep 2023 12:28:02 -0500 Subject: [PATCH 14/15] screenshot optimization settings in e2e test --- electron/ui/cypress/e2e/ScenarioTests.cy.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/electron/ui/cypress/e2e/ScenarioTests.cy.js b/electron/ui/cypress/e2e/ScenarioTests.cy.js index 2996e4c0..ae69e0a2 100644 --- a/electron/ui/cypress/e2e/ScenarioTests.cy.js +++ b/electron/ui/cypress/e2e/ScenarioTests.cy.js @@ -161,6 +161,8 @@ describe('scenario testing', () => { //run optimization with default settings cy.findByRole('button', {name: /continue to optimization/i}).click() + cy.screenshot(`${sc_count}_optimization settings`) + sc_count+=1 // cy.findByRole('button', {name: /optimize/i}).click() cy.findAllByRole('button', {name: /optimize/i}).eq(0).click() From a9d4f4bed432303d7769343519a38783b15508eb Mon Sep 17 00:00:00 2001 From: MichaelPesce Date: Tue, 26 Sep 2023 12:32:25 -0500 Subject: [PATCH 15/15] update parameter list --- backend/app/internal/get_data.py | 137 ++++++++++-------- backend/app/internal/pareto_stategic_model.py | 2 +- 2 files changed, 74 insertions(+), 65 deletions(-) diff --git a/backend/app/internal/get_data.py b/backend/app/internal/get_data.py index f822c9c0..11835bf5 100644 --- a/backend/app/internal/get_data.py +++ b/backend/app/internal/get_data.py @@ -621,69 +621,78 @@ def get_input_lists(): ] parameter_list = [ - "Units", - "PNA", - "CNA", - "CCA", - "NNA", - "NCA", - "NKA", - "NRA", - "NSA", - "FCA", - "RCA", - "RNA", - "RSA", - "SCA", - "SNA", - "PCT", - "PKT", - "FCT", - "CST", - "CCT", - "CKT", - "Elevation", - "CompletionsPadOutsideSystem", - "DesalinationTechnologies", - "DesalinationSites", - "TruckingTime", - "CompletionsDemand", - "PadRates", - "FlowbackRates", - "WellPressure", - "NodeCapacities", - "InitialPipelineCapacity", - "InitialPipelineDiameters", - "InitialDisposalCapacity", - "InitialTreatmentCapacity", - "FreshwaterSourcingAvailability", - "PadOffloadingCapacity", - "CompletionsPadStorage", - "DisposalOperationalCost", - "TreatmentOperationalCost", - "ReuseOperationalCost", - "PipelineOperationalCost", - "FreshSourcingCost", - "TruckingHourlyCost", - "PipelineDiameterValues", - "DisposalCapacityIncrements", - "InitialStorageCapacity", - "StorageCapacityIncrements", - "TreatmentCapacityIncrements", - "TreatmentEfficiency", - "RemovalEfficiency", - "DisposalExpansionCost", - "StorageExpansionCost", - "TreatmentExpansionCost", - "PipelineCapexDistanceBased", - "PipelineCapexCapacityBased", - "PipelineCapacityIncrements", - "PipelineExpansionDistance", - "Hydraulics", - "Economics", - "PadWaterQuality", - "StorageInitialWaterQuality", - "PadStorageInitialWaterQuality", - "DisposalOperatingCapacity", + "Units", + "PNA", + "CNA", + "CCA", + "NNA", + "NCA", + "NKA", + "NRA", + "NSA", + "FCA", + "RCA", + "RNA", + "RSA", + "SCA", + "SNA", + "ROA", + "SOA", + "NOA", + "PCT", + "PKT", + "FCT", + "CST", + "CCT", + "CKT", + "RST", + "ROT", + "SOT", + "Elevation", + "CompletionsPadOutsideSystem", + "DesalinationTechnologies", + "DesalinationSites", + "BeneficialReuseCredit", + "TruckingTime", + "CompletionsDemand", + "PadRates", + "FlowbackRates", + "WellPressure", + "NodeCapacities", + "InitialPipelineCapacity", + "InitialPipelineDiameters", + "InitialDisposalCapacity", + "InitialTreatmentCapacity", + "ReuseMinimum", + "ReuseCapacity", + "FreshwaterSourcingAvailability", + "PadOffloadingCapacity", + "CompletionsPadStorage", + "DisposalOperationalCost", + "TreatmentOperationalCost", + "ReuseOperationalCost", + "PipelineOperationalCost", + "FreshSourcingCost", + "TruckingHourlyCost", + "PipelineDiameterValues", + "DisposalCapacityIncrements", + "InitialStorageCapacity", + "StorageCapacityIncrements", + "TreatmentCapacityIncrements", + "TreatmentEfficiency", + "RemovalEfficiency", + "DisposalExpansionCost", + "StorageExpansionCost", + "TreatmentExpansionCost", + "PipelineCapexDistanceBased", + "PipelineCapexCapacityBased", + "PipelineCapacityIncrements", + "PipelineExpansionDistance", + "Hydraulics", + "Economics", + "PadWaterQuality", + "StorageInitialWaterQuality", + "PadStorageInitialWaterQuality", + "DisposalOperatingCapacity", ] return [set_list, parameter_list] \ No newline at end of file diff --git a/backend/app/internal/pareto_stategic_model.py b/backend/app/internal/pareto_stategic_model.py index 42260341..5f9b7a0f 100644 --- a/backend/app/internal/pareto_stategic_model.py +++ b/backend/app/internal/pareto_stategic_model.py @@ -90,7 +90,7 @@ def run_strategic_model(input_file, output_file, id, modelParameters, overrideVa optimality_gap = int(modelParameters["optimalityGap"])/100 except: optimality_gap = 0 - _log.info(f'optimality gap is {optimality_gap}') + # _log.info(f'optimality gap is {optimality_gap}') options = { "deactivate_slacks": True, "scale_model": modelParameters["scale_model"],