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

QUESTION: Clarification on Excessive Results for Member Internal Forces Retrieval #343

Open
Jeroen124 opened this issue Feb 27, 2024 · 8 comments
Assignees
Labels
question Further information is requested

Comments

@Jeroen124
Copy link

Jeroen124 commented Feb 27, 2024

I am currently working on optimizing data retrieval from RFEM models using the Python API, particularly focusing on member internal forces. However, I've encountered an issue where the number of results retrieved seems excessively high for a simple model scenario. Specifically, for a single beam, I am receiving 16 entries for a specific member query and 31 entries when querying all members. This seems counterintuitive, especially considering the model's simplicity.

Here's the code I am using for a simple cantilever:

from RFEM.LoadCasesAndCombinations.loadCasesAndCombinations import LoadCasesAndCombinations
from RFEM.LoadCasesAndCombinations.loadCase import LoadCase
from RFEM.Results.resultTables import ResultTables
from RFEM.BasicObjects.material import Material
from RFEM.BasicObjects.member import Member
from RFEM.BasicObjects.node import Node
from RFEM.BasicObjects.section import Section
from RFEM.TypesForNodes.nodalSupport import NodalSupport
from RFEM.Loads.nodalLoad import NodalLoad
from RFEM.LoadCasesAndCombinations.loadCombination import LoadCombination

from RFEM.LoadCasesAndCombinations.staticAnalysisSettings import StaticAnalysisSettings
from RFEM.enums import (
    AnalysisType,
    CaseObjectType,
    ImperfectionDirection,
    ImperfectionType,
    MemberImperfectionDefinitionType,
    MemberImperfectionType,
    SetType,
    NodalSupportType,
    NodalLoadDirection,
    ActionCategoryType
)


Model(new_model=True, model_name="Test", delete_all=True)
Model.clientModel.service.begin_modification("new")

# Making the model as simple as possible
LoadCasesAndCombinations(
    {
        "activate_combination_wizard_and_classification": False,
        "activate_combination_wizard": False,
        "result_combinations_active": False,
        "result_combinations_parentheses_active": False,
        "result_combinations_consider_sub_results": False,
        "combination_name_according_to_action_category": False,
    }
)


Material(1, 'S235')
Section(1, 'IPE 200')

Node(1, 0.0, 0.0, 0.0)
Node(2, 1, 0.0, 0.0)

Member(1, 1, 2, 0.0, 1, 1)

NodalSupport(1, '1', NodalSupportType.FIXED)

StaticAnalysisSettings.GeometricallyLinear(1, "Linear")

LoadCase.StaticAnalysis(1, 'Self-Weight',analysis_settings_no=1,self_weight=[True, 0.0, 0.0, 1.0])
NodalLoad(1, 1, '1', NodalLoadDirection.LOAD_DIRECTION_GLOBAL_Z_OR_USER_DEFINED_W, 1*1000)

LoadCombination(
    no=1,
    analysis_type=AnalysisType.ANALYSIS_TYPE_STATIC,
    name='Loadcomb1',
    consider_imperfection=False,
    combination_items=[[1, 1, 0, False]],
)

# Calculate
Calculate_all()

Model.clientModel.service.finish_modification()

# =============================================================================
# Results
# =============================================================================
AllMemberResults =ResultTables.MembersInternalForces(
    loading_type=CaseObjectType.E_OBJECT_TYPE_LOAD_COMBINATION, loading_no=1, object_no=0
)

SpecificMemberResults =ResultTables.MembersInternalForces(
    loading_type=CaseObjectType.E_OBJECT_TYPE_LOAD_COMBINATION, loading_no=1, object_no=1
)

print(len(AllMemberResults))
print(len(SpecificMemberResults))

Given the model consists of a single beam, I expected the results to be more streamlined – perhaps detailed results at the nodes and an overall summary for the member itself, rather than 16 or 31 distinct entries.

Could you please provide insight into:

Why the number of results entries is so high for a single member?
Is there a way to interpret these results more effectively, or a method to streamline the data retrieval to focus on key outputs?
Are there best practices or documentation available that guide the handling of results data, especially for simple models?
Any guidance or references to documentation would be greatly appreciated as I navigate optimizing my workflow with the RFEM Python API.

@Jeroen124 Jeroen124 added the bug Existing feature isn't working properly label Feb 27, 2024
@Jeroen124
Copy link
Author

This problem seems closely related to discussion 271:
#271

@OndraMichal OndraMichal added question Further information is requested and removed bug Existing feature isn't working properly labels Feb 29, 2024
@OndraMichal
Copy link
Contributor

OndraMichal commented Feb 29, 2024

Hi @Jeroen124,
it is no so counter intuitive if you understand that you are retrieving following tables:
object_no = 0 ... all tables incl. total max/min, 31 lines
object_no = 1 ... table for member 1, 16 lines
image

If you want you can use directly

Model.clientModel.service.get_results_for_members_internal_forces(loading_type.name, loading_no, object_no)

skipping ConvertResultsToListOfDct() function.

@OndraMichal OndraMichal self-assigned this Feb 29, 2024
@Jeroen124 Jeroen124 changed the title BUG: Clarification on Excessive Results for Member Internal Forces Retrieval QUESTION: Clarification on Excessive Results for Member Internal Forces Retrieval Mar 1, 2024
@Jeroen124
Copy link
Author

@OndraMichal Thank you for the feedback!

Your feedback has clarified the results we're obtaining. We're curious if there's a way to streamline the process by retrieving only the first two rows. (not the extremes) . Since we're handling the data in Python, and we are only retrieving 1 result at a time, we can do the filtering and finding max & min later in Python, potentially speeding up the overall process.

