Application Center - Maplesoft

App Preview:

Equilibrium Configurations of Cantilever Beam under Terminal Load

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application




restart:with(linalg):with(plots):

Equilibrium Configurations of  Cantilever Beam under Terminal Load

Milan Batista, University of Ljubljana, Slovenia, EU

Introduction

 

This worksheet implements the calculation of the equilibrium shapes of initially straight inextensible and unshearable elastic cantilever beam subject to terminal force. The parameter of the modela are:

• 

load parameter omega  ( w nondimensional)

• 

the CW angle beta ( b in degrees) between the x-axis and the direction of force  

• 

the CW angle alpha (a in degrees) between tangent to the beam base curve at the tip point and direction of the terminal force 

 

Three types of load conditions are implemented:

• 

Follower load -  the load parameter w and angle a are given. This problem has one solution.

• 

Load parameter problem - both a and b are given. This problem has infinitely  many solutions.

• 

Conservative load - load parameter w and angle b are given. This problem has finite number of solutions.

 

                            

 

 

Basic procedures

 

There are five basic procedures that implement the parametric equations of the beam base curve which are expressed in terms of Jacobi's elliptical functions. First two procedures calculate the coordinates of beam base curve in local coordinate system which is rotated CW with respect to space coordinate system by the angle b

#========================================

xi := proc( s, omega) global k, K, K1, E;  if omega = 0 then (1 - s)*(1 - 2*k**2) else  (2*E*K1-1)*(1 - s) + 2/omega*(JacobiZeta(omega,k) - JacobiZeta( omega*s, k) - k**2*(JacobiSN(omega,k)*JacobiCN(omega,k)/JacobiDN(omega,k)-JacobiSN(omega*s,k)*JacobiCN(omega*s,k)/JacobiDN(omega*s,k))) end if; end proc;

proc (s, omega) global k, K, K1, E; if omega = 0 then (1-s)*(1-2*k^2) else (2*E*K1-1)*(1-s)+2*(JacobiZeta(omega, k)-JacobiZeta(omega*s, k)-k^2*(JacobiSN(omega, k)*JacobiCN(omega, k)/JacobiDN(omega, k)-JacobiSN(omega*s, k)*JacobiCN(omega*s, k)/JacobiDN(omega*s, k)))/omega end if end proc

(1)

#========================================

eta := proc( s, omega) global k, k1, K; if omega = 0 then (1 - s)*2*k*k1 else 2*k*k1/omega*(JacobiSN(omega,k)/JacobiDN(omega,k) - JacobiSN(omega*s,k)/JacobiDN(omega*s,k)) end if; end proc;

proc (s, omega) global k, k1, K; if omega = 0 then 2*(1-s)*k*k1 else 2*k*k1*(JacobiSN(omega, k)/JacobiDN(omega, k)-JacobiSN(omega*s, k)/JacobiDN(omega*s, k))/omega end if end proc

(2)

#========================================

Next two procedures calculate the coordinates of beam base curve in space coordinates:

#========================================

x:=proc( s, omega) local xx, yy, beta0; global k, K; beta0:=beta(omega); xx:=xi( s, omega); yy:= eta(s, omega);xx*cos(beta0)+yy*sin(beta0);end proc;

proc (s, omega) local xx, yy, beta0; global k, K; beta0 := beta(omega); xx := xi(s, omega); yy := eta(s, omega); xx*cos(beta0)+yy*sin(beta0) end proc

(3)

#========================================

y:=proc( s, omega) local xx, yy, beta0; global k, K;beta0:=beta(omega); xx:=xi( s, omega); yy:= eta(s, omega);-xx*sin(beta0)+yy*cos(beta0);end proc;

proc (s, omega) local xx, yy, beta0; global k, K; beta0 := beta(omega); xx := xi(s, omega); yy := eta(s, omega); -xx*sin(beta0)+yy*cos(beta0) end proc

(4)

#==============================================

Finaly, calculation of angle b is implemented by the following procedure

#==============================================

beta:=proc( omega) global k; 2*arcsin(k*JacobiCN(omega,k)/JacobiDN(omega,k)) end proc;

proc (omega) global k; 2*arcsin(k*JacobiCN(omega, k)/JacobiDN(omega, k)) end proc

(5)

#==============================================

Global variables k , K and E  in above procedures represent modulus of elliptic functions and complete elliptic integral of first kind and second kind respectively. These must be for computational efficiency calculated before  use of the above procedures.  When a is known then we can for setting k and K use procedure

