Skip to content

Add example on how to get data by ID #726

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

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

GuillemBarroso
Copy link
Contributor

@GuillemBarroso GuillemBarroso commented Dec 23, 2022

Fix #725.

This PR proposes a new example showing how to retrieve data from a field by ID. The example follows:

  1. Load model and show the entire mesh.
  2. Create nodal scoping in only one available named selection.
  3. Apply scoping to displacements and mesh
  4. Show mesh for that named selection.
  5. Show how to access node ID and value for that node of the scoped displacement field.
    5.1. Index approach
    5.2. get_entity_data_by_id approach
  6. Comparision between the two approaches in 5.

@GuillemBarroso GuillemBarroso added documentation Improvements or additions to documentation examples Related to PyDPF-Core examples labels Dec 23, 2022
@GuillemBarroso GuillemBarroso self-assigned this Dec 23, 2022
@GuillemBarroso GuillemBarroso removed the documentation Improvements or additions to documentation label Dec 23, 2022
@github-actions github-actions bot added the documentation Improvements or additions to documentation label Dec 23, 2022
@codecov
Copy link

codecov bot commented Dec 23, 2022

Codecov Report

Merging #726 (d770951) into master (d503907) will increase coverage by 0.07%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master     #726      +/-   ##
==========================================
+ Coverage   88.56%   88.64%   +0.07%     
==========================================
  Files          71       71              
  Lines        8088     8081       -7     
==========================================
  Hits         7163     7163              
+ Misses        925      918       -7     

@GuillemBarroso
Copy link
Contributor Author

GuillemBarroso commented Dec 23, 2022

@rlagha, a couple comments:

  • It would be great to verify that this is indeed the most efficient way to get data by node ID inside a loop. How this approach compares to the get_entity_data_by_id method? Do we have access to an example with a big mesh (0.5, 1, 2 million nodes)? Then I could assess both approaches in a more realistic setting.

    I did a performance analysis with the mesh of the example and the results are:

    image

    For this mesh we're one order of magnitude more efficient.

  • We have to think how we expose this in PyDPF-Post. I would implement the by_id method to be applied to a certain field.
    Then, we could return two arrays with the nodal_ids and nodal_disp information as

    simulation = post.load_simulation("my_example")
    my_named_selection = "test"
    my_selection = select(named_selection=my_named_selection)
    nodal_ids, nodal_disp = simulation.displacement(select=my_selection).by_id()
    assert len(nodal_ids) == len(nodal_disp) == n_nodes
    assert type(nodal_ids) == np.ndarray or ints
    assert type(nodal_disp) == np.ndarray of floats

    or return a single displacement value associated to a certain node ID as

    simulation = post.load_simulation("my_example")
    my_named_selection = "test"
    my_selection = select(named_selection=my_named_selection)
    nodal_id, nodal_disp = simulation.displacement(select=my_selection).by_id(5)
    assert nodal_id == 5
    assert type(nodal_id) == int
    assert type(nodal_disp) == np.array of floats # (containing the three components of the displacement for that node)

    or even selecting just some ids as

    simulation = post.load_simulation("my_example")
    my_named_selection = "test"
    my_selection = select(named_selection=my_named_selection)
    nodal_ids, nodal_disp = simulation.displacement(select=my_selection).by_id([1, 5, 25])
    assert len(nodal_ids) == len(nodal_disp) == 3
    assert type(nodal_ids) == np.array of ints
    assert type(nodal_disp) == np.array of floats

Thoughts?

start = time.time()
nodal_disp_get_entity = np.zeros([mesh_selection.nodes.n_nodes, 3])
for idx, node_id in enumerate(ids):
node_disp = disp_selection.get_entity_data_by_id(node_id)
Copy link
Contributor

Choose a reason for hiding this comment

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

@guillem , this one is useless in this case. the right one in the one you wrote above.
we use the get_by_id:
-when we loop over several fields for example nodal stresses and displacements and want to get for a given node of the displacement field it's nodal stress for example.
-when we have a user defined scoping, which is different from the field scoping, and we want to extract data from the field. this can be important when we want to read the data once from the file in one request and then work on different named selections and extract data from the field instead of reading each time from a file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @rlagha. Yes, exactly.

Depending on what you want to do you should use one approach or the other. That is why I included the two of them in the example and a comparison between them.

Copy link
Contributor

Choose a reason for hiding this comment

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

@guillem, this can be important to mention these remarks in the example.

start = time.time()
nodal_disp_get_entity = np.zeros([mesh_selection.nodes.n_nodes, 3])
for idx, node_id in enumerate(ids):
node_disp = disp_selection.get_entity_data_by_id(node_id)
Copy link
Contributor

Choose a reason for hiding this comment

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

@guillem, this can be important to mention these remarks in the example.

# for that node
nodal_disp_index = np.zeros([mesh_selection.nodes.n_nodes, 3])
for idx, node_id in enumerate(ids):
node_disp = data[idx]
Copy link
Contributor

Choose a reason for hiding this comment

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

@guillem, this is true when you have nodal or elemental results. When you read stresses for example as Elemental nodal data, then you will need to use field.get_entity_data(idx) instead of data[idx], otherwise you will get only the first stress tensor, this is also true for layered results.
We may need to add a similar loop with field.get_entity_data(); when the server is in in-process mode I think that you will not have overhead, if the server is remote then you may need to use as_local_field option and field.get_entity_data()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation examples Related to PyDPF-Core examples
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add example on how to get data by ID
3 participants