How can I create the fibre orientation tensor file used by nCode using PyDPF-Composites?

Options
Javier Vique
Javier Vique Member, Employee Posts: 74
First Answer First Anniversary Name Dropper 5 Likes

When using fibre-share approach of Ansys nCode DesignLife Short-Fibre Composite, a csv file including the fibre orientation tensor per element is needed, which must be given in the same coordinate system as the stress analysis result. Can PyDPF-Composites help me on its creation?

Tagged:

Best Answer

  • Javier Vique
    Javier Vique Member, Employee Posts: 74
    First Answer First Anniversary Name Dropper 5 Likes
    Answer ✓
    Options

    The available examples in PyDPF-Composites allow us to understand how to read a11 and a22 from Mechanical. Good news is that nCode reads stresses in Solution Coordinate System and values of a11 & a22 are also given in that local coordinate system, so no reconstruct of the fiber orientation tensor in the global coordinate system is needed.
    We just need to bring a11 and a22 data into a .csv file with the format requested by Ansys nCode DesignLife. Below the code:

    import ansys.dpf.core as dpf
    import numpy as np
    import os
    
    from ansys.dpf.composites.constants import FailureOutput
    from ansys.dpf.composites.data_sources import get_composite_files_from_workbench_result_folder
    from ansys.dpf.composites.server_helpers import connect_to_or_start_server
    
    server = connect_to_or_start_server()
    
    # Read Workbench model
    data_sources = dpf.DataSources()
    data_sources.add_file_path(r'here your path\MECH\MatML.xml', "EngineeringData")
    data_sources.add_file_path(r'here your path\MECH\ds.dat', "dat")
    data_sources.set_result_file_path(r'here your path\MECH\file.rst', "rst")
    
    model = dpf.Model(data_sources)
    mesh = model.metadata.meshed_region
    
    field_variable_provider = dpf.Operator("composite::inistate_field_variables_provider")
    field_variable_provider.inputs.data_sources(data_sources)
    field_variable_provider.inputs.mesh(model.metadata.mesh_provider)
    
    field_variables = field_variable_provider.outputs.fields_container.get_data()
    a11 = field_variables[0]
    a22 = field_variables[1]
    
    ids = field_variables[0].scoping.ids
    a11data = a11.data_as_list
    a22data = a22.data_as_list
    
    a33data = np.ones(len(a11data))
    a33data = a33data - a11data - a22data
    a33data = np.around(a33data,6)
    
    FOT_file = os.path.join(r'here your path',"FOT.csv")
    with open(FOT_file, "w") as f:
        f.write('#HEADER\n')
        f.write('#CHANTITLE\n')
        f.write('Orientation Tensors\n')
        f.write('#TITLES\n')
        f.write('Element,Layer Number,Section Point,a11,a22,a33,a12,a23,a13\n')
        f.write('#KEYWORDS\n')
        f.write('ElementID,LayerNumber,SectionPoint,a11,a22,a33,a12,a23,a13\n')
        f.write('#DATATYPES\n')
        f.write('LONG,LONG,LONG,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT\n')
        f.write('#DATA\n')
        [f.write(str(ids[i]) + ',1,1,' + str(a11data[i]) + ','+ str(a22data[i]) + ','+ str(a33data[i]) 
                 + ',0.,0.,0.\n') for i in range(len(ids))]
    

