diff --git a/.gitignore b/.gitignore index 51095ee9..78f3fa8f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ requirements.txt .DS_Store *.lock *.json +all_messages_conf.log # C extensions *.so @@ -81,6 +82,8 @@ docs/reference/geophires-request.json docs/reference/parameters.rst docs/geophires-request.json docs/parameters.rst +docs/hip-ra-x-request.json +docs/hip_ra_x_parameters.rst _site/ /docs/geophires_x.rstx /docs/temperature.txt diff --git a/README.rst b/README.rst index d4ea51bf..10bfa656 100644 --- a/README.rst +++ b/README.rst @@ -349,6 +349,14 @@ Extending GEOPHIRES-X - `Extension example: SUTRA `__ + +HIP-RA: Heat in Place - Resource Assessment +------------------------------------------- + +* `HIP-RA-X README `__ +* `HIP-RA-X Parameters Reference `__ +.. TODO switch over to https://nrel.github.io/GEOPHIRES-X/hip_ra_x_parameters.html once merged + Monte Carlo ----------- diff --git a/docs/index.rst b/docs/index.rst index 157002af..a48bbd68 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,6 +8,7 @@ Contents overview parameters How-to-extend-GEOPHIRES-X + hip_ra_x_parameters Monte-Carlo-User-Guide .. reference/index diff --git a/src/geophires_x_schema_generator/.gitignore b/src/geophires_x_schema_generator/.gitignore index c30948cb..a1de5eca 100644 --- a/src/geophires_x_schema_generator/.gitignore +++ b/src/geophires_x_schema_generator/.gitignore @@ -1 +1,4 @@ -parameters.rst +*parameters.rst +all_messages_conf.log +!geophires-request.json +!hip-ra-x-request.json diff --git a/src/geophires_x_schema_generator/__init__.py b/src/geophires_x_schema_generator/__init__.py index c0868395..59293508 100644 --- a/src/geophires_x_schema_generator/__init__.py +++ b/src/geophires_x_schema_generator/__init__.py @@ -24,6 +24,7 @@ from geophires_x.SUTRAReservoir import SUTRAReservoir from geophires_x.SUTRAWellBores import SUTRAWellBores from geophires_x.TDPReservoir import TDPReservoir +from hip_ra_x.hip_ra_x import HIP_RA_X class GeophiresXSchemaGenerator: @@ -41,17 +42,9 @@ def _get_dummy_model(self): sys.argv = stash_sys_argv os.chdir(stash_cwd) - def get_parameters_json(self) -> Tuple[str, str]: + def get_parameter_sources(self) -> list[Tuple[Any, str]]: dummy_model = self._get_dummy_model() - - def with_category(param_dict: dict, category: str): - def _with_cat(p: Parameter, cat: str): - p.parameter_category = cat - return p - - return {k: _with_cat(v, category) for k, v in param_dict.items()} - - parameter_sources = [ + return [ (dummy_model.reserv, 'Reservoir'), (TDPReservoir(dummy_model), 'Reservoir'), (LHSReservoir(dummy_model), 'Reservoir'), @@ -72,6 +65,19 @@ def _with_cat(p: Parameter, cat: str): (EconomicsAddOns(dummy_model), 'Economics'), ] + def get_schema_title(self) -> str: + return 'GEOPHIRES-X' + + def get_parameters_json(self) -> Tuple[str, str]: + + def with_category(param_dict: dict, category: str): + def _with_cat(p: Parameter, cat: str): + p.parameter_category = cat + return p + + return {k: _with_cat(v, category) for k, v in param_dict.items()} + + parameter_sources = self.get_parameter_sources() output_params = {} input_params = {} for param_source in parameter_sources: @@ -112,7 +118,7 @@ def generate_json_schema(self) -> dict: 'definitions': {}, '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'object', - 'title': 'GEOPHIRES Schema', + 'title': f'{self.get_schema_title()} Schema', 'required': required, 'properties': properties, } @@ -132,10 +138,11 @@ def generate_parameters_reference_rst(self) -> str: input_params_by_category[category][input_param_name] = input_param def get_input_params_table(category_params, category_name) -> str: + category_display = category_name if category_name is not None else '' input_rst = f""" -{category_name} -{'-' * len(category_name)} - .. list-table:: {category_name} Parameters +{category_display} +{'-' * len(category_display)} + .. list-table:: {category_display}{' ' if len(category_display) > 0 else ''}Parameters :header-rows: 1 * - Name @@ -170,7 +177,7 @@ def get_input_params_table(category_params, category_name) -> str: output_rst = self.get_output_params_table_rst(output_params_json) - rst = f"""Parameters + rst = f"""{self.get_schema_title()} Parameters ========== .. contents:: @@ -230,3 +237,12 @@ def _get_min_and_max(param: dict, default_val='') -> Tuple: max_val = max(param['AllowableRange']) return (min_val, max_val) + + +class HipRaXSchemaGenerator(GeophiresXSchemaGenerator): + def get_parameter_sources(self) -> list[Tuple[Any, str]]: + dummy_model = HIP_RA_X() + return [(dummy_model, None)] + + def get_schema_title(self) -> str: + return 'HIP-RA-X' diff --git a/src/geophires_x_schema_generator/geophires-request.json b/src/geophires_x_schema_generator/geophires-request.json index de1ff81f..107a043e 100644 --- a/src/geophires_x_schema_generator/geophires-request.json +++ b/src/geophires_x_schema_generator/geophires-request.json @@ -2,7 +2,7 @@ "definitions": {}, "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", - "title": "GEOPHIRES Schema", + "title": "GEOPHIRES-X Schema", "required": [ "Reservoir Model", "Reservoir Depth", @@ -1103,7 +1103,7 @@ "maximum": 200.0 }, "Economic Model": { - "description": "Specify the economic model to calculate the levelized cost of energy.1: Fixed Charge Rate (FCR); 2: Standard Levelized Cost; 3: BICYCLE; 4: Simple (CLGS)", + "description": "Specify the economic model to calculate the levelized cost of energy. 1: Fixed Charge Rate (FCR); 2: Standard Levelized Cost; 3: BICYCLE; 4: Simple (CLGS)", "type": "integer", "units": null, "category": "Economics", @@ -1824,7 +1824,7 @@ "maximum": 50000 }, "CO2 produced by Natural Gas": { - "description": "CO2 intensity of buring natural gas (how much CO2 is produced per kWh of heat produced (0.407855 lbs/kWh))", + "description": "CO2 intensity of burning natural gas (how much CO2 is produced per kWh of heat produced (0.070324961 lbs/kWh; https://www.epa.gov/energy/greenhouse-gases-equivalencies-calculator-calculations-and-references))", "type": "number", "units": "lbs/kWh", "category": "Economics", diff --git a/src/geophires_x_schema_generator/hip-ra-x-request.json b/src/geophires_x_schema_generator/hip-ra-x-request.json new file mode 100644 index 00000000..a22da93d --- /dev/null +++ b/src/geophires_x_schema_generator/hip-ra-x-request.json @@ -0,0 +1,173 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "title": "HIP-RA-X Schema", + "required": [ + "Reservoir Temperature", + "Rejection Temperature", + "Reservoir Porosity", + "Reservoir Area", + "Reservoir Thickness", + "Reservoir Life Cycle", + "Rock Heat Capacity", + "Fluid Specific Heat Capacity", + "Density Of Reservoir Fluid", + "Density Of Reservoir Rock" + ], + "properties": { + "Reservoir Temperature": { + "description": "Reservoir Temperature [150 degC]", + "type": "number", + "units": "degC", + "category": null, + "default": 0.0, + "minimum": 50, + "maximum": 1000 + }, + "Rejection Temperature": { + "description": "Rejection Temperature [25 degC]", + "type": "number", + "units": "degC", + "category": null, + "default": 0.0, + "minimum": 0.1, + "maximum": 200 + }, + "Reservoir Porosity": { + "description": "Reservoir Porosity [18%]", + "type": "number", + "units": "%", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 100.0 + }, + "Reservoir Area": { + "description": "Reservoir Area [81 km2]", + "type": "number", + "units": "km**2", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 10000.0 + }, + "Reservoir Thickness": { + "description": "Reservoir Thickness [0.286 km]", + "type": "number", + "units": "kilometer", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 10000.0 + }, + "Reservoir Life Cycle": { + "description": "Reservoir Life Cycle [30 years]", + "type": "integer", + "units": "yr", + "category": null, + "default": null, + "minimum": 1, + "maximum": 100 + }, + "Rock Heat Capacity": { + "description": "Rock Heat Capacity [2.84E+12 kJ/km3C]", + "type": "number", + "units": "kJ/km**3C", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 100000000000000.0 + }, + "Fluid Specific Heat Capacity": { + "description": "Specific Heat Capacity Of Water [4.18 kJ/kgC]", + "type": "number", + "units": "kJ/kgC", + "category": null, + "default": 0.0, + "minimum": 3.0, + "maximum": 10.0 + }, + "Density Of Reservoir Fluid": { + "description": "Density Of Water [1.0E+12 kg/km3]", + "type": "number", + "units": "kg/km**3", + "category": null, + "default": 0.0, + "minimum": 100000000000.0, + "maximum": 10000000000000.0 + }, + "Density Of Reservoir Rock": { + "description": "Density Of Rock [2.55E+12 kg/km3]", + "type": "number", + "units": "kg/km**3", + "category": null, + "default": 0.0, + "minimum": 100000000000.0, + "maximum": 10000000000000.0 + }, + "Rock Recoverable Heat": { + "description": "percent of heat that is recoverable from the rock in the reservoir 0.66 for high-T reservoirs, 0.43 for low-T reservoirs (Garg and Combs (2011)", + "type": "number", + "units": "", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 1.0 + }, + "Fluid Recoverable Heat": { + "description": "percent of heat that is recoverable from the fluid in the reservoir 0.66 for high-T reservoirs, 0.43 for low-T reservoirs (Garg and Combs (2011)", + "type": "number", + "units": "", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 1.0 + }, + "Recoverable Fluid Factor": { + "description": "percent of fluid that is recoverable from the reservoir (0.5 = 50%)", + "type": "number", + "units": "", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 1.0 + }, + "Reservoir Depth": { + "description": "depth to top of reservoir (km). Calculated based on an assumed gradient and the reservoir temperature if no value given", + "type": "number", + "units": "kilometer", + "category": null, + "default": 0.0, + "minimum": 0.001, + "maximum": 15.0 + }, + "Reservoir Pressure": { + "description": "pressure of the of reservoir (in mPa). Calculated assuming hydrostatic pressure and reservoir depth & water density if no value given", + "type": "number", + "units": "mPa", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 10000.0 + }, + "Recoverable Heat from Rock": { + "description": "percent of fluid that is recoverable from the reservoir (0.75 = 75%)", + "type": "number", + "units": "", + "category": null, + "default": 0.0, + "minimum": 0.0, + "maximum": 1.0 + }, + "HTML Output File": { + "description": "Provide a HTML output name if you want to have HTML output (no output if not provided)", + "type": "string", + "units": null, + "category": null, + "default": null, + "minimum": null, + "maximum": null + } + } +} diff --git a/src/geophires_x_schema_generator/main.py b/src/geophires_x_schema_generator/main.py index d02b039f..7dfeea9a 100644 --- a/src/geophires_x_schema_generator/main.py +++ b/src/geophires_x_schema_generator/main.py @@ -3,6 +3,7 @@ from pathlib import Path from geophires_x_schema_generator import GeophiresXSchemaGenerator +from geophires_x_schema_generator import HipRaXSchemaGenerator if __name__ == '__main__': parser = argparse.ArgumentParser() @@ -20,18 +21,20 @@ build_dir.mkdir(exist_ok=True) - build_path = Path(build_dir, 'geophires-request.json') + def build(json_file_name: str, generator: GeophiresXSchemaGenerator, rst_file_name: str): + build_path = Path(build_dir, json_file_name) + schema_json = generator.generate_json_schema() - generator = GeophiresXSchemaGenerator() + with open(build_path, 'w') as f: + f.write(json.dumps(schema_json, indent=2)) + print(f'Wrote JSON schema file to {build_path}.') - schema_json = generator.generate_json_schema() + rst = generator.generate_parameters_reference_rst() - with open(build_path, 'w') as f: - f.write(json.dumps(schema_json, indent=2)) - print(f'Wrote schema file to {build_path}.') + build_path_rst = Path(build_dir, rst_file_name) + with open(build_path_rst, 'w') as f: + f.write(rst) + print(f'Wrote RST file to {build_path_rst}.') - rst = generator.generate_parameters_reference_rst() - - build_path_rst = Path(build_dir, 'parameters.rst') - with open(build_path_rst, 'w') as f: - f.write(rst) + build('geophires-request.json', GeophiresXSchemaGenerator(), 'parameters.rst') + build('hip-ra-x-request.json', HipRaXSchemaGenerator(), 'hip_ra_x_parameters.rst') diff --git a/src/hip_ra_x/README.md b/src/hip_ra_x/README.md index 588b5414..b160f269 100644 --- a/src/hip_ra_x/README.md +++ b/src/hip_ra_x/README.md @@ -1,3 +1,13 @@ -# HIP-RA-X +# HIP-RA: Heat In Place - Resource Assessment + +See: +1. [Heat in Place calculation: Muffler, P., and Raffaele Cataldi. "Methods for regional assessment of geothermal resources." Geothermics 7.2-4 (1978): 53-89.](https://github.com/NREL/GEOPHIRES-X/blob/95e21226faee12128b9ad5d5b12bbd662d02949b/References/Muffler-Cataldi_1978_%20HIP-RA.pdf) +1. [Garg, S.K. and J. Combs. 2011. A Reexamination of the USGS Volumetric "Heat in Place" Method. Stanford University, 36th Workshop on Geothermal Reservoir Engineering; SGP-TR-191, 5 pp.](https://github.com/NREL/GEOPHIRES-X/blob/95e21226faee12128b9ad5d5b12bbd662d02949b/References/Garg-Combs_2011_HIP-RA-Reexamination.pdf) + +## HIP-RA-X HIP-RA-X is the successor version to HIP-RA. + +## Parameters + +[Parameters Reference](https://softwareengineerprogrammer.github.io/GEOPHIRES-X/hip_ra_x_parameters.html) diff --git a/src/hip_ra_x/hip_ra_x.py b/src/hip_ra_x/hip_ra_x.py index 810b9f5b..fc40c02c 100644 --- a/src/hip_ra_x/hip_ra_x.py +++ b/src/hip_ra_x/hip_ra_x.py @@ -119,8 +119,8 @@ def parameter_dict_entry(param: Parameter) -> Parameter: PreferredUnits=TemperatureUnit.CELSIUS, CurrentUnits=TemperatureUnit.CELSIUS, Required=True, - ErrMessage='assume default reservoir temperature (150 deg-C)', - ToolTipText='Reservoir Temperature [150 dec-C]', + ErrMessage='assume default reservoir temperature (150 degC)', + ToolTipText='Reservoir Temperature [150 degC]', ) ) self.rejection_temperature: Parameter = parameter_dict_entry( @@ -133,8 +133,8 @@ def parameter_dict_entry(param: Parameter) -> Parameter: PreferredUnits=TemperatureUnit.CELSIUS, CurrentUnits=TemperatureUnit.CELSIUS, Required=True, - ErrMessage='assume default rejection temperature (25 deg-C)', - ToolTipText='Rejection Temperature [25 dec-C]', + ErrMessage='assume default rejection temperature (25 degC)', + ToolTipText='Rejection Temperature [25 degC]', ) ) self.reservoir_porosity: Parameter = parameter_dict_entry( @@ -260,10 +260,10 @@ def parameter_dict_entry(param: Parameter) -> Parameter: PreferredUnits=PercentUnit.TENTH, CurrentUnits=PercentUnit.TENTH, Required=False, - ErrMessage='assume 0.66 for high-T reservoirs (>150C), 0.43 for low-T reservoirs \ - (>90, Garg and Combs (2011)', - ToolTipText='percent of heat that is recoverable from the rock in the reservoir 0.66 for high-T reservoirs,\ - 0.43 for low-T reservoirs (Garg and Combs (2011)', + ErrMessage='assume 0.66 for high-T reservoirs (>150C), 0.43 for low-T reservoirs ' + '(>90, Garg and Combs (2011)', + ToolTipText='percent of heat that is recoverable from the rock in the reservoir 0.66 for high-T reservoirs, ' + '0.43 for low-T reservoirs (Garg and Combs (2011)', ) ) self.fluid_recoverable_heat: Parameter = parameter_dict_entry( @@ -276,10 +276,10 @@ def parameter_dict_entry(param: Parameter) -> Parameter: PreferredUnits=PercentUnit.TENTH, CurrentUnits=PercentUnit.TENTH, Required=False, - ErrMessage='assume 0.66 for high-T reservoirs (>150C), 0.43 for low-T reservoirs \ - (>90, Garg and Combs (2011)', - ToolTipText='percent of heat that is recoverable from the fluid in the reservoir 0.66 for high-T reservoirs,\ - 0.43 for low-T reservoirs (Garg and Combs (2011)', + ErrMessage='assume 0.66 for high-T reservoirs (>150C), 0.43 for low-T reservoirs ' + '(>90, Garg and Combs (2011)', + ToolTipText='percent of heat that is recoverable from the fluid in the reservoir 0.66 for high-T reservoirs, ' + '0.43 for low-T reservoirs (Garg and Combs (2011)', ) ) self.recoverable_fluid_factor: Parameter = parameter_dict_entry( @@ -308,8 +308,8 @@ def parameter_dict_entry(param: Parameter) -> Parameter: Required=False, Provided=False, ErrMessage='calculate based on an assumed gradient of 30 C/km and the reservoir temperature', - ToolTipText='depth to top of reservoir (km). Calculated based on an assumed gradient \ - and the reservoir temperature if no value given', + ToolTipText='depth to top of reservoir (km). Calculated based on an assumed gradient ' + 'and the reservoir temperature if no value given', ) ) self.reservoir_pressure: Parameter = parameter_dict_entry( @@ -324,8 +324,8 @@ def parameter_dict_entry(param: Parameter) -> Parameter: Required=False, Provided=False, ErrMessage='calculate assuming hydrostatic pressure and the reservoir depth & water density', - ToolTipText='pressure of the of reservoir (in mPa). Calculated assuming hydrostatic pressure and \ - reservoir depth & water density if no value given', + ToolTipText='pressure of the of reservoir (in mPa). Calculated assuming hydrostatic pressure and ' + 'reservoir depth & water density if no value given', ) ) self.recoverable_rock_heat: Parameter = parameter_dict_entry(