ansys / pydpf-core

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

PyMAPDL nodal stress averaging #841

Open agrishin opened 1 year ago

agrishin commented 1 year ago

From Costas Vogiatzis at Honeywell, Note two separate questions below (one in each paragraph):

"I am using the PyMAPDL reader to access stress/strain results in RST files. It appears that the nodal stresses are the reader returns are the equivalent of APDL “Full graphics”, i.e. they are the averaged values over all the elements that share that node, not only surface elements (which is the case in “Power Graphics” in APDL). Is there a way to get the equivalent of “Power graphics” nodal stresses/strains with the PyMAPDL reader? If not, can it be done with DPF?

Somewhat related to this… For a cyclic symmetric solution it is possible to get nodal stresses as complex numbers or at a user defined phase. Is there a way to do that for element stresses either with the PyMAPDL reader or DPF?"

Alex Grishin alex.grishin@padtinc.com PADT

germa89 commented 1 year ago

Editing to hide some personal data.

rlagha commented 1 year ago

Hi @agrishin, please could you try the script below using pyDPF to reproduce power graphics stress nodal averaging:

from ansys.dpf import core as dpf
model = dpf.Model(r"D:\temp\file.rst")
mesh = model.metadata.meshed_region
skinOp = dpf.operators.mesh.skin(mesh)
skin_mesh = skinOp.outputs.mesh()
stress = model.results.stress()
solidToSkin = dpf.operators.mapping.solid_to_skin(field=stress.outputs.fields_container, mesh_scoping=skin_mesh)
field = solidToSkin.eval()
toNodal = dpf.operators.averaging.to_nodal(solidToSkin.outputs.field)
fieldN = toNodal.eval()
print(fieldN)

#plot SX
compselector = dpf.operators.logic.component_selector(field = toNodal.outputs.field, component_number=0)
fieldSX = compselector.eval()
mesh.plot(fieldSX, notebook=False)

Regards

agrishin commented 1 year ago

That works for me, but unfortunately, I don’t have a model ready at-hand that shows an obvious difference full and power graphics in MAPDL. I’ll forward to the customer and see what he thinks…

Alex Grishin

rlagha commented 1 year ago

@agrishin please find bellow a new example in ansys-dpf-core showing how to get the cyclic results wrt base/duplicate sectors and also how to get results at a given cyclic phases: https://dpf.docs.pyansys.com/release/0.7/examples/11-cyclic-symmetry/02-modal_cyclic_no_expansion.html#sphx-glr-examples-11-cyclic-symmetry-02-modal-cyclic-no-expansion-py

Regards

agrishin commented 1 year ago

Thanks, Ramdane! I’ll forward to the customer…

Alex Grishin, PhD

germa89 commented 1 year ago

Once I have an got-to-go from Alex and/or Ramdame I will proceeded to close this issue.

rlagha commented 1 year ago

@germa89 , for the cyclic symmetry question, this is completely done. For the power graphics question, the proposed script allows to average the stresses taking into account only the elements having faces on the skin. In MAPDL we add an other criteria which avoids averaging cross sharp edges. we should add this capability but I'd like to have the feedback from @agrishin . We can close this one and create an enhancement issue in DPF side for the sharp edges.

costasva commented 1 year ago

@rlagha Script above fails. pip freeze output is in requirements.txt. ANSYS 2022R2 installed on the system where this is run.

python load_nodal_max.py Traceback (most recent call last): File "C:\Users\e092220\Documents\Software\FCDSLib-Dev\load_nodal_max.py", line 8, in field = solidToSkin.eval() File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\dpf_operator.py", line 626, in eval return self.outputs._outputs[0]() File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\outputs.py", line 58, in call return self.get_data() File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\outputs.py", line 55, in get_data return self._operator.get_output(self._pin, type_output) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\dpf_operator.py", line 455, in get_output parameters = {type_tuple[2]: type_tuple[1](self, pin)} File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\gate\errors.py", line 38, in wrapper out = func(*args, **kwargs) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\gate\operator_grpcapi.py", line 256, in operator_getoutput_field return OperatorGRPCAPI.get_output_finish(op, request, stype, subtype) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\gate\errors.py", line 46, in wrapper raise DPFServerException(details) from None ansys.dpf.gate.errors.DPFServerException: solid_to_skin:31<-a field or a field container containing one field is expected for this pin C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py:1236: UserWarning: Traceback (most recent call last): File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py", line 1224, in shutdown self._shutdown_func0 File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\grpc_channel.py", line 946, in call return _end_unary_response_blocking(state, call, False, None) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\grpc_channel.py", line 849, in _end_unary_response_blocking raise _InactiveRpcError(state) grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNIMPLEMENTED details = "" debug_error_string = "UNKNOWN:Error received from peer ipv4:127.0.0.1:50055 {grpc_message:"", grpc_status:12, created_time:"2023-03-14T14:24:13.907367647+00:00"}"

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py", line 1227, in shutdown if self.meet_version("4.0"): File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py", line 599, in meet_version return server_meet_version(required_version, self) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\check_version.py", line 29, in server_meet_version return meets_version(version, required_version) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\check_version.py", line 82, in meets_version from packaging.version import parse ImportError: sys.meta_path is None, Python is likely shutting down

requirements.txt

costasva commented 1 year ago

Issue persists with latest DPF packages requirements-latest.txt

germa89 commented 1 year ago

