Skip to content

Commit

Permalink
Merge pull request #347 from adtzlr/enhance-docs
Browse files Browse the repository at this point in the history
Enhance and Fix the Documentation
  • Loading branch information
adtzlr authored Nov 20, 2022
2 parents 466cc60 + 37bee30 commit cc59cac
Show file tree
Hide file tree
Showing 48 changed files with 406 additions and 322 deletions.
11 changes: 11 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Examples
========

.. toctree::
:maxdepth: 1
:caption: Tutorials:

examples/beam
examples/numcont
examples/platewithhole
examples/shear
26 changes: 13 additions & 13 deletions docs/tutorial/beam.rst → docs/examples/beam.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,27 @@ First, let's create a meshed cube out of hexahedron cells with ``n=(181, 9, 9)``
.. code-block:: python
import numpy as np
import felupe as fe
import felupe as fem
cube = fe.Cube(a=(0, 0, 0), b=(2000, 100, 100), n=(181, 9, 9))
region = fe.RegionHexahedron(cube)
displacement = fe.Field(region, dim=3)
field = fe.FieldContainer([displacement])
cube = fem.Cube(a=(0, 0, 0), b=(2000, 100, 100), n=(181, 9, 9))
region = fem.RegionHexahedron(cube)
displacement = fem.Field(region, dim=3)
field = fem.FieldContainer([displacement])
A fixed boundary condition is applied on the left end of the beam. The degrees of freedom are partitioned into active (``dof1``) and fixed or inactive (``dof0``) degrees of freedom.

.. code-block:: python
bounds = {"fixed": fe.dof.Boundary(displacement, fx=lambda x: x==0)}
dof0, dof1 = fe.dof.partition(field, bounds)
bounds = {"fixed": fem.dof.Boundary(displacement, fx=lambda x: x==0)}
dof0, dof1 = fem.dof.partition(field, bounds)
The material behavior is defined through a built-in isotropic linear-elastic material formulation.

