diff --git a/src/geophires_x/GeoPHIRESUtils.py b/src/geophires_x/GeoPHIRESUtils.py index 618fe0486..762edbde1 100644 --- a/src/geophires_x/GeoPHIRESUtils.py +++ b/src/geophires_x/GeoPHIRESUtils.py @@ -554,7 +554,7 @@ def read_input_file(return_dict_1, logger=None, input_file_name=None): comment = comment + elements[i] # done with parsing, now create the object and add to the dictionary - p_entry = ParameterEntry(description, s_val, comment) + p_entry = ParameterEntry(description, s_val, comment, line) return_dict_1[description] = p_entry # make the dictionary element else: diff --git a/src/geophires_x/Parameter.py b/src/geophires_x/Parameter.py index ded67d612..5e6634c63 100644 --- a/src/geophires_x/Parameter.py +++ b/src/geophires_x/Parameter.py @@ -43,6 +43,7 @@ class ParameterEntry: Name: str sValue: str Comment: Optional[str] = None + raw_entry: Optional[str] = None @dataclass @@ -253,10 +254,10 @@ def ReadParameter(ParameterReadIn: ParameterEntry, ParamToModify, model): """ ReadParameter: A method to take a single ParameterEntry object and use it to update the associated Parameter. Does validation as well as Unit and Currency conversion - :param ParameterEntry: The value the user wants to change and the value they want to change it to (as a string) + :param ParameterReadIn: The value the user wants to change and the value they want to change it to (as a string) and any comment they provided with it (as a string) - all in one object (ParameterEntry) that is passed in to this method as a parameter itself (ParameterReadIn) - see ParameterEntry class for details on the fields in it - :type ParameterEntry: :class:`~geophires_x.Parameter.ParameterEntry` + :type ParameterReadIn: :class:`~geophires_x.Parameter.ParameterEntry` :param ParamToModify: The Parameter that will be modified (assuming it passes validation and conversion) - this is the object that will be modified by this method - see Parameter class for details on the fields in it :type ParamToModify: :class:`~geophires_x.Parameter.Parameter` @@ -293,9 +294,9 @@ def ReadParameter(ParameterReadIn: ParameterEntry, ParamToModify, model): def default_parameter_value_message(new_val: Any, param_to_modify_name: str, default_value: Any) -> str: return ( - f'Parameter given ({str(New_val)}) for {ParamToModify.Name} is the same as the default value. ' - f'Consider removing {ParamToModify.Name} from the input file unless you wish ' - f'to change it from the default value of ({str(ParamToModify.DefaultValue)})' + f'Parameter given ({str(new_val)}) for {param_to_modify_name} is the same as the default value. ' + f'Consider removing {param_to_modify_name} from the input file unless you wish ' + f'to change it from the default value of ({str(default_value)})' ) if isinstance(ParamToModify, intParameter): @@ -370,16 +371,23 @@ def default_parameter_value_message(new_val: Any, param_to_modify_name: str, def model.logger.warning(msg) model.logger.info(f'Complete {str(__name__)}: {sys._getframe().f_code.co_name}') return - # All is good. With a list, we have to use the last character of the Description to get the position. - # I.e., "Gradient 1" should yield a position = 0 ("1" - 1) else: - parts = ParameterReadIn.Name.split(' ') - position = int(parts[1]) - 1 - if position >= len(ParamToModify.value): - ParamToModify.value.append(New_val) # we are adding to the list, so use append - else: # we are replacing a value, so pop the value we want to replace, then insert a new one - ParamToModify.value.pop(position) - ParamToModify.value.insert(position, New_val) + if ' ' in ParamToModify.Name: + # Some list parameters are read in with enumerated parameter names; in these cases we use the last + # character of the description to get the position i.e., "Gradient 1" is position 0. + parts = ParameterReadIn.Name.split(' ') + position = int(parts[1]) - 1 + if position >= len(ParamToModify.value): + ParamToModify.value.append(New_val) # we are adding to the list, so use append + else: # we are replacing a value, so pop the value we want to replace, then insert a new one + ParamToModify.value.pop(position) + ParamToModify.value.insert(position, New_val) + else: + # In an ideal world this would be handled in ParameterEntry such that its sValue and Comment are + # correct; however that would only be practical if ParameterEntry had typing information to know + # whether to treat text after a second comma as a comment or list entry. + ParamToModify.value = [float(x.strip()) for x in ParameterReadIn.raw_entry.split('--')[0].split(',')[1:] + if x.strip() != ''] elif isinstance(ParamToModify, boolParameter): if ParameterReadIn.sValue == "0": New_val = False diff --git a/src/geophires_x/Reservoir.py b/src/geophires_x/Reservoir.py index bb1cca8b5..b41c79fd6 100644 --- a/src/geophires_x/Reservoir.py +++ b/src/geophires_x/Reservoir.py @@ -593,30 +593,15 @@ def read_parameters(self, model: Model) -> None: # fracshape = 4 Rectangular fracture ParameterToModify.value = FractureShape.RECTANGULAR - elif ParameterToModify.Name.startswith('Gradient'): + elif ParameterToModify.Name.startswith('Gradient '): parts = ParameterReadIn.Name.split(' ') position = int(parts[1]) - 1 model.reserv.gradient.value[position] = ParameterToModify.value - if model.reserv.gradient.value[position] > 1.0: - # TODO refactor to avoid heuristic-based unit conversions - model.reserv.gradient.value[position] = model.reserv.gradient.value[ - position] / 1000.0 # convert C/m - model.reserv.gradient.CurrentUnits = TemperatureGradientUnit.DEGREESCPERM - if model.reserv.gradient.value[position] < 1e-6: - # convert 0 C/m gradients to very small number, avoids divide by zero errors later - model.reserv.gradient.value[position] = 1e-6 - - elif ParameterToModify.Name.startswith('Thickness'): + elif ParameterToModify.Name.startswith('Thickness '): parts = ParameterReadIn.Name.split(' ') position = int(parts[1]) - 1 model.reserv.layerthickness.value[position] = ParameterToModify.value - if model.reserv.layerthickness.value[position] < 100.0: - model.reserv.layerthickness.value[position] = model.reserv.layerthickness.value[ - position] * 1000.0 # convert m - model.reserv.layerthickness.CurrentUnits = LengthUnit.METERS - # set thickness of bottom segment to large number to override lower, unused segments - model.reserv.layerthickness.value[position + 1] = 100_000.0 elif ParameterToModify.Name.startswith("Fracture Separation"): self.fracsepcalc.value = self.fracsep.value @@ -635,6 +620,31 @@ def read_parameters(self, model: Model) -> None: coerce_int_params_to_enum_values(self.ParameterDict) + for position in range(len(model.reserv.gradient.value)): + if model.reserv.gradient.value[position] > 1.0: + # TODO refactor to avoid heuristic-based unit conversions + model.reserv.gradient.value[position] = model.reserv.gradient.value[ + position] / 1000.0 # convert to C/m + model.reserv.gradient.CurrentUnits = TemperatureGradientUnit.DEGREESCPERM + + if model.reserv.gradient.value[position] < 1e-6: + # convert 0 C/m gradients to very small number, avoids divide by zero errors later + model.reserv.gradient.value[position] = 1e-6 + + for position in range(len(model.reserv.layerthickness.value)): + if model.reserv.layerthickness.value[position] < 100.0: + # TODO refactor to avoid heuristic-based unit conversions + model.reserv.layerthickness.value[position] = model.reserv.layerthickness.value[ + position] * 1000.0 # convert to m + model.reserv.layerthickness.CurrentUnits = LengthUnit.METERS + + # set thickness of bottom segment to large number to override lower, unused segments + while len(model.reserv.layerthickness.value) < model.reserv.numseg.value: + model.reserv.layerthickness.value.append(100_000.0) + + model.reserv.layerthickness.value[model.reserv.numseg.value-1] = 100_000.0 + + model.logger.info(f'complete {str(__class__)}: {sys._getframe().f_code.co_name}') @lru_cache(maxsize=1024) diff --git a/src/geophires_x/SBTReservoir.py b/src/geophires_x/SBTReservoir.py index 9f42b1cc9..2dcdedde6 100644 --- a/src/geophires_x/SBTReservoir.py +++ b/src/geophires_x/SBTReservoir.py @@ -5,6 +5,7 @@ import pandas as pd from scipy.special import erf, erfc, jv, yv, exp1 from scipy.interpolate import interp1d +import scipy.io as sio import matplotlib.pyplot as plt import geophires_x.Model as Model @@ -451,7 +452,7 @@ def Calculate_Coaxial(self, model): g = 9.81 # Gravitational acceleration [m/s²] gamma = 0.577215665 # Euler's constant alpha_m = self.krock.value / (self.rhorock.value * self.cprock.value) # Rock thermal diffusivity [m²/s] - alpha_m_boiler = self.krock.value_boiler / (self.rhorock.value * self.cprock.value) # Boiler rock thermal diffusivity [m²/s] + alpha_m_boiler = self.krock.value / (self.rhorock.value * self.cprock.value) # Boiler rock thermal diffusivity [m²/s] outerradiuscenterpipe = radiuscenterpipe + thicknesscenterpipe # Outer radius of inner pipe [m] A_flow_annulus = np.pi * (radius ** 2 - outerradiuscenterpipe ** 2) # Flow area of annulus pipe [m²] diff --git a/tests/examples/example_multiple_gradients-2.out b/tests/examples/example_multiple_gradients-2.out new file mode 100644 index 000000000..f73cb7dec --- /dev/null +++ b/tests/examples/example_multiple_gradients-2.out @@ -0,0 +1,253 @@ + ***************** + ***CASE REPORT*** + ***************** + +Simulation Metadata +---------------------- + GEOPHIRES Version: 3.4.34 + Simulation Date: 2024-06-19 + Simulation Time: 07:44 + Calculation Time: 0.596 sec + + ***SUMMARY OF RESULTS*** + + End-Use Option: Electricity + Average Net Electricity Production: 8.00 MW + Electricity breakeven price: 9.15 cents/kWh + Number of production wells: 2 + Number of injection wells: 2 + Flowrate per production well: 60.0 kg/sec + Well depth (or total length, if not vertical): 4.0 kilometer + Segment 1 Geothermal gradient: 50 degC/km + Segment 1 Thickness: 1 kilometer + Segment 2 Geothermal gradient: 40 degC/km + Segment 2 Thickness: 1 kilometer + Segment 3 Geothermal gradient: 30 degC/km + Segment 3 Thickness: 1 kilometer + Segment 4 Geothermal gradient: 50 degC/km + + + ***ECONOMIC PARAMETERS*** + + Economic Model = Fixed Charge Rate (FCR) + Fixed Charge Rate (FCR): 5.00 + Accrued financing during construction: 0.00 + Project lifetime: 30 yr + Capacity factor: 90.0 % + Project NPV: -54.68 MUSD + Project IRR: -3.25 % + Project VIR=PI=PIR: 0.28 + Project MOIC: -0.23 + Project Payback Period: N/A + Estimated Jobs Created: 17 + + ***ENGINEERING PARAMETERS*** + + Number of Production Wells: 2 + Number of Injection Wells: 2 + Well depth (or total length, if not vertical): 4.0 kilometer + Water loss rate: 2.0 + Pump efficiency: 80.0 + Injection temperature: 50.0 degC + User-provided production well temperature drop + Constant production well temperature drop: 2.0 degC + Flowrate per production well: 60.0 kg/sec + Injection well casing ID: 7.000 in + Production well casing ID: 7.000 in + Number of times redrilling: 0 + Power plant type: Supercritical ORC + + + ***RESOURCE CHARACTERISTICS*** + + Maximum reservoir temperature: 400.0 degC + Number of segments: 4 + Segment 1 Geothermal gradient: 50 degC/km + Segment 1 Thickness: 1 kilometer + Segment 2 Geothermal gradient: 40 degC/km + Segment 2 Thickness: 1 kilometer + Segment 3 Geothermal gradient: 30 degC/km + Segment 3 Thickness: 1 kilometer + Segment 4 Geothermal gradient: 50 degC/km + + + ***RESERVOIR PARAMETERS*** + + Reservoir Model = Multiple Parallel Fractures Model + Bottom-hole temperature: 190.00 degC + Fracture model = Square + Well separation: fracture height: 600.00 meter + Fracture area: 360000.00 m**2 + Reservoir volume: 1000000000 m**3 + Reservoir hydrostatic pressure: 38390.69 kPa + Plant outlet pressure: 1530.99 kPa + Production wellhead pressure: 1599.94 kPa + Productivity Index: 5.00 kg/sec/bar + Injectivity Index: 5.00 kg/sec/bar + Reservoir density: 2700.00 kg/m**3 + Reservoir thermal conductivity: 2.70 W/m/K + Reservoir heat capacity: 1000.00 J/kg/K + + + ***RESERVOIR SIMULATION RESULTS*** + + Maximum Production Temperature: 188.0 degC + Average Production Temperature: 185.1 degC + Minimum Production Temperature: 177.8 degC + Initial Production Temperature: 188.0 degC + Average Reservoir Heat Extraction: 67.23 MW + Wellbore Heat Transmission Model = Constant Temperature Drop: 2.0 degC + Average Injection Well Pump Pressure Drop: -122.6 kPa + Average Production Well Pump Pressure Drop: 1138.5 kPa + + + ***CAPITAL COSTS (M$)*** + + Drilling and completion costs: 33.28 MUSD + Drilling and completion costs per well: 8.32 MUSD + Stimulation costs: 3.02 MUSD + Surface power plant costs: 30.27 MUSD + Field gathering system costs: 2.26 MUSD + Total surface equipment costs: 32.53 MUSD + Exploration costs: 7.41 MUSD + Total capital costs: 76.24 MUSD + Annualized capital costs: 3.81 MUSD + + + ***OPERATING AND MAINTENANCE COSTS (M$/yr)*** + + Wellfield maintenance costs: 0.62 MUSD/yr + Power plant maintenance costs: 1.25 MUSD/yr + Water costs: 0.06 MUSD/yr + Total operating and maintenance costs: 1.93 MUSD/yr + + + ***SURFACE EQUIPMENT SIMULATION RESULTS*** + + Initial geofluid availability: 0.15 MW/(kg/s) + Maximum Total Electricity Generation: 8.54 MW + Average Total Electricity Generation: 8.19 MW + Minimum Total Electricity Generation: 7.32 MW + Initial Total Electricity Generation: 8.54 MW + Maximum Net Electricity Generation: 8.37 MW + Average Net Electricity Generation: 8.00 MW + Minimum Net Electricity Generation: 7.09 MW + Initial Net Electricity Generation: 8.37 MW + Average Annual Total Electricity Generation: 64.20 GWh + Average Annual Net Electricity Generation: 62.72 GWh + Initial pumping power/net installed power: 2.05 % + Average Pumping Power: 0.19 MW + + ************************************************************ + * HEATING, COOLING AND/OR ELECTRICITY PRODUCTION PROFILE * + ************************************************************ + YEAR THERMAL GEOFLUID PUMP NET FIRST LAW + DRAWDOWN TEMPERATURE POWER POWER EFFICIENCY + (degC) (MW) (MW) (%) + 1 1.0000 188.00 0.1715 8.3701 12.1869 + 2 1.0000 188.00 0.1715 8.3701 12.1869 + 3 1.0000 188.00 0.1715 8.3701 12.1869 + 4 1.0000 188.00 0.1715 8.3701 12.1869 + 5 1.0000 188.00 0.1715 8.3701 12.1868 + 6 1.0000 188.00 0.1715 8.3699 12.1867 + 7 1.0000 187.99 0.1716 8.3690 12.1860 + 8 0.9998 187.97 0.1717 8.3663 12.1839 + 9 0.9996 187.93 0.1720 8.3606 12.1795 + 10 0.9992 187.85 0.1724 8.3506 12.1717 + 11 0.9986 187.73 0.1731 8.3352 12.1597 + 12 0.9977 187.57 0.1741 8.3138 12.1431 + 13 0.9966 187.35 0.1754 8.2861 12.1214 + 14 0.9951 187.09 0.1770 8.2519 12.0947 + 15 0.9935 186.77 0.1789 8.2115 12.0630 + 16 0.9916 186.42 0.1811 8.1652 12.0265 + 17 0.9894 186.01 0.1835 8.1134 11.9856 + 18 0.9871 185.57 0.1862 8.0565 11.9405 + 19 0.9845 185.09 0.1890 7.9952 11.8916 + 20 0.9818 184.58 0.1921 7.9299 11.8393 + 21 0.9789 184.04 0.1953 7.8612 11.7839 + 22 0.9759 183.48 0.1986 7.7895 11.7258 + 23 0.9728 182.89 0.2021 7.7153 11.6653 + 24 0.9696 182.29 0.2056 7.6390 11.6027 + 25 0.9663 181.66 0.2093 7.5609 11.5383 + 26 0.9629 181.03 0.2130 7.4815 11.4723 + 27 0.9595 180.39 0.2167 7.4010 11.4050 + 28 0.9560 179.73 0.2205 7.3197 11.3366 + 29 0.9525 179.07 0.2243 7.2379 11.2673 + 30 0.9490 178.41 0.2282 7.1557 11.1971 + + + ******************************************************************* + * ANNUAL HEATING, COOLING AND/OR ELECTRICITY PRODUCTION PROFILE * + ******************************************************************* + YEAR ELECTRICITY HEAT RESERVOIR PERCENTAGE OF + PROVIDED EXTRACTED HEAT CONTENT TOTAL HEAT MINED + (GWh/year) (GWh/year) (10^15 J) (%) + 1 66.0 541.5 376.05 0.52 + 2 66.0 541.5 374.10 1.03 + 3 66.0 541.5 372.15 1.55 + 4 66.0 541.5 370.20 2.06 + 5 66.0 541.5 368.25 2.58 + 6 66.0 541.5 366.30 3.09 + 7 66.0 541.4 364.35 3.61 + 8 65.9 541.3 362.41 4.13 + 9 65.9 541.1 360.46 4.64 + 10 65.8 540.7 358.51 5.16 + 11 65.6 540.1 356.57 5.67 + 12 65.4 539.4 354.63 6.18 + 13 65.2 538.4 352.69 6.70 + 14 64.9 537.3 350.75 7.21 + 15 64.6 536.0 348.82 7.72 + 16 64.2 534.5 346.90 8.23 + 17 63.7 532.8 344.98 8.74 + 18 63.3 531.0 343.07 9.24 + 19 62.8 529.1 341.16 9.74 + 20 62.3 527.0 339.27 10.25 + 21 61.7 524.9 337.38 10.75 + 22 61.1 522.6 335.50 11.24 + 23 60.5 520.3 333.62 11.74 + 24 59.9 517.9 331.76 12.23 + 25 59.3 515.4 329.90 12.72 + 26 58.7 512.9 328.06 13.21 + 27 58.0 510.3 326.22 13.70 + 28 57.4 507.8 324.39 14.18 + 29 56.7 505.1 322.57 14.66 + 30 46.8 419.0 321.07 15.06 + + + ******************************** + * REVENUE & CASHFLOW PROFILE * + ******************************** +Year Electricity | Heat | Cooling | Carbon | Project +Since Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | OPEX Net Rev. Net Cashflow +Start (cents/kWh)(MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(USD/tonne) (MUSD/yr) (MUSD) |(MUSD/yr) (MUSD/yr) (MUSD) +________________________________________________________________________________________________________________________________________________________________________________________ + 1 0.00 -76.24 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -76.24 -76.24 + 2 5.50 1.70 3.63 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -74.54 + 3 5.50 1.70 7.26 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -72.84 + 4 5.50 1.70 10.89 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -71.14 + 5 5.50 1.70 14.52 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -69.44 + 6 5.50 1.70 18.15 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -67.74 + 7 5.50 1.70 21.78 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -66.04 + 8 5.50 1.70 25.40 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -64.33 + 9 5.50 1.70 29.03 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -62.64 + 10 5.50 1.70 32.65 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.70 -60.94 + 11 5.50 1.69 36.27 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.69 -59.25 + 12 5.50 1.68 39.88 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.68 -57.57 + 13 5.50 1.67 43.48 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.67 -55.90 + 14 5.50 1.66 47.07 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.66 -54.24 + 15 5.50 1.64 50.64 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.64 -52.60 + 16 5.50 1.62 54.19 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.62 -50.97 + 17 5.50 1.60 57.72 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.60 -49.37 + 18 5.50 1.58 61.22 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.58 -47.79 + 19 5.50 1.55 64.70 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.55 -46.24 + 20 5.50 1.53 68.16 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.53 -44.72 + 21 5.50 1.50 71.58 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.50 -43.22 + 22 5.50 1.47 74.97 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.47 -41.75 + 23 5.50 1.43 78.34 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.43 -40.32 + 24 5.50 1.40 81.66 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.40 -38.92 + 25 5.50 1.37 84.96 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.37 -37.55 + 26 5.50 1.33 88.22 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.33 -36.22 + 27 5.50 1.30 91.45 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.30 -34.92 + 28 5.50 1.26 94.64 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.26 -33.66 + 29 5.50 1.23 97.80 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.23 -32.43 + 30 5.50 1.19 100.92 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 1.93 1.19 -31.23 diff --git a/tests/examples/example_multiple_gradients-2.txt b/tests/examples/example_multiple_gradients-2.txt new file mode 100644 index 000000000..2ab0d45d1 --- /dev/null +++ b/tests/examples/example_multiple_gradients-2.txt @@ -0,0 +1,67 @@ +# Example: Multiple Gradients 2: Equivalent to Multiple Gradients example except with list-style Gradients & Thicknesses parameters. + + +***Subsurface technical parameters*** +************************************* +Reservoir Model,1, ---Multiple Fractures reservoir model +Reservoir Depth,4, ---[km] +Number of Segments,4, ---[-] +Gradients, 50, 40, 30, 50 +Thicknesses, 1, 1, 1, -- equal thicknesses +Maximum Temperature,400, ---[deg.C] +Number of Production Wells,2, ---[-] +Number of Injection Wells,2, ---[-] +Production Well Diameter,7, ---[inch] +Injection Well Diameter,7, ---[inch] +Ramey Production Wellbore Model,0, ---0 if disabled 1 if enabled +Production Wellbore Temperature Drop,2, ---[deg.C] +Injection Wellbore Temperature Gain,0, ---[deg.C] +Production Flow Rate per Well,60, ---[kg/s] +Fracture Shape,3, ---[-] Should be 1 2 3 or 4. See manual for details +Fracture Height,600, ---[m] +Reservoir Volume Option,3, ---[-] Should be 1 2 3 or 4. See manual for details +Number of Fractures,20, ---[-] +Reservoir Volume,1000000000, ---[m^3] +Water Loss Fraction,.02, ---[-] +Productivity Index,5, ---[kg/s/bar] +Injectivity Index,5, ---[kg/s/bar] +Injection Temperature,50, ---[deg.C] +Maximum Drawdown,1, ---[-] no redrilling considered +Reservoir Heat Capacity,1000, ---[J/kg/K] +Reservoir Density,2700, ---[kg/m^3] +Reservoir Thermal Conductivity,2.7, ---[W/m/K] + +***SURFACE TECHNICAL PARAMETERS*** +********************************** +End-Use Option,1, ---[-] Electricity +Power Plant Type,2, ---[-] Supercritcal ORC +Circulation Pump Efficiency,.8, ---[-] between .1 and 1 +Utilization Factor,.9, ---[-] between .1 and 1 +Surface Temperature,20, ---[deg.C] +Ambient Temperature,20, ---[deg.C] + +***FINANCIAL PARAMETERS*** +************************** +Plant Lifetime,30, ---[years] +Economic Model,1, ---[-] Fixed Charge Rate Model +Fixed Charge Rate,.05, ---[-] between 0 and 1 +Inflation Rate During Construction,0, ---[-] + +***CAPITAL AND O&M COST PARAMETERS*** +************************************* +Well Drilling and Completion Capital Cost Adjustment Factor,1, ---[-] Use built-in correlations +Well Drilling Cost Correlation,1, ---[-] Use built-in correlations +Reservoir Stimulation Capital Cost Adjustment Factor,1, ---[-] Use built-in correlations +Surface Plant Capital Cost Adjustment Factor,1, ---[-] Use built-in correlations +Field Gathering System Capital Cost Adjustment Factor,1, ---[-] Use built-in correlations +Exploration Capital Cost Adjustment Factor,1, ---[-] Use built-in correlations +Wellfield O&M Cost Adjustment Factor,1, ---[-] Use built-in correlations +Surface Plant O&M Cost Adjustment Factor,1, ---[-] Use built-in correlations +Water Cost Adjustment Factor,1, ---[-] Use built-in correlations + + +***Simulation Parameters*** +*************************** + +Print Output to Console,1, ---[-] Should be 0 (don't print results) or 1 (print results) +Time steps per year,6, ---[1/year] diff --git a/tests/geophires_x_client_tests/input_comments.txt b/tests/geophires_x_client_tests/input_comments.txt index ba3559c7d..1bcf49f64 100644 --- a/tests/geophires_x_client_tests/input_comments.txt +++ b/tests/geophires_x_client_tests/input_comments.txt @@ -7,6 +7,8 @@ Gradient 1, 69 Reservoir Depth, 5, -- comment here End-Use Option, 1, # another comment Power Plant Type, 4, comments galore +Gradients, 10, 20, 30, 40, -- gradiance +Thicknesses, 3,2, 1 # another, comment, with, commas, down here # comment with space diff --git a/tests/test_geophires_utils.py b/tests/test_geophires_utils.py index b9f8c0c1c..f3b3b1c1d 100644 --- a/tests/test_geophires_utils.py +++ b/tests/test_geophires_utils.py @@ -538,10 +538,36 @@ def test_input_comments(self): self.assertDictEqual( d, { - 'Gradient 1': ParameterEntry(Name='Gradient 1', sValue='69', Comment=''), - 'Reservoir Depth': ParameterEntry(Name='Reservoir Depth', sValue='5', Comment='-- comment here'), - 'End-Use Option': ParameterEntry(Name='End-Use Option', sValue='1', Comment='# another comment'), - 'Power Plant Type': ParameterEntry(Name='Power Plant Type', sValue='4', Comment='comments galore'), + 'Gradient 1': ParameterEntry(Name='Gradient 1', sValue='69', Comment='', raw_entry='Gradient 1, 69'), + 'Reservoir Depth': ParameterEntry( + Name='Reservoir Depth', + sValue='5', + Comment='-- comment here', + raw_entry='Reservoir Depth, 5, -- comment here', + ), + 'End-Use Option': ParameterEntry( + Name='End-Use Option', + sValue='1', + Comment='# another comment', + raw_entry='End-Use Option, 1, # another comment', + ), + 'Power Plant Type': ParameterEntry( + Name='Power Plant Type', + sValue='4', + Comment='comments galore', + raw_entry='Power Plant Type, 4, comments galore', + ), + # Note sValue and Comment are, obviously, inaccurate for list-type parameters - this is handled in + # geophires_x.Parameter.ReadParameter where raw_entry value is parsed instead. + 'Gradients': ParameterEntry( + Name='Gradients', + sValue='10', + Comment=' 20 30 40 -- gradiance', + raw_entry='Gradients, 10, 20, 30, 40, -- gradiance', + ), + 'Thicknesses': ParameterEntry( + Name='Thicknesses', sValue='3', Comment='2 1', raw_entry='Thicknesses, 3,2, 1' + ), }, )