Body mass modification in Mechanical ACT
(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:
- making a copy of given material (System's Engineering Data) for all target bodies
- Calculate target density and change it in the copied materials
- 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
-
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).
0
Answers
-
Thanks for confirmation Pierre!
0 -
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
0