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)\)

Shell.add_point_load()

line force per unit length along \(y\) at \(x\)

Shell.add_distr_load_fixed_x()

line force per unit length along \(x\) at \(y\)

Shell.add_distr_load_fixed_y()

pressure over the domain or over a patch

Shell.add_pressure_load()

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

\[\boldsymbol{F}_{ext}(\lambda) = \boldsymbol{F}_{ext_0} + \lambda \boldsymbol{F}_{ext_\lambda}\]

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)