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 it but 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