How to create a Python Result with a node scoping option and results coming from another result obj?
I evaluated a result with “Max over Time” on hundres of steps, which takes a lot of time to evaluate. Now, I would like to zoom into certain area, select FE items, say Nodes, plot this result only on those nodes without having to change the scope of the original result and reevaluate. Python result seems to be a solution. An example could help.
Answers
-
One could create a python result to extract results from an already evaluated result object via obj.PlotData option, and pass the result data to a custom field which can then be plotted via Python Result.
Here is an example. There are two parts. Script part and Property Provider path. Please paste them at respective locations once you insert a new python result object, then Reload properties, select an already evaluated result (give a unique name if there are duplicates), select some nodes, and evaluate the python result.
This can be extended to element selection as well I suppose with some more changes.
Script part:
def post_started(sender, analysis):# Do not edit this line define_dpf_workflow(analysis) # Uncomment this function to enable retrieving results from the table/chart # def table_retrieve_result(value):# Do not edit this line # import mech_dpf # import Ans.DataProcessing as dpf # wf = dpf.Workflow(this.WorkflowId) # wf.Connect('contour_selector', value) # this.Evaluate() def define_dpf_workflow(analysis): import mech_dpf import Ans.DataProcessing as dpf mech_dpf.setExtAPI(ExtAPI) dataSource = dpf.DataSources(analysis.ResultFileName) nodeIdsScoped = this.GetCustomPropertyByPath("My Properties/Scoping Property/Geometry Selection").Value.Ids myResult = this.GetCustomPropertyByPath("My Properties/Result Selection").ValueString myResultObj = DataModel.GetObjectsByName(myResult)[0] myResultPlotData = myResultObj.PlotData node_to_result = dict(zip(myResultPlotData["Node"], myResultPlotData["Values"])) filtered_results = [node_to_result[node_id] for node_id in nodeIdsScoped] npl_field = dpf.FieldsFactory.CreateScalarField(nodeIdsScoped.Count, "Nodal") npl_field.Data = filtered_results my_scoping = dpf.Scoping() my_scoping.Location = "Nodal" my_scoping.Ids = nodeIdsScoped npl_field.Scoping = my_scoping forward = dpf.operators.utility.forward_field() forward.inputs.field.Connect(npl_field) dpf_workflow = dpf.Workflow() dpf_workflow.Add(forward) dpf_workflow.SetOutputContour(forward) dpf_workflow.Record('wf_id', False) this.WorkflowId = dpf_workflow.GetRecordedId()
Property Provider part: Paste the below 3 functions in place of already existing reload_props() function. So, the old reload_props() is replaced and two new functions added i.e. get_options_handler() and dropDownValid().
def reload_props(): this.PropertyProvider = None # comment the following return to allow the rest of the function definition to be executed and add properties #return """ Some sample code is provided below that shows how to: 1. Create an instance of the Provider. The Provider class is used to add custom properties to the details. 2. Use the Provider instance to add custom properties. 3. Configure those custom properties. """ # Create the property instance provider = Provider() #expression_prop = group.AddProperty("Expression Property 1", Control.Expression) # Expression is a string # ## Configure the double property to be parameterizable. As a default the property will be an input parameter. ## However, by updating the ParameterType property, it can be configured to be a output parameter as well. ## double_prop.CanParameterize = True ## double_prop.ParameterType = ParameterType.Output # ## The valid range set here is used by the IsValid handler in the Provider class, please look at the class definition above. ## If interested in the implementation, please look at the class definition below #double_prop.ValidRange = (1.0, 4.0) # Create a new group named Group 2. group_two = provider.AddGroup("My Properties") options_prop = group_two.AddProperty("Result Selection", Control.Options) options_prop.GetOptionsCallback= get_options_handler options_prop.IsValidCallback = dropDownValid # Add a scoping property to the second group created above scoping_prop = group_two.AddProperty("Scoping Property", "Scoping", "property_templates") ## Add an options property to the second group #options_prop = group_two.AddProperty("Options Property", Control.Options) # ## Add a couple options to the options property. #options_prop.Options = {1 : "Value 1", 2 : "Value 2"} # 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 def get_options_handler(prop): global opt try: numOptions_beforeRefresh = len(opt) except: ExtAPI.Log.WriteMessage("Opt is not yet defined") opt = {} num_opt=1 for comp in [child for child in ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.Result) if child.Parent == this.Parent]: opt[num_opt] = comp.Name num_opt+=1 if prop.Value != None: if str(prop.Value) > str(len(opt)): prop.Value = None if "numOptions_beforeRefresh" in locals(): if numOptions_beforeRefresh > len(opt): prop.Value = None return opt def dropDownValid(prop): if prop.Value==None: return False elif prop.ValueString.isnumeric() == True: return False else: return True
0