Body mass modification in Mechanical ACT

Pavel
Pavel Member Posts: 9
First Comment Photogenic Name Dropper First Answer
**
edited June 2023 in Structures

(I was about to drop this in SR but maybe it will be more useful in this public space.)

We have a need for modifying mass of bodies in Mechanical. That is: mass that doesn't match the material density*volume.

So my question is whether there is some way to implement this either natively (enhancement request) or using ACT? The closets I can think of is:

  1. making a copy of given material (System's Engineering Data) for all target bodies
  2. Calculate target density and change it in the copied materials
  3. Assign the copied materials to those scoped bodies.

Things get more complicated with multiple materials involved with multiple bodies but that's just mathematical and results with more material duplicates. This is ok solution but I'd like to hear from you whether you have some better idea to achieve this.

Alternatives

We don't find these handy but adding for context of what we've considered or even implemented

  • Previously we employed APDL and made ACT object wrapper for the APDL code but one big drawback is that we don't get to see that change inside Mechanical. Additionally I'm not sure how well this works when combining systems into assemblies (connecting more Systems into another).
  • The native option right now is to use distributed mass but it has 2 issues: 1 - the added mass does not appear in selection information panel, 2 - cannot have negative mass (e.g. cannot set body mass to less than it was), 3 - distribution is not homogenous since only surfaces are used, not to mention the added surface elements to the solution.

Best Answer

  • Pierre Thieffry
    Pierre Thieffry Member, Moderator, Employee Posts: 107
    5 Likes Name Dropper First Comment First Answer
    ✭✭✭✭
    Answer ✓

    Hi @Pavel , sounds familiar :-) I think your proposed solution with duplicating material models is the right one. You will have a hard time to reduce the mass otherwise (of course APDL tweaks like you did work as well but yes, you can't check prior to solving and commands may get lost in assemblies).

Answers

  • Pavel
    Pavel Member Posts: 9
    First Comment Photogenic Name Dropper First Answer
    **

    Thanks for confirmation Pierre!

  • M
    M Member, Employee Posts: 236
    100 Comments Photogenic 5 Likes Name Dropper
    ✭✭✭✭
    edited April 25

    This is possible but not real reliably, with the script below. Please check the data at the end! _Not sure the executecommand is still supported but it still worked in 24R1. _

    The first part of the script will get the name,material,volume,mass,ids of bodies in the tree and then add a simple scaling factor to the list (set to 1/3 for the example). This list of lists is then written to file.

    The second part of the script will import the data written to file (you can set your scaling as you require) and then create a material copy of the material for each line in the imported data with the scaled density (just for the example, any property could be altered) and sets the body to that material.

    Based on the fine work by Ayush: (https://discuss.ansys.com/discussion/1557/how-to-add-materials-from-material-library-in-mechanical-with-act?utm_source=community-search&utm_medium=organic-search&utm_term=material).

    # Part 1 ####################
    
    import os
    
    save_directory = 'D:\\temp'
    save_file = 'body_data.csv'
    mass_scaling = 0.333
    
    bodies = Model.Geometry.GetChildren(DataModelObjectCategory.Body, True)
    
    data = [] # result will be written to data
    
    for body in bodies:
        name = body.Name
        volume = body.Volume.Value #.Value for numeric results without units, !always be sure of your units
        mass = body.Mass.Value
        material = body.Material # Name of material
        id = body.ObjectId
        data.append([name,material,volume,mass,id, mass_scaling])
    
    with open(os.path.join(save_directory,save_file),'w') as f: # 'w' is to write to file
        for line in data:
            for data_point in line:
                f.write(str(data_point) + ',')
            f.write('\n')
    # Part 2 ####################
    import os
    
    save_directory = 'D:\\temp'
    save_file = 'body_data.csv'
    
    
    def newmat(old_name,new_dens,new_name):
        cmd = '''
    system1 = GetSystem(Name="SYS")
    engineeringData1 = system1.GetContainer(ComponentName="Engineering Data")
    material1 = engineeringData1.GetMaterial(Name="%s")
    matl1 = material1.Duplicate(TargetContainer=engineeringData1)
    matlProp1 = matl1.GetProperty(Name="Density")
    matlProp1.SetData(Variables=["Density"],Values=[["%s [kg m^-3]"]])
    matl1.DisplayName = "%s"
    '''%(old_name,new_dens, new_name)
        return cmd
    
    with open(os.path.join(save_directory,save_file),'r') as f: # 'r' is to read the file
        data = f.readlines()
        for line in data:
            d = line.split(',')
            mat_old = d[1]
            new_density = float(d[3])*float(d[5])
            mat_new = 'MAT_' + d[0]
            print(mat_old,new_density,mat_new)
            cmd = newmat(mat_old,new_density,mat_new)
            ExtAPI.Application.ScriptByName('journaling').ExecuteCommand(cmd)
            ExtAPI.DataModel.Project.Model.RefreshMaterials()
            body = ExtAPI.DataModel.GetObjectById(int(d[4]))
            body.Material = mat_new