Transferred to DPF repo.

rlagha commented 1 year ago

@PProfizi , please could you have a look into this issue?

PProfizi commented 1 year ago

@rlagha Script above fails. pip freeze output is in requirements.txt. ANSYS 2022R2 installed on the system where this is run.

python load_nodal_max.py Traceback (most recent call last): File "C:\Users\e092220\Documents\Software\FCDSLib-Dev\load_nodal_max.py", line 8, in field = solidToSkin.eval() File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\dpf_operator.py", line 626, in eval return self.outputs._outputs0 File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\outputs.py", line 58, in call return self.get_data() File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\outputs.py", line 55, in get_data return self._operator.get_output(self._pin, type_output) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\dpf_operator.py", line 455, in get_output parameters = {type_tuple[2]: type_tuple[1](self, pin)} File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\gate\errors.py", line 38, in wrapper out = func(*args, kwargs) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\gate\operator_grpcapi.py", line 256, in operator_getoutput_field return OperatorGRPCAPI.get_output_finish(op, request, stype, subtype) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\gate\errors.py", line 46, in wrapper raise DPFServerException(details) from None ansys.dpf.gate.errors.DPFServerException: solid_to_skin:31<-a field or a field container containing one field is expected for this pin C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py:1236: UserWarning: Traceback (most recent call last): File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py", line 1224, in shutdown self._shutdown_func0 File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\grpc_channel.py", line 946, in call** return _end_unary_response_blocking(state, call, False, None) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\grpc_channel.py", line 849, in _end_unary_response_blocking raise _InactiveRpcError(state) grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNIMPLEMENTED details = "" debug_error_string = "UNKNOWN:Error received from peer ipv4:127.0.0.1:50055 {grpc_message:"", grpc_status:12, created_time:"2023-03-14T14:24:13.907367647+00:00"}"

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py", line 1227, in shutdown if self.meet_version("4.0"): File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\server_types.py", line 599, in meet_version return server_meet_version(required_version, self) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\check_version.py", line 29, in server_meet_version return meets_version(version, required_version) File "C:\Users\e092220.venv\3.9.6\fcdslib-ansys22R2\lib\site-packages\ansys\dpf\core\check_version.py", line 82, in meets_version from packaging.version import parse ImportError: sys.meta_path is None, Python is likely shutting down

requirements.txt

Hello @costasva, it seems from the error message that the solid_to_skin operator in the script provided is given data which is partitioned instead of being "flat": ansys.dpf.gate.errors.DPFServerException: solid_to_skin:31<-a field or a field container containing one field is expected for this pin What this most likely means is that in your case, the data is partitioned by element shape (shell vs solid) or for real vs imaginary part.

Based on the initial question (For a cyclic symmetric solution it is possible to get nodal stresses as complex numbers or at a user defined phase) I think the script provided could be modified to handle the case of complex data and/or shell+solid data, .

The following modified script should be able to handle your case:

from ansys.dpf import core as dpf

# Load the data in a Model
model = dpf.Model(r"D:\temp\file.rst")

# Get result of interest
stress = model.results.stress()  # stress operator (elemental nodal data)

# Treat complex data
requested_phase = 90.
sweep_phase = dpf.operators.math.sweeping_phase_fc(  # sweeping_phase operator
    fields_container=stress.outputs.fields_container,  # connect the stress operator output
    angle=requested_phase,  # phase
    unit_name="degree",  # unit of phase
    abs_value=False,  # whether to return absolute values
)

# Treat shell data
change_shell_layer = dpf.operators.utility.change_shell_layers(  # select a shell layer to plot
    fields_container=sweep_phase.outputs.fields_container,
    e_shell_layer=dpf.shell_layers.top.value,  # ask for top layer data
)
merge_shell_and_solids = dpf.operators.logic.solid_shell_fields(  # merge solid and shell data
    fields_container=change_shell_layer.outputs.fields_container_as_fields_container
)

# Skin operation
mesh = model.metadata.meshed_region  # get the volume mesh
skinOp = dpf.operators.mesh.skin(mesh)  # mesh skin operator
skin_mesh = skinOp.outputs.mesh()  # mesh skin operator output
solidToSkin = dpf.operators.mapping.solid_to_skin(  # data to skin operator
    field=merge_shell_and_solids.outputs.fields_container,  # sweep_phase operator output
    mesh_scoping=skin_mesh  # mesh skin operator output
)
field = solidToSkin.eval()  # map data on mesh skin

# Nodal averaging
toNodal = dpf.operators.averaging.to_nodal(solidToSkin.outputs.field)  # average on nodes operator
fieldN = toNodal.eval()  # evaluate average on nodes

# Component selection
compselector = dpf.operators.logic.component_selector(  # component selection operator
    field=toNodal.outputs.field,  # data
    component_number=0  # select X
)
fieldSX = compselector.eval()  # evaluate component selection
print(fieldSX)

# Plotting
mesh.plot(fieldSX, notebook=False)  # Plot the result on the solid mesh

Btw, the next release of PyDPF-Post (by the end of month) will enable you to handle the case of result extraction for a phase with a one-liner.

costasva commented 1 year ago

Hello @PProfizi - Can you please explain how the above can be done with a one-liner in the current DPF version?

rlagha commented 1 year ago

@cbellot000 , please could you share you experience on doing the cyclic expansion only on external element layer, and on the skin? @costasva