-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(ASIM-4459) Add equipment list for annulus description #210
(ASIM-4459) Add equipment list for annulus description #210
Conversation
3587aa6
to
cebf988
Compare
Codecov Report
@@ Coverage Diff @@
## rb-ASIM-v1.10.0 #210 +/- ##
================================================
Coverage 99.90% 99.90%
================================================
Files 42 42
Lines 4333 4344 +11
================================================
+ Hits 4329 4340 +11
Misses 4 4 |
20976ab
to
b42c565
Compare
@@ -424,7 +424,9 @@ | |||
pvt_model="gavea", | |||
top_node="mass_source_node", | |||
initial_conditions=INITIAL_CONDITIONS_DESCRIPTION, | |||
gas_lift_valve_equipment={"My gas-lift valve": GAS_LIST_VALVE_DESCRIPTION}, | |||
equipment=case_description.AnnulusEquipmentDescription( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to use the existing description here.
equipment=case_description.AnnulusEquipmentDescription( | |
equipment=ANNULUS_EQUIPMENT_DESCRIPTION, |
@@ -1492,7 +1492,7 @@ def load_annulus_description( | |||
"pvt_model": load_value, | |||
"top_node": load_value, | |||
"initial_conditions": load_initial_conditions_description, | |||
"gas_lift_valve_equipment": load_gas_lift_valve_equipment_description, | |||
"equipment": load_annulus_equipment_description, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you test the auto loaders?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by auto loaders do you mean these loaders (load_annulus_equipment_...)? If so some tests already cover it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #210 (comment)
Maybe using directly
load_instance
.
return update_multi_input_flags(document, item_description) | ||
|
||
return { | ||
key.data: generate_leak_equipment_description( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Food for thought.
I ask myself why DescriptionDocument
do not have an items
method.
@attr.s
class DescriptionDocument:
...
def items(self):
for key, value in self.content.items():
yield key, type(self)(value, self.file_path)
Probably will be expected to have other helper methods.
"gas_lift_valves": load_gas_lift_valve_equipment_description, | ||
"leaks": load_leak_equipment_description, | ||
} | ||
return _generate_description( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try to use auto loaders?
Maybe using directly load_instance
.
I would expect all case descriptions that only use those attrib_*
or are plain values to be loadeble by auto loaders.
I will like to see this file with as lest code possible like case_to_alfacase
.
@@ -1742,6 +1762,7 @@ def load_equipment_description( | |||
"reservoir_inflows": load_reservoir_inflow_equipment_description, | |||
"heat_sources": load_heat_source_equipment_description, | |||
"compressors": load_compressor_equipment_description, | |||
"leaks": load_leak_equipment_description, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try to use auto loaders?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, tried, it worked in some places, see the most recent commits
Wouldnt be a good idea to create a tech debit and update everything that is possible?
7ccfd27
to
4a62789
Compare
Return a load instance function pre-populate with the class_. @ramon change the docstring | ||
""" | ||
|
||
def _get_dict_of_loader(alfacase_content: DescriptionDocument, class_: Type[T]) -> T: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename _get_dict_of_loader
-> load_dict_of_instance
an move it to global scope.
@@ -137,8 +125,25 @@ def get_instance_loader(*, class_: type) -> Callable: | |||
return partial(load_instance, class_=class_) | |||
|
|||
|
|||
@lru_cache(maxsize=None) | |||
def get_dict_of_loader(*, class_: type) -> Callable: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def get_dict_of_loader(*, class_: type) -> Callable: | |
def get_dict_of_instance_loader(*, class_: type) -> Callable: |
There is get_dict_of_arrays_loader
and get_curve_dict_loader
. My bad using inconsistent names.
def get_case_description_attribute_loader_dict( | ||
class_: Any, explicit_loaders: Optional[Dict[str, Callable]] = None | ||
class_: Any, explicit_loaders: Optional[Dict[str, Callable]]=None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this pass by precommit check?
There is a lot of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, I didn't thought that was why it didnt pass the precommit check, but I'll revert it just to be sure
@@ -1492,7 +1498,7 @@ def load_annulus_description( | |||
"pvt_model": load_value, | |||
"top_node": load_value, | |||
"initial_conditions": load_initial_conditions_description, | |||
"gas_lift_valve_equipment": load_gas_lift_valve_equipment_description, | |||
"equipment": partial(load_instance, class_=case_description.AnnulusEquipmentDescription), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"equipment": partial(load_instance, class_=case_description.AnnulusEquipmentDescription), | |
"equipment": get_instance_loader(class_=case_description.AnnulusEquipmentDescription), |
If not using auto loaders at least keep it simple as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't that "using auto loaders" thou?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it uses part of the autoloaders infra.
Those dicts are explicit loaders:
explicit_loaders_for_DecriptionType = {
"attr_name_FOO": load_vale,
"attr_name_BAR": load_BAR_description,
"attr_name_XXX": get_instance_loader(class_=case_description.XXXDescription),
}
could be written as:
explicit_loaders = {
"attr_name_BAR": load_BAR_description,
}
loaders = get_case_description_attribute_loader_dict(DecriptionType, explicit_loaders)
load_value
it the default loader when no explicit loader is supplied and no metadata is present.
If "attr_name_BAR" is also declared with have metadata (and the autloader is exits) no explicit loader is required and possibly we can remove load_BAR_description
altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suguest, first just try
def load_annulus_description(
document: DescriptionDocument,
) -> case_description.AnnulusDescription:
return load_instance(document, case_description.AnnulusDescription)
If this works you probably can remove load_initial_conditions_description
if its no longer used (probably is used by the main pipe loader).
If the full autloader do not work try:
# Change `load_instance` to accept optional explict loaders.
def load_instance(alfacase_content: DescriptionDocument, class_: Type[T], explicit_loaders: Optional[Dict[str, Callable]] = None) -> T:
"""
Create an instance of class_ with the attributes found in alfacase_content.
"""
alfacase_to_case_description = get_case_description_attribute_loader_dict(class_, explicit_loaders)
case_values = to_case_values(alfacase_content, alfacase_to_case_description)
item_description = class_(**case_values)
return update_multi_input_flags(alfacase_content, item_description)
def load_annulus_description(
document: DescriptionDocument,
) -> case_description.AnnulusDescription:
explicit_loaders= {
"initial_conditions": load_initial_conditions_description,
}
return load_instance(document, case_description.AnnulusDescription, explicit_loaders)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, explicit_loaders
are not actually used today. I did add it to help with progressive adoption of the autoloaders infrastructure.
I did use it in the initial port of the loaders already ported.
- Update the loader to use the autoloaders infrastructure with explict loaders;
- Add necessary metadata and autoloaders support;
- When the explict loader dict is empty just delete the function =);
This allow to keep the tests passing while progressively implementing the loaders. Implement 1, run the tests, another, run the test. This makes if easier to track a problem when implementing.
@@ -1742,6 +1748,7 @@ def load_equipment_description( | |||
"reservoir_inflows": load_reservoir_inflow_equipment_description, | |||
"heat_sources": load_heat_source_equipment_description, | |||
"compressors": load_compressor_equipment_description, | |||
"leaks": partial(load_instance, class_=case_description.LeakEquipmentDescription), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"leaks": partial(load_instance, class_=case_description.LeakEquipmentDescription), | |
"leaks": get_instance_loader(class_=case_description.LeakEquipmentDescription), |
@@ -402,8 +402,12 @@ def attrib_dict_of(type_: type) -> attr._make._CountingAttr: | |||
Create a new attr attribute with validator for an atribute that is a dictionary with keys as str (to represent | |||
the name) and the content of an instance of type_ | |||
""" | |||
metadata = {"type": "dict_of", "class_": type_} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
metadata = {"type": "dict_of", "class_": type_} | |
metadata = {"type": "dict_of_instance", "class_": type_} |
plz =)
Possibly this must be different for values and case description instances, but all occurrences I found use case description instances so lets not over complicate things now.
BTW, if pre-commit fails the mergeable check I think it don't even check the formatting. |
4a62789
to
0bb9ae4
Compare
51a7c88
to
6cf9c9a
Compare
6cf9c9a
to
92dc608
Compare
@@ -6,6 +6,11 @@ History | |||
0.12.0 (unreleased) | |||
=================== | |||
|
|||
* **Breaking Change**: Change in ``AnnulusDescription`` to support different types of annulus equipment. Now ``AnnulusDescription``` has an attribute ``AnnulusEquipmentDescription``, which holds a dict that can contain multiple different equipment types, for which the current available options are: | |||
|
|||
- ``LeakEquipmentDescription``; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@oliveira-mauricio
Don't you think we should to start to mention explicitly how this affects alfacase files in the history?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like an example? I guess it's ok. I'm a bit afraid it can get too big, but let's give it a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something like this?
- Here is an example of how to update previous .alfacase files with annulus equipment:
Before
annulus:
gas_lift_valve_equipment:
Gas Lift Valve (Well 1 > Annulus) 1:
position:
value: 100.0
unit: m
... # Other properties
After
annulus:
equipment:
gas_lift_valves:
Gas Lift Valve (Well 1 > Annulus) 1:
position:
value: 100.0
unit: m
... # Other properties
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And maybe add that on the previous release entry too?
- Here is an example of how to update previous .alfacase files with trends:
Before
trends:
- curve_names:
- timestep
location: not_defined
- curve_names:
- flow pattern
- pressure
element_name: Conn 1
... # Other properties
After
trends:
positional_pipe_trends:
- curve_names:
- flow pattern
- pressure
element_name: Conn 1
... # Other properties
overall_pipe_trends: []
global_trends:
- curve_names:
- timestep
equipment_trends: []
separator_trends: []
|
||
pressure_boosts: Array = attr.ib( | ||
default=Array( | ||
pressure_boosts = attrib_array(Array( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect black to nag about this, but OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, how odd... 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is black used for the alfasim-sdk tho? It never asked me to use it regardless of how "unformatted" the code seemed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is:
Locally you need to run pre-commit install
once, and from that point on, every commit will run the pre-commit checks (which includes black).
But regardless we use pre-commit.ci, which runs a pre-commit job here which would automatically format your code. That's why that's curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear: don't worry about it, we were just wondering, there's no action to be taken on your side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, I figured that, since the jobs passed. I just find it odd, since black complains all the time with my commits fo other reps, but never had a problem with the sdk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh it might be that pre-commit.ci
pushes commits fixing the checks when possible. 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mystery solved
# fmt: off
@attr.s(frozen=True, slots=True, kw_only=True)
class TablePumpDescription:
...
pressure_boosts = attrib_array(Array(
[0.0] * 12
+[
12.0, 10.0, 9.0, 7.5, 5.0, 0.0, 10.0, 9.0, 8.0, 6.0, 3.5, 0.0,
14.0, 12.0, 10.0, 8.0, 5.5, 0.0, 13.5, 11.2, 9.5, 7.6, 5.2, 0.0,
],
'bar',
)
)
...
# fmt: on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a request for a change now.
If we move the fmt: off/on
directive to inside the big array it is restricted to that structure.
I would recomend doing
pressure_boosts = attrib_array(
Array(
[0.0] * 12
+ [
# fmt: off
12.0, 10.0, 9.0, 7.5, 5.0, 0.0, 10.0, 9.0, 8.0, 6.0, 3.5, 0.0,
14.0, 12.0, 10.0, 8.0, 5.5, 0.0, 13.5, 11.2, 9.5, 7.6, 5.2, 0.0,
# fmt: on
],
"bar",
)
)
To avoid problems in the future.
0cd1169
to
86778ec
Compare
for more information, see https://pre-commit.ci
No description provided.