Note
Go to the end to download the full example code
Large lateral deflection of unequal stiffness springs#
- Problem description:
A two-spring system is subjected to a force \(F\) as shown below. Determine the strain energy of the system and the displacements \(\delta_x\) and \(\delta_y\).
- Reference:
G. N. Vanderplaats, Numerical Optimization Techniques for Engineering Design with Applications, McGraw-Hill Book Co., Inc., New York, NY,1984, pp. 72-73, ex. 3-1.
- Analysis type(s):
Nonlinear Transient Dynamic Analysis (
ANTYPE = 4
)
- Element type(s):
Spring-damper elements (COMBIN14)
Spring-damper elements (COMBIN40)
- Material properties
\(k_1 = 8\,N/cm\)
\(k_2 = 1\,N/cm\)
\(m = 1\)
- Geometric properties:
\(l = 10\,cm\)
- Loading:
\(F = 5{\sqrt[2]{2}}\,N\)
\(\alpha = 45\,º\)
- Analysis assumptions and modeling notes:
The solution to this problem is best obtained by adding mass and using the “slow dynamics” technique with approximately critical damping. Combination elements
COMBIN40
are used to provide damping in the \(X\) and \(Y\) directions. Approximate damping coefficients \(c_x\) and \(c_y\), in the \(X\) and \(Y\) directions respectively, are determined from:\(c_x = \sqrt[2]{k_xm}\)
\(c_y = \sqrt[2]{k_ym}\)
where m is arbitrarily assumed to be unity.
\(k_x\) and \(k_y\) cannot be known before solving so are approximated by \(k_y = k_2 = 1\,N/cm\) and \(k_x = k_y/2 = 0.5\,N/cm\), hence \(c_x = 1.41\) and \(c_y = 2.0\). Large deflection analysis is performed due to the fact that the resistance to the load is a function of the deformed position.
POST1
is used to extract results from the solution phase.
# sphinx_gallery_thumbnail_path = '_static/vm9_setup.png'
Start MAPDL#
Start MAPDL and import Numpy and Pandas libraries.
from ansys.mapdl.core import launch_mapdl
import numpy as np
import pandas as pd
# Start MAPDL.
mapdl = launch_mapdl()
Pre-processing#
Enter verification example mode and the pre-processing routine.
mapdl.clear()
mapdl.verify()
mapdl.prep7(mute=True)
Parameterization#
Parameterization block includes main variables as :
\(l = 10\,cm\) - spring length.
\(k_1 = 8\,N/cm\) - stiffness of the 1st spring.
\(k_2 = 1\,N/cm\) - stiffness of the 2nd spring.
\(m = 1\) - mass.
\(F = 5\sqrt[2]{2}\,N\) - main load
\(\alpha = 45\,º\) - force angle
\(c_x = \sqrt[2]{k_xm} = 1,41\) - damping coefficient, x-direction.
\(c_y = \sqrt[2]{k_ym} = 2.0\) - damping coefficient, y-direction.
Define element type#
Set up the element types.
# Element type COMBIN14.
mapdl.et(1, "COMBIN14")
# Special Features are defined by keyoptions of the element COMBIN14.
# KEYOPT(3)(2)
# Degree-of-freedom selection for 2-D and 3-D behavior:
# 2-D longitudinal spring-damper (2-D elements must lie in an X-Y plane)
mapdl.keyopt(1, 3, 2)
# Element type COMBIN40.
mapdl.et(3, "COMBIN40")
# Special features are defined by keyoptions of the element COMBIN40.
# KEYOPT(3)(1)
# Element degrees of freedom:
# UX (Displacement along nodal X axes)
mapdl.keyopt(3, 3, 1)
# KEYOPT(6)(2)
# Mass location:
# Mass at node J
mapdl.keyopt(3, 6, 2)
# Element type COMBIN40.
mapdl.et(4, "COMBIN40")
# Special features are defined by keyoptions of the element COMBIN40.
# KEYOPT(3)(2)
# Element degrees of freedom:
# UX (Displacement along nodal X axes)
mapdl.keyopt(4, 3, 2)
# KEYOPT(6)(2)
# Mass location:
# Mass at node J
mapdl.keyopt(4, 6, 2)
# Print the list of the elements and their attributes.
print(mapdl.etlist())
LIST ELEMENT TYPES FROM 1 TO 4 BY 1
*****MAPDL VERIFICATION RUN ONLY*****
DO NOT USE RESULTS FOR PRODUCTION
ELEMENT TYPE 1 IS COMBIN14 SPRING-DAMPER
KEYOPT( 1- 6)= 0 0 2 0 0 0
KEYOPT( 7-12)= 0 0 0 0 0 0
KEYOPT(13-18)= 0 0 0 0 0 0
ELEMENT TYPE 3 IS COMBIN40 COMBINATION
KEYOPT( 1- 6)= 0 0 1 0 0 2
KEYOPT( 7-12)= 0 0 0 0 0 0
KEYOPT(13-18)= 0 0 0 0 0 0
ELEMENT TYPE 4 IS COMBIN40 COMBINATION
KEYOPT( 1- 6)= 0 0 2 0 0 2
KEYOPT( 7-12)= 0 0 0 0 0 0
KEYOPT(13-18)= 0 0 0 0 0 0
CURRENT NODAL DOF SET IS UX UY
THREE-DIMENSIONAL MODEL
Define real constants#
Define damping coefficients \(c_x = 1.41\), \(c_y = 2.0\) and stiffness values \(k_1 = 8\,N/cm\), \(k_2 = 1\,N/cm\) for the spring elements.
# Define real constant 1 with stiffness k2.
mapdl.r(nset=1, r1=k_spring2) # SPRING STIFFNESS = 1
# Define real constant 2 with stiffness k1.
mapdl.r(nset=2, r1=k_spring1) # SPRING STIFFNESS = 8
# Define real constant 3 with damping coef. in X-direction and mass.
mapdl.r(nset=3, r2=c_damp_x, r3=mass)
# Define real constant 4 with damping coef. in y-direction and mass.
mapdl.r(nset=4, r2=c_damp_y, r3=mass)
# Print the real constant list.
print(mapdl.rlist())
*****MAPDL VERIFICATION RUN ONLY*****
DO NOT USE RESULTS FOR PRODUCTION
LIST REAL SETS 1 TO 4 BY 1
REAL CONSTANT SET 1 ITEMS 1 TO 6
1.0000 0.0000 0.0000 0.0000 0.0000 0.0000
REAL CONSTANT SET 2 ITEMS 1 TO 6
8.0000 0.0000 0.0000 0.0000 0.0000 0.0000
REAL CONSTANT SET 3 ITEMS 1 TO 6
0.0000 1.4100 1.0000 0.0000 0.0000 0.0000
REAL CONSTANT SET 4 ITEMS 1 TO 6
0.0000 2.0000 1.0000 0.0000 0.0000 0.0000
Define nodes#
Set up the nodes coordinates using python for
loop.
# Lists with nodes coordinates.
node_x_coord = [0, 0, 0, -1, 0]
node_y_coord = [0, 10, 20, 10, 9]
# Create nodes.
for i in range(0, 5):
mapdl.n(node=i + 1, x=node_x_coord[i], y=node_y_coord[i])
# Print the list of the created nodes.
print(mapdl.nlist())
LIST ALL SELECTED NODES. DSYS= 0
*****MAPDL VERIFICATION RUN ONLY*****
DO NOT USE RESULTS FOR PRODUCTION
NODE X Y Z THXY THYZ THZX
1 0.0000 0.0000 0.0000 0.00 0.00 0.00
2 0.0000 10.000 0.0000 0.00 0.00 0.00
3 0.0000 20.000 0.0000 0.00 0.00 0.00
4 -1.0000 10.000 0.0000 0.00 0.00 0.00
5 0.0000 9.0000 0.0000 0.00 0.00 0.00
Create elements#
Create the elements through the nodes.
# Create spring element COMBIN14 between nodes 1 nad 2
# with stiffness k_2 = 1 N/cm.
mapdl.type(1)
mapdl.real(1)
mapdl.e(1, 2)
# Create spring element COMBIN14 between nodes 2 nad 3
# with stiffness k_1 = 8 N/cm.
mapdl.type(1)
mapdl.real(2)
mapdl.e(2, 3)
# Create spring element COMBIN40 between nodes 4 nad 2
# with damping coefficient c_x = 1.41.
mapdl.type(3)
mapdl.real(3)
mapdl.e(4, 2)
# Create spring element COMBIN40 between nodes 5 nad 2
# with damping coefficient c_y = 2.0.
mapdl.type(4)
mapdl.real(4)
mapdl.e(5, 2)
# Print the list of the created elements.
print(mapdl.elist())
LIST ALL SELECTED ELEMENTS. (LIST NODES)
*****MAPDL VERIFICATION RUN ONLY*****
DO NOT USE RESULTS FOR PRODUCTION
ELEM MAT TYP REL ESY SEC NODES
1 1 1 1 0 1 1 2
2 1 1 2 0 1 2 3
3 1 3 3 0 1 4 2
4 1 4 4 0 1 5 2
Define boundary conditions#
Application of boundary conditions (BC) for the spring model.
# Unselect the node where the force is applied.
mapdl.nsel("U", "NODE", vmin=2)
# Apply BC to the selected set of the nodes.
mapdl.d("ALL", "ALL")
mapdl.nsel("ALL")
# Finish pre-processing mode.
mapdl.finish(mute=True)
Solution settings#
Enter solution mode and apply settings for Transient Dynamic Analysis.
# Starts solution (/solu) mode.
mapdl.slashsolu()
# Define transient analysis with large deflection setting.
mapdl.antype("TRANS")
mapdl.nlgeom("ON")
# Specifies the stepped loading condition within a load step.
mapdl.kbc(1)
# Apply forces to the node 2.
mapdl.f(2, "FX", f_x)
mapdl.f(2, "FY", f_y)
# Uses automatic time stepping.
mapdl.autots("ON")
# Specifies the number of substeps to be taken this load step.
mapdl.nsubst(30)
# Controls the solution printout.
mapdl.outpr("", "LAST")
mapdl.outpr("VENG", "LAST")
# Sets the time for a load step.
mapdl.time(15, mute=True)
Solve#
Solve the system , avoiding the printing output.
# Run the simulation.
mapdl.solve()
mapdl.finish(mute=True)
Post-processing#
Enter post-processing, avoiding the printing output.
# Enter the post-processing mode.
mapdl.post1(mute=True)
Getting displacements#
Enter post-processing. To get results of the strain energy and displacements
in X and Y directions from the node where the force is applied using
Mapdl.get_value
.
# Defines the data set to be read from the results file by the time-point.
mapdl.set(time=15)
# Fills a table of element values for further processing for strain energy.
mapdl.etable("SENE", "SENE")
# Sum all active entries in element stress table.
mapdl.ssum()
# Get the value of the stain energy of the spring elements.
strain_energy = mapdl.get_value(entity="SSUM", entnum=0, item1="ITEM", it1num="SENE")
# Prints nodal solution results of the X, Y, and Z structural displacements
# and vector sum.
print(mapdl.prnsol("U", "COMP"))
# Get the value of the displacements in X-direction.
disp_x = mapdl.get_value(entity="NODE", entnum=2, item1="U", it1num="X")
# Get the value of the displacements in Y-direction.
disp_y = mapdl.get_value(entity="NODE", entnum=2, item1="U", it1num="Y")
PRINT U NODAL SOLUTION PER NODE
*****MAPDL VERIFICATION RUN ONLY*****
DO NOT USE RESULTS FOR PRODUCTION
***** POST1 NODAL DEGREE OF FREEDOM LISTING *****
LOAD STEP= 1 SUBSTEP= 25
TIME= 15.000 LOAD CASE= 0
THE FOLLOWING DEGREE OF FREEDOM RESULTS ARE IN THE GLOBAL COORDINATE SYSTEM
NODE UX UY UZ USUM
1 0.0000 0.0000 0.0000 0.0000
2 8.6319 4.5321 0.0000 9.7494
3 0.0000 0.0000 0.0000 0.0000
4 0.0000 0.0000 0.0000 0.0000
5 0.0000 0.0000 0.0000 0.0000
MAXIMUM ABSOLUTE VALUES
NODE 0 0 0 0
VALUE 8.6319 4.5321 0.0000 9.7494
Check results#
Finally we have the results of the strain energy and displacements in \(X\) and \(Y\) directions, which can be compared with expected target values:
Strain energy of the system \(U_{\mathrm{(energy)}} = 24.01\;N\,cm\).
Displacement in X-direction \(U_x = 8.631\,cm\).
Displacement in Y-direction \(U_y = 4.533\,cm\).
For better representation of the results we can use pandas
dataframe
with following settings below:
# Define the names of the rows.
row_names = ["Strain Energy, N-cm", "Deflection-x , cm", "Deflection-y , cm"]
# Define the names of the columns.
col_names = ["Target", "Mechanical APDL", "RATIO"]
# Define the values of the target results.
target_res = np.asarray([24.01, 8.631, 4.533])
# Create an array with outputs of the simulations.
simulation_res = np.asarray([strain_energy, disp_x, disp_y])
# Identifying and filling corresponding columns.
main_columns = {
"Target": target_res,
"Mechanical APDL": simulation_res,
"Ratio": list(np.divide(simulation_res, target_res)),
}
# Create and fill the output dataframe with pandas.
df2 = pd.DataFrame(main_columns, index=row_names).round(2)
# Apply settings for the dataframe.
df2.head()
Stop MAPDL.
mapdl.exit()
Total running time of the script: (0 minutes 0.337 seconds)