.. code-block:: python
umat = fe.LinearElastic(E=206000, nu=0.3)
umat = fem.LinearElastic(E=206000, nu=0.3)
density = 7850 * 1e-12
Expand All @@ -53,7 +53,7 @@ The body force is now assembled. Note that the gravity vector has to be reshaped
gravity = np.array([0, 0, 9.81]) * 1e3
bodyforce = fe.IntegralForm(
bodyforce = fem.IntegralForm(
fun=[density * gravity.reshape(-1, 1, 1)],
v=field,
dV=region.dV,
Expand All @@ -69,7 +69,7 @@ The weak form of linear elasticity is assembled into the stiffness matrix, where
.. code-block:: python
stiffness = fe.IntegralForm(
stiffness = fem.IntegralForm(
fun=umat.elasticity(),
v=field,
dV=region.dV,
Expand All @@ -80,10 +80,10 @@ The linear equation system may now be solved. First, a partition into active and

.. code-block:: python
system = fe.solve.partition(field, stiffness, dof1, dof0, r=-bodyforce)
field += fe.solve.solve(*system)
system = fem.solve.partition(field, stiffness, dof1, dof0, r=-bodyforce)
field += fem.solve.solve(*system)
fe.save(region, field, filename="bodyforce.vtk")
fem.save(region, field, filename="bodyforce.vtk")
.. image:: images/beam_bodyforce.png
Expand Down
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
26 changes: 13 additions & 13 deletions docs/tutorial/platewithhole.rst → docs/examples/platewithhole.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Let's create a meshed plate with a hole out of quad cells with the help of ``pyg

.. code-block:: python
import felupe as fe
import felupe as fem
import pygmsh
h = 1.0
Expand All @@ -46,7 +46,7 @@ The points and cells of the above mesh are used to initiate a FElupe mesh.

.. code-block:: python
mesh = fe.Mesh(
mesh = fem.Mesh(
points=mesh.points[:, :2],
cells=mesh.cells[1].data,
cell_type=mesh.cells[1].type
Expand All @@ -60,11 +60,11 @@ A numeric quad-region created on the mesh in combination with a vector-valued di

.. code-block:: python
region = fe.RegionQuad(mesh)
displacement = fe.Field(region, dim=2)
field = fe.FieldContainer([displacement])
region = fem.RegionQuad(mesh)
displacement = fem.Field(region, dim=2)
field = fem.FieldContainer([displacement])
boundaries, loadcase = fe.dof.uniaxial(
boundaries, loadcase = fem.dof.uniaxial(
field, move=0.001, right=L, clamped=False
)
Expand All @@ -73,7 +73,7 @@ The material behavior is defined through a built-in isotropic linear-elastic mat

.. code-block:: python
umat = fe.LinearElasticPlaneStress(E=210000, nu=0.3)
umat = fem.LinearElasticPlaneStress(E=210000, nu=0.3)
The weak form of linear elasticity is assembled into the stiffness matrix, where the constitutive elasticity matrix is generated with :func:`umat.hessian` (or the alias :func:`umat.elasticity`).
Expand All @@ -85,7 +85,7 @@ The weak form of linear elasticity is assembled into the stiffness matrix, where
.. code-block:: python
K = fe.IntegralForm(
K = fem.IntegralForm(
fun=umat.elasticity(),
v=field,
dV=region.dV,
Expand All @@ -100,8 +100,8 @@ The linear equation system may now be solved. First, a partition into active and
dof0 = loadcase["dof0"]
ext0 = loadcase["ext0"]
system = fe.solve.partition(field, K, dof1, dof0)
field += fe.solve.solve(*system, ext0)
system = fem.solve.partition(field, K, dof1, dof0)
field += fem.solve.solve(*system, ext0)
Let's evaluate the deformation gradient from the displacement field and calculate the stress tensor. This process is also called *stress recovery*.

Expand All @@ -126,8 +126,8 @@ However, the stress results are still located at the numeric integration points.
stress[0, 0] * stress[1, 1]
)
stress_projected = fe.project(stress, region)
vonmises_projected = fe.project(vonmises, region)
stress_projected = fem.project(stress, region)
vonmises_projected = fem.project(vonmises, region)
Results are saved as VTK-files, where additional point-data is passed within the ``point_data`` argument. Stresses are normalized by the mean value of the stress at the right end-face in order to visualize a normalized stress distribution over the plate.
Expand All @@ -136,7 +136,7 @@ Results are saved as VTK-files, where additional point-data is passed within the
right = mesh.points[:, 0] == L
fe.save(
fem.save(
region,
field,
filename="plate_with_hole.vtk",
Expand Down
28 changes: 14 additions & 14 deletions docs/tutorial/shear.rst → docs/examples/shear.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ degrees of freedom. Hence, we have to drop our MPC-centerpoint from that list.
.. code-block:: python
import numpy as np
import felupe as fe
import felupe as fem
H = 10
L = 20
Expand All @@ -43,7 +43,7 @@ degrees of freedom. Hence, we have to drop our MPC-centerpoint from that list.
n = 21
a = min(L / n, H / n)
mesh = fe.Rectangle((0, 0), (L, H), n=(round(L / a), round(H / a)))
mesh = fem.Rectangle((0, 0), (L, H), n=(round(L / a), round(H / a)))
mesh.points = np.vstack((mesh.points, [0, 2 * H]))
mesh.update(mesh.cells)
mesh.points_without_cells = np.array([], dtype=bool)
Expand All @@ -56,18 +56,18 @@ displacement field for plane-strain as well as scalar-valued fields for the hydr

.. code-block:: python
region = fe.RegionQuad(mesh)
fields = fe.FieldsMixed(region, n=3, planestrain=True)
region = fem.RegionQuad(mesh)
fields = fem.FieldsMixed(region, n=3, planestrain=True)
f0 = lambda y: np.isclose(y, 0)
f2 = lambda y: np.isclose(y, 2* H)
boundaries = {
"fixed": fe.Boundary(fields[0], fy=f0),
"control": fe.Boundary(fields[0], fy=f2, skip=(0, 1)),
"fixed": fem.Boundary(fields[0], fy=f0),
"control": fem.Boundary(fields[0], fy=f2, skip=(0, 1)),
}
dof0, dof1 = fe.dof.partition(fields, boundaries)
dof0, dof1 = fem.dof.partition(fields, boundaries)
The micro-sphere material formulation is used for the rubber. It is defined
Expand Down Expand Up @@ -97,15 +97,15 @@ as a hyperelastic material in matADi. The material formulation is finally applie
bulk=5000.0,
)
rubber = fe.SolidBody(umat=mat.ThreeFieldVariation(umat), field=fields)
rubber = fem.SolidBody(umat=mat.ThreeFieldVariation(umat), field=fields)
At the centerpoint of a multi-point constraint (MPC) the external shear
movement is prescribed. It also ensures a force-free top plate in direction
:math:`y`.

.. code-block:: python
mpc = fe.MultiPointConstraint(
mpc = fem.MultiPointConstraint(
field=fields,
points=np.arange(mesh.npoints)[mesh.points[:, 1] == H],
centerpoint=mesh.npoints - 1,
Expand All @@ -126,7 +126,7 @@ job. A job returns a generator object with the results of all substeps.

.. code-block:: python
UX = fe.math.linsteps([0, 15], 15)
UX = fem.math.linsteps([0, 15], 15)
UY = []
FX = []
Expand All @@ -146,12 +146,12 @@ job. A job returns a generator object with the results of all substeps.
.. code-block:: python
step = fe.Step(
step = fem.Step(
items=[rubber, mpc],
ramp={boundaries["control"]: UX},
boundaries=boundaries
)
job = fe.Job(steps=[step], callback=callback)
job = fem.Job(steps=[step], callback=callback)
res = job.evaluate()
For the maximum deformed model a VTK-file containing principal stretches
Expand All @@ -164,9 +164,9 @@ projected to mesh points is exported.
F = fields[0].extract()
C = dot(transpose(F), F)
stretches = fe.project(np.sqrt(eigh(C)[0]), region)
stretches = fem.project(np.sqrt(eigh(C)[0]), region)
fe.save(region, fields, point_data={
fem.save(region, fields, point_data={
"Maximum-principal-stretch": np.max(stretches, axis=1),
"Minimum-principal-stretch": np.min(stretches, axis=1),
})
Expand Down
22 changes: 14 additions & 8 deletions docs/felupe/global/constitution.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,55 @@ Constitution
~~~~~~~~~~~~

.. autoclass:: felupe.NeoHooke
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.LinearElastic
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.LinearElasticPlaneStress
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.LinearElasticPlaneStrain
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.LinearElasticPlasticIsotropicHardening
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.ThreeFieldVariation
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.UserMaterialStrain
:members:
:undoc-members:
:inherited-members:

.. autofunction:: felupe.constitution.linear_elastic

.. autofunction:: felupe.constitution.linear_elastic_plastic_isotropic_hardening

.. autoclass:: felupe.LineChange
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.AreaChange
:noindex:
:members:
:undoc-members:
:inherited-members:

.. autoclass:: felupe.VolumeChange
:noindex:
:members:
:undoc-members:
:inherited-members:
2 changes: 1 addition & 1 deletion docs/felupe/global/mechanics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Mechanics
:undoc-members:
:show-inheritance:

.. autoclass:: felupe.SolidBodyTensor
.. autoclass:: felupe.SolidBodyNearlyIncompressible
:members:
:undoc-members:
:show-inheritance:
Expand Down
4 changes: 3 additions & 1 deletion docs/howto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ How-To Guides
:maxdepth: 1
:caption: How-To:

howto/building_blocks
howto/meshgen
howto/rbe2
howto/mixed
howto/axi
howto/solvers
howto/composite
howto/forms
howto/solid
howto/solid
howto/umat
16 changes: 8 additions & 8 deletions docs/howto/axi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ For axisymmetric analyses an axisymmetric vector-valued field has to be created

.. code-block:: python
import felupe as fe
import felupe as fem
mesh = fe.Rectangle(n=3)
region = fe.RegionQuad(mesh)
u = fe.FieldAxisymmetric(region, dim=2)
field = fe.FieldContainer([u])
mesh = fem.Rectangle(n=3)
region = fem.RegionQuad(mesh)
u = fem.FieldAxisymmetric(region, dim=2)
field = fem.FieldContainer([u])
Now it gets important: The 3x3 deformation gradient for an axisymmetric problem is obtained with :meth:`felupe.FieldAxisymmetric.grad` or :meth:`felupe.FieldAxisymmetric.extract` methods. For instances of :class:`felupe.FieldAxisymmetric` the gradient is modified to return a 3x3 gradient as described in :ref:`theory-axi`.

Expand All @@ -22,7 +22,7 @@ For simplicity, let's assume a (built-in) Neo-Hookean material.

.. code-block:: python
umat = fe.NeoHooke(mu=1, bulk=5)
umat = fem.NeoHooke(mu=1, bulk=5)
FElupe provides an adopted :class:`felupe.IntegralFormAxisymmetric` class for the integration and the sparse matrix assemblage of axisymmetric problems under hood. It uses the additional information (e.g. radial coordinates at integration points) stored in :class:`felupe.FieldAxisymmetric` to provide a consistent interface in comparison to default IntegralForms.
Expand All @@ -31,7 +31,7 @@ FElupe provides an adopted :class:`felupe.IntegralFormAxisymmetric` class for th
dA = region.dV
r = fe.IntegralForm(umat.gradient(F), field, dA).assemble()
K = fe.IntegralForm(umat.hessian(F), field, dA, field).assemble()
r = fem.IntegralForm(umat.gradient(F), field, dA).assemble()
K = fem.IntegralForm(umat.hessian(F), field, dA, field).assemble()
To sum up, for axisymmetric problems use :class:`felupe.FieldAxisymmetric`. Of course, Mixed-field formulations may be applied on axisymmetric scenarios too.
Loading

0 comments on commit cc59cac

Please sign in to comment.