Tools#

class felupe.tools.NewtonResult(x, fun=None, jac=None, success=None, iterations=None, xnorms=None, fnorms=None)[source]#

A data class which represents the result found by Newton’s method. All parameters are available as attributes.

Parameters:
  • x (felupe.FieldContainer or ndarray) – Array or Field container with values at a solution found by Newton’s method.

  • fun (ndarray or None, optional) – Values of objective function (default is None).

  • jac (ndarray or None, optional) – Values of the Jacobian of the objective function (default is None).

  • success (bool or None, optional) – A boolean flag which is True if the solution converged (default is None).

  • iterations (int or None, optional) – Number of iterations until solution converged (default is None).

  • xnorms (array of float or None, optional) – List with norms of the values of the solution (default is None).

  • fnorms (float or None, optional) – List with norms of the objective function (default is None).

Notes

The objective function’s norm is relative based on the function values on the prescribed degrees of freedom \((\bullet)_0\). A small number \(\varepsilon\) is added to avoid numeric instabilities.

\[\text{norm}(\boldsymbol{f}) = \frac{||\boldsymbol{f}_1||} {\varepsilon + ||\boldsymbol{f}_0||}\]
felupe.newtonrhapson(x0=None, fun=<function fun>, jac=<function jac>, solve=<function solve>, maxiter=16, update=<function update>, check=<function check>, args=(), kwargs={}, tol=1.4901161193847656e-08, items=None, dof1=None, dof0=None, ext0=None, solver=<function spsolve>, verbose=True)[source]#

Find a root of a real function using the Newton-Raphson method.

Parameters:
  • x0 (felupe.FieldContainer, ndarray or None (optional)) – Array or Field container with values of unknowns at a valid starting point (default is None).

  • fun (callable, optional) – Callable which assembles the vector-valued objective function. Additional args and kwargs are passed. Function signature of a user-defined function has to be fun = lambda x, *args, **kwargs: f.

  • jac (callable, optional) – Callable which assembles the matrix-valued Jacobian. Additional args and kwargs are passed. Function signature of a user-defined Jacobian has to be jac = lambda x, *args, **kwargs: K.

  • solve (callable, optional) – Callable which prepares the linear equation system and solves it. If a keyword- argument from the list ["x", "dof1", "dof0", "ext0", "solver"] is found in the function-signature, then these arguments are passed to solve.

  • maxiter (int, optional) – Maximum number of function iterations (default is 16).

  • update (callable, optional) – Callable to update the unknowns. Function signature must be update = lambda x0, dx: x.

  • check (callable, optional) – Callable to the check the result.

  • tol (float, optional) – Tolerance value to check if the function has converged (default is 1.490e-8).

  • items (list or None, optional) – List with items which provide methods for assembly, e.g. like felupe.SolidBody (default is None).

  • dof1 (ndarray or None, optional) – 1d-array of int with all active degrees of freedom (default is None).

  • dof0 (ndarray or None, optional) – 1d-array of int with all prescribed degress of freedom (default is None).

  • ext0 (ndarray or None, optional) – Field values at mesh-points for the prescribed components of the unknowns based on dof0 (default is None).

  • solver (callable, optional) – A sparse or dense solver (default is scipy.sparse.linalg.spsolve()). For a more performant alternative install PyPardiso and use pypardiso.spsolve().

  • verbose (bool or int, optional) – Verbosity level: False or 0 for no logging, True or 1 for a progress bar and 2 for a text-based logging output (default is True).

Returns:

The result object.

Return type:

felupe.tools.NewtonResult

Notes

Nonlinear equilibrium equations \(f(x)\) as a function of the unknowns \(x\) are solved by linearization of \(f\) at a valid starting point of given unknowns \(x_0\).

\[f(x_0) = 0\]

The linearization is given by

\[f(x_0 + dx) \approx f(x_0) + K(x_0) \ dx \ (= 0)\]

with the Jacobian, evaluated at given unknowns \(x_0\),

\[K(x_0) = \frac{\partial f}{\partial x}(x_0)\]

and is rearranged to an equation system with left- and right-hand sides.

\[K(x_0) \ dx = -f(x_0)\]

After a solution is found, the unknowns are updated.

\[ \begin{align}\begin{aligned}dx &= \text{solve} \left( K(x_0), -f(x_0) \right)\\x &= x_0 + dx\end{aligned}\end{align} \]

Repeated evaluations lead to an incrementally updated solution of \(x\). Herein \(x_n\) refer to the inital unknowns whereas \(x\) are the updated unknowns (the subscript \((\bullet)_{n+1}\) is dropped for readability).

(1)#\[ \begin{align}\begin{aligned}dx &= \text{solve} \left( K(x_n), -f(x_n) \right)\\ x &= x_n + dx\end{aligned}\end{align} \]

Then, the nonlinear equilibrium equations are evaluated with the updated unknowns \(f(x)\). The procedure is repeated until convergence is reached.

Examples

>>> import felupe as fem
>>> region = fem.RegionHexahedron(fem.Cube(n=6))
>>> field = fem.FieldContainer([fem.Field(region, dim=3)])
>>> boundaries, loadcase = fem.dof.uniaxial(field, move=0.2, clamped=True)
>>> solid = fem.SolidBody(umat=fem.NeoHooke(mu=1.0, bulk=2.0), field=field)
>>> res = fem.newtonrhapson(items=[solid], **loadcase)

Newton’s method had success

>>> res.success
True

and 4 iterations were needed to converge within the specified tolerance.

>>> res.iterations
4

The norm of the objective function for all active degrees of freedom is lower than 3e-15.

>>> np.linalg.norm(res.fun[loadcase["dof1"]])
2.7482611016095555e-15
felupe.save(region, field, forces=None, gradient=None, filename='result.vtu', cell_data=None, point_data=None)[source]#

Write field-data to a VTU file.

Parameters:
  • region (Region) – The region to be saved.

  • field (FieldContainer) – The field container to be saved.

  • forces (ndarray, optional) – Array with reaction forces to be saved (default is None).

  • gradient (list of ndarray, optional) – The result of umat.gradient() with the first Piola-Kirchhoff stress tensor as the first list item (default is None).

  • filename (str, optional) – The filename for the results (default is “result.vtu”).

  • cell_data (dict or None, optional) – Additional dict with cell data (default is None).

  • point_data (dict or None, optional) – Additional dict with point data (default is None).

Examples

>>> import felupe as fem
>>>
>>> mesh = fem.Cube(n=6)
>>> region = fem.RegionHexahedron(mesh)
>>> field = fem.FieldContainer([fem.Field(region, dim=3)])
>>>
>>> boundaries, loadcase = fem.dof.uniaxial(field, clamped=True, move=0.3)
>>>
>>> umat = fem.NeoHooke(mu=1)
>>> solid = fem.SolidBodyNearlyIncompressible(umat, field, bulk=5000)
>>> step = fem.Step(items=[solid], boundaries=boundaries)
>>> job = fem.CharacteristicCurve(steps=[step], boundary=boundaries["move"])
>>> job.evaluate()
>>> fem.save(region, field, forces=job.res.fun, gradient=solid.results.stress)
felupe.topoints(values, region, sym=True, mode='tensor')[source]#

Shift of scalar or tensorial values at quadrature points to mesh-points.

felupe.project(values, region, average=True, mean=False)[source]#

Projection (and optionally averaging) of scalar or vectorial values at quadrature points to mesh-points.

felupe.tools.force(field, forces, boundary)[source]#

Evaluate the force vector sum on points of a boundary.

felupe.tools.moment(field, forces, boundary, centerpoint=array([0., 0., 0.]))[source]#

Evaluate the moment vector sum on points of a boundary at a given center point.