Script Tip Friday- Export temperature results for each DP of a DOE analysis

Script Tip Friday- Export temperature results for each DP of a DOE analysis

No alt text provided for this image

This week’s script tip comes from our very own?Pernelle Marone-Hitz, Lead Application Engineer at Ansys. In this tip, we’ll be exploring how to export temperature results for each DP of a DOE analysis.



The Python Code object can be used for this.

First, insert a temperature result that will be used for all DPs:

No alt text provided for this image

Then, insert a Python Code object

No alt text provided for this image

this will be triggered after post:

No alt text provided for this image

Modify the Property Provider so that this object uses an input parameter:

def reload_props():
    this.PropertyProvider = None
    # Create the property instance
    provider = Provider()
    # Create a group named Group 1.
    group = provider.AddGroup("Parameter")
    # Create a property with control type Expression and a property with control type Double, and add it to the Group 1
    double_prop = group.AddProperty("DPValue", Control.Double)
    double_prop.CanParameterize = True
    double_prop.ParameterType = ParameterType.Input
    
    this.PropertyProvider = provider
    

# region Property Provider Template
from Ansys.ACT.Mechanical.AdditionalProperties import PropertyProviderAdapter
from Ansys.ACT.Mechanical.AdditionalProperties import *

"""
The property_templates module is located in %awp_root212%\aisol\DesignSpace\DSPages\Python\mech_templates
"""
from mech_templates import property_templates

property_templates.set_ext_api(ExtAPI)

class Provider(Ansys.ACT.Interfaces.Mechanical.IPropertyProvider):
    """
    Provider template that implements IPropertyProvider to demonstrate the usage of IPropertyProvider.
    It provides helper methods and classes that manage properties that can be dynamically added to an object.
    """
    
    # region These are callbacks that as a user you may want to modify to get specific behavior
    def IsValid(self, prop):
        """
        Called when checking the validity of a property, with the property instance.
        """

        # for double property use the ValidRange property to check validity
        if(isinstance(prop, DoubleProperty)):
            return prop.ValidRange[0] <= prop.Value and prop.ValidRange[1] >= prop.Value
        
        return True
    
    def IsReadOnly(self, prop):
        """
        Called when checking if a property should be readonly, with the property instance.
        """

        return False
    
    def IsVisible(self, prop):
        """
        Called when checking if a property should be visible, with the property instance.
        """

        return True
    
    def SetValue(self, prop, val):
        """
        Allows you to override the setter of the Value property on the property instance. 
        Keyword Arguments:
            prop -- property of which the value is being set
            val -- the value that was set
        Returns:
            The value that the Value property should be set to
        """
        return val

    def GetValue(self, prop, val):
        """
        Allows you to override the getter of the Value property on the property instance. 
        Keyword Arguments:
            prop -- property of which the value is being set
            val -- current value of the Value property
        Returns:
            The value that the getter on the internal value should return
        """
        return val
    # endregion   
    
    # structures that hold property instances
    prop_list = []
    prop_map = {}
    prop_groups = set()

    class __AnsGroup():
        """
        Helper group class to group properties, and provides methods to add properties to groups.
        """
        provider = None
        def __init__(self,name=None, provider=None):
            self.name = name
            self.provider = provider
        
        def __AddScopingProperty(self, name):
            """
            Adds a scoping property with a given name to this group.
            
            Keyword Arguments : 
                name -- unique name for the scoping property
            """
            scoping_prop = property_templates.ScopingProperty(name, self.name)
            
            for prop in scoping_prop.GetGroupedProps():
                self.provider.AddProperty(prop)
            return scoping_prop.GetGroupedProps()
        
        def AddProperty(self, name=None, prop_control=None, module_name=None):
            """
            Creates an instance of the property and connects delgates in 
            the associated Property Propvider.

            Keyword Arguments : 
                name -- unique name for the scoping property
                prop_control -- one of the built in controls, or extended controls
                module_name -- module where the control is defined
            """

# special case for scoping property
if(prop_control == "Scoping" and module_name == "property_templates"):
                return self.__AddScopingProperty(name)

# if no module_name is passed, use the globals in current module
# that has the built in controls imported
prop_mod_globals = None
         if(module_name != None):
                if(module_name not in globals()):
                    raise Exception("Unknown module : " + module_name)
                
                prop_mod_globals = globals()[module_name].get_globals()
            else:
                prop_mod_globals = globals()
            
            #class name is built based on control + "Property"
            #    Double - > DoubleProperty
            prop_class_name = str(prop_control) + "Property"
            
            if(prop_class_name not in prop_mod_globals):
                raise Exception("Unknown property class : " + prop_class_name)
            # instantiate the property based on module and class name
            prop = prop_mod_globals[prop_class_name](self.name + "/" + name, self.name)
            
            if(prop == None):
                raise Exception("Issue while creating the property instance.")
            # set the delegates to property provider functions
            prop.IsValidCallback = self.provider.IsValid
            prop.IsReadOnlyCallback = self.provider.IsReadOnly
            prop.IsVisibleCallback = self.provider.IsVisible
            prop.GetValueCallback = self.provider.GetValue
            prop.SetValueCallback = self.provider.SetValue