#===================================================

setup := proc( alpha) global k, k1, K, K1, E; k:=evalf(sin(rad(alpha)/2)); k1:= sqrt(1 - k**2); K:=EllipticK(k); E:=EllipticE(k); if k < 1 then K1 := 1/K else K1 := 0 end if; end proc;

proc (alpha) global k, k1, K, K1, E; k := evalf(sin((1/2)*rad(alpha))); k1 := sqrt(1-k^2); K := EllipticK(k); E := EllipticE(k); if k < 1 then K1 := 1/K else K1 := 0 end if end proc

(6)

#====================================================

For displaying the applied force we need the following procedure

#===================================================

force:=(f,beta0)-><-f*cos(beta0),f*sin(beta0)>;

proc (f, beta0) options operator, arrow; `<,>`(-f*cos(beta0), f*sin(beta0)) end proc

(7)

#====================================================

# Utility functions

#=======================

rad:=alpha->evalf(alpha*Pi/180): # convert deg to rad

deg:=alpha->evalf(alpha*180/Pi): # convert rad to deg

#====================================

The variables that controls plots are:

• 

number of points that is used for approximation of deformed beam

NumPts:=100; # number of points for beam shape

100

(8)
• 

number of points used for approximation of beam tip path

NumPtsPath:=180;

180

(9)
• 

the scale factor for the displaying  the applied force

ForceScale:=0.025; # Scale for force

0.25e-1

(10)
• 

 number of frames used for animations

NumFrames:=50; # number of frames for animations

50

(11)

Note that for larger value of load parameters the number of digits must be increased

Digits:=14;

14

(12)

 

Follower load

 

We first give four examples of calculation of beam equilibrium shape in the case of follower load. For this we need two data items. the angle a

#========================================

alpha0:=150.; #Input

150.

(13)

setup(alpha0): # Now K is availabe

and the load parameter

omega0:=5.3*K; # Input

14.670734670455

(14)

Note that K is globaly available and can thus be used for specifying load parameter.  

#ForceScale:=0.025:   # scale for force

#NumPts:=100:  # number of points

This figure show the shape of deformed beam in local coordinate system

beta0:=beta(omega0): # we need this to show beam root

Beam:=plot([xi(s,omega0),eta(s,omega0),s=0..1],numpoints = NumPts, color=black, thickness=2, scaling=constrained,caption=typeset("omega = ", omega0," alpha = ",alpha0)): # Local coordinates

ForceVect:= arrow(<xi(0,omega0),eta(0,omega0)>,<-ForceScale,0>):

BeamRoot:=pointplot( [[ForceScale*sin(beta0),-ForceScale*cos(beta0)],[-ForceScale*sin(beta0),ForceScale*cos(beta0)]],connect=true):

display( Beam, ForceVect,BeamRoot);

 

#-------------------------------------

and this figure the shape of deformed beam in global coordinate system

#-------------------------

ForceVect:= arrow(<x(0,omega0),y(0,omega0)>,force(ForceScale,beta0)):

Beam:=plot([x(s,omega0),y( s , omega0),s=0..1],numpoints = NumPts, color=black, thickness=2, scaling=constrained,caption=typeset("omega = ", omega0," alpha = ",alpha0,"  beta = ",evalf(beta0*180/Pi))): # Space coordinates

display( Beam, ForceVect);

#========================================

#  Follower load problem

#========================================

This animation shows continiuous deformation of beam when load factor is constant and a increase from 0 to 180 deg. The dots shows trace of beam tip.

# Constant load parameter -------------------------------------------------

#omega0:=12; # Input

#NumFrames := 50;

ForceScale:=0.15:

#NumPtsPath:=180:

xx0:=array(1..NumPtsPath):yy0:=array(1..NumPtsPath):

for i from 0 to NumPtsPath-1 do; alpha:=i/NumPtsPath; setup(alpha*180); xx0[i+1]:=x(0,omega0);yy0[i+1]:=y(0,omega0);od:

TipPath:=pointplot( {seq( [xx0[i],yy0[i]],i=1..NumPtsPath)}, color=red , symbolsize=10):

NumPts:=50:

BaseCurve:=array(1..NumFrames):ForceVect:=array(1..NumFrames):