Additionally, maybe we can perhaps reduce the complexity of the ConvertResultsToListOfDct() function by minimizing the use of nested try-except blocks? This will increase the efficiency as well?

Would submitting a PR for fixing the ConvertResultsToListOfDct() help?

Please let me know your thoughts. 👍

@gvandewiel86
Copy link

I was running into a similar problem and was also wondering how to distinguish between different members when requesting MEMBERS_INTERNAL_FORCES with object_no=0. As the output is not providing the member number, only the node numbers. Hence you end up with a whole bunch of data without the member reference, given that a lot of "additional" data is provided.

When retrieving MEMBERS_INTERNAL_FORCES_BY_SECTION the member_number is provided.

@heetrojivadiya
Copy link
Member

heetrojivadiya commented Mar 27, 2024

I was running into a similar problem and was also wondering how to distinguish between different members when requesting MEMBERS_INTERNAL_FORCES with object_no=0. As the output is not providing the member number, only the node numbers. Hence you end up with a whole bunch of data without the member reference, given that a lot of "additional" data is provided.

When retrieving MEMBERS_INTERNAL_FORCES_BY_SECTION the member_number is provided.

Hello @gvandewiel86,

thank you for reaching out to us. I have tested ResultTables.MembersInternalForces(object_no=0) and you are correct. It doesn't include member numbers in the result while the default value for include_base is set as False so which means only attributes belonging to row are extracted for result tables and converted to a list of dictionaries.

(members_internal_forces_row){
         no = 14
         description = "1"
         row =
            (members_internal_forces){
               node_number =
                  (variant){
                     type = 2
                     value = "1"
                  }
               location = 0.0
               location_flags = "M"
               internal_force_label = "M<sub>y</sub>"
               internal_force_n = -4355.875
               internal_force_vy = 0.0
               internal_force_vz = -185.8513946533203
               internal_force_mt = 0.0
               internal_force_my = 617.5512084960938
               internal_force_mz = 0.0
               specification = "Beam | 1 - IPE 200 | L : 10.000 m"
            }

But if you use ResultTables.MembersInternalForces(object_no=0, include_base = True) then you can extract the complete result table including no and description, where no represents the row number and description represents the content of the member number column.

For example:

result = ResultTables.MembersInternalForces(object_no=0, include_base=True)
print(result[13])  # row number 

output: {'no': 14.0, 'description': 1.0, 'internal_force_vz': -185.8513946533203, 'internal_force_my': 617.5512084960938, 'internal_force_mz': 0.0, 'internal_force_n': -4355.875, 'internal_force_label': 'M<sub>y</sub>', 'internal_force_mt': 0.0, 'location': 0.0, 'node_number': 1.0, 'internal_force_vy': 0.0, 'specification': 'Beam | 1 - IPE 200 | L : 10.000 m', 'location_flags': 'M'}

So, in the above part of the result 'no' = 14.0 is row number 14, and 'description' = 1.0 is member number 1, which can be seen in the below image.

image

I hope this answer clarifies your issue. If not then feel free to contact us.

@heetrojivadiya
Copy link
Member

@OndraMichal Thank you for the feedback!

Your feedback has clarified the results we're obtaining. We're curious if there's a way to streamline the process by retrieving only the first two rows. (not the extremes) . Since we're handling the data in Python, and we are only retrieving 1 result at a time, we can do the filtering and finding max & min later in Python, potentially speeding up the overall process.

Additionally, maybe we can perhaps reduce the complexity of the ConvertResultsToListOfDct() function by minimizing the use of nested try-except blocks? This will increase the efficiency as well?

Would submitting a PR for fixing the ConvertResultsToListOfDct() help?

Please let me know your thoughts. 👍

Hello @Jeroen124,

I understood your concern that you want to omit extremes rows in result tables and will find max/min from first two rows for each members later. But in some cases max/min values are not on member start and end node (see figure). So, you may need to get extremes rows too. Although, you can omit repeating rows of extremes by adding few lines in your code to optimize result table.

results = ResultTables.MembersInternalForces(object_no=0, include_base=True)

result, combos, combo = [], [], ()

for item in results:
    description = item.get('description')
    location = item.get('location')
    node = item.get('node_number')
    if isinstance(description, float) or description == 'Extremes':
        if description == 'Extremes':
            description = results[results.index(item) - 1].get('description')
        if location != None: combo = (description, node, location)
        if combo not in combos:
            combos.append(combo)
            item.pop('no', None)
            result.append(item)

print(result)

image

By implementing above lines in script, we can get only important lines from result tables. As soon as possible we will update this in some important static methods of ResultTables by additional parameters something like without_extremes = True/False.

image

@Jeroen124
Copy link
Author

Hi @heetrojivadiya thank you for your answer. As previously mentioned we are currently trying to speed up the results retrieval process from RFEM. With this goal in mind, we are actively scanning the market for the fastest API solvers to overcome this challenge, hopefully RFEM can improve this process. Although filtering after retrieving the results is an option, our priority is to streamline the entire result collection process.

@heetrojivadiya
Copy link
Member

Hi @heetrojivadiya thank you for your answer. As previously mentioned we are currently trying to speed up the results retrieval process from RFEM. With this goal in mind, we are actively scanning the market for the fastest API solvers to overcome this challenge, hopefully RFEM can improve this process. Although filtering after retrieving the results is an option, our priority is to streamline the entire result collection process.

Hey @Jeroen124, I understood your issue of time-consuming. You may follow discussion #339 for speeding up the data extraction process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants