Open mitchute opened 1 week ago
Moving the interface from GHEDesigner
into pygfunction
? Much of this is already encapsulated in the gt.gfunction.gFunction
object. This proposed api.get_g_function
method has a nearly identical API to gt.gfunction.gFunction
.
A proper gt.Borefield
object would have an API that allows append(gt.borehole.Borehole)
. Once a Borefield object is created, it should be easier to interface into this package (from GHEDesigner). Massimo is diligent enough about his API that dependency declaration of pygfunction~=2.2
should be sufficient enough to maintain a wrapper in GHEDesigner. If you guys want new features in pygfunction~=2.3
etc. then what's wrong with modifying a line on your end? Essentially, should Massimo cater to every design tool that comes along? :wink:
TLDR; Create Borefield
in gt.boreholes
. Scratch this new API module and politely ask GHEDesigner
s to manage interfacing their coordinates
with Borefield
on their own.
My two cents. Massimo supersedes.
I like the idea of a simplified API but I think it would be more beneficial for all to create your own wrapper package with pygfunction dependency than patching pygfunction and increase maintenance load this end as @j-c-cook said.
Simplified access to pygfunction could help some especially those who don't need or want GHEDesigner.
The intent is to create the a very simple interface for passing in a set of descriptive static parameters, and returning g-function values. This is a minimal addition that will provide easier access with near zero maintenance.
Thank you @mitchute for the PR and thank you @j-c-cook and @ikijano for the input.
I agree having a more streamlined way of generating g-functions is a positive addition to the project. If I can summarize the PR, it is proposed to add a bore field class that (i) checks and formats geometrical parameters of the bore field and (ii) provides a class method to calculate the g-function. In addition, the bore field class can be initialized by lists of geometrical parameters.
Do we need a separate api
module for these features or would it also suit your usage to implement the changes in the boreholes
module? We already have the boreholes.field_from_file
function. A boreholes.field_from_lists
(or similar) function could be a nice addition to the module.
I would see basic usage as:
field = gt.boreholes.field_from_lists(x, y, H, D, r_b, tilt=0., orientation=0.)
gfunc = field.evaluate_g_function(alpha, time, method='equivalent', boundary_condition='similarities', options={})
Some points for discussion:
__init__
and initialize_borehole_field_generic
?evaluate_g_function
method to have the same default parameters as in the gFunction
class. We could add a parameter (e.g. output='object'
) for the user to decide whether to return the g-function as a g-function object, an array, or a list.Let me know your thoughts. This could provide the basic interface before later working on the integration of the bore field class into the other modules (in #210).
@MassimoCimmino Considering the order of modules listed in __init__.py
, and gfunction.py
s dependence on boreholes.py
, what you have proposed may result in a circular import dependency issue. Please consider the following alternative, where gfunc
is the evaluated g-function when output = 'result'
, and gFunction object when output = 'object'
.
field = gt.boreholes.field_from_lists(x, y, H, D, r_b, tilt=0., orientation=0.)
gfunc = gt.gfunction.get_g_function(field, alpha, time, method='equivalent', boundary_condition='similarities', options={output='result'})
Here's my response to your points:
gt.boreholes.Field
object, and modify it throughout the design process. The current __init__
function allows that creation early on for them. initialize_borefield_generic
is a function they could call multiple times as the coordinates and then heights are adjusted. A name change may be suitable, perhaps update
. output
. Though, like mentioned above, I propose for that method to be located inside of the gfunction
module. @MassimoCimmino thanks for supporting this effort. Your summary of the PR is accurate. Also, thank you for pointing out issue #210. I think this aligns well with that.
I'll try to respond to your points below.
I'm OK with putting this wherever you prefer it be. In my opinion, having it be in api
creates a clear signal to the user that this is what they should be using. A second possible option would be to put it in a new file called borefield
or similar, since as I understand it, boreholes
generally relates to single instances of boreholes, and this would encompass functionality related to the collection of boreholes. We could also put it in boreholes
if you prefer, though that file is already getting a somewhat long. Also, I generally prefer to adhere to one-class-one-file just to keep things simple.
The reason we are not using __init__
is to eventually allow multiple methods for construction. One idea would be to integrate all of the standalone functions in boreholes
for defining the field arrangement (rectangular, L, U, etc.). This would unify how these are constructed and used.
field_1 = BoreField()
field_1.init_l_shaped(L_shaped_args...)
field_1.generate_g_functions(args...)
field_2 = BoreField()
field_2.init_u_shaped(U_shaped_args...)
field_2.generate_g_functions(args...)
I'm OK with making the function take numpy arrays or lists. If they are using pygfunction
they will already have numpy, but I would prefer we do not require use of numpy just to interact with this interface.
I'm OK with making function arguments mirror the gFunction
class. If you think there's a use case for needing to return the class instance itself vs. the actual list of g-function values, then I think those should be separated with different function calls, such as get_gFunction_instance
and get_g_function_values
. Having the return type be a conditional switch just seems like more complication than is needed.
This PR creates some structures to simplify using
pygfunction
as a g-function calculator. The API proposed collects the necessary data into a class, and provides a few methods and the necessary structure to enable passing static borehole field parameters as inputs, and returning the g-function values.