Skip to content

Commit f85d6ae

Browse files
templatize sensitivity fracture count range
1 parent c5094fc commit f85d6ae

5 files changed

Lines changed: 24 additions & 17 deletions

docs/Fervo_Project_Red.md.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ baseline provides the tightest statistical fit for the current two-year empirica
212212
the effective fracture surface area inherently relies on analytical interpretation.
213213

214214
To evaluate the bounding envelope of the reservoir's thermal drawdown, a sensitivity analysis was performed on this
215-
effective `Number of Fractures`. By expanding the model to include other plausible values (ranging from 57 to 69
215+
effective `Number of Fractures`. By expanding the model to include other plausible values (ranging from {{ fracture_sensitivity_range_low }} to {{ fracture_sensitivity_range_high }}
216216
fractures), the analysis demonstrates the sensitivity of the long-term thermal decline to the idealized fracture surface area.
217217

218218
![](_images/fervo_project_red-2026_production-temperature-data-vs-modeling-fracture-sensitivity-1.png)
28.1 KB
Loading
27.4 KB
Loading
18 KB
Loading

src/geophires_docs/generate_fervo_project_red_2026_docs.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949

5050
_LONG_TERM_FORECAST_PLANT_LIFETIME_YEARS = 8
5151

52+
NUMBER_OF_FRACTURES_PARAM_NAME = 'Number of Fractures'
53+
5254
_GRAPH_DPI = 300
5355
_SAVEFIG_ARGS = {'dpi': _GRAPH_DPI, 'metadata': {'Date': None}}
5456

@@ -502,6 +504,18 @@ def get_long_term_geophires_profile() -> pd.Series:
502504
return pd.Series(data=geophires_y, index=geophires_x)
503505

504506

507+
def _get_fracture_sensitivity_fracture_counts() -> list[int]:
508+
base_input_params: GeophiresInputParameters = get_project_red_input_params_and_result()[0]
509+
base_number_of_fractures = int(_get_input_parameters_dict(base_input_params)[NUMBER_OF_FRACTURES_PARAM_NAME])
510+
return [
511+
base_number_of_fractures,
512+
base_number_of_fractures - 6,
513+
base_number_of_fractures - 3,
514+
base_number_of_fractures + 3,
515+
base_number_of_fractures + 6,
516+
]
517+
518+
505519
def _generate_fracture_sensitivity_graph(
506520
df_prod: pd.DataFrame,
507521
steady_state_start_years: float,
@@ -545,18 +559,10 @@ def _generate_fracture_sensitivity_graph(
545559
label='Measured Temperature (Thermal Conditioning & Transient Operations)',
546560
)
547561

548-
number_of_fractures_param_name = 'Number of Fractures'
549-
550562
base_input_params: GeophiresInputParameters = get_project_red_input_params_and_result()[0]
551-
base_number_of_fractures = int(_get_input_parameters_dict(base_input_params)[number_of_fractures_param_name])
563+
base_number_of_fractures = int(_get_input_parameters_dict(base_input_params)[NUMBER_OF_FRACTURES_PARAM_NAME])
552564

553-
fracture_counts = [
554-
base_number_of_fractures,
555-
base_number_of_fractures - 6,
556-
base_number_of_fractures - 3,
557-
base_number_of_fractures + 3,
558-
base_number_of_fractures + 6,
559-
]
565+
fracture_counts = _get_fracture_sensitivity_fracture_counts()
560566
client = GeophiresXClient()
561567

562568
colors = {
@@ -583,7 +589,7 @@ def _generate_fracture_sensitivity_graph(
583589
input_params: GeophiresInputParameters = ImmutableGeophiresInputParameters(
584590
from_file_path=base_input_params.as_file_path(),
585591
params={
586-
number_of_fractures_param_name: frac_count,
592+
NUMBER_OF_FRACTURES_PARAM_NAME: frac_count,
587593
'Plant Lifetime': _LONG_TERM_FORECAST_PLANT_LIFETIME_YEARS,
588594
'Gringarten-Stehfest Precision': 10, # Speed up build with only minor effect on precision
589595
'Print Output to Console': 0,
@@ -615,8 +621,7 @@ def _generate_fracture_sensitivity_graph(
615621
final_temp_degc = float(geophires_y[-1]) if geophires_y else 0.0
616622
power_data.append(
617623
{
618-
number_of_fractures_param_name: frac_count,
619-
#'Average Net Electricity Production (MW)': avg_generation_v,
624+
NUMBER_OF_FRACTURES_PARAM_NAME: frac_count,
620625
f'{avg_generation_param} ({avg_generation_u})': avg_generation_v,
621626
f'Year {_LONG_TERM_FORECAST_PLANT_LIFETIME_YEARS} Flowing Temperature (°C)': final_temp_degc,
622627
}
@@ -674,16 +679,16 @@ def _savefig(version: int | str) -> None:
674679
plt.close(fig)
675680

676681
df_power = pd.DataFrame(power_data)
677-
df_power = df_power.sort_values(number_of_fractures_param_name).reset_index(drop=True)
682+
df_power = df_power.sort_values(NUMBER_OF_FRACTURES_PARAM_NAME).reset_index(drop=True)
678683
df_power.to_csv(power_csv_path, index=False)
679684

680685
fig_pwr, ax_pwr = plt.subplots(figsize=(8, 5))
681-
x_labels = [str(x) for x in df_power[number_of_fractures_param_name]]
686+
x_labels = [str(x) for x in df_power[NUMBER_OF_FRACTURES_PARAM_NAME]]
682687
y_values = df_power[f'{avg_generation_param} ({avg_generation_u})']
683688

684689
bars = ax_pwr.bar(x_labels, y_values, color='#1f77b4', alpha=0.8, edgecolor='black')
685690

686-
baseline_idx = df_power.index[df_power[number_of_fractures_param_name] == base_number_of_fractures].tolist()[0]
691+
baseline_idx = df_power.index[df_power[NUMBER_OF_FRACTURES_PARAM_NAME] == base_number_of_fractures].tolist()[0]
687692
bars[baseline_idx].set_color('green')
688693
bars[baseline_idx].set_edgecolor('black')
689694

@@ -765,6 +770,8 @@ def _get_input_params_dict_with_nbsp() -> dict[str, Any]:
765770
'geophires_r2': f'{geophires_stats_alignment.r2:.4f}',
766771
'geophires_bias_degc': f'{geophires_stats_alignment.bias_degc:.2f}',
767772
'long_term_forecast_years': _LONG_TERM_FORECAST_PLANT_LIFETIME_YEARS,
773+
'fracture_sensitivity_range_low': min(_get_fracture_sensitivity_fracture_counts()),
774+
'fracture_sensitivity_range_high': max(_get_fracture_sensitivity_fracture_counts()),
768775
}
769776

770777
# Set up Jinja environment

0 commit comments

Comments
 (0)