for i from 0 to NumFrames - 1 do alpha:=i/NumPts; setup(alpha*180);beta0:=beta(omega0);BaseCurve[i+1]:= plot([x(s,omega0),y(s,omega0), s=0..1],scaling=constrained,numpoints = NumPts, color=black, thickness=3,caption=typeset("frame #",i,"/",NumFrames," omega = ", omega0," alpha = ",alpha*180.,"  beta = ",evalf(beta0*180/Pi))); ForceVect[i+1]:= arrow(<x(0,omega0),y(0,omega0)>,force(ForceScale,beta0)):od:

Beam := display(seq(BaseCurve[i],i=1..NumFrames),insequence = true, scaling=constrained):

Force :=display(seq(ForceVect[i],i=1..NumFrames),insequence = true, scaling=constrained):

display( Beam, Force,TipPath);

 

Load parameter problem

 

There are two variants of the problem. In first we as data have  the angle b:

#========================================

#  Load parameter problem

#========================================

# These functions calculate load parameter as function of alpha and wave number n

#-------------------------------------------------------------------------

f1:=(alpha,n)->(-InverseJacobiSN(sin(beta0*Pi/360)/sin(alpha*Pi/2),sin(alpha*Pi/2)))+(4*n+1)*EllipticK(sin(alpha*Pi/2)):

f2:=(alpha,n)->-(-InverseJacobiSN(sin(beta0*Pi/360)/sin(alpha*Pi/2),sin(alpha*Pi/2)))+(4*n+3)*EllipticK(sin(alpha*Pi/2)):

#---------------------------------------------------------

beta0:=30.; # Input

30.

(15)

if beta0 < 0 then beta0 := -beta0 end if:

and the signed wave number

m:=2; # Input wave number

2

(16)

The load parameter that correspond to these data items is represented by branch curve on the bifurcation diagram on (alpha,omega) plane. In the example, as shown in the graph below, the number of load parameters equals the number of frames for animation. These values are shown as circles on the corresponding branch curve.

if beta0 < 0 then beta0 := -beta0 end if;p:=evalf(sin(rad(beta0)/2)): # Check data

ma:=abs(m):if modp(abs(m),2) = 1 then n:=floor((ma-1)/2);else n:=floor(ma/2-1);end if:da:=(0.999-beta0/180)/(NumFrames-1):

for i from 0 to NumFrames - 1 do if m > 0 then alpha:=evalf(beta0/180+da*i) else alpha := evalf(-beta0/180 - da*i); end if; setup(evalf(alpha*180));omega0:=Re(-InverseJacobiSN(p/k,k));if modp(n,2) = 1 then w[i+1]:=omega0+(4*n+1)*K else  w[i+1]:=-omega0 + (4*n + 3)*K end if; aa[i+1]:=alpha;od:

ss:=seq([aa[i],w[i]],i=1..NumFrames):

ww:=pointplot( {ss},color=black, symbol=circle,symbolsize = 10 ):

mx:=w[NumFrames]:

unassign('alpha');tt:=plot({seq(f1(alpha,n),n=0..2),seq(f2(alpha,n),n=0..2)},alpha=-1..1,y=0..mx,color=red,labels=["alpha/pi","omega"]):

display(tt,ww);

Equilibrium shapes belonging to the above load parameter values areshown in the following animation

ForceScale:=0.2: # force scale factor

NumPts:=50:

for i from 0 to NumFrames - 1 do alpha:=aa[i+1]; setup(evalf(alpha*180));omega:=w[i+1]; BaseCurve[i+1]:= plot([x(s,omega),y(s,omega), s=0..1],scaling=constrained,numpoints = NumPts, color=black, thickness=3,caption=typeset("frame #",i+1,"/",NumFrames," m = ",m," omega = ", omega," alpha = ",alpha*180.,"  beta = ",evalf(beta0))); ForceVect[i+1]:= arrow(<x(0,omega),y(0,omega)>,force(ForceScale*omega/w[NumFrames],evalf(beta0*Pi/180))):od:

Beam := display(seq(BaseCurve[i],i=1..NumFrames),insequence = true, scaling=constrained):

Force :=display(seq(ForceVect[i],i=1..NumFrames),insequence = true, scaling=constrained):

display( Beam, Force);

This example assume that both angles are given

beta0:=40; # Input

40

(17)

alpha0:=145; # Input alpha

145

(18)

and the wave numbers increase from 1  to

NumWaves:=6; # How many waves

6

(19)

ForceScale:=0.15: # force scale factor

if beta0 < 0 then beta0 := -beta0 end if:p:=evalf(sin(beta0*Pi/180/2)):setup(alpha0): # check beta

In this graph  the corresponding load parameter values are indicated by circles

for i from 1 to NumWaves do omega0:=Re(K-InverseJacobiSN(p/k,k));if modp(abs(i),2) = 1 then n:=(abs(i)-1)/2;  w[i]:=omega0+4*n*K else n:=abs(i)/2-1; w[i]:=-omega0 + 4*(n + 1)*K end if;od:

ss:=seq([alpha0/180.,w[i]],i=1..NumWaves):

ww:=pointplot( {ss},color=black, symbol=solidcircle,symbolsize = 10,labels=["alpha/pi","omega"] ):

unassign('alpha');nn:=floor(NumWaves/2)+1:graph:=plot({seq(f1(alpha,n),n=0..nn),seq(f2(alpha,n),n=0..nn)},alpha=-1..1,y=0..w[NumWaves],color=red,labels=["alpha/pi","omega"]):

alp:=pointplot( [[alpha0/180,0],[alpha0/180,w[NumWaves]]],connect=true,color=black,thickness=1,labels=["alpha/pi","omega"]):

display(graph,ww, alp);

and this animation shows coresponding equilibrium configurations (for better view decrease the speed of the animation)

for i from 1 to NumWaves do omega:=w[i]; BaseCurve[i]:= plot([x(s,omega),y(s,omega), s=0..1],scaling=constrained,numpoints = NumPts, color=black, thickness=2,caption=typeset("wave = ",i," omega = ", omega," alpha = ",alpha0,"  beta = ",evalf(beta0))); ForceVect[i]:= arrow(<x(0,omega),y(0,omega)>,force(ForceScale*omega/w[NumWaves],evalf(beta0*Pi/180))):od:

Beam := display(seq(BaseCurve[i],i=1..NumWaves),insequence = true, scaling=constrained):

Force :=display(seq(ForceVect[i],i=1..NumWaves),insequence = true, scaling=constrained):

display( Beam, Force);

This picture display all  equilibrium configurations

Beam := display(seq(BaseCurve[i],i=1..NumWaves), scaling=constrained):

Force :=display(seq(ForceVect[i],i=1..NumWaves), scaling=constrained):

display( Beam, Force);

Conservative Load

 

In this kind of problem the load parameter and the space direction of force are constant.  The load parameter for this example is

#========================================

#  (3) Conservative Load Problem

#========================================

gc(): # cleanup

omega0:=15; # Input

15

(20)

 

N := 5

(21)

#---------------------------------------------

# This is variant of procedure beta where also k and K are calculates

f:=proc(alpha,omega) global k, K; k:=evalf(sin(alpha/2));K:=EllipticK(k); beta(omega); end proc:

#------------------------------------------

# This is first derivative of function f which is needed to calculate extrem values

df := (k,omega)->2*(JacobiSN(omega,k)*omega*EllipticK(k)*k^2-JacobiSN(omega,k)*omega*EllipticK(k)+JacobiCN(omega,k)*JacobiDN(omega,k)*EllipticK(k)+JacobiSN(omega,k)*JacobiZeta(omega,k)*EllipticK(k)+JacobiSN(omega,k)*omega*EllipticE(k))/JacobiDN(omega,k)^2/EllipticK(k)/((-1+k^2)/(-1+k^2*JacobiSN(omega,k)^2))^(1/2):

#---------------------------------------------

# These two functions enclose n-th root of function f

f1:=n->2*arcsin(sqrt(1-exp(Pi-omega0*2/(2*n-1)))):f2:=n->2*arcsin(sqrt(1-16*exp(-omega0*2/(2*n-1)))):

#----------------------------------

# Calculate roots of f in the interval -Pi..Pi

#--------------------------------------------

For calculation of zeros the number of digits is increased becouse the intervals near the end of domain of force inclination angle becomes very small

dg:=Digits: Digits:=22;   # Increase number of digits

N:=floor(omega0/Pi+1/2):  # half number of possible nontrivial eqilibrium configurations

22

(22)

The maximum number of possible equilibrium configurations for this case is

M:=2*N+1;                 # max. number of equilibrium configurations

11

(23)

z0:=array(1..M):          # initialize array

unassign('alpha'):for n from 1 to N do alpha1:=evalf(f1(n)); alpha2:=evalf(f2(n));z0[n]:=evalf(fsolve(f(alpha,omega0),alpha=alpha1..alpha2)/Pi);od:

# obtain rest of roots by symetry

z0[N+1]:=0:for n from 1 to N do z0[N+1+n]:=-z0[N+1-n] od:

#------------------------

# Form graph

#---------------------

zero0:=(seq( pointplot( [z0[i],0], symbol = circle, symbolsize = 10),i=1..M)):

graph:=plot({evalf(f(alpha*Pi,omega0)/Pi)},alpha=-1..1, color=black, numpoints=400): # note that number of points should be relatively large

#display(graph,zero0);

#-------------------------------------

# Calculate extems of function f

#------------------------------------

s:=array(1..M+1):r:=array(1..M+1):

s[1]:=1:r[1]:=evalf(Pi):

for n from 1 to M-1 do;if modp(n,2) =1 then xx:=fsolve(df(evalf(sin(alpha*Pi/2)),omega0),alpha=z0[n+1]..z0[n]); else xx:=fsolve(df(evalf(sin(alpha*Pi/2)),omega0),alpha=z0[n+1]..z0[n]); end if; s[n+1]:=xx;r[n+1]:=f(xx*Pi,omega0) od:s[M+1]:=-1:r[M+1]:=evalf(-Pi):

#for i from 1 to M do z0[i],r[i]; od;

ext0:=(seq( pointplot( [s[i],evalf(r[i]/Pi)], symbol = circle, symbolsize = 10, color=blue),i=1..M+1)):

#display(graph,zero0,ext0);

The inclination angle of the fors iss

beta0:=0; # Input <---------

0

(24)

#unassign('alpha'):fsolve(f(evalf(alpha*Pi),omega0)-rad(beta0),alpha=z0[1]..r[1]);z0[1];r[1];

if beta0 < 0 then beta0 := -beta0 end if; # Check

#-------------------------------------- Here the calulation phase is done !

if (beta0 > 0) then n:=0;for i from 1 to M do zz:=fsolve(f(evalf(alpha*Pi),omega0)-rad(beta0),alpha=z0[i]..s[i]): if type(zz,numeric) then n:=n+1;zzz[n]:=zz end if; zz:=fsolve(f(evalf(alpha*Pi),omega0)-rad(beta0),alpha=s[i+1]..z0[i]): if type(zz,numeric) then n:=n+1;zzz[n]:=zz end if; od: else n:=M; for i from 1 to M do zzz[i]:=z0[i] od; end if:

The actual number of equilibrium configurations is

NumShape:=n;

11

(25)

and the angle  a (in deg)  for each of these configurations is

for i from 1 to NumShape do i,180*zzz[i] od;

1, 179.9998597847047351274

2, 176.9089297455494782142

3, 156.5334326876769380586

4, 118.9799356724180117880

5, 55.08706864069855582607

6, 0

7, -55.08706864069855582607

8, -118.9799356724180117880

9, -156.5334326876769380586

10, -176.9089297455494782142

11, -179.9998597847047351274

(26)

These values are displayed as red circles on the following graph (the blue cicles are extrems of function)

zero:=(seq( pointplot( [zzz[i],evalf(beta0/180)], symbol = solidcircle, symbolsize = 12, color=red),i=1..n)):

display(graph,zero0,ext0,zero,plot(beta0/180,t=-1..1),labels=["alpha/pi","beta/Pi"]);

The coresponding equilibrium configurations are shown on the following animation ((for better view decrease the speed of the animation)

NumPts:=50:for i from 1 to NumShape do alpha:=zzz[i]; setup(alpha*180); BaseCurve[i]:= plot([x(s,omega0),y(s,omega0), s=0..1],scaling=constrained,numpoints = NumPts, color=black, thickness=2,caption=typeset("shape = ",i,"/",NumShape," omega = ", omega0," alpha = ",alpha*180.,"  beta = ",evalf(beta0))); ForceVect[i]:= arrow(<x(0,omega0),y(0,omega0)>,force(ForceScale,evalf(beta0*Pi/180))):od:

Beam := display(seq(BaseCurve[i],i=1..NumShape), scaling=constrained, insequence = true):

Force :=display(seq(ForceVect[i],i=1..NumShape), scaling=constrained, insequence = true):

display( Beam, Force);

On this picture all equilibrium configurations are shown

Beam := display(seq(BaseCurve[i],i=1..NumShape), scaling=constrained):

#Force :=display(seq(ForceVect[i],i=1..NumShape), scaling=constrained):

display( Beam);

Digits:=dg: # reset number of digits

# END