How to calculate locality of modes based on the modal energy.

Ayush Kumar
Ayush Kumar Member, Moderator, Employee Posts: 467
100 Answers 250 Likes 100 Comments Second Anniversary
✭✭✭✭
edited November 20 in Structures

I am trying to assess the locality of modes based on the modal energy.

Is it possible get all the elements that represent 90% of the total kinetic or stiffness energy of the mode and plot them? Rest of the model should be grey.

Comments

  • Ayush Kumar
    Ayush Kumar Member, Moderator, Employee Posts: 467
    100 Answers 250 Likes 100 Comments Second Anniversary
    ✭✭✭✭

    Tested with 22R2:

    Python Script:

    def post_started(sender, analysis):# Do not edit this line
        define_dpf_workflow(analysis)
    
    
    def define_dpf_workflow(analysis):
    
        import time
        from System import Array
        import mech_dpf
        import clr
        import Ans.DataProcessing as dpf
        mech_dpf.setExtAPI(ExtAPI)
    
        t0 = time.time()
        mode = int(this.GetCustomPropertyByPath("Info/Select Mode").ValueString)
        threshold_fraction = float(this.GetCustomPropertyByPath("Info/Threshold Fraction").ValueString)
        energy_prop = this.GetCustomPropertyByPath("Info/Select Energy").ValueString
    
        ds = dpf.DataSources(analysis.ResultFileName)
        model = dpf.Model(ds)
        mesh = model.Mesh
    
        tfs = dpf.Scoping()
        tfs.Ids = [mode]
    
        if energy_prop == "Kinetic Energy":
            energy = dpf.operators.result.kinetic_energy(data_sources=ds, time_scoping=tfs)
        else:
            energy = dpf.operators.result.stiffness_matrix_energy(data_sources=ds, time_scoping=tfs)
        energy_fc = energy.outputs.fields_container.GetData()
    
        total_energy = dpf.operators.math.accumulate_fc(fields_container=energy_fc)
        total_energy_fc = total_energy.outputs.fields_container.GetData()
    
        energy_sort = dpf.operators.logic.descending_sort_fc(fields_container=energy_fc)
        energy_sort_fc = energy_sort.outputs.fields_container.GetData()
        energy_sorted = energy_sort_fc[0].Data
        energy_ids = energy_sort_fc[0].Scoping.Ids
    
        threshold = threshold_fraction * total_energy_fc[0].Data[0]
    
        # Get cumulative KE
        cumulative_energy = []
        current_sum = 0
        for number in energy_sort_fc[0].Data:
            current_sum += number
            cumulative_energy.append(current_sum)
    
        # Get index of 90% KE
        clr.AddReference('System')
    
        array = Array[float](cumulative_energy)
        index = Array.BinarySearch(array, threshold)
    
        if index < 0:
            index = int(index * (-1.0) - 1)
    
        # Slice the arrays up to that index
        new_all_ke = list(energy_sorted)[:index + 1]
        new_ke_ids = list(energy_ids)[:index + 1]
    
        field_n = dpf.FieldsFactory.CreateScalarField(len(new_ke_ids))
        field_n.Unit = energy_sort_fc[0].Unit
        field_n.Location = energy_sort_fc[0].Location
        field_n.Scoping.Ids = new_ke_ids
        field_n.Data = new_all_ke
    
        field_fwd = dpf.operators.utility.forward_field(field=field_n)
    
        displacement = dpf.operators.result.displacement(data_sources=ds, time_scoping=tfs)
    
        dpf_workflow = dpf.Workflow()
        dpf_workflow.Add(displacement)
        dpf_workflow.SetOutputContour(field_fwd, dpf.enums.GFXContourType.FEElementalScoping)
        # dpf_workflow.SetOutputContour(field_fwd)
        dpf_workflow.SetOutputWarpField(displacement)
        dpf_workflow.SetOutputMesh(mesh)
        dpf_workflow.Record('wf_id', False)
        this.WorkflowId = dpf_workflow.GetRecordedId()
        t1 = time.time()
        ExtAPI.Application.LogInfo("Total time - %s" % (t1 - t0))
    
    

    Property Provider code:

        mode_prop = group.AddProperty("Select Mode", Control.Options)
        res_prop = group.AddProperty("Select Energy", Control.Options)
        res_prop.Options = {1: "Kinetic Energy", 2: "Stiffness Matrix Energy"}
        threshold = group.AddProperty("Threshold Fraction", Control.Double)
        max_modes = Model.Analyses[0].AnalysisSettings.MaximumModesToFind
        mode_prop_dict = {}
        for mode in range(1, max_modes + 1):
            mode_prop_dict.update({mode: mode})
        mode_prop.Options = mode_prop_dict
    

    Results: