Validation Case: Multi-Material Bar in Compression
Problem Statement
This mechanical simulation is part of the series of validation cases performed using OnScale Solve.
A bar assembly with 4 parts is fixed at one end with a pressure load applied to the opposite end.
The FEA model and resulting comparison of simulation results against the analytical calculations validates the use of the following conditions for linear elastic static analysis:
- Pressure load
- Restraint conditions
- von Mises stress calculation
Geometry:
The geometry is a long bar as shown in fig. 1.
The CAD file for this geometry is available as an Onshape document. The dimensions (in mm) of the base sketch are shown in fig. 2.
The structure is extruded in the 3rd dimension by 2 mm to create the 3D bar.


Boundary conditions
A pressure load of 1 MPa boundary is placed at the base of the long bar on Part 1. A restraint, fixing all degrees of freedom is placed on the opposite side of the bar on Part 4. This is shown in fig. 1
Material Properties
Homogeneous isotropic linear elastic properties are used:
Part | Young’s Modulus (E) | Poisson’s ratio (\nu) |
---|---|---|
1 | 193 GPa | 0.0 |
2 | 71 GPa | 0.0 |
3 | 200 GPa | 0.0 |
4 | 110 GPa | 0.0 |
With Poisson’s ratio set to zero for all materials, the problem will simplify to a uniaxial (1D) stress case.
Mesh
OnScale Solve generated a second-order tetrahedral mesh. Five simulations are run with the mesh density ranging from very coarse to very fine.
Mesh density | # of elements | # of dofs |
---|---|---|
very coarse | 933 | 5,454 |
coarse | 2,373 | 12,888 |
medium | 5,829 | 29,994 |
fine | 13,858 | 68,301 |
very fine | 71,807 | 336,096 |
Results
With Poisson’s ratio set to zero in all materials, transverse strain is zero.
\nu = -\frac{\epsilon_\text{trans}}{\epsilon_\text{axial}} = 0
Transverse normal stress (\sigma_2, \sigma_3) components will also be zero thus, the stress is uniaxial.
\sigma_{1} \neq 0, \sigma_{2} = \sigma_{3} = 0
For this uniaxial stress case, the maximum equivalent stress or von Mises stress (\sigma_\text{vM}) in all parts will be equal to the applied pressure, P, in the axial direction.
P = \frac{\text{Force}}{\text{Area}}
\sigma_{1} = \frac{\text{Force}}{\text{Area}} = \sigma_\text{vM}
The table below compares the absolute difference in the simulated von Mises stress values to the reference solution (1 \times 10^{6} Pa) determined by analytical method described above.
Mesh density | # of dofs | Abs. \Delta\sigma_\text{vM} [Pa] | \Delta\sigma_\text{vM} / Ref. [%] |
---|---|---|---|
very coarse | 5,454 | 1.00 \times 10^{-2} | 1.00 \times 10^{-8} |
coarse | 12,888 | 1.00 \times 10^{-2} | 1.00 \times 10^{-8} |
medium | 29,994 | 9.99 \times 10^{-3} | 9.99 \times 10^{-9} |
fine | 68,301 | 9.99 \times 10^{-3} | 9.99 \times 10^{-9} |
very fine | 336,096 | 1.00 \times 10^{-2} | 1.00 \times 10^{-8} |
Simulation Definition
The complete simulation definition is given below. The metadata tags for parts and faces correspond to the version of the CAD file that was imported from Onshape.
""" Auto-generated simulation code. """
import onscale as on
with
on.Simulation('Simulation', 'Generated in SOLVE', version = '0.8.1') as sim:
# General simulation settings
on.settings.EnabledPhysics(["mechanical"])
# Define geometry
geometry = on.CadFile('Assembly_1.x_t', unit="m") point = on.Point(0.001, 0.001, 0.01)
# Define meshing
on.meshes.MeshFile('medium_mesh_volume.msh')
# Define material database and materials
materials = on.CloudMaterials('onscale') material = materials['material'] material.alias = 'Part 1' material >> geometry.parts.search('MDY94bjrM5jH0rOaI', field='partIDTag') material.set('density', 1000.0) material.set('youngs_modulus', 193000000000.0) material.set('poissons_ratio', 0.0) material_2 = materials['material'] material_2.alias = 'Part 2' material_2 >> geometry.parts.search('M7PQ+V9UMiGGRZea4', field='partIDTag') material_2.set('density', 1000.0) material_2.set('youngs_modulus', 71000000000.0) material_2.set('poissons_ratio', 0.0) material_3 = materials['material'] material_3.alias = 'Part 3' material_3 >> geometry.parts.search('MIioDu97YJJr/R3uY', field='partIDTag') material_3.set('density', 1000.0) material_3.set('youngs_modulus', "200e9") material_3.set('poissons_ratio', 0.0) material_4 = materials['material'] material_4.alias = 'Part 4' material_4 >> geometry.parts.search('MQ8JJ5NQ1PS2IiXmk', field='partIDTag') material_4.set('density', 1000.0) material_4.set('youngs_modulus', 110000000000.0) material_4.set('poissons_ratio', 0.0)
# Define and apply loads
restraint = on.loads.Restraint(x=True, y=True, z=True, alias='Fixture 1') restraint >> geometry.parts.search('MQ8JJ5NQ1PS2IiXmk', field='partIDTag').faces.search('KUSB', field='faceIDTag') pressure = on.loads.Pressure(1000000, alias='Pressure 1') pressure >> geometry.parts.search('MDY94bjrM5jH0rOaI', field='partIDTag').faces.search('JUG', field='faceIDTag')
# Define output variables
field_sensor = on.sensors.FieldSensor(data=["Displacement", "VonMises", "Stress", "Strain", "PrincipalStress", "PrincipalStrain", "StrainEnergyDensity", "EigenVector"], alias='Global Sensor') field_sensor >> geometry probe_sensor = on.sensors.ProbeSensor(data=["Stress", "VonMises", "Displacement", "Strain"], alias='Sensor 1') probe_sensor >> point reaction_sensor = on.sensors.ReactionSensor(alias='Reaction_Fixture 1') reaction_sensor >> restraint
# For OnScale System use only
geometry.set('onshape_workspace_id', "111c4f05d67fa6b8e9f981cc") geometry.set('onshape_doc_id', "e8607673f8bfbbbca153cd23") geometry.set('onshape_doc_microversion', "54c8644664bd2bb74461a9c1") geometry.set('onshape_assembly_id', "ca67559820b7c905854fe7a7") geometry.set('onshape_assembly_microversion', "4793f9925c4425dd536c9b6e")