ansys / pydpf-core

Data Processing Framework - Python Core
http://dpf.docs.pyansys.com/
MIT License
70 stars 25 forks source link

Need to extract top 20 maximum values from a feild #202

Open sarunarthy opened 2 years ago

sarunarthy commented 2 years ago

I would like to extract top 20 Nodes/Elements on which the stress is maximum from a stess_von_mises operator

I am getting feild container of stress as shown below. From the Fields_container i would like to extract top 20 Nodal/Elements having maximum stress value.

 EQ_op = dpf.operators.result.stress_von_mises()
 EQ_op.inputs.data_sources.connect(_StressDataSource_)
 EQ_op.inputs.mesh_scoping.connect(result_mesh_scoping)
 EQ_op_output= EQ_op.outputs.fields_container()

Any suggestions of existing utility or operators ?

rlagha commented 2 years ago

Hi @sarunarthy , Next release we will have the sort operator. Meanwhile you can use the high pass filter with a given threshold, here I use 0.85, to only get nodes having stress eqv > 0.85*max

model = dpf.Model(path2file)

# Get the von mises equivalent stress, requires an operator
s_eqv_op = dpf.operators.result.stress_von_mises()  
s_eqv_op.inputs.requested_location.connect(dpf.common.locations.nodal)
s_eqv_op.inputs.streams_container.connect(model.metadata.streams_provider)
vm_stress_fields = s_eqv_op.outputs.fields_container()

min_max = dpf.operators.min_max.min_max()
min_max.inputs.connect(vm_stress_fields)

scale =  dpf.operators.math.scale(min_max.outputs.field_max, 0.85)
high_pass = dpf.operators.filter.field_high_pass(s_eqv_op.outputs.fields_container,scale)
high_pass_out = high_pass.outputs.field()
print(high_pass_out.data)
print(high_pass_out.scoping.ids)
#high_pass_out.plot()
pthieffry commented 2 years ago

@sarunarthy for the time being, you can use something like this:

# Define results file to be used
dataSource = dpf.DataSources(rst_file)

# Number of values to retrieve
num_values=20
# Minimal stress value (will speedup operations)
threshold_stress=75.

# Dictionaries to store results
max_values={}

vmises = dpf.operators.result.stress_von_mises(data_sources=dataSource)

# Min_max operator will be used to identify highest values
min_max = dpf.operators.min_max.min_max() # operator instanciation

# Temporary operator
current_mises = vmises.outputs.fields_container()

# Filter used to progressively filter data when maxima are found
temp_filter = dpf.operators.filter.field_low_pass() # operator instanciation

# Filter out stresses below thresholdStress
init_filter = dpf.operators.filter.field_high_pass() # operator instanciation
init_filter.inputs.field.connect(current_mises)
init_filter.inputs.threshold.connect(threshold_stress)

# update currentMises with results from filter
current_mises = init_filter.outputs.field()

# Start looking for highest values
num_found=0
for num_found in range(0,num_values):
    # in current stress field, search for max value
    min_max.inputs.field.connect(current_mises)
    max_data = min_max.outputs.field_max.get_data()    

    max_values[num_found]=float(max_data.data[0])

    # Filter out anything above last max value from currentMises
    temp_filter.inputs.field.connect(current_mises)
    temp_filter.inputs.threshold.connect(max_values[num_found])    
    current_mises = temp_filter.outputs.field()

print(max_values)