Answers

  • Javier Vique
    Javier Vique Member, Employee Posts: 74
    First Answer First Anniversary Name Dropper 5 Likes
    Options

    Here the script if we would like to stay at mech-dpf:

    def _load_plugins():
        # utility function to load the dpf composites plugins
        import os
        import mech_dpf
        import Ans.DataProcessing as dpf
    
        version = Ansys.Utilities.ApplicationConfiguration.DefaultConfiguration.VersionInfo.VersionString
        dpf_root = os.path.join(os.environ["AWP_ROOT"+version], "dpf")
        composites_root = os.path.join(dpf_root, "plugins", "dpf_composites")
        dpf.DataProcessingCore.LoadLibrary('EngineeringData', os.path.join(dpf_root, 'bin', 'winx64', 'Ans.Dpf.EngineeringData.dll'), 'LoadOperators')
        dpf.DataProcessingCore.LoadLibrary('composites', os.path.join(composites_root, 'composite_operators.dll'), 'LoadOperators')
    ########################################################
    
    _load_plugins()
    
    analysis = ExtAPI.DataModel.Project.Model.Analyses[0]
    working_directory = analysis.WorkingDir
    
    engd_path = os.path.join(working_directory, "MatML.xml")
    rst_path = os.path.join(working_directory, "file.rst")
    dat_path = os.path.join(working_directory, "ds.dat")
    
    data_sources = dpf.DataSources()
    data_sources.AddFilePath(engd_path, "EngineeringData")
    data_sources.AddFilePath(dat_path, "dat")
    
    rst_data_source = dpf.DataSources()
    rst_data_source.SetResultFilePath(rst_path)
    model=dpf.Model(rst_data_source)
    mesh = model.Mesh
    
    fot_values = dpf.Operator("composite::inistate_field_variables_provider")
    fot_values.Connect(4, data_sources)
    fot_values.Connect(7, mesh)
    
    # extract a11 & a22 data
    extract_field = dpf.operators.utility.extract_field()
    extract_field.inputs.fields_container.Connect(fot_values, 0)
    extract_field.inputs.indices.Connect([0])
    a11_data = extract_field.outputs.field.GetData()
    extract_field.inputs.indices.Connect([1])
    a22_data = extract_field.outputs.field.GetData()
    ids = a11_data.ScopingIds
    a11data = a11_data.Data
    a22data = a22_data.Data
    a33data = [1.0] * len(ids)
    a33data = [x - y - z for x, y, z in zip(a33data, a11data, a22data)]
    FOT_file = os.path.join(r'here your path',"FOT.csv")
    with open(FOT_file, "w") as f:
        f.write('#HEADER\n')
        f.write('#CHANTITLE\n')
        f.write('Orientation Tensors\n')
        f.write('#TITLES\n')
        f.write('Element,Layer Number,Section Point,a11,a22,a33,a12,a23,a13\n')
        f.write('#KEYWORDS\n')
        f.write('ElementID,LayerNumber,SectionPoint,a11,a22,a33,a12,a23,a13\n')
        f.write('#DATATYPES\n')
        f.write('LONG,LONG,LONG,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT\n')
        f.write('#DATA\n')
        [f.write(str(ids[i]) + ',1,1,' + str(a11data[i]) + ','+ str(a22data[i]) + ','+ str(a33data[i]) + ',0.,0.,0.\n') for i in range(len(ids))]
    
  • Javier Vique
    Javier Vique Member, Employee Posts: 74
    First Answer First Anniversary Name Dropper 5 Likes
    Options

    If our analysis is made with WB-Dyna, nCode input file can be also created. 2 imported material fields needs to be created with a11 and a22 values and then make use of the method ExportToTextFile(). Depending on model size, more time might be needed between creating a11 & a22 files and reading them. Here the script:

    import time
    import os
    
    my_path = 'here_your_path'
    
    a11 = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.ImportedMaterialField)[0]
    a22 = ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.ImportedMaterialField)[1]
    a11.ExportToTextFile(os.path.join(my_path,'a11.txt'))
    a22.ExportToTextFile(os.path.join(my_path,'a22.txt'))
    
    time.sleep(5)
    FOT = {}
    
    with open(os.path.join(my_path,'a11.txt'),'r') as f:
        data = f.readlines()
        data = data[1:]
        for row in data:
            FOT[row.split('\t')[0]] = [row.split('\t')[4]]
    
    with open(os.path.join(my_path,'a22.txt'),'r') as f:
        data = f.readlines()
        data = data[1:]
        for row in data:
            FOT[row.split('\t')[0]].append(row.split('\t')[4])
    
    FOT_file = os.path.join(my_path,'FOT.csv')
    with open(FOT_file, "w") as f:
        f.write('#HEADER\n')
        f.write('#CHANTITLE\n')
        f.write('Orientation Tensors\n')
        f.write('#TITLES\n')
        f.write('Element,Layer Number,Section Point,a11,a22,a33,a12,a23,a13\n')
        f.write('#KEYWORDS\n')
        f.write('ElementID,LayerNumber,SectionPoint,a11,a22,a33,a12,a23,a13\n')
        f.write('#DATATYPES\n')
        f.write('LONG,LONG,LONG,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT\n')
        f.write('#DATA\n')
        [f.write(i + ',1,1,' + FOT[i][0] + ','+ FOT[i][1] + ','+ 
                str(1.0-float(FOT[i][0])-float(FOT[i][1])) + ',0.,0.,0.\n') for i in FOT.keys()]