Loads#
The loads of a Shell are stored as lists of its attributes and
converted into the external force vector \(\boldsymbol{F}_{ext}\) by
Shell.calc_fext(), see shell_fext(), as the virtual work of
the loads on the approximation functions. In a MultiDomain, the
loads are added to its domains and MultiDomain.calc_fext()
assembles their vectors, whereas StiffPanelBay.calc_fext() takes
the point forces of the attribute forces_skin of the bay and of the
attributes forces_flange of its BladeStiff2D stiffeners.
Types of loads#
load |
method |
|---|---|
point force \((f_x, f_y, f_z)\) at \((x, y)\) |
|
line force per unit length along \(y\) at \(x\) |
|
line force per unit length along \(x\) at \(y\) |
|
pressure over the domain or over a patch |
|
The components are along the local axes of the shell, \(z\) being the normal
of the mid-surface, positive outwards for the cylinders, such that an
external pressure on a cylinder is negative. The line forces are functions
of the coordinate along the line, and the pressure a constant or a function
\(p(x, y)\). A pressure is a dead load by default, or a follower load, normal
to the deformed mid-surface, with follower=True, see
Follower pressure loads: theory. Shell.clear_loads() removes all of them.
Each load is constant (cte=True, the default) or incremented
(cte=False), stored in separate lists, and
is the vector returned by calc_fext(inc=lambda). The non-linear solvers
of structsolve call
calc_fext(inc=1.) and scale the whole vector by their load factor, and
pass their load factor as inc to the methods that accept it, e.g.
Shell.calc_fint() and Shell.calc_kC() for the follower loads
proportional to the load factor.
Prescribed displacements, also constant or incremented, enter the external force vector with the penalty method, see Boundary conditions.
Stress resultants of a prestress#
The geometric stiffness matrix of a linear buckling analysis is calculated
from the membrane stress resultants of a prestress: the constant attributes
Nxx, Nyy and Nxy of the shell, in closed form, superposed with
those of a static solution c given to Shell.calc_kG(), the
matrix being then integrated numerically. The attributes Nxx_cte,
Nyy_cte and Nxy_cte give instead a constant prestress, whose
geometric stiffness is added to the constitutive stiffness by
Shell.calc_kC() and is therefore not multiplied by the eigenvalue of
lb(kC, kG). See Linear buckling analysis.
Example#
A simply supported isotropic square plate under a uniform pressure, whose central deflection is compared with the Navier series:
def make_shell(model=CLPT, a=1., b=1., h=0.01, m=10, n=10, r=None,
stack=(0,), laminaprop=(E, NU), **kwargs):
s = Shell(a=a, b=b, r=r, stack=list(stack), plyt=h/len(stack),
laminaprop=laminaprop, m=m, n=n, model=model, **kwargs)
s._rebuild()
return s
def central_deflection(s, fext):
c = solve(s.calc_kC(), fext, silent=True)
_, fields = s.uvw(c, xs=np.array([s.a/2]), ys=np.array([s.b/2]))
return fields['w'][0]
def test_uniform_pressure_timoshenko():
r"""SSSS isotropic square plate, `w = 0.00406235 q a^4/D`"""
a = 1.
h = 0.01
q = 1.e3
D = E*h**3/(12*(1 - NU**2))
s = make_shell(CLPT, a=a, b=a, h=h, m=15, n=15)
s.add_pressure_load(q)
w = central_deflection(s, s.calc_fext())
assert np.isclose(w, 0.00406235*q*a**4/D, rtol=1e-4)
The constant and incremented parts of the external force vector:
def test_increment():
s = make_shell()
s.add_pressure_load(1., cte=True)
s.add_pressure_load(-2., x1=0.1, x2=0.4, cte=False)
f0 = s.calc_fext(inc=0.)
f1 = s.calc_fext(inc=1.)
f3 = s.calc_fext(inc=3.)
assert np.allclose(f3 - f0, 3*(f1 - f0), rtol=1e-12, atol=1e-14)
s.clear_loads()
s.add_pressure_load(1.)
assert np.allclose(s.calc_fext(inc=0.), f0, rtol=1e-14, atol=0)
s.clear_loads()
assert s.pressure_loads == [] and s.pressure_loads_inc == []
assert np.all(s.calc_fext() == 0)