Skip to content

Commit

Permalink
Add getem_costs_eqn_calc and test
Browse files Browse the repository at this point in the history
  • Loading branch information
dguittet committed Jan 3, 2025
1 parent 0cd67b2 commit e3a14d4
Show file tree
Hide file tree
Showing 5 changed files with 314 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/lists/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
Geothermal monthly and hourly models using general power block code from TRNSYS Type 224 code by M.Wagner, and some GETEM model code.

:doc:`../modules/GeothermalCosts` (HD)
Geothermal monthly and hourly models using general power block code from TRNSYS Type 224 code by M.Wagner, and some GETEM model code.
Geothermal cost equations.

:doc:`../modules/Grid` (HD)
Grid model
Expand Down
151 changes: 148 additions & 3 deletions modules/GeothermalCosts.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "PySAM_utils.h"

#include "GeothermalCosts_eqns.c"


/*
* GeoHourly Group
Expand Down Expand Up @@ -209,6 +211,78 @@ GeoHourly_set_flash_count(VarGroupObject *self, PyObject *value, void *closure)
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_flash_count_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_conf_multiplier(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_conf_multiplier_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_conf_multiplier(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_conf_multiplier_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_conf_non_drill(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_conf_non_drill_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_conf_non_drill(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_conf_non_drill_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_conf_num_wells(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_conf_num_wells_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_conf_num_wells(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_conf_num_wells_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_expl_multiplier(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_expl_multiplier_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_expl_multiplier(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_expl_multiplier_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_expl_non_drill(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_expl_non_drill_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_expl_non_drill(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_expl_non_drill_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_expl_num_wells(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_expl_num_wells_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_expl_num_wells(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_expl_num_wells_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_inj_cost_curve(VarGroupObject *self, void *closure)
{
Expand Down Expand Up @@ -305,6 +379,18 @@ GeoHourly_set_geotherm_cost_prod_wells_drilled(VarGroupObject *self, PyObject *v
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_prod_wells_drilled_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_geotherm_cost_stim_non_drill(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_GeoHourly_geotherm_cost_stim_non_drill_nget, self->data_ptr);
}

static int
GeoHourly_set_geotherm_cost_stim_non_drill(VarGroupObject *self, PyObject *value, void *closure)
{
return PySAM_double_setter(value, SAM_GeothermalCosts_GeoHourly_geotherm_cost_stim_non_drill_nset, self->data_ptr);
}

static PyObject *
GeoHourly_get_gross_cost_output(VarGroupObject *self, void *closure)
{
Expand Down Expand Up @@ -603,6 +689,24 @@ static PyGetSetDef GeoHourly_getset[] = {
{"flash_count", (getter)GeoHourly_get_flash_count,(setter)GeoHourly_set_flash_count,
PyDoc_STR("*float*: Flash Count [(1 -2)]\n\n**Required:**\nRequired if conversion_type=1"),
NULL},
{"geotherm_cost_conf_multiplier", (getter)GeoHourly_get_geotherm_cost_conf_multiplier,(setter)GeoHourly_set_geotherm_cost_conf_multiplier,
PyDoc_STR("*float*: Confirmation cost multiplier\n\n**Options:**\n?=1.2\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_conf_non_drill", (getter)GeoHourly_get_geotherm_cost_conf_non_drill,(setter)GeoHourly_set_geotherm_cost_conf_non_drill,
PyDoc_STR("*float*: Confirmation non drilling costs [$]\n\n**Options:**\n?=250000\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_conf_num_wells", (getter)GeoHourly_get_geotherm_cost_conf_num_wells,(setter)GeoHourly_set_geotherm_cost_conf_num_wells,
PyDoc_STR("*float*: Number of confirmation wells\n\n**Options:**\n?=2\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_expl_multiplier", (getter)GeoHourly_get_geotherm_cost_expl_multiplier,(setter)GeoHourly_set_geotherm_cost_expl_multiplier,
PyDoc_STR("*float*: Exploration cost multiplier\n\n**Options:**\n?=0.5\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_expl_non_drill", (getter)GeoHourly_get_geotherm_cost_expl_non_drill,(setter)GeoHourly_set_geotherm_cost_expl_non_drill,
PyDoc_STR("*float*: Exploration non drilling costs [$]\n\n**Options:**\n?=750000\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_expl_num_wells", (getter)GeoHourly_get_geotherm_cost_expl_num_wells,(setter)GeoHourly_set_geotherm_cost_expl_num_wells,
PyDoc_STR("*float*: Number of exploration wells\n\n**Options:**\n?=2\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_inj_cost_curve", (getter)GeoHourly_get_geotherm_cost_inj_cost_curve,(setter)GeoHourly_set_geotherm_cost_inj_cost_curve,
PyDoc_STR("*float*: Injection well diameter type [0/1]\n\n**Options:**\n0=LargerDiameter,1=SmallerDiameter\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
Expand All @@ -627,6 +731,9 @@ static PyGetSetDef GeoHourly_getset[] = {
{"geotherm_cost_prod_wells_drilled", (getter)GeoHourly_get_geotherm_cost_prod_wells_drilled,(setter)GeoHourly_set_geotherm_cost_prod_wells_drilled,
PyDoc_STR("*float*: Number of drilled production wells [0/1]\n\n**Options:**\n0=LargerDiameter,1=SmallerDiameter\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"geotherm_cost_stim_non_drill", (getter)GeoHourly_get_geotherm_cost_stim_non_drill,(setter)GeoHourly_set_geotherm_cost_stim_non_drill,
PyDoc_STR("*float*: Stimulation non drilling costs [$]\n\n**Options:**\n?=0\n\n**Required:**\nRequired if calc_drill_costs=1"),
NULL},
{"gross_cost_output", (getter)GeoHourly_get_gross_cost_output,(setter)GeoHourly_set_gross_cost_output,
PyDoc_STR("*float*: Gross output from GETEM for cost calculations [MW]\n\n**Required:**\nTrue"),
NULL},
Expand Down Expand Up @@ -820,6 +927,24 @@ Outputs_get_baseline_cost(VarGroupObject *self, void *closure)
return PySAM_double_getter(SAM_GeothermalCosts_Outputs_baseline_cost_nget, self->data_ptr);
}

static PyObject *
Outputs_get_conf_total_cost(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_Outputs_conf_total_cost_nget, self->data_ptr);
}

static PyObject *
Outputs_get_drilling_total_cost(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_Outputs_drilling_total_cost_nget, self->data_ptr);
}

static PyObject *
Outputs_get_expl_total_cost(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_Outputs_expl_total_cost_nget, self->data_ptr);
}

static PyObject *
Outputs_get_inj_total_cost(VarGroupObject *self, void *closure)
{
Expand All @@ -832,15 +957,33 @@ Outputs_get_prod_total_cost(VarGroupObject *self, void *closure)
return PySAM_double_getter(SAM_GeothermalCosts_Outputs_prod_total_cost_nget, self->data_ptr);
}

static PyObject *
Outputs_get_stim_total_cost(VarGroupObject *self, void *closure)
{
return PySAM_double_getter(SAM_GeothermalCosts_Outputs_stim_total_cost_nget, self->data_ptr);
}

static PyGetSetDef Outputs_getset[] = {
{"baseline_cost", (getter)Outputs_get_baseline_cost,(setter)0,
PyDoc_STR("*float*: Baseline Cost [$/kW]"),
PyDoc_STR("*float*: Baseline cost [$/kW]"),
NULL},
{"conf_total_cost", (getter)Outputs_get_conf_total_cost,(setter)0,
PyDoc_STR("*float*: Total confirmation well cost [$]"),
NULL},
{"drilling_total_cost", (getter)Outputs_get_drilling_total_cost,(setter)0,
PyDoc_STR("*float*: Total drilling cost [$]"),
NULL},
{"expl_total_cost", (getter)Outputs_get_expl_total_cost,(setter)0,
PyDoc_STR("*float*: Total exploration well cost [$]"),
NULL},
{"inj_total_cost", (getter)Outputs_get_inj_total_cost,(setter)0,
PyDoc_STR("*float*: Total Injection well cost [$/kW]"),
PyDoc_STR("*float*: Total injection well cost [$]"),
NULL},
{"prod_total_cost", (getter)Outputs_get_prod_total_cost,(setter)0,
PyDoc_STR("*float*: Total Production well cost [$/kW]"),
PyDoc_STR("*float*: Total production well cost [$]"),
NULL},
{"stim_total_cost", (getter)Outputs_get_stim_total_cost,(setter)0,
PyDoc_STR("*float*: Total stimulation well cost [$]"),
NULL},
{NULL} /* Sentinel */
};
Expand Down Expand Up @@ -1019,6 +1162,8 @@ static PyMethodDef GeothermalCosts_methods[] = {
PyDoc_STR("unassign(name) -> None\n Unassign a value in any of the variable groups.")},
{"get_data_ptr", (PyCFunction)GeothermalCosts_get_data_ptr, METH_VARARGS,
PyDoc_STR("get_data_ptr() -> Pointer\n Get ssc_data_t pointer")},
{"getem_om_cost_calc", (PyCFunction)getem_om_cost_calc, METH_VARARGS | METH_KEYWORDS,
getem_om_cost_calc_doc},
{NULL, NULL} /* sentinel */
};

Expand Down
116 changes: 116 additions & 0 deletions src/GeothermalCosts_eqns.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include "SAM_eqns.h"

char getem_om_cost_calc_doc[] =
"Add documentation here \\n\\n"
"Input: var_table with key-value pairs\\n"
// " 'gross_output': double [units]\\n"
// " 'conversion_type': double [units]\\n"
" 'baseline_cost': double [$] \\n"
// " 'ppi_base_year': double [year] \\n"
// " 'cwflow': double [units] \\n"
" 'drilling_cost': double [$] \\n"
" 'field_gathering_system_cost': double [units] \\n"
// " 'GF_flowrate': double [units] \\n"
" 'num_wells': double [units] \\n"
" 'water_loss': double [units] \\n"
" 'total_installed_cost': double [$] \\n"
" 'pump_cost_install': double [units] \\n"
" 'pump_only_cost': double [units] \\n"
" 'pump_type': double [units] \\n"
" 'pump_depth': double \\n"
"Output: key-value pairs added to var_table\\n"
" 'total_getem_om_cost': double [$]";

static PyObject* getem_om_cost_calc(PyObject *self, PyObject *args, PyObject *keywds)
{
double baseline_cost;
double drilling_cost;
double field_gathering_system_cost;
double num_wells;
double water_loss;
double total_installed_cost;
double pump_cost_install;
double pump_only_cost;
double pump_type;
double pump_depth;

static char *kwlist[] = {"baseline_cost", "drilling_cost",
"field_gathering_system_cost", "num_wells", "water_loss", "total_installed_cost",
"pump_cost_install", "pump_only_cost", "pump_type", "pump_depth", NULL};

if (!PyArg_ParseTupleAndKeywords(args, keywds, "dddddddddd", kwlist,
&baseline_cost, &drilling_cost,
&field_gathering_system_cost, &num_wells, &water_loss, &total_installed_cost,
&pump_cost_install, &pump_only_cost, &pump_type, &pump_depth))
return NULL;

// these variables are ones available as inputs to Geothermal_costs. So use those values directly
// instead of expecting user to provide them
double gross_output;
double conversion_type;
double ppi_base_year;
double cwflow;
double GF_flowrate;

VarGroupObject* self_obj = (VarGroupObject*)self;
SAM_error error = new_error();
gross_output = (int)SAM_GeothermalCosts_GeoHourly_gross_output_nget(self_obj->data_ptr, &error);
if (PySAM_has_error(error)){
return NULL;
}
error = new_error();
conversion_type = (int)SAM_GeothermalCosts_GeoHourly_conversion_type_nget(self_obj->data_ptr, &error);
if (PySAM_has_error(error)){
return NULL;
}
error = new_error();
ppi_base_year = (int)SAM_GeothermalCosts_GeoHourly_ppi_base_year_nget(self_obj->data_ptr, &error);
if (PySAM_has_error(error)){
return NULL;
}
error = new_error();
cwflow = (int)SAM_GeothermalCosts_GeoHourly_cwflow_nget(self_obj->data_ptr, &error);
if (PySAM_has_error(error)){
return NULL;
}
error = new_error();
GF_flowrate = (int)SAM_GeothermalCosts_GeoHourly_GF_flowrate_nget(self_obj->data_ptr, &error);
if (PySAM_has_error(error)){
return NULL;
}

SAM_table data = SAM_table_construct(NULL);
SAM_table_set_num(data, "gross_output", gross_output, NULL);
SAM_table_set_num(data, "conversion_type", conversion_type, NULL);
SAM_table_set_num(data, "baseline_cost", baseline_cost, NULL);
SAM_table_set_num(data, "ppi_base_year", ppi_base_year, NULL);
SAM_table_set_num(data, "cwflow", cwflow, NULL);
SAM_table_set_num(data, "drilling_cost", drilling_cost, NULL);
SAM_table_set_num(data, "GF_flowrate", GF_flowrate, NULL);
SAM_table_set_num(data, "field_gathering_system_cost", field_gathering_system_cost, NULL);
SAM_table_set_num(data, "num_wells", num_wells, NULL);
SAM_table_set_num(data, "water_loss", water_loss, NULL);
SAM_table_set_num(data, "total_installed_cost", total_installed_cost, NULL);
SAM_table_set_num(data, "pump_cost_install", pump_cost_install, NULL);
SAM_table_set_num(data, "pump_only_cost", pump_only_cost, NULL);
SAM_table_set_num(data, "pump_type", pump_type, NULL);
SAM_table_set_num(data, "pump_depth", pump_depth, NULL);

error = new_error();
SAM_getem_om_cost_calc_eqn(data, &error);

if (PySAM_has_error(error)){
return NULL;
}

error = new_error();
double total_getem_om_cost = SAM_table_get_num(data, "total_getem_om_cost", &error);

if (PySAM_has_error(error)){
return NULL;
}

SAM_table_destruct(data, NULL);

return PyFloat_FromDouble(total_getem_om_cost);
}
13 changes: 13 additions & 0 deletions stubs/stubs/GeothermalCosts.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class GeothermalCosts(object):
def __init__(self, *args, **kwargs):
pass

def getem_om_cost_calc(self, args):
pass
class GeoHourly(object):
def assign(self):
pass
Expand All @@ -45,6 +47,12 @@ class GeothermalCosts(object):
dt_prod_well = float
eff_secondlaw = float
flash_count = float
geotherm_cost_conf_multiplier = float
geotherm_cost_conf_non_drill = float
geotherm_cost_conf_num_wells = float
geotherm_cost_expl_multiplier = float
geotherm_cost_expl_non_drill = float
geotherm_cost_expl_num_wells = float
geotherm_cost_inj_cost_curve = float
geotherm_cost_inj_cost_curve_welldiam = float
geotherm_cost_inj_cost_curve_welltype = float
Expand All @@ -53,6 +61,7 @@ class GeothermalCosts(object):
geotherm_cost_prod_cost_curve_welldiam = float
geotherm_cost_prod_cost_curve_welltype = float
geotherm_cost_prod_wells_drilled = float
geotherm_cost_stim_non_drill = float
gross_cost_output = float
gross_output = float
hp_flash_pressure = float
Expand Down Expand Up @@ -89,8 +98,12 @@ class GeothermalCosts(object):


baseline_cost = float
conf_total_cost = float
drilling_total_cost = float
expl_total_cost = float
inj_total_cost = float
prod_total_cost = float
stim_total_cost = float



Expand Down
Loading

0 comments on commit e3a14d4

Please sign in to comment.