# as a default make the property name the property display name
prop.DisplayName = name
            # add property to the provider
            self.provider.AddProperty(prop)
            
            return prop
        
    def __init__(self):
        pass

    def GetProperties(self):
        """
        Returns a list of properties in the order that they were added to the property provider. 
        """
        return [self.prop_map[propName] for propName in self.prop_list]
    
    def AddGroup(self, name=None):
        """
        Creates an instance of helper group class and returns it.
        """
        if name in self.prop_groups:
            raise Exception("Group with name " + name + " already exists, please use a unique group name.")
        # keep groups names so we can make sure no duplicate groups are added
        self.prop_groups.add(name)
        
        return self.__AnsGroup(name, self)
    
    def AddProperty(self, prop):
        """
        Method used by the helper group class to add the property to the data-structure holding
        the property instances.
        """
        if(prop.Name in self.prop_map):
            raise Exception("Property name must be unique, property with name '" + prop.Name + "' already exisits.")
        
        self.prop_list.append(prop.Name)
        self.prop_map[prop.Name] = prop
# end region
"""
Reload the properties at the end to make sure the class definition is executed before instantiation
"""
reload_props()
# special case for scoping property
            if(prop_control == "Scoping" and module_name == "property_templates"):
                return self.__AddScopingProperty(name)
            # if no module_name is passed, use the globals in current module
# that has the built in controls imported
prop_mod_globals = None
            if(module_name != None):
                if(module_name not in globals()):
                    raise Exception("Unknown module : " + module_name)
                
                prop_mod_globals = globals()[module_name].get_globals()
            else:
                prop_mod_globals = globals()
            
            #class name is built based on control + "Property"
            #    Double - > DoubleProperty
            prop_class_name = str(prop_control) + "Property"
            
            if(prop_class_name not in prop_mod_globals):
                raise Exception("Unknown property class : " + prop_class_name)
            # instantiate the property based on module and class name
            prop = prop_mod_globals[prop_class_name](self.name + "/" + name, self.name)
            
            if(prop == None):
                raise Exception("Issue while creating the property instance.")
            # set the delegates to property provider functions
            prop.IsValidCallback = self.provider.IsValid
            prop.IsReadOnlyCallback = self.provider.IsReadOnly
            prop.IsVisibleCallback = self.provider.IsVisible
            prop.GetValueCallback = self.provider.GetValue
            prop.SetValueCallback = self.provider.SetValue
# as a default make the property name the property display name
prop.DisplayName = name
            # add property to the provider
            self.provider.AddProperty(prop)
            
            return prop
        
    def __init__(self):
        pass

    def GetProperties(self):
        """
        Returns a list of properties in the order that they were added to the property provider. 
        """
        return [self.prop_map[propName] for propName in self.prop_list]
    
    def AddGroup(self, name=None):
        """
        Creates an instance of helper group class and returns it.
        """
        if name in self.prop_groups:
            raise Exception("Group with name " + name + " already exists, please use a unique group name.")
        # keep groups names so we can make sure no duplicate groups are added
        self.prop_groups.add(name)
        
        return self.__AnsGroup(name, self)
    
    def AddProperty(self, prop):
        """
        Method used by the helper group class to add the property to the data-structure holding
        the property instances.
        """
        if(prop.Name in self.prop_map):
            raise Exception("Property name must be unique, property with name '" + prop.Name + "' already exisits.")
        
        self.prop_list.append(prop.Name)
        self.prop_map[prop.Name] = prop
# end region
"""
Reload the properties at the end to make sure the class definition is executed before instantiation
"""
reload_props()        

As for the script part, two methods are used. One to grab the user_files directory, one called during execution to grab the existing temperature result and export the data to a csv file:

import os

def GetUserFileFolder(analysis):
    '''
        Return UserDir: path of the folder
    '''
    try:
        WorkDir = analysis.WorkingDir
        UserDir = os.path.dirname(WorkDir)
        for i in range(3):
            UserDir = os.path.dirname(UserDir)
        UserDir = os.path.join(UserDir, 'user_files')
        if not os.path.exists(UserDir):
            os.makedirs(UserDir)
        return UserDir
    except:
        ExtAPI.Log.WriteMessage("Error : Exception in GetUserFileFolder()")
        return None

def after_post(this, solution):# Do not edit this line
    temp_result = ExtAPI.DataModel.Project.Model.GetChildren(DataModelObjectCategory.TemperatureResult,True)[0]
    user_files = GetUserFileFolder(solution.Parent)
    DPValue = this.GetCustomPropertyByPath("Parameter/DPValue").Value
    file_name = "TemperatureResult_" + str(DPValue) + ".csv"
    temp_result.ExportToTextFile(os.path.join(user_files,file_name))        

From the parameter set, define a value for the DPValue parameter (defined in the properties provider) so that each export file has a different name:

No alt text provided for this image

When the DPs are updated, the exported files will be saved to the user_files directory:

No alt text provided for this image

Finally, some other useful tips:

  • For the exported file to include nodal location, from Mechanical, go to File / Options / Export / Include Node Location.
  • For the Python code object to work during a DOE, from the WB project schematic, go to Tools / Options / Mechanical / Connect run Python code objects when Mechanical is launched

Do YOU have a Script Tip you'd like to share? Comment below and someone from Ansys will reach out so we can feature you on the next Script Tip Friday!

要查看或添加评论,请登录

Ansys Structures的更多文章

社区洞察

其他会员也浏览了