Closed jlcuadros closed 2 years ago
Hi @jlcuadros, thank you for your enthusiasm! To apply an operator on a custom part of a field, you can use filtering operators. With your example, you can use a field_low_pass_fc operator with your fields_container as input and 0. as threshold. You can then connect this filtering operator as an input of the invert operator. Does that help?
Thank you for you quick response @cbellot000
I've tried but I dont understand
I have:
> s_m
DPF stress_1.s Field
Location: Nodal
Unit: MPa
3 entities
Data:6 components and 3 elementary `data`
> s_m.Data
[-0.17979685543105, 0.0533131614793092, ...
> Ratio
DPF Fields Container
with 1 field(s)
defined on labels: unknown
with:
- field 0 {unknown: 1} with Nodal location, 6 components and 3 entities.
> Ratio[0].Data
[1.5000009356126, 0.66666745519402, 0.666666726794763 ...
Then I do
op = dpf.operators.filter.field_low_pass() # operator instanciation
op.inputs.field.Connect(s_m)
op.inputs.threshold.Connect(0)
my_LowFilter = op.outputs.field.GetData()
my_LowFilter.Data
[-0.17979685543105, 0.0533131614793092, ...
but now... how can I use my_LowFilter
to invert only those values in Ratio
that correspond to nodes with s_m <0?
op = dpf.operators.math.invert_fc() # operator instanciation
op.inputs.fields_container.Connect(Ratio)
# where and how connect my_LowFilter??
my_fields_container = op.outputs.fields_container.GetData()
I´m sorry but I´m very new at dpf... I really appreciate your help, maybe there is an example with filters somewhere (I didn't find anything)
I feel that when I undestand the way this tool works it can changes all our workflow
Best regards
Jose
Are you using dpf in cpython with the ansys-dpf-core package or in mechanical? (I see that the syntax that you use is not the one of ansys-dpf-core). But anyways to connect your operators you can do:
low_pass = dpf.operators.filter.field_low_pass_fc() # operator instanciation
low_pass.inputs.fields_container.Connect(s_m)
low_pass.inputs.threshold.Connect(0.)
invert = dpf.operators.math.invert_fc() # operator instanciation
invert.inputs.fields_container.Connect(low_pass.outputs.fields_container)
my_fields_container = op.outputs.fields_container.GetData()
I´m using inside mechanical In your code, you dont use 'ratio', it looks like your are inverting the values of s_m that are <0 but that is not what I need I want to invert only those values in Ratio that correspond to values in s_m that are <0
s_m has 3 elementary data (3 nodes) and 6 components ratio has 3 elementary data (3 nodes) and 6 components
for each component ins_m
that is <0 I want to invert the component in ratio
that is in the same position
I also do not understand why after the aplication of the filter there are positive and negative values (-0.17.. and 0.05 for instance)
op = dpf.operators.filter.field_low_pass() # operator instanciation
op.inputs.field.Connect(s_m)
op.inputs.threshold.Connect(0.)
my_LowFilter = op.outputs.field.GetData()
[-0.17979685543105, 0.0533131614793092, 0.542114140465856, 0.000454103919764748, 1.3995936177671, 0.000625587835202168, -0.145697603467852, 0.0486476499354467, ...
Thanks again
Okay, sorry I misunderstood your needs, you can then use:
low_pass = dpf.operators.filter.scoping_low_pass() # operator instanciation
low_pass.inputs.fields_container.Connect(s_m)
low_pass.inputs.threshold.Connect(0.)
rescope = dpf.operators.scoping.rescope()
rescope.inputs.fields.Connect(Ratio)
rescope.inputs.mesh_scoping.Connect(low_pass.outputs.scoping)
invert = dpf.operators.math.invert_fc() # operator instantiation
invert.Connect(rescope)
my_fields_container = invert.outputs.fields_container.GetData()
scoping_low_pass returns the entity ids of the filtering and you can then rescope a field to those ids.
I needed a small change to run your code (field in stead of fields_container) low_pass.inputs.field.Connect(s_m) but still it does not do the job, it inverts everything. , that is not what I need, what i need is for each component in s_m that is <0 I want to invert the component in ratio that is in the same position
Ratio[0].Data
[1.5000009356126, 0.66666745519402, 0.666666726794763, 0.66653856190867, 0.666666611954064, 0.66670685133499, 1.50000022772077, 0.666664463751834, 0.666666619278295, 1.50000526100635, 0.666666662262696, 0.666667075884813, 1.49999693971766, 0.666667565459518, 0.666666673980272, 0.666666293928673, 0.666666655373701, 0.666666622787982]
>>>
my_fields_container[0].Data
[0.666666250839105, 1.49999822581555, 1.4999998647118, 1.50028829110268, 1.50000012310337, 1.49990958994592, 0.666666565457453, 1.50000495657475, 1.50000010662384, 0.666664328449823, 1.50000000990893, 1.49999907925974, 0.666668026794924, 1.49999797771881, 1.49999998354439, 1.50000083866095, 1.50000002540917, 1.50000009872705]
>>>
s_m.Data
[-0.17979685543105, 0.0533131614793092, 0.542114140465856, 0.000454103919764748, 1.3995936177671, 0.000625587835202168, -0.145697603467852, 0.0486476499354467, 0.545916012488306, -0.0191545530105941, 1.40982243791223, 0.0629022142384201, -0.0530191787402146, 0.034251943230629, 0.565960440784693, 0.0123628541768994, 1.46612031012774, 0.106124712154269]
This is the only way I could perform what i was looking for. I suppose it is very slow but I find no other way
Any suggestion to avoid the for loop is more than wellcome
thank you in advance and best regards
Jose Luis
op = dpf.operators.math.component_wise_divide_fc()
op.inputs.fields_containerA.Connect(sv_max)
op.inputs.fields_containerB.Connect(sv_min)
RatioMm = op.outputs.fields_container.GetData()
op.inputs.fields_containerA.Connect(sv_min)
op.inputs.fields_containerB.Connect(sv_max)
Ratio = op.outputs.fields_container.GetData()
lista =[]
for i,val in enumerate(s_m.Data):
if val >0:
lista.append(Ratio[0].Data[i])
else:
lista.append(RatioMm[0].Data[i])
Ratio[0].Data=lista
del(RatioMm)
sv_max, sv_min are nodal based DPF Fields Container with 1 field(s) defined on labels: unknown
with: field 0 {unknown: 1} with Nodal location, 6 components and 3 entities.
stress.inputs.mesh_scoping.Connect(scoping)
stress.inputs.time_scoping.Connect(time_scoping)
sv =stress.outputs.fields_container.GetData()
op_maxm = dpf.operators.min_max.min_max_over_time_by_entity()
op_maxm.inputs.fields_container.Connect(sv)
sv_max = sx_max=op_maxm.outputs.max.GetData()
sv_min = sx_min=op_maxm.outputs.min.GetData()
# s_m is
suma = dpf.operators.math.add()
suma.inputs.fieldA.Connect(sv_max)
suma.inputs.fieldB.Connect(sv_min)
aux= suma.outputs.field.GetData()
escala = dpf.operators.math.scale()
escala.inputs.field.Connect(aux)
escala.inputs.ponderation.Connect(0.5)
s_m = escala.outputs.field.GetData()
In stead of using a 6 component FC now I use 6 Fields so I can use rescoping to perform the task. Maybe there is a better way but this should be much faster than the "for" loop
Regards
Jose
Yes, dividing your stress fields by component (using the operator "component_selector_fc" for example) will allow you to remove the loops
Thank you for this fantastic tool!
Please I dont figure out this How can I apply a operation (ie invert the value) to certain elements of a FC?
I have a mesh and several load Cases I compute for each node the max over time and min over time stresses (Smax, Smin). I compute for each node Sm =(Smax+Smin)*0.5 I compute for each node R=Smin/Smax I want to invert in R only for those nodes with Sm<0
Thank you in advance
Best regards
Jose