Convert PlotData of User Defined Result to a DPF field and plot it

In Mechanical scripting, how can I retrieve the data from a user-defined result and plot it as a Python Result ?
Answers
-
A user-defined result (UDR) is inserted in Mechanical :
A property is added to the Python Result for the user to provide the name of the UDR:
This is achieved by modifying the Property Provider of the Python Result:
The piece of code of interest here is:
- def reload_props():
- this.PropertyProvider = None
- # Create the property instance
- provider = Provider()
- input_group = provider.AddGroup("Input")
- ns_prop = input_group.AddProperty("UDR Name", Control.Expression)
- # Connects the provider instance back to the object by setting the PropertyProvider member on this, 'this' being the
- # current instance of the Python Code object.
- this.PropertyProvider = provider
Then, the Script part of the Python Result is edited:
The code that is needed here is :
- def post_started(sender, analysis):# Do not edit this line
- define_dpf_workflow(analysis)
- def define_dpf_workflow(analysis):
- # import DPF
- import mech_dpf
- import Ans.DataProcessing as dpf
- mech_dpf.setExtAPI(ExtAPI)
- # Connect to result file
- dataSource = dpf.DataSources(analysis.ResultFileName)
- # Retrieve mesh
- model=dpf.Model(dataSource)
- mesh=model.Mesh # whole mesh
- # Retrieve property values
- udr_name = str(this.GetCustomPropertyByPath("Input/UDR Name").Value)
- # Access User Defined Result and create a field out of it
- udr = ExtAPI.DataModel.GetObjectsByName(udr_name)[0]
- nb_nodes = len(udr.PlotData['Node']) # get number of nodes
- udr_field = dpf.FieldsFactory.CreateScalarField(nb_nodes) # instanciate field
- udr_field.MeshedRegionSupport = mesh # attach mesh
- udr_field.ScopingIds = udr.PlotData['Node'] # give list of nodes
- udr_field.Data = [0. for i in range(0,nb_nodes)]# fill field with zeros
- node_ids = udr.PlotData['Node']
- values = [value for value in udr.PlotData['Values']]
- for ii in range(0,nb_nodes):
- index=udr_field.ScopingIds.IndexOf(node_ids[ii]) # get index of node in created field
- udr_field.UpdateEntityDataByEntityIndex(index,[values[ii]])
- # Create field operator for plotting
- forward = dpf.operators.utility.forward_field()
- forward.inputs.field.Connect(udr_field)
- dpf_workflow = dpf.Workflow()
- dpf_workflow.Add(forward)
- dpf_workflow.SetOutputContour(forward)
- dpf_workflow.Record('wf_id', False)
- this.WorkflowId = dpf_workflow.GetRecordedId()
This code grabs the UDR, extract the values in it thanks to PlotData, and passes those values to a DPF Field to be able to plot it in the Python Result object.
1 -
Pernelle:
Thanks so much for posting this!
I was able to do some (work) cool application by mouse click applying itbut it failed with automation
Why? DPF Python Result is "def post_started(sender, analysis):", i.e. it runs before UDR data is populated by post. On the other hand, a Python Code object is "def after_post(this, solution)", i.e. it runs after UDR data is populated by post - what is needed to use UDR results in DPF with automation. Do you have any suggestions for how to do this? I tried putting time.sleep(time_sleep) in the DPF code but it did not work.
Cordially,
Ray0 -
Hi @Ray_Greene , glad you found that post useful! Indeed I hadn't realized this would not work in an automated way. There is unfortunately no workaround possible, the only solution would be to execute the two objects manually and in a successive manner.
I also tried having a Python Code object in "after post" unsuppress the Python Result and evaluate, but Python Results do not have a Suppressed / Unsuppressed status so this is not a viable path either.
Looks like something that could be improved, I'll let the developers know.0