Skip to content
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

Merged

Conversation

dettmerramon
Copy link
Contributor

No description provided.

@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch 4 times, most recently from 3587aa6 to cebf988 Compare November 28, 2021 21:06
@codecov
Copy link

codecov bot commented Nov 29, 2021

Codecov Report

Merging #210 (3e945d4) into rb-ASIM-v1.10.0 (efab4f8) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@               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           

@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch 5 times, most recently from 20976ab to b42c565 Compare November 30, 2021 14:26
@@ -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(

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.

Suggested change
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,
Copy link
Member

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?

Copy link
Contributor Author

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

Copy link
Member

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(
Copy link
Member

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(
Copy link
Member

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,
Copy link
Member

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?

Copy link
Contributor Author

@dettmerramon dettmerramon Dec 8, 2021

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?

@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch 2 times, most recently from 7ccfd27 to 4a62789 Compare December 8, 2021 21:28
@dettmerramon dettmerramon changed the base branch from master to rb-ASIM-v1.10.0 December 9, 2021 13:16
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:
Copy link
Member

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
Copy link
Member

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.

Copy link
Contributor Author

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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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.

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Member

@prusse-martin prusse-martin Dec 13, 2021

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)

Copy link
Member

@prusse-martin prusse-martin Dec 13, 2021

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.

  1. Update the loader to use the autoloaders infrastructure with explict loaders;
  2. Add necessary metadata and autoloaders support;
  3. 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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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_}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

@prusse-martin prusse-martin mentioned this pull request Dec 13, 2021
@prusse-martin
Copy link
Member

BTW, if pre-commit fails the mergeable check I think it don't even check the formatting.
In other words, I think you will need to solve this conflict, maybe rebasing.

@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch from 4a62789 to 0bb9ae4 Compare December 14, 2021 17:26
@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch 2 times, most recently from 51a7c88 to 6cf9c9a Compare December 15, 2021 17:50
@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch from 6cf9c9a to 92dc608 Compare December 15, 2021 17:51
@@ -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``;
Copy link
Member

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. 👍

Copy link

@haensch-mauricio haensch-mauricio Dec 17, 2021

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.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

Copy link

@haensch-mauricio haensch-mauricio Dec 17, 2021

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(
Copy link
Member

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.

Copy link
Member

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... 🤔

Copy link
Contributor Author

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

Copy link
Member

@nicoddemus nicoddemus Dec 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is:

https://github.com/ESSS/alfasim-sdk/blob/fb-ASIM-4459-equipment-list-annulus-description/.pre-commit-config.yaml#L17-L24

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.

Copy link
Member

@nicoddemus nicoddemus Dec 17, 2021

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.

Copy link
Contributor Author

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.

Copy link
Member

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. 😉

Copy link
Member

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

Copy link
Member

@prusse-martin prusse-martin Dec 20, 2021

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.

black playgound example

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.

@dettmerramon dettmerramon force-pushed the fb-ASIM-4459-equipment-list-annulus-description branch from 0cd1169 to 86778ec Compare December 20, 2021 17:02
@dettmerramon dettmerramon merged commit 837eba4 into rb-ASIM-v1.10.0 Dec 21, 2021
@dettmerramon dettmerramon deleted the fb-ASIM-4459-equipment-list-annulus-description branch December 21, 2021 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants