From 97c9bf28f555b1a09143d52488d46763d192b6c6 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 6 Sep 2024 15:59:13 +0200 Subject: [PATCH 001/125] Update __about__.py --- src/felupe/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/felupe/__about__.py b/src/felupe/__about__.py index 6dcf770e..e54ff8ae 100644 --- a/src/felupe/__about__.py +++ b/src/felupe/__about__.py @@ -1 +1 @@ -__version__ = "9.0.0" +__version__ = "9.1.0-dev" From 7e5f2e3f6d9cb79ad0efbe82849b641cb67e1606 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:13:40 +0200 Subject: [PATCH 002/125] Add `QuadraticQuad.hessian()` (#851) * Add `QuadraticQuad.hessian()` * Update _quad.py * Update ex20_third-medium-contact.py * Update test_element.py * Update README.md * Update ex20_third-medium-contact.py --- CHANGELOG.md | 3 + README.md | 2 +- examples/ex20_third-medium-contact.py | 292 +++++++++----------------- src/felupe/element/_quad.py | 36 +++- tests/test_element.py | 2 + 5 files changed, 136 insertions(+), 199 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1be6c620..1a983f0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. The format ## [Unreleased] +### Added +- Add the hessian of the element shape functions for a quadratic quad element `QuadraticQuad.hessian()`. + ## [9.0.0] - 2024-09-06 ### Added diff --git a/README.md b/README.md index 7cf3ec56..5e320f7e 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ FElupe is a Python 3.8+ 🐍 finite element analysis package 📦 focusing on th href="https://felupe.readthedocs.io/en/latest/examples/ex17_torsion-gif.html"> + href="https://felupe.readthedocs.io/en/latest/examples/ex20_third-medium-contact.html">

# Highlights diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index 063f0bc2..60c4e07d 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -2,240 +2,150 @@ Third Medium Contact -------------------- -.. topic:: Frictionless contact method simulated by a third medium. +.. topic:: Frictionless contact method simulated by a third medium [1]_. * create a mesh container with multiple meshes * define multiple solid bodies and create a top-level field - * plot the Cauchy stress component :math:`\sigma_{22}` - -This contact method uses a third medium for two solid contact bodies. - -.. note:: - - This example starts with a transversal isotropic hyperelastic strain energy function - for the third medium [1]_. Instead of a transversal isotropic hyperelastic strain - energy function, a Hessian-based regularization is also possible ([2]_, [3]_). - -First, let's create a rectangular mesh with quad cells for the upper solid body. The -:meth:`~felupe.Mesh.add_runouts`-method is used to modify the geometry according to -[1]_. Another rectangle is used for the elastic foundation. As both solid bodies will -use the same material model formulation and properties, both meshes are merged by -stacking the meshes of the :class:`mesh container ` into a -:class:`mesh `. -""" - -# sphinx_gallery_thumbnail_number = -1 -import numpy as np -import tensortrax.math as tm + * create an animation of the deformed solid +This contact method uses a third medium for two solid contact bodies with a a Hessian- +based regularization [2]_. First, let's create sub meshes with quad cells for the solid +body. All sub meshes are merged by stacking the meshes of the +:class:`mesh container ` into a :class:`mesh `. +""" import felupe as fem -from felupe.math import dddot, hess -top = fem.Rectangle(a=(-1, 1.1), b=(1, 2), n=(11, 4)) -block = top.add_runouts([-1 / 3], normalize=True, centerpoint=[0, 2], exponent=2) -assert np.isclose(block.y[block.x == 1].min(), 1.4) +t = 0.1 +L = 1 +H = 0.5 -rect = fem.Rectangle(a=(-2, 0), b=(2, 1), n=(21, 6)) -structure = fem.MeshContainer([block, rect], merge=True).stack() +nt, nL, nH = (2, 10, 4) -# %% -# The mesh for the background material (third medium) is filled with quads between two -# line meshes with identical number of points. The points inside are shifted slightly -# to reproduce the mesh from [1]_. -line = fem.mesh.Line(n=11) -lower = line.copy( - points=rect.points[ - np.logical_and.reduce([rect.y == rect.y.max(), rect.x >= -1, rect.x <= 1]) - ], -) -upper = line.copy(points=block.points[top.y == top.y.min()]) -medium = lower.fill_between(upper, n=3) +a = fem.Rectangle(a=(0, 0), b=(t, t), n=nt) +b = a.translate(move=H - t, axis=1) +c = fem.Rectangle(a=(t, 0), b=(L, t), n=(nL, nt)) +d = c.translate(move=H - t, axis=1) +e = fem.Rectangle(a=(0, t), b=(t, H - t), n=(nt, nH)) +body = fem.MeshContainer([a, b, c, d, e], merge=True).stack() # %% -# The left- and right-rectangles are also added to the third medium to visualize the -# deformation of the background mesh in a region where no contact occurs. -air = [ - fem.Rectangle( - a=(-2, block.y[block.x == -1].min()), b=(-1, 2), n=(6, 4) - ), # top-left - fem.Rectangle( - a=(-2, 1), b=(-1, block.y[block.x == 1].min()), n=(6, 3) - ), # bottom-l. - fem.Rectangle(a=(1, block.y[block.x == 1].min()), b=(2, 2), n=(6, 4)), # top-right - fem.Rectangle(a=(1, 1), b=(2, block.y[block.x == 1].min()), n=(6, 3)), # bottom-r. -] -medium = fem.MeshContainer([medium, *air], merge=True).stack() -medium.points[ - np.logical_and(medium.y == 2, np.logical_or(medium.x < -1, medium.x > 1)), 1 -] -= 0.02 +# This is repeated for the medium, where two meshes are added to a mesh container. Extra +# cells are added on the right edge to improve convergence. +f = fem.Rectangle(a=(t, t), b=(L, H - t), n=(nL, nH)) +g = fem.Rectangle(a=(L, 0), b=(L + t / (nt - 1), H), n=(2, 2 * (nt - 1) + nH)) +medium = fem.MeshContainer([f, g], merge=True).stack() # %% -# Both meshes are added to a mesh container. For each mesh of the container, quad -# regions and plane-strain vector-fields for the displacements are created. -container = fem.MeshContainer([structure, medium], merge=True, decimals=6) - -plotter = container.plot(colors=["darkgrey", "lightgrey"]) -plotter.show_bounds(xtitle="", ytitle="") -plotter.add_legend([("solid", "darkgrey"), ("medium", "lightgrey")], bcolor="white") -plotter.show() - -regions = [ - fem.RegionQuad(container.meshes[0]), - fem.RegionQuad(container.meshes[1]), -] -fields = [fem.FieldContainer([fem.FieldPlaneStrain(r, dim=2)]) for r in regions] +# Both stacked meshes are added to a top-level mesh container. For each mesh of the +# container, quad regions and plane-strain vector-fields for the displacements are +# created. The Neo-Hookean isotropic hyperelastic material formulation from the solid +# body is also used for the isotropic part of the background material but with scaled +# down material parameters. +G = 5 / 14 +K = 5 / 3 +gamma = 2e-6 + +container = fem.MeshContainer([body, medium], merge=True) +regions = [fem.RegionQuad(m, hess=True) for m in container.meshes] +fields = [fem.FieldPlaneStrain(r, dim=2).as_container() for r in regions] +umats = [fem.NeoHooke(mu=G, bulk=K), fem.NeoHooke(mu=G * gamma, bulk=K * gamma)] +solids = [fem.SolidBody(umat, f) for umat, f in zip(umats, fields)] # %% # A top-level plane-strain field is created on a stacked mesh. This field includes all # unknowns and is required for the selection of prescribed degrees of freedom as well -# as for Newton's method. -mesh = container.stack() -region = fem.RegionQuad(mesh) -field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)]) - -boundaries, loadcase = fem.dof.uniaxial(field, axis=1, sym=False, clamped=True) -move = fem.math.linsteps([0, -0.1], num=5) - - -# %% -# The background material is assumed to be transversly isotropic hyperelastic [1]_, -# splitted into isotropic and anisotropic parts. The isotropic part is used for rigid -# body movements and hence, its elastic stiffness must be magnitudes lower than the one -# from the solid bodies. The anisotropic part acts in the direction of the -# smallest principal (squared) stretch which is used as an assumption for the surface -# normal vector. -def third_medium_contact(C, mu=1, a1=1, a2=1, a3=1, a4=23, a5=100, tol=0.5): - """Transversly isotropic hyperelastic strain energy density function for the - third medium.""" - - # isotropic invariants - I1 = tm.trace(C) - I2 = (I1**2 - tm.trace(C @ C)) / 2 - I3 = tm.linalg.det(C) - - # anisotropic invariant for minimum principal squared stretch - w, M = tm.linalg.eigh(C) - λ2min = w[0] - J4 = tm.special.ddot(C, M[0]) - - # isotropic material paramter - d = 2 * a1 + 4 * a2 + 2 * a3 - - # deformation dependent material parameter - c = tm.if_else(λ2min >= tol, 0 * λ2min, a5 / λ2min**2) - - # strain energy density functions - W_iso = a1 * I1 + a2 * I2 + a3 * I3 - d * tm.log(I3) / 2 - W_aniso = c / (a4 + 1) * (1 - J4) ** (a4 + 1) - - return mu * W_iso + W_aniso - - -# %% -# A :class:`Neo-Hookean ` material model formulation is used for both -# solid bodies. The third medium uses a general -# :class:`hyperelastic ` material class with automatic -# differentiation. -solids = [ - fem.SolidBody(fem.NeoHooke(mu=2692.3, bulk=5833.3), fields[0]), - fem.SolidBody(fem.Hyperelastic(third_medium_contact, mu=1, a5=1e-2), fields[1]), -] - -step = fem.Step(solids, boundaries=boundaries, ramp={boundaries["move"]: move}) -job = fem.Job([step]).evaluate(x0=field) - -# %% -# The vertical component of the Cauchy stress :math:`\sigma_{22}` is shifted to and -# averaged inside the solid body at the mesh points. -plotter = solids[0].plot("Cauchy Stress", component=1, project=fem.topoints) -plotter.show_bounds(xtitle="", ytitle="") -plotter.show() - -# %% -# The deformed wireframe mesh shows the deformation of the background material. -field.plot(style="wireframe", nonlinear_subdivision=2, line_width=2).show() +# as for Newton's method. The left end edge is fixed and the vertical displacement is +# prescribed on the outermost top-right point. +region = fem.RegionQuad(container.stack()) +field = fem.FieldPlaneStrain(region, dim=2).as_container() + +bounds = dict( + fixed=fem.Boundary(field[0], fx=0), + move=fem.Boundary(field[0], fx=L, fy=H, mode="and", skip=(1, 0)), +) # %% -# Instead of using a transversly anisotropic material formulation for the third medium -# contact method, a hessian-regularization may be used. Therefore, we must reload the -# region of the background material and enable the flag to evaluate the Hessian. -regions[1].reload(hess=True) +# The so-called HuHu-regularization is created by two weak-:func:`form ` +# expressions, see Eq. :eq:`huhu-regularization` [3_]. +# +# .. math:: +# :label: huhu-regularization +# +# \Pi &= \frac{1}{2} \int_V +# \mathbb{H} \boldsymbol{u} \vdots \mathbb{H} \boldsymbol{u} \ dV +# +# \delta \Pi &= \int_V +# \mathbb{H} \delta \boldsymbol{u} \vdots \mathbb{H} \boldsymbol{u} \ dV +# +# \Delta \delta \Pi &= \int_V +# \mathbb{H} \delta \boldsymbol{u} \vdots \mathbb{H} \Delta \boldsymbol{u} \ dV +# +from felupe.math import dddot, hess -# %% -# The so-called HuHu-regularization is created by two weak-:func:`form ` -# expressions. This time, the Neo-Hookean isotropic hyperelastic material formulation -# from the solid bodies is also used for the isotropic part of the background material -# but with scaled down material parameters. -@fem.Form(v=fields[1], u=fields[1]) -def bilinearform(): - return [lambda v, u: dddot(hess(v), hess(u))] +@fem.Form(v=fields[1], u=fields[1], kwargs={"kr": None}) +def Δδ_ψ(): + return [lambda v, u, kr: kr * dddot(hess(u), hess(v))] -@fem.Form(v=fields[1]) -def linearform(): +@fem.Form(v=fields[1], kwargs={"kr": 1.0}) +def δ_ψ(): u = fields[1][0] - return [lambda v: dddot(hess(v), hess(u)[:2, :2, :2])] + return [lambda v, kr: kr * dddot(hess(v), hess(u)[:2, :2, :2])] -solids = [ - fem.SolidBody(fem.NeoHooke(mu=2692.3, bulk=5833.3), fields[0]), - fem.SolidBody(fem.NeoHooke(mu=2692.3 * 1e-3, bulk=5833.3 * 1e-3), fields[1]), - fem.FormItem(bilinearform, linearform), -] +regularization = fem.FormItem(Δδ_ψ, δ_ψ, kwargs=dict(kr=K * L**2 * gamma)) # %% -# The fields are resetted in order to restart the simulation with the Hessian-based -# regularization. This time, the enforced vertical displacement on the top edge of the -# upper body is doubled. -field[0].fill(0.0) -[f[0].fill(0.0) for f in fields] - -move = fem.math.linsteps([0, -0.2], num=15) -step = fem.Step(solids, boundaries=boundaries, ramp={boundaries["move"]: move}) -job = fem.Job([step]).evaluate(x0=field) +# The prescribed displacement is ramped up to the maximum value and released until zero. +move = fem.math.linsteps([0, 0.6, 1, 0.6, 0], num=15) +step = fem.Step( + items=[*solids, regularization], + ramp={bounds["move"]: move * -0.5 * L}, + boundaries=bounds, +) # %% -# The vertical component of the Cauchy stress :math:`\sigma_{22}` is plotted for the -# maximum applied vertical displacement. -plotter = solids[0].plot("Cauchy Stress", component=1, project=fem.topoints) -plotter.show_bounds(xtitle="", ytitle="") -plotter.show() +# The deformation is captured in a GIF-file. +plotter = regions[0].mesh.plot(line_width=3, off_screen=True) +plotter = regions[1].mesh.plot(style="wireframe", plotter=plotter) +plotter.open_gif("third-medium-contact.gif", fps=30) -# %% -# Now, the upper solid body is moved along the horizontal direction and the vertical -# Cauchy stress component is plotted again. -boundaries, loadcase = fem.dof.shear(field, axes=(0, 1), sym=False, moves=(0, 0, -0.2)) -move = fem.math.linsteps([0, 0.5], num=10) -step = fem.Step(solids, boundaries=boundaries, ramp={boundaries["move"]: move}) -job = fem.Job([step]).evaluate(x0=field) +def record(stepnumber, substepnumber, substep, plotter): + "Update the mesh of the plotter and write a frame." + for m in plotter.meshes: + m.points[:, :2] = region.mesh.points + field[0].values + plotter.write_frame() -plotter = solids[0].plot("Cauchy Stress", component=1, project=fem.topoints) -plotter.show_bounds(xtitle="", ytitle="") -plotter.show() # %% -# The deformed wireframe mesh shows again the deformation of the background material. -field.plot(style="wireframe", nonlinear_subdivision=2, line_width=2).show() +# The top-level field has to be passed as the ``x0``-argument for +# :func:`Newton's method `, which is called on evaluation. +job = fem.Job([step], callback=record, plotter=plotter) +job.evaluate(x0=field) + +plotter.close() # %% # References # ~~~~~~~~~~ -# .. [1] P. Wriggers, J. Schröder, and A. Schwarz, "A finite element method for contact -# using a third medium", Computational Mechanics, vol. 52, no. 4. Springer -# Science and Business Media LLC, pp. 837–847, Mar. 30, 2013. |DOI-1|. # -# .. [2] https://en.wikipedia.org/wiki/Third_medium_contact_method +# .. [1] https://en.wikipedia.org/wiki/Third_medium_contact_method # -# .. [3] G. L. Bluhm, O. Sigmund, and K. Poulios, "Internal contact modeling for finite +# .. [2] G. L. Bluhm, O. Sigmund, and K. Poulios, "Internal contact modeling for finite # strain topology optimization", Computational Mechanics, vol. 67, no. 4. -# Springer Science and Business Media LLC, pp. 1099–1114, Mar. 04, 2021. |DOI-3|. +# Springer Science and Business Media LLC, pp. 1099–1114, Mar. 04, 2021. |DOI-2|. # -# .. |DOI-1| image:: https://zenodo.org/badge/DOI/10.1007/s00466-013-0848-5.svg -# :target: https://www.doi.org/10.1007/s00466-013-0848-5 +# .. [3] A. H. Frederiksen, O. Sigmund, and K. Poulios, "Topology optimization of self- +# contacting structures", Computational Mechanics, vol. 73, no. 4. Springer +# Science and Business Media LLC, pp. 967–981, Oct. 07, 2023. doi: |DOI-3|. # -# .. |DOI-3| image:: https://zenodo.org/badge/DOI/10.1007/s00466-021-01974-x.svg +# .. |DOI-2| image:: https://zenodo.org/badge/DOI/10.1007/s00466-021-01974-x.svg # :target: https://www.doi.org/10.1007/s00466-021-01974-x +# +# .. |DOI-3| image:: https://zenodo.org/badge/DOI/10.1007/s00466-023-02396-7.svg +# :target: https://www.doi.org/10.1007/s00466-023-02396-7 +# diff --git a/src/felupe/element/_quad.py b/src/felupe/element/_quad.py index e54e1d67..3491181f 100644 --- a/src/felupe/element/_quad.py +++ b/src/felupe/element/_quad.py @@ -226,18 +226,40 @@ def gradient(self, rs): ra * (1 + sa * s) * (ra * r + sa * s - 1) / 4 + (1 + ra * r) * (1 + sa * s) * ra / 4 ) + dhds = ( + sa * (1 + ra * r) * (ra * r + sa * s - 1) / 4 + + (1 + ra * r) * (1 + sa * s) * sa / 4 + ) + + dhdr[ra == 0] = -r * (1 + sa[ra == 0] * s) + dhds[ra == 0] = (1 - r**2) * sa[ra == 0] / 2 - dhdr[ra == 0] = -2 * r * (1 + sa[ra == 0] * s) / 2 dhdr[sa == 0] = ra[sa == 0] * (1 - s**2) / 2 + dhds[sa == 0] = (1 + ra[sa == 0] * r) * -s - dhds = (1 + ra * r) * sa * (ra * r + sa * s - 1) / 4 + (1 + ra * r) * ( - 1 + sa * s - ) * sa / 4 + return np.vstack([dhdr, dhds]).T - dhds[ra == 0] = (1 - r**2) * sa[ra == 0] / 2 - dhds[sa == 0] = (1 + ra[sa == 0] * r) * -2 * s / 2 + def hessian(self, rs): + "Return the hessian of shape functions at given coordinates (r, s)." - return np.vstack([dhdr, dhds]).T + r, s = rs + ra, sa = self.points.T + + d2hdrdr = ra**2 * (1 + sa * s) / 2 + d2hdsds = sa**2 * (1 + ra * r) / 2 + + d2hdrds = ra * sa * (1 + 2 * ra * r + 2 * sa * s) / 4 + + d2hdrdr[ra == 0] = -(1 + sa[ra == 0] * s) + d2hdsds[sa == 0] = -(1 + ra[sa == 0] * r) + + d2hdrdr[sa == 0] = 0 + d2hdsds[ra == 0] = 0 + + d2hdrds[ra == 0] = sa[ra == 0] * -r + d2hdrds[sa == 0] = ra[sa == 0] * -s + + return np.array([[d2hdrdr, d2hdrds], [d2hdrds, d2hdsds]]).T class BiQuadraticQuad(Element): diff --git a/tests/test_element.py b/tests/test_element.py index 13fa938c..f90aaac8 100644 --- a/tests/test_element.py +++ b/tests/test_element.py @@ -105,9 +105,11 @@ def test_quad8(): h = quad8.function(r) dhdr = quad8.gradient(r) + d2hdrdr = quad8.hessian(r) assert h[0] == 1 assert np.all(dhdr[0] == -1.5) + assert d2hdrdr.shape == (8, 2, 2) assert quad8.shape == dhdr.shape From 08e8244202e531542c2b7685bbf63c1391d2e7ba Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:37:56 +0200 Subject: [PATCH 003/125] Update core.rst --- docs/felupe/constitution/core.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/felupe/constitution/core.rst b/docs/felupe/constitution/core.rst index b28a5398..a45f7e21 100644 --- a/docs/felupe/constitution/core.rst +++ b/docs/felupe/constitution/core.rst @@ -18,8 +18,8 @@ This page contains the core (hard-coded) constitutive material model formulation .. autosummary:: LinearElastic - LinearElasticPlaneStrain LinearElasticPlaneStress + constitution.LinearElasticPlaneStrain constitution.LinearElasticTensorNotation LinearElasticLargeStrain LinearElasticOrthotropic From c5140f58e3e3023505b9374847f38220b4095a7d Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:38:42 +0200 Subject: [PATCH 004/125] Update core.rst --- docs/felupe/constitution/core.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/felupe/constitution/core.rst b/docs/felupe/constitution/core.rst index a45f7e21..7cd91dd3 100644 --- a/docs/felupe/constitution/core.rst +++ b/docs/felupe/constitution/core.rst @@ -77,7 +77,7 @@ This page contains the core (hard-coded) constitutive material model formulation :undoc-members: :inherited-members: -.. autoclass:: felupe.LinearElasticPlaneStrain +.. autoclass:: felupe.constitution.LinearElasticPlaneStrain :members: :undoc-members: :inherited-members: From e4cead19b46832ac1c1c9e99a407d9d22e1d6880 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:39:49 +0200 Subject: [PATCH 005/125] Update _region.py --- src/felupe/region/_region.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/felupe/region/_region.py b/src/felupe/region/_region.py index c47b3120..b5f2dade 100644 --- a/src/felupe/region/_region.py +++ b/src/felupe/region/_region.py @@ -189,7 +189,7 @@ def copy( hess=None, uniform=None, ): - """Return a copy of the region and reload it if necessary. + r"""Return a copy of the region and reload it if necessary. Parameters ---------- @@ -247,7 +247,7 @@ def reload( hess=None, uniform=None, ): - """Reload the numeric region inplace. + r"""Reload the numeric region inplace. Parameters ---------- From 80a4503fcfb89c0f62719c34dc1ef84a6089b3ca Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:43:57 +0200 Subject: [PATCH 006/125] Update ex17_torsion-gif.py --- examples/ex17_torsion-gif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex17_torsion-gif.py b/examples/ex17_torsion-gif.py index 9ee77e6e..a137d492 100644 --- a/examples/ex17_torsion-gif.py +++ b/examples/ex17_torsion-gif.py @@ -52,7 +52,7 @@ # %% # The reaction moment on the centerpoint of the right end face is tracked by a # ``callback()`` function when we :meth:`~felupe.Job.evaluate` the :class:`~felupe.Job`. -# During the callback, the animated deformed body is recored in a GIF-file. After all +# During the callback, the animated deformed body is recorded in a GIF-file. After all # frames are recorded, it is important to ``close()`` the plotter. moment = [] From a529da51c6e4bbd8ebd4e654289bdc2d74dc2c6a Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:44:08 +0200 Subject: [PATCH 007/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index 60c4e07d..2450fee5 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -1,4 +1,4 @@ -""" +r""" Third Medium Contact -------------------- From 6b42a03442164abd9c2994d1eee2603dd8ec6d4e Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 16:52:22 +0200 Subject: [PATCH 008/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index 2450fee5..b7f38fa4 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -109,8 +109,7 @@ def δ_ψ(): # %% # The deformation is captured in a GIF-file. -plotter = regions[0].mesh.plot(line_width=3, off_screen=True) -plotter = regions[1].mesh.plot(style="wireframe", plotter=plotter) +plotter = container.plot(colors=["grey", "white"], line_width=3, off_screen=True) plotter.open_gif("third-medium-contact.gif", fps=30) From f7d59b3ace5e3b9ca45f348bc914aeed2ac52d38 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 17:10:17 +0200 Subject: [PATCH 009/125] Update ex20_third-medium-contact.py move all plotter-related lines into one code-block --- examples/ex20_third-medium-contact.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index b7f38fa4..dde874b7 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -108,7 +108,9 @@ def δ_ψ(): ) # %% -# The deformation is captured in a GIF-file. +# The deformation is captured in a GIF-file. The top-level field has to be passed as the +# ``x0``-argument for :func:`Newton's method `, which is called on +# evaluation. After all frames are recorded, it is important to ``close()`` the plotter. plotter = container.plot(colors=["grey", "white"], line_width=3, off_screen=True) plotter.open_gif("third-medium-contact.gif", fps=30) @@ -120,9 +122,6 @@ def record(stepnumber, substepnumber, substep, plotter): plotter.write_frame() -# %% -# The top-level field has to be passed as the ``x0``-argument for -# :func:`Newton's method `, which is called on evaluation. job = fem.Job([step], callback=record, plotter=plotter) job.evaluate(x0=field) From 33c3c44587f58a6d4befa6050756c9180b654bb5 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 17:27:21 +0200 Subject: [PATCH 010/125] Fix unicode symbols on Windows --- README.md | 2 +- docs/index.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e320f7e..a4af59fc 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![FElupe](https://img.shields.io/badge/%F0%9F%94%8D-FElupe-white)](https://felupe.readthedocs.io) [![PyPI version shields.io](https://img.shields.io/pypi/v/felupe.svg)](https://pypi.python.org/pypi/felupe/) [![Documentation Status](https://readthedocs.org/projects/felupe/badge/?version=latest)](https://felupe.readthedocs.io/en/latest/?badge=latest) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![codecov](https://codecov.io/gh/adtzlr/felupe/branch/main/graph/badge.svg?token=J2QP6Y6LVH)](https://codecov.io/gh/adtzlr/felupe) [![DOI](https://zenodo.org/badge/360657894.svg)](https://zenodo.org/badge/latestdoi/360657894) ![Codestyle black](https://img.shields.io/badge/code%20style-black-black) ![PyPI - Downloads](https://img.shields.io/pypi/dm/felupe) [![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://adtzlr.github.io/felupe-web/lab?path=01_Getting-Started.ipynb) Open In Colab -FElupe is a Python 3.8+ 🐍 finite element analysis package 📦 focusing on the formulation and numerical solution of nonlinear problems in continuum mechanics 🔧 of solid bodies 🪨. This package is intended for scientific research 💻, but is also suitable for running nonlinear simulations 🚂 in general 🏎️. In addition to the transformation of general weak forms into sparse vectors and matrices, FElupe provides an efficient high-level abstraction layer for the simulation of the deformation of solid bodies. +FElupe is a Python 3.8+ 🐍 finite element analysis package 📦 focusing on the formulation and numerical solution of nonlinear problems in continuum mechanics of solid bodies 🔧. This package is intended for scientific research 💻, but is also suitable for running nonlinear simulations 🚂 in general 🏎️. In addition to the transformation of general weak forms into sparse vectors and matrices, FElupe provides an efficient high-level abstraction layer for the simulation of the deformation of solid bodies.

Date: Wed, 11 Sep 2024 17:27:23 +0200 Subject: [PATCH 011/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index dde874b7..94829f37 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -74,13 +74,13 @@ # :label: huhu-regularization # # \Pi &= \frac{1}{2} \int_V -# \mathbb{H} \boldsymbol{u} \vdots \mathbb{H} \boldsymbol{u} \ dV +# \mathbb{H}(\boldsymbol{u})~\vdots~\mathbb{H}(\boldsymbol{u})~dV # # \delta \Pi &= \int_V -# \mathbb{H} \delta \boldsymbol{u} \vdots \mathbb{H} \boldsymbol{u} \ dV +# \mathbb{H}(\delta \boldsymbol{u})~\vdots~\mathbb{H}(\boldsymbol{u})~dV # # \Delta \delta \Pi &= \int_V -# \mathbb{H} \delta \boldsymbol{u} \vdots \mathbb{H} \Delta \boldsymbol{u} \ dV +# \mathbb{H}(\delta \boldsymbol{u})~\vdots~\mathbb{H}(\Delta \boldsymbol{u})~dV # from felupe.math import dddot, hess From b052184387b78918f1483b2a9405d4482213a1be Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 17:29:29 +0200 Subject: [PATCH 012/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index 94829f37..e0329435 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -68,7 +68,7 @@ # %% # The so-called HuHu-regularization is created by two weak-:func:`form ` -# expressions, see Eq. :eq:`huhu-regularization` [3_]. +# expressions, see Eq. :eq:`huhu-regularization` [3]_. # # .. math:: # :label: huhu-regularization From 965d3d19039640c6dd5dc40c6978c275d7cb1770 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 11 Sep 2024 17:30:03 +0200 Subject: [PATCH 013/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index e0329435..fe291e87 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -139,7 +139,7 @@ def record(stepnumber, substepnumber, substep, plotter): # # .. [3] A. H. Frederiksen, O. Sigmund, and K. Poulios, "Topology optimization of self- # contacting structures", Computational Mechanics, vol. 73, no. 4. Springer -# Science and Business Media LLC, pp. 967–981, Oct. 07, 2023. doi: |DOI-3|. +# Science and Business Media LLC, pp. 967–981, Oct. 07, 2023. |DOI-3|. # # .. |DOI-2| image:: https://zenodo.org/badge/DOI/10.1007/s00466-021-01974-x.svg # :target: https://www.doi.org/10.1007/s00466-021-01974-x From 2bcbdcc8519d0e0155f6c82ae2d07079ce840813 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 12 Sep 2024 11:39:36 +0200 Subject: [PATCH 014/125] Examples: reduce the number of frames in the GIF files to speed-up the build time for read-the-docs --- examples/ex17_torsion-gif.py | 19 ++++++++++--------- examples/ex20_third-medium-contact.py | 21 ++++++++++++++------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/examples/ex17_torsion-gif.py b/examples/ex17_torsion-gif.py index a137d492..76b42061 100644 --- a/examples/ex17_torsion-gif.py +++ b/examples/ex17_torsion-gif.py @@ -59,18 +59,19 @@ plotter = field.plot( "Principal Values of Logarithmic Strain", clim=[0, 0.2], off_screen=True ) -plotter.open_gif("result.gif", fps=10) +plotter.open_gif("result.gif", fps=5) def record(stepnumber, substepnumber, substep, plotter): - # update the mesh-points and the scalars of the plotter - name = plotter.mesh.active_scalars_info.name - data = substep.x.evaluate.log_strain(tensor=False).mean(-2)[-1] - - plotter.mesh.points[:] = mesh.points + field[0].values - plotter.mesh[name] = data - # plotter.update_scalar_bar_range(clim=[min(data), max(data)]) - plotter.write_frame() + "Update the mesh-points and the scalars of the plotter." + if substepnumber in np.arange(len(move), step=2): + name = plotter.mesh.active_scalars_info.name + data = substep.x.evaluate.log_strain(tensor=False).mean(-2)[-1] + + plotter.mesh.points[:] = mesh.points + field[0].values + plotter.mesh[name] = data + + plotter.write_frame() # evaluate the reaction moment at the centerpoint of the right end face forces = substep.fun diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index fe291e87..e2156457 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -15,6 +15,8 @@ body. All sub meshes are merged by stacking the meshes of the :class:`mesh container ` into a :class:`mesh `. """ +import numpy as np + import felupe as fem t = 0.1 @@ -86,17 +88,21 @@ @fem.Form(v=fields[1], u=fields[1], kwargs={"kr": None}) -def Δδ_ψ(): +def bilinearform(): return [lambda v, u, kr: kr * dddot(hess(u), hess(v))] @fem.Form(v=fields[1], kwargs={"kr": 1.0}) -def δ_ψ(): +def linearform(): u = fields[1][0] return [lambda v, kr: kr * dddot(hess(v), hess(u)[:2, :2, :2])] -regularization = fem.FormItem(Δδ_ψ, δ_ψ, kwargs=dict(kr=K * L**2 * gamma)) +regularization = fem.FormItem( + bilinearform=bilinearform, + linearform=linearform, + kwargs={"kr": K * L**2 * gamma}, +) # %% # The prescribed displacement is ramped up to the maximum value and released until zero. @@ -112,14 +118,15 @@ def δ_ψ(): # ``x0``-argument for :func:`Newton's method `, which is called on # evaluation. After all frames are recorded, it is important to ``close()`` the plotter. plotter = container.plot(colors=["grey", "white"], line_width=3, off_screen=True) -plotter.open_gif("third-medium-contact.gif", fps=30) +plotter.open_gif("third-medium-contact.gif", fps=5) def record(stepnumber, substepnumber, substep, plotter): "Update the mesh of the plotter and write a frame." - for m in plotter.meshes: - m.points[:, :2] = region.mesh.points + field[0].values - plotter.write_frame() + if substepnumber in np.arange(len(move), step=5): + for m in plotter.meshes: + m.points[:, :2] = region.mesh.points + field[0].values + plotter.write_frame() job = fem.Job([step], callback=record, plotter=plotter) From d8fb6cad9bb046377c632f9ea8e946cb5d7a14ec Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 12 Sep 2024 13:07:08 +0200 Subject: [PATCH 015/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index e2156457..f0c8232b 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -69,21 +69,16 @@ ) # %% -# The so-called HuHu-regularization is created by two weak-:func:`form ` -# expressions, see Eq. :eq:`huhu-regularization` [3]_. +# The so-called HuHu-regularization is created by two weak-:func:`forms `, +# which are derived from the regularization potential, see Eq. +# :eq:`huhu-regularization` [3]_. # # .. math:: # :label: huhu-regularization # -# \Pi &= \frac{1}{2} \int_V +# \Pi = \frac{1}{2} \int_V # \mathbb{H}(\boldsymbol{u})~\vdots~\mathbb{H}(\boldsymbol{u})~dV # -# \delta \Pi &= \int_V -# \mathbb{H}(\delta \boldsymbol{u})~\vdots~\mathbb{H}(\boldsymbol{u})~dV -# -# \Delta \delta \Pi &= \int_V -# \mathbb{H}(\delta \boldsymbol{u})~\vdots~\mathbb{H}(\Delta \boldsymbol{u})~dV -# from felupe.math import dddot, hess From 9cdbe2d97b4adaca8b986cc260a9784621254adb Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 12 Sep 2024 15:09:37 +0200 Subject: [PATCH 016/125] Update ex20_third-medium-contact.py --- examples/ex20_third-medium-contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index f0c8232b..af43ad3d 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -82,7 +82,7 @@ from felupe.math import dddot, hess -@fem.Form(v=fields[1], u=fields[1], kwargs={"kr": None}) +@fem.Form(v=fields[1], u=fields[1], kwargs={"kr": 1.0}) def bilinearform(): return [lambda v, u, kr: kr * dddot(hess(u), hess(v))] From 727dbd037aff800f6f804b02c06b68664571e456 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 14:16:43 +0200 Subject: [PATCH 017/125] Update _scene.py --- src/felupe/view/_scene.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/felupe/view/_scene.py b/src/felupe/view/_scene.py index 24e9d06d..50a300ba 100644 --- a/src/felupe/view/_scene.py +++ b/src/felupe/view/_scene.py @@ -20,7 +20,7 @@ class Scene: - """Base class for plotting a static scene. + r"""Base class for plotting a static scene. Attributes ---------- @@ -28,6 +28,28 @@ class Scene: A generalized Dataset with the mesh as well as point- and cell-data. This is not an instance of :class:`felupe.Mesh`. + Examples + -------- + .. pyvista-plot:: + :force_static: + + >>> import numpy as np + >>> import felupe as fem + >>> + >>> scene = fem.view.Scene() + >>> scene.mesh = fem.Cube(n=3).as_unstructured_grid() + >>> scene.mesh.point_data["Displacement"] = np.arange(81).reshape(27, 3) / 300 + >>> scene.mesh.set_active_scalars(None) + >>> + >>> scene.plot("Displacement", component=None).show() + + See Also + -------- + felupe.view.ViewMesh : Provide Visualization methods for a mesh with optional given + dicts of point- and cell-data items. + felupe.view.ViewField : Provide Visualization methods for a field container. + felupe.view.ViewSolid : Provide Visualization methods for a field container or a + solid body. """ def plot( From 9317a4c38e8884ba53671e0996286e55efce68e8 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 14:23:57 +0200 Subject: [PATCH 018/125] Update _field.py --- src/felupe/view/_field.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/felupe/view/_field.py b/src/felupe/view/_field.py index ec7e5fd5..d05f3f2e 100644 --- a/src/felupe/view/_field.py +++ b/src/felupe/view/_field.py @@ -21,7 +21,7 @@ class ViewField(ViewMesh): - """Provide Visualization methods for :class:`felupe.FieldContainer`. The warped + r"""Provide Visualization methods for :class:`felupe.FieldContainer`. The warped (deformed) mesh is created from the values of the first field (displacements). By default, the "Deformation Gradient" tensor, the "Logarithmic Strain" tensor and the "Principal Values of Logarithmic Strain" are evaluated as field-related items of the @@ -49,10 +49,30 @@ class ViewField(ViewMesh): A generalized Dataset with the mesh as well as point- and cell-data. This is not an instance of :class:`felupe.Mesh`. + Examples + -------- + .. pyvista-plot:: + :force_static: + + >>> import numpy as np + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> region = fem.RegionHexahedron(mesh) + >>> u = np.sqrt(1 + np.arange(81)).reshape(27, 3) / 100 + >>> field = fem.FieldContainer([fem.Field(region, values=u)]) + >>> + >>> view = fem.view.ViewField(field, project=fem.project) + >>> view.plot("Principal Values of Logarithmic Strain").show() + See Also -------- + felupe.view.Scene : Base class for plotting a static scene. + felupe.view.ViewMesh : Provide Visualization methods for a mesh with optional given + dicts of point- and cell-data items. + felupe.view.ViewSolid : Provide Visualization methods for a field container or a + solid body. felupe.project: Project given values at quadrature-points to mesh-points. - """ def __init__( From 92b73ec6fb055929baca9853dcd71481e0ad6286 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 14:23:59 +0200 Subject: [PATCH 019/125] Update _mesh.py --- src/felupe/view/_mesh.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/felupe/view/_mesh.py b/src/felupe/view/_mesh.py index 5c5c1eac..a54d61d8 100644 --- a/src/felupe/view/_mesh.py +++ b/src/felupe/view/_mesh.py @@ -20,7 +20,7 @@ class ViewMesh(Scene): - """Provide Visualization methods for :class:`felupe.Mesh` with optional given + r"""Provide Visualization methods for :class:`felupe.Mesh` with optional given dicts of point- and cell-data items. Parameters @@ -40,6 +40,27 @@ class ViewMesh(Scene): A generalized Dataset with the mesh as well as point- and cell-data. This is not an instance of :class:`felupe.Mesh`. + Examples + -------- + .. pyvista-plot:: + :force_static: + + >>> import numpy as np + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> displacement = np.arange(81).reshape(27, 3) / 300 + >>> view = fem.view.ViewMesh(mesh, point_data={"Displacement": displacement}) + >>> + >>> view.plot("Displacement", component=None).show() + + See Also + -------- + felupe.view.Scene : Base class for plotting a static scene. + felupe.view.ViewField : Provide Visualization methods for a field container. + felupe.view.ViewSolid : Provide Visualization methods for a field container or a + solid body. + """ def __init__(self, mesh, point_data=None, cell_data=None, cell_type=None): From ff9ea3e3a0b641c763e510ea46691fd86397ba59 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 18:06:22 +0200 Subject: [PATCH 020/125] enhance docstrings of view-classes --- src/felupe/view/_field.py | 6 +++--- src/felupe/view/_mesh.py | 6 +++--- src/felupe/view/_scene.py | 6 +++--- src/felupe/view/_solid.py | 23 ++++++++++++++++++++++- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/felupe/view/_field.py b/src/felupe/view/_field.py index d05f3f2e..dbc3575d 100644 --- a/src/felupe/view/_field.py +++ b/src/felupe/view/_field.py @@ -62,15 +62,15 @@ class ViewField(ViewMesh): >>> u = np.sqrt(1 + np.arange(81)).reshape(27, 3) / 100 >>> field = fem.FieldContainer([fem.Field(region, values=u)]) >>> - >>> view = fem.view.ViewField(field, project=fem.project) + >>> view = fem.ViewField(field, project=fem.project) >>> view.plot("Principal Values of Logarithmic Strain").show() See Also -------- felupe.view.Scene : Base class for plotting a static scene. - felupe.view.ViewMesh : Provide Visualization methods for a mesh with optional given + felupe.ViewMesh : Provide Visualization methods for a mesh with optional given dicts of point- and cell-data items. - felupe.view.ViewSolid : Provide Visualization methods for a field container or a + felupe.ViewSolid : Provide Visualization methods for a field container or a solid body. felupe.project: Project given values at quadrature-points to mesh-points. """ diff --git a/src/felupe/view/_mesh.py b/src/felupe/view/_mesh.py index a54d61d8..4f179542 100644 --- a/src/felupe/view/_mesh.py +++ b/src/felupe/view/_mesh.py @@ -50,15 +50,15 @@ class ViewMesh(Scene): >>> >>> mesh = fem.Cube(n=3) >>> displacement = np.arange(81).reshape(27, 3) / 300 - >>> view = fem.view.ViewMesh(mesh, point_data={"Displacement": displacement}) + >>> view = fem.ViewMesh(mesh, point_data={"Displacement": displacement}) >>> >>> view.plot("Displacement", component=None).show() See Also -------- felupe.view.Scene : Base class for plotting a static scene. - felupe.view.ViewField : Provide Visualization methods for a field container. - felupe.view.ViewSolid : Provide Visualization methods for a field container or a + felupe.ViewField : Provide Visualization methods for a field container. + felupe.ViewSolid : Provide Visualization methods for a field container or a solid body. """ diff --git a/src/felupe/view/_scene.py b/src/felupe/view/_scene.py index 50a300ba..8a86028c 100644 --- a/src/felupe/view/_scene.py +++ b/src/felupe/view/_scene.py @@ -45,10 +45,10 @@ class Scene: See Also -------- - felupe.view.ViewMesh : Provide Visualization methods for a mesh with optional given + felupe.ViewMesh : Provide Visualization methods for a mesh with optional given dicts of point- and cell-data items. - felupe.view.ViewField : Provide Visualization methods for a field container. - felupe.view.ViewSolid : Provide Visualization methods for a field container or a + felupe.ViewField : Provide Visualization methods for a field container. + felupe.ViewSolid : Provide Visualization methods for a field container or a solid body. """ diff --git a/src/felupe/view/_solid.py b/src/felupe/view/_solid.py index 325220a1..7ecfbbd0 100644 --- a/src/felupe/view/_solid.py +++ b/src/felupe/view/_solid.py @@ -35,7 +35,7 @@ class ViewSolid(ViewField): solid : felupe.SolidBody or felupe.SolidBodyIncompressible or None, optional A solid body to evaluate the (Cauchy) stress (default is None). stress_type : str, optional - The type of stress, either "Cauchy" or "Kirchhoff, which is exported (default is + The type of stress which is exported, either "Cauchy" or "Kirchhoff" (default is "Cauchy"). point_data : dict or None, optional Additional point-data dict (default is None). @@ -54,8 +54,29 @@ class ViewSolid(ViewField): A generalized Dataset with the mesh as well as point- and cell-data. This is not an instance of :class:`felupe.Mesh`. + Examples + -------- + .. pyvista-plot:: + :force_static: + + >>> import numpy as np + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> region = fem.RegionHexahedron(mesh) + >>> u = np.sqrt(1 + np.arange(81)).reshape(27, 3) / 100 + >>> field = fem.FieldContainer([fem.Field(region, values=u)]) + >>> solid = fem.SolidBody(umat=fem.NeoHooke(mu=1, bulk=2), field=field) + >>> + >>> view = fem.ViewSolid(field, solid, project=fem.project) + >>> view.plot("Principal Values of Cauchy Stress").show() + See Also -------- + felupe.view.Scene : Base class for plotting a static scene. + felupe.ViewMesh : Provide Visualization methods for a mesh with optional given + dicts of point- and cell-data items. + felupe.ViewField : Provide Visualization methods for a field container. felupe.project: Project given values at quadrature-points to mesh-points. """ From c2fd524d47029bf2ebb42a0befcc7c518cb81b63 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 18:19:01 +0200 Subject: [PATCH 021/125] Add more examples in the docstrings of lower-level classes --- src/felupe/field/_base.py | 30 +++++++++------- src/felupe/field/_container.py | 66 ++++++++++++++++++---------------- src/felupe/field/_dual.py | 26 +++++++++----- src/felupe/field/_evaluate.py | 21 +++++++++++ 4 files changed, 92 insertions(+), 51 deletions(-) diff --git a/src/felupe/field/_base.py b/src/felupe/field/_base.py index 39465b04..0a12b9b3 100644 --- a/src/felupe/field/_base.py +++ b/src/felupe/field/_base.py @@ -65,14 +65,17 @@ class Field: Examples -------- - >>> import felupe as fem - - >>> mesh = fem.Cube(n=6) - >>> region = fem.RegionHexahedron(mesh) - >>> displacement = fem.Field(region, dim=3) - - >>> u = displacement.interpolate() - >>> dudX = displacement.grad() + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=6) + >>> region = fem.RegionHexahedron(mesh) + >>> displacement = fem.Field(region, dim=3) + >>> + >>> u = displacement.interpolate() + >>> dudX = displacement.grad() To obtain deformation-related quantities like the right Cauchy-Green deformation tensor or the principal stretches, use the math-helpers from FElupe. These @@ -82,11 +85,14 @@ class Field: \boldsymbol{C} = \boldsymbol{F}^T \boldsymbol{F} - >>> from felupe.math import dot, transpose, eigvalsh, sqrt + .. pyvista-plot:: + :context: - >>> F = displacement.extract(grad=True, add_identity=True) - >>> C = dot(transpose(F), F) - >>> λ = sqrt(eigvalsh(C)) + >>> from felupe.math import dot, transpose, eigvalsh, sqrt + >>> + >>> F = displacement.extract(grad=True, add_identity=True) + >>> C = dot(transpose(F), F) + >>> λ = sqrt(eigvalsh(C)) """ diff --git a/src/felupe/field/_container.py b/src/felupe/field/_container.py index 8920795b..6de65a9f 100644 --- a/src/felupe/field/_container.py +++ b/src/felupe/field/_container.py @@ -30,7 +30,7 @@ class FieldContainer: Parameters ---------- - fields : list or tuple of Field, FieldAxisymmetric or FieldPlaneStrain + fields : list or tuple of :class:`~felupe.Field`, :class:``~felupe.FieldAxisymmetric` or :class:``~felupe.FieldPlaneStrain` List with fields. The region is linked to the first field. Attributes @@ -42,40 +42,46 @@ class FieldContainer: Examples -------- - >>> import felupe as fem - >>> - >>> mesh = fem.Cube(n=3) - >>> region = fem.RegionHexahedron(mesh) - >>> region_dual = fem.RegionConstantHexahedron(mesh.dual(points_per_cell=1)) - >>> displacement = fem.Field(region, dim=3) - >>> pressure = fem.Field(region_dual) - >>> field = fem.FieldContainer([displacement, pressure]) - >>> field - - Number of fields: 2 - Dimension of fields: - Field: 3 - Field: 1 + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> region = fem.RegionHexahedron(mesh) + >>> region_dual = fem.RegionConstantHexahedron(mesh.dual(points_per_cell=1)) + >>> displacement = fem.Field(region, dim=3) + >>> pressure = fem.Field(region_dual) + >>> field = fem.FieldContainer([displacement, pressure]) + >>> field + + Number of fields: 2 + Dimension of fields: + Field: 3 + Field: 1 A new :class:`~felupe.FieldContainer` is also created by one of the logical-and combinations of a :class:`~felupe.Field`, :class:`~felupe.FieldAxisymmetric`, :class:`~felupe.FieldPlaneStrain` or :class:`~felupe.FieldContainer`. - >>> displacement & pressure - - Number of fields: 2 - Dimension of fields: - Field: 3 - Field: 1 - - >>> volume_ratio = fem.Field(region_dual) - >>> field & volume_ratio # displacement & pressure & volume_ratio - - Number of fields: 3 - Dimension of fields: - Field: 3 - Field: 1 - Field: 1 + .. pyvista-plot:: + :context: + + >>> displacement & pressure + + Number of fields: 2 + Dimension of fields: + Field: 3 + Field: 1 + + >>> volume_ratio = fem.Field(region_dual) + >>> field & volume_ratio # displacement & pressure & volume_ratio + + Number of fields: 3 + Dimension of fields: + Field: 3 + Field: 1 + Field: 1 See Also -------- diff --git a/src/felupe/field/_dual.py b/src/felupe/field/_dual.py index 694800bc..93d5dfd0 100644 --- a/src/felupe/field/_dual.py +++ b/src/felupe/field/_dual.py @@ -65,15 +65,23 @@ class FieldDual(Field): Examples -------- - >>> import felupe as fem - >>> - >>> mesh = fem.Cube(n=6) - >>> region = fem.RegionHexahedron(mesh) - >>> - >>> displacement = fem.Field(region, dim=3) - >>> pressure = fem.FieldDual(region) - >>> - >>> field = fem.FieldContainer([displacement, pressure]) + .. pyvista-plot:: + + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=6) + >>> region = fem.RegionHexahedron(mesh) + >>> + >>> displacement = fem.Field(region, dim=3) + >>> pressure = fem.FieldDual(region) + >>> + >>> field = fem.FieldContainer([displacement, pressure]) + >>> field + + Number of fields: 2 + Dimension of fields: + Field: 3 + FieldDual: 1 See Also -------- diff --git a/src/felupe/field/_evaluate.py b/src/felupe/field/_evaluate.py index 3843b021..05cc920c 100644 --- a/src/felupe/field/_evaluate.py +++ b/src/felupe/field/_evaluate.py @@ -27,6 +27,27 @@ class EvaluateFieldContainer: ---------- field : FieldContainer A container for fields. + + Examples + -------- + .. pyvista-plot:: + + >>> import felupe as fem + >>> + >>> mesh = fem.Rectangle(n=4) + >>> region = fem.RegionQuad(mesh) + >>> field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)]) + >>> + >>> evaluate = fem.field.EvaluateFieldContainer(field) + >>> F = evaluate.deformation_gradient() + >>> + >>> F.shape # (3, 3, nquadraturepoints, ncells) + (3, 3, 4, 9) + + >>> F[..., 0, 0] # deformation gradient of first cell, first quadrature point + array([[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]]) """ def __init__(self, field): From 68e205de99075c8e3a1fc15c470ea1f802d710d9 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 18:19:28 +0200 Subject: [PATCH 022/125] Update _evaluate.py --- src/felupe/field/_evaluate.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/felupe/field/_evaluate.py b/src/felupe/field/_evaluate.py index 05cc920c..3250e918 100644 --- a/src/felupe/field/_evaluate.py +++ b/src/felupe/field/_evaluate.py @@ -20,7 +20,7 @@ class EvaluateFieldContainer: - """Methods to evaluate the deformation gradient and strain measures of a field + r"""Methods to evaluate the deformation gradient and strain measures of a field container. Parameters @@ -48,6 +48,10 @@ class EvaluateFieldContainer: array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + See Also + -------- + felupe.FieldContainer : A container which holds one or multiple (mixed) fields. """ def __init__(self, field): From dd2d8bd5ead2e8169100207cb87c6c30334fecda Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 21 Sep 2024 23:55:27 +0200 Subject: [PATCH 023/125] Update issue templates (#855) --- .github/ISSUE_TEMPLATE/bug_report.md | 28 +++++++++++++++++++ .../ISSUE_TEMPLATE/enhancement-suggestion.md | 20 +++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/enhancement-suggestion.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..f7460bd0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,28 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Environment (please complete the following information):** + - OS: [e.g. win11] + - Python Interpreter [e.g. 3.12] + - FElupe version [e.g. 9.0.0] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/enhancement-suggestion.md b/.github/ISSUE_TEMPLATE/enhancement-suggestion.md new file mode 100644 index 00000000..f07a6f17 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement-suggestion.md @@ -0,0 +1,20 @@ +--- +name: Enhancement suggestion +about: Suggest an enhancement for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 60e73846f9cfef7800288cd3499e22a724a6adc5 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 00:37:31 +0200 Subject: [PATCH 024/125] Fix pyOpenSci basic checks (#854) * Update CONTRIBUTING.md fix links and refer also to discussions * Update CODE_OF_CONDUCT.md * Simplify the install section in README.md * Add development install instructions to the docs * Update README.md --- CODE_OF_CONDUCT.md | 4 +--- CONTRIBUTING.md | 49 ++++++++++++++++++++-------------------------- README.md | 13 +----------- docs/index.rst | 14 +++++++++++++ 4 files changed, 37 insertions(+), 43 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 831c20ff..98b844ff 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,3 @@ - # Contributor Covenant Code of Conduct ## Our Pledge @@ -61,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -a.dutzler@gmail.com. +. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the @@ -131,4 +130,3 @@ For answers to common questions about this code of conduct, see the FAQ at [Mozilla CoC]: https://github.com/mozilla/diversity [FAQ]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef0451c8..65a6eaed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,4 @@ + # Contributing to FElupe First off, thanks for taking the time to contribute! ❤️ @@ -10,7 +11,7 @@ All types of contributions are encouraged and valued. See the [Table of Contents > - Refer this project in your project's readme > - Mention the project at local meetups and tell your friends/colleagues - + ## Table of Contents - [Code of Conduct](#code-of-conduct) @@ -19,63 +20,58 @@ All types of contributions are encouraged and valued. See the [Table of Contents - [Reporting Bugs](#reporting-bugs) - [Suggesting Enhancements](#suggesting-enhancements) - ## Code of Conduct This project and everyone participating in it is governed by the -[CONTRIBUTING.md Code of Conduct](blob/main/CODE_OF_CONDUCT.md). +[CONTRIBUTING.md Code of Conduct](https://github.com/adtzlr/felupe/blob/main/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior -to <>. - +to . ## I Have a Question -> If you want to ask a question, we assume that you have read the available [Documentation](). +> If you want to ask a question, we assume that you have read the available [Documentation](https://felupe.readthedocs.io/). -Before you ask a question, it is best to search for existing [Issues](/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. +Before you ask a question, it is best to search for existing [Issues](https://github.com/adtzlr/felupe/issues) and [Discussions](https://github.com/adtzlr/felupe/discussions) that might help you. In case you have found a suitable issue or discussion and still need clarification, you can write your question in this issue or discussion. It is also advisable to search the internet for answers first. If you then still feel the need to ask a question and need clarification, we recommend the following: -- Open an [Issue](/issues/new). +- Open a [Discussion](https://github.com/adtzlr/felupe/discussions/new/choose). - Provide as much context as you can about what you're running into. -- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. +- Provide project and platform versions, depending on what seems relevant. We will then take care of the issue as soon as possible. - - ## I Want To Contribute > ### Legal Notice -> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project [license](blob/main/LICENSE). +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project [license](https://github.com/adtzlr/felupe/blob/main/LICENSE). ### Reporting Bugs - + #### Before Submitting a Bug Report A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. - Make sure that you are using the latest version. - Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://felupe.readthedocs.io/). If you are looking for support, you might want to check [this section](#i-have-a-question)). -- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](issues?q=label%3Abug). +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/adtzlr/felupe/issues?q=label%3Abug). - Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. - Collect information about the bug: - Stack trace (Traceback) - OS, Platform and Version (Windows, Linux, macOS, x86, ARM) -- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant. +- Version of the interpreter, runtime environment, package manager, depending on what seems relevant. - Possibly your input and the output - Can you reliably reproduce the issue? And can you also reproduce it with older versions? - + #### How Do I Submit a Good Bug Report? > You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to . - We use GitHub issues to track bugs and errors. If you run into an issue with the project: -- Open an [Issue](/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) +- Open an [Issue](https://github.com/adtzlr/felupe/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) - Explain the behavior you would expect and the actual behavior. - Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. - Provide the information you collected in the previous section. @@ -86,25 +82,23 @@ Once it's filed: - A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps. - If the team is able to reproduce the issue, the issue will be left to be [implemented by someone](#your-first-code-contribution). - - - + ### Suggesting Enhancements This section guides you through submitting an enhancement suggestion for FElupe, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. - + #### Before Submitting an Enhancement - Make sure that you are using the latest version. - Read the [documentation](https://felupe.readthedocs.io/) carefully and find out if the functionality is already covered. -- Perform a [search](/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. -- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. - +- Perform a [search](https://github.com/adtzlr/felupe/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an [add-on/plugin library](https://github.com/adtzlr/felupe?tab=readme-ov-file#extension-packages). + #### How Do I Submit a Good Enhancement Suggestion? -Enhancement suggestions are tracked as [GitHub issues](/issues). +Enhancement suggestions are tracked as [GitHub issues](https://github.com/adtzlr/felupe/issues). - Use a **clear and descriptive title** for the issue to identify the suggestion. - Provide a **step-by-step description of the suggested enhancement** in as many details as possible. @@ -112,7 +106,6 @@ Enhancement suggestions are tracked as [GitHub issues](/issues). - You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. - **Explain why this enhancement would be useful** to most FElupe users. You may also want to point out the other projects that solved it better and which could serve as inspiration. - - + ## Attribution This guide is based on the **contributing.md**. [Make your own](https://contributing.md/)! diff --git a/README.md b/README.md index a4af59fc..80a0aeaf 100644 --- a/README.md +++ b/README.md @@ -51,18 +51,7 @@ Install Python, fire up 🔥 a terminal and run 🏃 pip install felupe[all] ``` -where `[all]` is a combination of `[io,parallel,plot,progress,view]` and installs all optional dependencies. FElupe has minimal requirements, all available at PyPI supporting all platforms. -* [`numpy`](https://github.com/numpy/numpy) for array operations -* [`scipy`](https://github.com/scipy/scipy) for sparse matrices -* [`tensortrax`](https://github.com/adtzlr/tensortrax) for automatic differentiation - -In order to make use of all features of FElupe 💎💰💍👑💎, it is suggested to install all optional dependencies. -* [`einsumt`](https://github.com/mrkwjc/einsumt) for parallel (threaded) assembly -* [`h5py`](https://github.com/h5py/h5py) for writing XDMF result files -* [`matplotlib`](https://github.com/matplotlib/matplotlib) for plotting graphs -* [`meshio`](https://github.com/nschloe/meshio) for mesh-related I/O -* [`pyvista`](https://github.com/pyvista/pyvista) for interactive visualizations -* [`tqdm`](https://github.com/tqdm/tqdm) for showing progress bars during job evaluations +The [documentation](https://felupe.readthedocs.io/) covers more details, like required and optional dependencies and how to install the latest development version. # Getting Started This tutorial covers the essential high-level parts of creating and solving problems with FElupe. As an introductory example 👨‍🏫, a quarter model of a solid cube with hyperelastic material behaviour is subjected to a uniaxial elongation applied at a clamped end-face. diff --git a/docs/index.rst b/docs/index.rst index 1d9fb431..5fd248e0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -78,6 +78,20 @@ In order to make use of all features of FElupe 💎💰💍👑💎, it is sugge * `pyvista `_ for interactive visualizations * `tqdm `_ for showing progress bars during job evaluations +The development version may contain not yet released bug fixes and features. Consider using the ``--user`` option to install the package into your home directory (see `pip documentation `_ for more details). To install FElupe from the latest development branch, use + +.. code-block:: shell + + pip install git+https://github.com/adtzlr/felupe.git@main + +or clone the repository and install the package in editable mode. + +.. code-block:: shell + + git clone https://github.com/adtzlr/felupe.git + cd felupe + pip install --editable . + Extension Packages ------------------ From 3f8557d09a7b9bb7b987c21241e71dfe6027b959 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 00:40:31 +0200 Subject: [PATCH 025/125] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 65a6eaed..88a776ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,7 +80,7 @@ Once it's filed: - The project team will label the issue accordingly. - A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps. -- If the team is able to reproduce the issue, the issue will be left to be [implemented by someone](#your-first-code-contribution). +- If the team is able to reproduce the issue, the issue will be left to be implemented by someone. ### Suggesting Enhancements From 5e30f78981bbd81649d687547e7ec30cb35bf67e Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 00:41:23 +0200 Subject: [PATCH 026/125] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88a776ce..efc730a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,7 +90,7 @@ This section guides you through submitting an enhancement suggestion for FElupe, #### Before Submitting an Enhancement -- Make sure that you are using the latest version. +- Make sure that you are using the [latest development version](https://felupe.readthedocs.io/en/latest/#installation). - Read the [documentation](https://felupe.readthedocs.io/) carefully and find out if the functionality is already covered. - Perform a [search](https://github.com/adtzlr/felupe/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. - Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an [add-on/plugin library](https://github.com/adtzlr/felupe?tab=readme-ov-file#extension-packages). From c4227f1a14ba8f943feff02bd801e77a4ad7da8f Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 00:42:44 +0200 Subject: [PATCH 027/125] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index efc730a0..dc1e5d7e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,7 @@ We will then take care of the issue as soon as possible. A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. -- Make sure that you are using the latest version. +- Make sure that you are using the [latest version](https://felupe.readthedocs.io/en/latest/#installation). - Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://felupe.readthedocs.io/). If you are looking for support, you might want to check [this section](#i-have-a-question)). - To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/adtzlr/felupe/issues?q=label%3Abug). - Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. From fc3ed0c0240ff823fd96a5bc38746bf451c3b3c5 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 00:46:42 +0200 Subject: [PATCH 028/125] Update CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dc1e5d7e..b841903f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,9 +69,9 @@ A good bug report shouldn't leave others needing to chase you up for more inform > You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to . -We use GitHub issues to track bugs and errors. If you run into an issue with the project: +We use [GitHub issues](https://github.com/adtzlr/felupe/issues) to track bugs and errors. If you run into an issue with the project: -- Open an [Issue](https://github.com/adtzlr/felupe/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) +- Open an [Issue](https://github.com/adtzlr/felupe/issues/new/choose). - Explain the behavior you would expect and the actual behavior. - Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. - Provide the information you collected in the previous section. From de2ea6bcb4761ebdaff26eae4e78156f54259ed1 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 12:38:35 +0200 Subject: [PATCH 029/125] Enhance the highlights section add the base cartesian field --- README.md | 2 +- docs/index.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 80a0aeaf..30fd43fa 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ FElupe is a Python 3.8+ 🐍 finite element analysis package 📦 focusing on th - [x] nonlinear deformation of [solid bodies](https://felupe.readthedocs.io/en/latest/felupe/mechanics.html#felupe.SolidBody) - [x] interactive views on meshes, fields and solid bodies (using [PyVista](https://pyvista.org/)) - [x] typical [finite elements](https://felupe.readthedocs.io/en/latest/felupe/element.html) -- [x] axisymmetric, plane strain and mixed fields +- [x] cartesian, axisymmetric, plane strain and mixed fields - [x] [hyperelastic material models](https://felupe.readthedocs.io/en/latest/felupe/constitution/hyperelasticity.html) - [x] strain energy density functions with [automatic differentiation](https://felupe.readthedocs.io/en/latest/felupe/constitution/hyperelasticity.html#felupe.Hyperelastic) diff --git a/docs/index.rst b/docs/index.rst index 5fd248e0..2a97847b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -45,7 +45,7 @@ FElupe is a Python 3.8+ 🐍 finite element analysis package 📦 focusing on th + typical :ref:`finite elements ` - + axisymmetric, plane strain and mixed fields + + cartesian, axisymmetric, plane strain and mixed fields + :ref:`hyperelastic material models ` From 2961ad1e98286acc9dda2520a28bc6426b9a1de1 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 22 Sep 2024 12:43:08 +0200 Subject: [PATCH 030/125] Update umat.rst --- docs/howto/umat.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/howto/umat.rst b/docs/howto/umat.rst index 921dbe7f..36bffce7 100644 --- a/docs/howto/umat.rst +++ b/docs/howto/umat.rst @@ -14,7 +14,9 @@ A user material (``umat``) based on the incremental small-strain tensor, e.g. su +----------+---------------+---------------------------------------+ | Argument | ζn | list of old state variables | +----------+---------------+---------------------------------------+ -| Return | σ | tangent modulus | +| Return | dσdε | tangent modulus | ++----------+---------------+---------------------------------------+ +| Return | σ | new stress tensor | +----------+---------------+---------------------------------------+ | Return | ζ | list of new state variables | +----------+---------------+---------------------------------------+ From 9a83fdd04615bc50a405dc26f63c29b3a9c0b22a Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 23 Sep 2024 21:54:08 +0200 Subject: [PATCH 031/125] Extract C-contiguous arrays by default from fields (#856) * Extract field data as C-contiguous array this enhances the time spent on assembly * Change to default `np.einsum(..., order="C")` in `Field` * Update _container.py --- CHANGELOG.md | 4 +++ src/felupe/field/_axi.py | 33 ++++++++++++++------ src/felupe/field/_base.py | 43 +++++++++++++++++++++----- src/felupe/field/_container.py | 19 ++++++++++-- src/felupe/field/_planestrain.py | 52 ++++++++++++++++++++++++-------- src/felupe/region/_region.py | 4 +-- 6 files changed, 122 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a983f0e..439c021a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format ### Added - Add the hessian of the element shape functions for a quadratic quad element `QuadraticQuad.hessian()`. +- Add the `order`-argument to `FieldContainer.extract(order="C")` to return C-contiguous arrays by default. + +### Changed +- Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric` and `FieldPlaneStrain`. ## [9.0.0] - 2024-09-06 diff --git a/src/felupe/field/_axi.py b/src/felupe/field/_axi.py index 231204d1..66857e69 100644 --- a/src/felupe/field/_axi.py +++ b/src/felupe/field/_axi.py @@ -88,7 +88,7 @@ def __init__(self, region, dim=2, values=0.0, dtype=None): # in the region self.radius = self.scalar.interpolate() - def _interpolate_2d(self, dtype=None, out=None): + def _interpolate_2d(self, dtype=None, out=None, order="C"): """Interpolate 2D field values at points and evaluate them at the integration points of all cells in the region.""" @@ -101,20 +101,22 @@ def _interpolate_2d(self, dtype=None, out=None): self.region.h, dtype=dtype, out=out, + order=order, ) - def interpolate(self, dtype=None, out=None): + def interpolate(self, dtype=None, out=None, order="C"): # out-argument is not supported # if out is not None: # out = out[:2] - # extend dimension of in-plane 2d-gradient + # extend dimension of in-plane 2d-gradient (out-keyword can't be used here) return np.pad( - self._interpolate_2d(dtype=dtype, out=None), ((0, 1), (0, 0), (0, 0)) + self._interpolate_2d(dtype=dtype, out=None, order=order), + ((0, 1), (0, 0), (0, 0)), ) - def _grad_2d(self, sym=False, dtype=None, out=None): - """In-plane 2D gradient as partial derivative of field values at points + def _grad_2d(self, sym=False, dtype=None, out=None, order="C"): + r"""In-plane 2D gradient as partial derivative of field values at points w.r.t. the undeformed coordinates, evaluated at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is returned. @@ -130,6 +132,12 @@ def _grad_2d(self, sym=False, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -148,6 +156,7 @@ def _grad_2d(self, sym=False, dtype=None, out=None): self.region.dhdX, dtype=dtype, out=out, + order=order, ) if sym: @@ -155,7 +164,7 @@ def _grad_2d(self, sym=False, dtype=None, out=None): else: return g - def grad(self, sym=False, dtype=None, out=None): + def grad(self, sym=False, dtype=None, out=None, order="C"): r"""3D-gradient as partial derivative of field values at points w.r.t. the undeformed coordinates, evaluated at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is @@ -182,6 +191,12 @@ def grad(self, sym=False, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -197,11 +212,11 @@ def grad(self, sym=False, dtype=None, out=None): # extend dimension of in-plane 2d-gradient g = np.pad( - self._grad_2d(sym=sym, dtype=dtype, out=None), + self._grad_2d(sym=sym, dtype=dtype, out=None, order=order), ((0, 1), (0, 1), (0, 0), (0, 0)), ) # set dudX_33 = u_r / R - g[-1, -1] = self.interpolate(dtype=dtype)[1] / self.radius + g[-1, -1] = self.interpolate(dtype=dtype, order=order)[1] / self.radius return g diff --git a/src/felupe/field/_base.py b/src/felupe/field/_base.py index 0a12b9b3..835f56b1 100644 --- a/src/felupe/field/_base.py +++ b/src/felupe/field/_base.py @@ -138,7 +138,7 @@ def _indices_per_cell(self, cells, dim): return cai, ai - def grad(self, sym=False, dtype=None, out=None): + def grad(self, sym=False, dtype=None, out=None, order="C"): r"""Gradient as partial derivative of field values w.r.t. undeformed coordinates, evaluated at the integration points of all cells in the region. Optionally, the symmetric part the gradient is evaluated. @@ -159,6 +159,12 @@ def grad(self, sym=False, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -177,6 +183,7 @@ def grad(self, sym=False, dtype=None, out=None): self.region.dhdX, dtype=dtype, out=out, + order=order, ) if sym: @@ -184,7 +191,7 @@ def grad(self, sym=False, dtype=None, out=None): else: return g - def hess(self, dtype=None, out=None): + def hess(self, dtype=None, out=None, order="C"): r"""Hessian as second partial derivative of field values w.r.t. undeformed coordinates, evaluated at the integration points of all cells in the region. @@ -204,6 +211,12 @@ def hess(self, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -222,11 +235,12 @@ def hess(self, dtype=None, out=None): self.region.d2hdXdX, dtype=dtype, out=out, + order=order, ) return h - def interpolate(self, dtype=None, out=None): + def interpolate(self, dtype=None, out=None, order="C"): r"""Interpolate field values located at mesh-points to the quadrature points ``q`` of cells ``c`` in the region. @@ -243,6 +257,12 @@ def interpolate(self, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -259,10 +279,13 @@ def interpolate(self, dtype=None, out=None): self.values[self.region.mesh.cells], self.region.h, dtype=dtype, - out=None, + out=out, + order=order, ) - def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None): + def extract( + self, grad=True, sym=False, add_identity=True, dtype=None, out=None, order="C" + ): """Generalized extraction method which evaluates either the gradient or the field values at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is evaluated and/or the identity matrix is @@ -284,6 +307,12 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None) A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -298,7 +327,7 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None) """ if grad: - gr = self.grad(out=out, dtype=dtype) + gr = self.grad(out=out, dtype=dtype, order=order) if sym: gr = symmetric(gr, out=gr) @@ -308,7 +337,7 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None) return gr else: - return self.interpolate(out=out, dtype=dtype) + return self.interpolate(out=out, dtype=dtype, order=order) def copy(self): "Return a copy of the field." diff --git a/src/felupe/field/_container.py b/src/felupe/field/_container.py index 6de65a9f..5d359883 100644 --- a/src/felupe/field/_container.py +++ b/src/felupe/field/_container.py @@ -117,7 +117,9 @@ def __repr__(self): return "\n".join([header, size, fields_header, *fields]) - def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None): + def extract( + self, grad=True, sym=False, add_identity=True, dtype=None, out=None, order="C" + ): """Generalized extraction method which evaluates either the gradient or the field values at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is evaluated and/or the identity matrix is @@ -142,6 +144,12 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None) A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + orders : str or list of str, optional + Controls the memory layout of the outputs. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -153,13 +161,18 @@ def extract(self, grad=True, sym=False, add_identity=True, dtype=None, out=None) if isinstance(grad, bool): grad = (grad,) + if isinstance(order, str): + order = (order,) + if out is None: out = [None] * len(self.fields) grads = np.pad(grad, (0, len(self.fields) - 1)) + orders = order * len(self.fields) + return tuple( - f.extract(g, sym, add_identity=add_identity, dtype=dtype, out=res) - for g, f, res in zip(grads, self.fields, out) + f.extract(g, sym, add_identity=add_identity, dtype=dtype, out=res, order=od) + for g, f, res, od in zip(grads, self.fields, out, orders) ) def values(self): diff --git a/src/felupe/field/_planestrain.py b/src/felupe/field/_planestrain.py index af93ed13..406a0ed9 100644 --- a/src/felupe/field/_planestrain.py +++ b/src/felupe/field/_planestrain.py @@ -67,7 +67,7 @@ def __init__(self, region, dim=2, values=0.0, dtype=None): # init base Field super().__init__(region, dim=dim, values=values, dtype=dtype) - def _interpolate_2d(self, dtype=None, out=None): + def _interpolate_2d(self, dtype=None, out=None, order="C"): """Interpolate 2D field values at points and evaluate them at the integration points of all cells in the region.""" @@ -80,19 +80,21 @@ def _interpolate_2d(self, dtype=None, out=None): self.region.h, dtype=dtype, out=out, + order=order, ) - def interpolate(self, dtype=None, out=None): + def interpolate(self, dtype=None, out=None, order="C"): # out-argument is not supported # if out is not None: # out = out[:2] - # extend dimension of in-plane 2d-gradient + # extend dimension of in-plane 2d-gradient (out-keyword can't be used here) return np.pad( - self._interpolate_2d(dtype=dtype, out=None), ((0, 1), (0, 0), (0, 0)) + self._interpolate_2d(dtype=dtype, out=None, order=order), + ((0, 1), (0, 0), (0, 0)), ) - def _grad_2d(self, sym=False, dtype=None, out=None): + def _grad_2d(self, sym=False, dtype=None, out=None, order="C"): """In-plane 2D gradient as partial derivative of field values at points w.r.t. the undeformed coordinates, evaluated at the integration points of all cells in the region. Optionally, the symmetric part of the @@ -109,6 +111,12 @@ def _grad_2d(self, sym=False, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -127,6 +135,7 @@ def _grad_2d(self, sym=False, dtype=None, out=None): self.region.dhdX, dtype=dtype, out=out, + order=order, ) if sym: @@ -134,7 +143,7 @@ def _grad_2d(self, sym=False, dtype=None, out=None): else: return g - def _hess_2d(self, dtype=None, out=None): + def _hess_2d(self, dtype=None, out=None, order="C"): r"""In-plane 2D Hessian as second partial derivative of field values w.r.t. undeformed coordinates, evaluated at the integration points of all cells in the region. @@ -148,6 +157,12 @@ def _hess_2d(self, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -166,11 +181,12 @@ def _hess_2d(self, dtype=None, out=None): self.region.d2hdXdX, dtype=dtype, out=out, + order=order, ) return h - def grad(self, sym=False, dtype=None, out=None): + def grad(self, sym=False, dtype=None, out=None, order="C"): """3D-gradient as partial derivative of field values at points w.r.t. the undeformed coordinates, evaluated at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is @@ -193,6 +209,12 @@ def grad(self, sym=False, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -206,15 +228,15 @@ def grad(self, sym=False, dtype=None, out=None): # if out is not None: # out = out[:2, :2] - # extend dimension of in-plane 2d-gradient + # extend dimension of in-plane 2d-gradient (out-keyword can't be used here) g = np.pad( - self._grad_2d(sym=sym, dtype=dtype, out=None), + self._grad_2d(sym=sym, dtype=dtype, out=None, order=order), ((0, 1), (0, 1), (0, 0), (0, 0)), ) return g - def hess(self, dtype=None, out=None): + def hess(self, dtype=None, out=None, order="C"): """3D-Hessian as second partial derivative of field values at points w.r.t. the undeformed coordinates, evaluated at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is @@ -231,6 +253,12 @@ def hess(self, dtype=None, out=None): A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly- allocated array is returned (default is None). + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should be C + contiguous. 'F' means it should be Fortran contiguous, 'A' means it should + be 'F' if the inputs are all 'F', 'C' otherwise. 'K' means it should be as + close to the layout as the inputs as is possible, including arbitrarily + permuted axes. Default is 'C'. Returns ------- @@ -240,9 +268,9 @@ def hess(self, dtype=None, out=None): of all cells in the region. """ - # extend dimension of in-plane 2d-hessian + # extend dimension of in-plane 2d-hessian (out-keyword can't be used here) h = np.pad( - self._hess_2d(dtype=dtype, out=None), + self._hess_2d(dtype=dtype, out=None, order=order), ((0, 1), (0, 1), (0, 1), (0, 0), (0, 0)), ) diff --git a/src/felupe/region/_region.py b/src/felupe/region/_region.py index b5f2dade..cc088cc5 100644 --- a/src/felupe/region/_region.py +++ b/src/felupe/region/_region.py @@ -344,8 +344,8 @@ def reload( if uniform: cells = cells[:1] - region.dXdr = np.ascontiguousarray( - np.einsum("caI,aJqc->IJqc", region.mesh.points[cells], region.dhdr) + region.dXdr = np.einsum( + "caI,aJqc->IJqc", region.mesh.points[cells], region.dhdr, order="C" ) # determinant and inverse of dXdr From c918ce13779a3ce33e614d89fdbba36e691f9568 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 23 Sep 2024 22:13:50 +0200 Subject: [PATCH 032/125] Docs: update benchmark results --- docs/_static/benchmark.png | Bin 29928 -> 68153 bytes docs/index.rst | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_static/benchmark.png b/docs/_static/benchmark.png index c25747398ab799be2a225fa384f1c2a5f8511400..dc75000f534032e2a6916dc0fecb444c62761a35 100644 GIT binary patch literal 68153 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 literal 29928 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 diff --git a/docs/index.rst b/docs/index.rst index 2a97847b..a7bf281a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -122,9 +122,9 @@ This is a simple benchmark to compare assembly times for linear elasticity and h +----------------+-------------------+ | Analysis | DOF/s | +================+===================+ - | Linear-Elastic | 136193 +/-22916 | + | Linear-Elastic | 130039 +/-23464 | +----------------+-------------------+ - | Hyperelastic | 100613 +/-18702 | + | Hyperelastic | 116819 +/-21979 | +----------------+-------------------+ Tested on: Windows 10, Python 3.11, Intel® Core™ i7-11850H @ 2.50GHz, 32GB RAM. From 9ca89df1aaaade0d8258c2b0cc03540f86a53835 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 23 Sep 2024 22:20:24 +0200 Subject: [PATCH 033/125] Docs: Run the beginner's guide in interactive mode --- docs/tutorial/examples/README.rst | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/tutorial/examples/README.rst b/docs/tutorial/examples/README.rst index c2b8ca2b..62759094 100644 --- a/docs/tutorial/examples/README.rst +++ b/docs/tutorial/examples/README.rst @@ -7,7 +7,8 @@ This minimal code-block covers the essential high-level parts of creating and so First, let’s import FElupe and create a meshed :class:`cube ` out of :class:`hexahedron ` cells with a given number of points per axis. A numeric :class:`region `, pre-defined for hexahedrons, is created on the mesh. A vector-valued displacement :class:`field ` is initiated on the region. Next, a :class:`field container ` is created on top of this field. -.. code-block:: python +.. pyvista-plot:: + :context: import felupe as fem @@ -17,27 +18,31 @@ First, let’s import FElupe and create a meshed :class:`cube ` out A :func:`~felupe.dof.uniaxial` load case is applied on the displacement :class:`field ` stored inside the :class:`field container `. This involves setting up :func:`~felupe.dof.symmetry` planes as well as the absolute value of the prescribed displacement at the mesh-points on the right-end face of the cube. The right-end face is *clamped* 🛠️: only displacements in direction *x* are allowed. The dict of :class:`boundary ` conditions for this pre-defined load case are returned as ``boundaries`` and the partitioned degrees of freedom as well as the external displacements are stored within the returned dict ``loadcase``. -.. code-block:: python +.. pyvista-plot:: + :context: boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) An isotropic pseudo-elastic :class:`Ogden-Roxburgh ` Mullins-softening model formulation in combination with an isotropic hyperelastic :class:`Neo-Hookean ` material formulation is applied on the displacement :class:`field ` of a :class:`nearly-incompressible solid body `. -.. code-block:: python +.. pyvista-plot:: + :context: umat = fem.NeoHooke(mu=1) solid = fem.SolidBodyNearlyIncompressible(umat, field, bulk=5000) A :class:`step ` generates the consecutive substep-movements of a given :class:`boundary ` condition. -.. code-block:: python +.. pyvista-plot:: + :context: move = fem.math.linsteps([0, 1], num=5) step = fem.Step(items=[solid], ramp={boundaries["move"]: move}, boundaries=boundaries) The :class:`step ` is further added to a list of steps of a :class:`job ` 👩‍💻 (here, a :class:`characteristic curve ` 📈 job is used). During :meth:`evaluation ` ⏳, each substep of each :class:`step ` is solved by an iterative :func:`Newton-Rhapson ` procedure ⚖️. The :func:`solution ` is exported after each completed substep as a time-series ⌚ XDMF file. -.. code-block:: python +.. pyvista-plot:: + :context: job = fem.CharacteristicCurve(steps=[step], boundary=boundaries["move"]) job.evaluate(filename="result.xdmf") @@ -47,9 +52,22 @@ The :class:`step ` is further added to a list of steps of a :class: ylabel="Normal Force $F_1$ in N $\longrightarrow$", ) +.. pyvista-plot:: + :include-source: False + :context: + :force_static: + + import pyvista as pv + + fig = ax.get_figure() + chart = pv.ChartMPL(fig) + chart.show() + Finally, the result of the last completed substep is plotted. -.. code-block:: python +.. pyvista-plot:: + :context: + :force_static: solid.plot("Principal Values of Cauchy Stress").show() From 7744b8db44666ebf02564b52e1b40504219b9c04 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 23 Sep 2024 22:32:08 +0200 Subject: [PATCH 034/125] Docs: Switch to static plots for some 2d meshes --- docs/tutorial/examples/README.rst | 1 - src/felupe/mesh/_container.py | 2 ++ src/felupe/mesh/_dual.py | 28 +++++++++++++++------------- src/felupe/mesh/_geometry.py | 9 +++++++-- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/tutorial/examples/README.rst b/docs/tutorial/examples/README.rst index 62759094..7f98f88e 100644 --- a/docs/tutorial/examples/README.rst +++ b/docs/tutorial/examples/README.rst @@ -67,7 +67,6 @@ Finally, the result of the last completed substep is plotted. .. pyvista-plot:: :context: - :force_static: solid.plot("Principal Values of Cauchy Stress").show() diff --git a/src/felupe/mesh/_container.py b/src/felupe/mesh/_container.py index 631f6414..29ff3d95 100644 --- a/src/felupe/mesh/_container.py +++ b/src/felupe/mesh/_container.py @@ -82,6 +82,7 @@ class MeshContainer: .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> @@ -171,6 +172,7 @@ def stack(self, idx=None): .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> diff --git a/src/felupe/mesh/_dual.py b/src/felupe/mesh/_dual.py index d4a21fac..ae039e8d 100644 --- a/src/felupe/mesh/_dual.py +++ b/src/felupe/mesh/_dual.py @@ -74,19 +74,21 @@ def dual( Examples -------- - >>> import felupe as fem - >>> - >>> mesh = fem.Rectangle(n=5).add_midpoints_edges() - >>> region = fem.RegionQuadraticQuad(mesh=mesh) - >>> - >>> mesh_dual = fem.mesh.dual(mesh, points_per_cell=1, disconnect=False) - >>> region_dual = fem.RegionConstantQuad( - ... mesh_dual, quadrature=region.quadrature, grad=False - ... ) - >>> - >>> displacement = fem.FieldPlaneStrain(region, dim=2) - >>> pressure = fem.Field(region_dual) - >>> field = fem.FieldContainer([displacement, pressure]) + .. pyvista-plot:: + + >>> import felupe as fem + >>> + >>> mesh = fem.Rectangle(n=5).add_midpoints_edges() + >>> region = fem.RegionQuadraticQuad(mesh=mesh) + >>> + >>> mesh_dual = fem.mesh.dual(mesh, points_per_cell=1, disconnect=False) + >>> region_dual = fem.RegionConstantQuad( + ... mesh_dual, quadrature=region.quadrature, grad=False + ... ) + >>> + >>> displacement = fem.FieldPlaneStrain(region, dim=2) + >>> pressure = fem.Field(region_dual) + >>> field = fem.FieldContainer([displacement, pressure]) See Also -------- diff --git a/src/felupe/mesh/_geometry.py b/src/felupe/mesh/_geometry.py index 652abd20..50eb2920 100644 --- a/src/felupe/mesh/_geometry.py +++ b/src/felupe/mesh/_geometry.py @@ -76,11 +76,12 @@ class Line(Mesh): -------- .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> >>> mesh = fem.mesh.Line(a=-2.1, b=3.5, n=3) - >>> mesh.plot().show() + >>> mesh.plot(line_width=8).show() >>> mesh @@ -125,6 +126,7 @@ class Rectangle(Mesh): -------- .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> @@ -236,6 +238,7 @@ class Grid(Mesh): -------- .. pyvista-plot:: :include-source: True + :force_static: >>> import numpy as np >>> import felupe as fem @@ -299,6 +302,7 @@ class RectangleArbitraryOrderQuad(Rectangle): Examples -------- .. pyvista-plot:: + :force_static: >>> import felupe as fem >>> @@ -370,7 +374,7 @@ class Circle(Mesh): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -475,6 +479,7 @@ class Triangle(Mesh): -------- .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> From 8268e9daa301c0dc4f769519d3bdc1e61c50105e Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 23 Sep 2024 22:49:35 +0200 Subject: [PATCH 035/125] Force more static plots in mesh-api examples hopefulle to reduce read-the-docs build errors --- docs/howto/solvers.rst | 14 ++++++----- src/felupe/mesh/_geometry.py | 32 ++++++++++++++----------- src/felupe/mesh/_mesh.py | 46 ++++++++++++++++++++---------------- 3 files changed, 51 insertions(+), 41 deletions(-) diff --git a/docs/howto/solvers.rst b/docs/howto/solvers.rst index 74ba7f32..c6ae8bb8 100644 --- a/docs/howto/solvers.rst +++ b/docs/howto/solvers.rst @@ -1,14 +1,16 @@ Use external solvers -------------------- -FElupe uses SuperLU as direct sparse solver by default because it is shipped with SciPy (and SciPy is already a dependency of FElupe). While it is definitely a good choice for small to mid-sized problems, faster alternatives are easy to install and use. This section demonstrates several possibilities, e.g. a fast direct solver from `PyPardiso `_ (``pip install pypardiso``) and the ``minres`` iterative solver from ``SciPy``. Custom solvers may be passed to the evaluation of a job. +FElupe uses SuperLU as direct sparse solver by default because it is shipped with SciPy (and SciPy is already a dependency of FElupe). While it is definitely a good choice for small to mid-sized problems, faster alternatives are easy to install and use. This section demonstrates several possibilities, e.g. a fast direct solver from `PyPardiso `_ (``pip install pypardiso``) and the :func:`~scipy.sparse.linalg.minres` iterative solver from ``SciPy``. Custom solvers may be passed to the evaluation of a :class:`~felupe.Job`. .. code-block:: python import felupe as fem + + from scipy.sparse.linalg import spsolve # (default) job = fem.Job(steps) - job.evaluate(solver=solver) # function `x = solver(A, b)` + job.evaluate(solver=spsolve) # function `x = spsolve(A, b)` Solvers from SciPy Sparse: @@ -17,7 +19,7 @@ Solvers from SciPy Sparse: .. code-block:: python # the default solver - from scipy.sparse.linalg import spsolve as solver + from scipy.sparse.linalg import spsolve .. tab:: SciPy Sparse (iterative) @@ -30,7 +32,7 @@ Solvers from SciPy Sparse: import scipy.sparse.linalg as spla def solver(A, b): - "Wrapper function for iterative solvers from scipy.sparse." + "Wrapper function for iterative solvers from scipy.sparse.linalg." return spla.minres(A, b)[0] @@ -46,7 +48,7 @@ Solvers from external packages: .. code-block:: python - from pypardiso import spsolve as solver + from pypardiso import spsolve .. tab:: PyPardiso (direct, symmetric) @@ -61,7 +63,7 @@ Solvers from external packages: from pypardiso import PyPardisoSolver from scipy.sparse import triu - def solver(A, b): + def spsolve(A, b): # mtype = 1: real and structurally symmetric, supernode pivoting # mtype = 2: real and symmetric positive definite # mtype =-2: real and symmetric indefinite, diff --git a/src/felupe/mesh/_geometry.py b/src/felupe/mesh/_geometry.py index 50eb2920..3079da27 100644 --- a/src/felupe/mesh/_geometry.py +++ b/src/felupe/mesh/_geometry.py @@ -34,20 +34,22 @@ class Point(Mesh): Examples -------- - >>> import felupe as fem - - >>> mesh = fem.Point(a=-2.1) - >>> mesh - - Number of points: 1 - Number of cells: - vertex: 1 - - >>> mesh.points - array([[-2.1]]) - - >>> mesh.cells - array([[0]]) + .. pyvista-plot:: + + >>> import felupe as fem + >>> + >>> mesh = fem.Point(a=-2.1) + >>> mesh + + Number of points: 1 + Number of cells: + vertex: 1 + + >>> mesh.points + array([[-2.1]]) + + >>> mesh.cells + array([[0]]) """ def __init__(self, a=0.0): @@ -184,6 +186,7 @@ class Cube(Mesh): -------- .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> @@ -328,6 +331,7 @@ class CubeArbitraryOrderHexahedron(Cube): Examples -------- .. pyvista-plot:: + :force_static: >>> import felupe as fem >>> diff --git a/src/felupe/mesh/_mesh.py b/src/felupe/mesh/_mesh.py index dd085083..2ee1ccc9 100644 --- a/src/felupe/mesh/_mesh.py +++ b/src/felupe/mesh/_mesh.py @@ -92,7 +92,7 @@ class Mesh(DiscreteGeometry): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import numpy as np >>> import felupe as fem @@ -532,6 +532,7 @@ def modify_corners(self, point_ids=None): -------- .. pyvista-plot:: :context: + :force_static: >>> import numpy as np >>> import felupe as fem @@ -541,6 +542,7 @@ def modify_corners(self, point_ids=None): .. pyvista-plot:: :context: + :force_static: >>> mesh = mesh.modify_corners() # inplace >>> mesh.plot().show() @@ -697,7 +699,7 @@ def expand(self, n=11, z=1, axis=-1, expand_dim=True): Expand a rectangle to a cube. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -743,7 +745,7 @@ def rotate(self, angle_deg, axis, center=None, mask=None): Rotate a rectangle in the xy-plane by 35 degree. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -790,7 +792,7 @@ def revolve(self, n=11, phi=180, axis=0, expand_dim=True): Revolve a cylinder from a rectangle. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -840,7 +842,7 @@ def merge_duplicate_points(self, decimals=None): :context: >>> import felupe as fem - + >>> >>> rect1 = fem.Rectangle(n=11) >>> rect2 = fem.Rectangle(a=(0.9, 0), b=(1.9, 1), n=11) >>> rect2 @@ -875,11 +877,12 @@ def merge_duplicate_points(self, decimals=None): Number of cells: quad: 200 - After merging the duplicated points and cells, the number of points is reduced but - the number of cells is unchanged. + After merging the duplicated points and cells, the number of points is reduced + but the number of cells is unchanged. .. pyvista-plot:: :context: + :force_static: >>> mesh = stack.merge_duplicate_points() >>> mesh @@ -888,7 +891,7 @@ def merge_duplicate_points(self, decimals=None): Number of cells: quad: 200 - >>> ax = mesh.imshow(opacity=0.6) + >>> mesh.plot(opacity=0.6).show() .. note:: The :class:`~felupe.MeshContainer` may be directly created with @@ -930,7 +933,7 @@ def merge_duplicate_cells(self): :context: >>> import felupe as fem - + >>> >>> rect1 = fem.Rectangle(n=11) >>> rect2 = fem.Rectangle(a=(0.9, 0), b=(1.9, 1), n=11) >>> rect2 @@ -970,6 +973,7 @@ def merge_duplicate_cells(self): .. pyvista-plot:: :context: + :force_static: >>> mesh = stack.merge_duplicate_points() >>> mesh @@ -978,7 +982,7 @@ def merge_duplicate_cells(self): Number of cells: quad: 200 - >>> ax = mesh.imshow(opacity=0.6) + mesh.plot(opacity=0.6).show() .. note:: The :class:`~felupe.MeshContainer` may be directly created with @@ -1029,7 +1033,7 @@ def fill_between(self, other_mesh, n=11): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1135,7 +1139,7 @@ def mirror(self, normal=[1, 0, 0], centerpoint=[0, 0, 0], axis=None): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1143,7 +1147,7 @@ def mirror(self, normal=[1, 0, 0], centerpoint=[0, 0, 0], axis=None): >>> mesh.plot().show() .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1209,7 +1213,7 @@ def triangulate(self, mode=3): Use ``mode=0`` to convert a mesh of hexahedrons into tetrahedrons [1]_. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1219,7 +1223,7 @@ def triangulate(self, mode=3): Use ``mode=3`` to convert a mesh of hexahedrons into tetrahedrons [1]_. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1275,7 +1279,7 @@ def add_runouts( Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1285,7 +1289,7 @@ def add_runouts( >>> mesh.plot().show() .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1352,7 +1356,7 @@ def convert( the cell edges. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1426,7 +1430,7 @@ def add_midpoints_edges(self, cell_type=None): the cell edges. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1469,7 +1473,7 @@ def add_midpoints_faces(self, cell_type=None): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1511,7 +1515,7 @@ def add_midpoints_volumes(self, cell_type=None): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> import pyvista as pv From bf315fc5df71c643ec40c2179106ed4935eb2c33 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 23 Sep 2024 23:03:31 +0200 Subject: [PATCH 036/125] Enhance the docs --- docs/tutorial/examples/README.rst | 4 ++-- src/felupe/constitution/_material.py | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/docs/tutorial/examples/README.rst b/docs/tutorial/examples/README.rst index 7f98f88e..75f5664c 100644 --- a/docs/tutorial/examples/README.rst +++ b/docs/tutorial/examples/README.rst @@ -48,8 +48,8 @@ The :class:`step ` is further added to a list of steps of a :class: job.evaluate(filename="result.xdmf") fig, ax = job.plot( - xlabel="Displacement $d_1$ in mm $\longrightarrow$", - ylabel="Normal Force $F_1$ in N $\longrightarrow$", + xlabel=r"Displacement $d_1$ in mm $\longrightarrow$", + ylabel=r"Normal Force $F_1$ in N $\longrightarrow$", ) .. pyvista-plot:: diff --git a/src/felupe/constitution/_material.py b/src/felupe/constitution/_material.py index e54c8761..f84ad311 100644 --- a/src/felupe/constitution/_material.py +++ b/src/felupe/constitution/_material.py @@ -184,20 +184,21 @@ def hessian(x, **kwargs): Examples -------- The compressible isotropic hyperelastic Neo-Hookean material formulation is given - by the strain energy density function. + by the strain energy density function .. math:: - \psi &= \psi(\boldsymbol{C}) - - \psi(\boldsymbol{C}) &= \frac{\mu}{2} \text{tr}(\boldsymbol{C}) + \psi(\boldsymbol{C}) = \frac{\mu}{2} \text{tr}(\boldsymbol{C}) - \mu \ln(J) + \frac{\lambda}{2} \ln(J)^2 - with + with the determinant of the deformation gradient and the right Cauchy Green + deformation tensor. .. math:: - J = \text{det}(\boldsymbol{F}) + J &= \text{det}(\boldsymbol{F}) + + C &= \boldsymbol{F}^T\ \boldsymbol{F} The first Piola-Kirchhoff stress tensor is evaluated as the gradient of the strain energy density function. @@ -227,6 +228,7 @@ def hessian(x, **kwargs): >>> import numpy as np >>> import felupe as fem + >>> >>> from felupe.math import ( ... cdya_ik, ... cdya_il, @@ -255,7 +257,6 @@ def hessian(x, **kwargs): ... (mu - lmbda * np.log(J)) * cdya_il(iFT, iFT) ... ] >>> - >>> umat = fem.Material(stress, elasticity, mu=1.0, lmbda=2.0) The material formulation is tested in a minimal example of non-homogeneous uniaxial tension. @@ -263,11 +264,15 @@ def hessian(x, **kwargs): .. pyvista-plot:: :context: - >>> mesh = fem.Cube(n=6) + >>> mesh = fem.Cube(n=3) >>> region = fem.RegionHexahedron(mesh) >>> field = fem.FieldContainer([fem.Field(region, dim=3)]) - >>> boundaries, loadcase = fem.dof.uniaxial(field, clamped=True, move=0.5) + >>> + >>> umat = fem.Material(stress, elasticity, mu=1.0, lmbda=2.0) >>> solid = fem.SolidBodyNearlyIncompressible(umat, field, bulk=5000) + >>> + >>> boundaries, loadcase = fem.dof.uniaxial(field, clamped=True, move=0.5) + >>> >>> step = fem.Step(items=[solid], boundaries=boundaries) >>> job = fem.Job(steps=[step]).evaluate() From 8eff506a6fca5b7525f3f604a380a3b007a2a7f7 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 24 Sep 2024 10:20:53 +0200 Subject: [PATCH 037/125] Enhance the docstring of `FieldContainer.extract()` --- CHANGELOG.md | 4 ++-- src/felupe/field/_container.py | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 439c021a..9ded64c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,10 @@ All notable changes to this project will be documented in this file. The format ### Added - Add the hessian of the element shape functions for a quadratic quad element `QuadraticQuad.hessian()`. -- Add the `order`-argument to `FieldContainer.extract(order="C")` to return C-contiguous arrays by default. +- Add the `order`-argument to `FieldContainer.extract(order="C")` as well as for `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` to return C-contiguous arrays by default. ### Changed -- Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric` and `FieldPlaneStrain`. +- Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. ## [9.0.0] - 2024-09-06 diff --git a/src/felupe/field/_container.py b/src/felupe/field/_container.py index 5d359883..ffc15d1d 100644 --- a/src/felupe/field/_container.py +++ b/src/felupe/field/_container.py @@ -120,13 +120,13 @@ def __repr__(self): def extract( self, grad=True, sym=False, add_identity=True, dtype=None, out=None, order="C" ): - """Generalized extraction method which evaluates either the gradient or the + r"""Generalized extraction method which evaluates either the gradient or the field values at the integration points of all cells in the region. Optionally, the symmetric part of the gradient is evaluated and/or the identity matrix is added to the gradient. - Arguments - --------- + Parameters + ---------- grad : bool or list of bool, optional Flag(s) for gradient evaluation(s). A boolean value is appplied on the first field only and all other fields are extracted with ``grad=False``. To @@ -156,6 +156,33 @@ def extract( tuple of ndarray (Symmetric) gradient or interpolated field values evaluated at the integration points of each cell in the region. + + Notes + ----- + If the gradient is not requested, the interpolation method returns the field + values evaluated at the numeric integration points ``q`` for each cell ``c`` in + the region (so-called *trailing axes*). + + .. math:: + + u_{i(qc)} = \hat{u}_{ai}\ h_{a(qc)} + + On the other hand, the gradient method returns the gradient of the field values + w.r.t. the undeformed mesh point coordinates, evaluated at the integration + points of all cells in the region. + + .. math:: + + \left( \frac{\partial u_i}{\partial X_J} \right)_{(qc)} = + \hat{u}_{ai} \left( \frac{\partial h_a}{\partial X_J} \right)_{(qc)} + + See Also + -------- + felupe.Field.interpolate : Interpolate field values located at mesh-points to + the quadrature points in the region. + felupe.Field.grad : Gradient as partial derivative of field values w.r.t. + undeformed coordinates. + """ if isinstance(grad, bool): From 79a6c5931736296c14fc416827dd7aa9074f9b15 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 24 Sep 2024 16:22:17 +0200 Subject: [PATCH 038/125] Update _axi.py --- src/felupe/assembly/_axi.py | 52 ++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/felupe/assembly/_axi.py b/src/felupe/assembly/_axi.py index 8bb488bf..6ccbb007 100644 --- a/src/felupe/assembly/_axi.py +++ b/src/felupe/assembly/_axi.py @@ -24,14 +24,36 @@ class IntegralFormAxisymmetric(IntegralFormCartesian): r"""An Integral Form for axisymmetric fields. + + Parameters + ---------- + fun : array + The pre-evaluated function array. If the array is not contiguous, a C-contiguous + copy is made. + v : FieldAxisymmetric + The axisymmetric test field. + dV : array + The differential volumes. + u : FieldAxisymmetric, optional + If a field is passed, a bilinear form is created (default is None). + grad_v : bool, optional + Flag to activate the gradient on the test field ``v`` (default is False). + grad_u : bool, optional + Flag to activate the gradient on the trial field ``u`` (default is False). Notes ----- - Axisymmetric scenarios are modeled with a 2D-mesh and consequently, a 2D element - formulation. The rotation axis is chosen along the global X-axis - :math:`(X,Y,Z) \widehat{=} (Z,R,\varphi)`. The 3x3 deformation gradient consists of - an in-plane 2x2 sub-matrix and one additional entry for the out-of-plane stretch - which is equal to the ratio of deformed and undeformed radius. + Axisymmetric integral forms are created with a two-dimensional mesh, a two- + dimensional element formulation and an axisymmetric field. + + .. note:: + + The rotation axis is chosen along the global X-axis + :math:`(X,Y,Z) \widehat{=} (Z,R,\varphi)`. + + The three-dimensional deformation gradient consists of four in-plane components and + one additional non-zero entry for the out-of-plane stretch, which is equal to the + ratio of the deformed and the undeformed radius. .. math:: @@ -45,9 +67,9 @@ class IntegralFormAxisymmetric(IntegralFormCartesian): .. math:: - \delta \boldsymbol{F}_{(2D)} = \delta \frac{ + \delta \boldsymbol{F}_{(2D)} = \delta \left( \frac{ \partial \boldsymbol{u}}{\partial \boldsymbol{X} - } \qquad \text{and} \qquad \delta \left(\frac{r}{R}\right) + } \right) \qquad \text{and} \qquad \delta \left(\frac{r}{R}\right) = \frac{\delta u_r}{R} Again, the internal virtual work leads to two seperate terms. @@ -100,20 +122,20 @@ class IntegralFormAxisymmetric(IntegralFormCartesian): .. math:: - \mathbb{A}_{(2D),(2D)} &= \frac{ - \partial \psi}{\partial \boldsymbol{F}_{(2D)} \partial \boldsymbol{F}_{(2D)} + \mathbb{A}_{(2D)~(2D)} &= \frac{ + \partial \psi}{\partial \boldsymbol{F}_{(2D)}~\partial \boldsymbol{F}_{(2D)} } - \mathbb{A}_{(2D),33} &= \frac{ - \partial \psi}{\partial \boldsymbol{F}_{(2D)} \partial F^3_{\hphantom{3}3}} - \left ( = \mathbb{A}_{33,(2D)} \right ) + \mathbb{A}_{(2D)~33} &= \frac{ + \partial \psi}{\partial \boldsymbol{F}_{(2D)}\ \partial F_{33}} + \left ( = \mathbb{A}_{33~(2D)} \right ) - \mathbb{A}_{33,33} &= \frac{\partial \psi}{F^3_{\hphantom{3}3} - \partial F^3_{\hphantom{3}3}} + \mathbb{A}_{33~33} &= \frac{\partial \psi}{\partial F_{33}~\partial F_{33}} See Also -------- - felupe.IntegralForm : Mixed-field integral form container with methods for integration and assembly. + felupe.IntegralForm : Mixed-field integral form container with methods for + integration and assembly. felupe.assembly.IntegralFormCartesian : Single-field integral form. """ From 29c0931a112378675e067ce264f9cb5167d10460 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 15 Oct 2024 23:14:00 +0200 Subject: [PATCH 039/125] Add a docstring for the multi-point-constraint --- src/felupe/mechanics/_multipoint.py | 129 +++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/src/felupe/mechanics/_multipoint.py b/src/felupe/mechanics/_multipoint.py index a5dbee12..eeecaed3 100644 --- a/src/felupe/mechanics/_multipoint.py +++ b/src/felupe/mechanics/_multipoint.py @@ -23,10 +23,134 @@ class MultiPointConstraint: + """A Multi-point-constraint which connects a center-point to a list of points. + + Parameters + ---------- + field : FieldContainer + A field container with the displacement field as first field. + points : (n,) ndarray + An array with indices of points to be connected to the center-point. + centerpoint : int + The index of the centerpoint. + skip : 3-tuple of bool, optional + A tuple with boolean values for each axis to skip. If True, the respective axis + is not connected. Default is (False, False, False). + multiplier : float, optional + A multiplier to penalize the relative displacements between the center-point and + the points. Default is 1e-3. + + Notes + ----- + A :class:`~felupe.MultiPointConstraint` is supported as an item in a + :class:`~felupe.Step`. Rotational degrees-of-freedom of the center-point are + not connected to the points. + + Examples + -------- + This example shows how to use a :class:`~felupe.MultiPointConstraint`. + + An additional center-point is added to a mesh. By default, all *hanging* points are + collected in the mesh-attribute :attr:`~felupe.Mesh.points_without_cells`. The + degrees of freedom of these points are considered as fixed, i.e. they are ignored. + The center-point is not connected to any cell and is added to the points-without- + cells list. Hence, we have to remove the center-point. + + .. pyvista-plot:: + :context: + + >>> import numpy as np + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> mesh.update(points=np.vstack([mesh.points, [2.0, 0.5, 0.5]])) + >>> + >>> # prevent the field-values at the center-point to be treated as dof0 + >>> mesh.points_without_cells = mesh.points_without_cells[:-1] + >>> + >>> region = fem.RegionHexahedron(mesh) + >>> displacement = fem.Field(region, dim=3) + >>> field = fem.FieldContainer([displacement]) + >>> + >>> umat = fem.NeoHooke(mu=1.0, bulk=2.0) + >>> solid = fem.SolidBody(umat=umat, field=field) + + A :class:`~felupe.MultiPointConstraint` defines the multi-point constraint which + connects the displacement degrees of freedom of the center-point with the dofs of + points located at :math:`x=1`. + + .. pyvista-plot:: + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> mpc = fem.MultiPointConstraint( + ... field=field, + ... points=np.arange(mesh.npoints)[mesh.x == 1], + ... centerpoint=-1, + ... ) + >>> + >>> plotter = pv.Plotter() + >>> actor_1 = plotter.add_points( + ... mesh.points[mpc.points], + ... point_size=16, + ... color="red", + ... ) + >>> actor_2 = plotter.add_points( + ... mesh.points[[mpc.centerpoint]], + ... point_size=16, + ... color="green", + ... ) + >>> mesh.plot(plotter=mpc.plot(plotter=plotter)).show() + + The mesh is fixed on the left end face and a ramped :class:`~felupe.PointLoad` is + applied on the center-point of the :class:`~felupe.MultiPointConstraint`. All items + are added to a step and a job is evaluated. + + .. pyvista-plot:: + :context: + + >>> boundaries = {"fixed": fem.Boundary(displacement, fx=0)} + >>> load = fem.PointLoad(field, points=[-1]) + >>> table = fem.math.linsteps([0, 1], num=5, axis=0, axes=3) + >>> + >>> step = fem.Step( + ... [solid, mpc, load], boundaries=boundaries, ramp={load: table} + ... ) + >>> job = fem.Job([step]).evaluate() + + A view on the deformed mesh including the :class:`~felupe.MultiPointConstraint` is + plotted. + + .. pyvista-plot:: + :context: + :force_static: + + >>> plotter = pv.Plotter() + >>> actor_1 = plotter.add_points( + ... mesh.points[mpc.points] + displacement.values[mpc.points], + ... point_size=16, + ... color="red", + ... ) + >>> actor_2 = plotter.add_points( + ... mesh.points[[mpc.centerpoint]] + displacement.values[[mpc.centerpoint]], + ... point_size=16, + ... color="green", + ... ) + >>> field.plot( + ... "Displacement", component=None, plotter=mpc.plot(plotter=plotter) + ... ).show() + + See Also + -------- + felupe.MultiPointContact : A frictionless point-to-rigid (wall) contact. + + """ + def __init__( self, field, points, centerpoint, skip=(False, False, False), multiplier=1e3 ): - "RBE2 Multi-point-constraint." self.field = field self.mesh = field.region.mesh self.points = np.asarray(points) @@ -97,7 +221,8 @@ class MultiPointContact: def __init__( self, field, points, centerpoint, skip=(False, False, False), multiplier=1e6 ): - "RBE2 Multi-point-bolt-constraint." + "A frictionless point-to-rigid (wall) contact." + self.field = field self.mesh = field.region.mesh self.points = np.asarray(points) From 4626afb619df2228086f9ab1967ff540e05225c4 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 16 Oct 2024 15:40:46 +0200 Subject: [PATCH 040/125] Update _multipoint.py --- src/felupe/mechanics/_multipoint.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/felupe/mechanics/_multipoint.py b/src/felupe/mechanics/_multipoint.py index eeecaed3..8dc0e3ea 100644 --- a/src/felupe/mechanics/_multipoint.py +++ b/src/felupe/mechanics/_multipoint.py @@ -83,15 +83,13 @@ class MultiPointConstraint: :context: :force_static: - >>> import pyvista as pv - >>> >>> mpc = fem.MultiPointConstraint( ... field=field, ... points=np.arange(mesh.npoints)[mesh.x == 1], ... centerpoint=-1, ... ) >>> - >>> plotter = pv.Plotter() + >>> plotter = mpc.plot() >>> actor_1 = plotter.add_points( ... mesh.points[mpc.points], ... point_size=16, @@ -102,7 +100,7 @@ class MultiPointConstraint: ... point_size=16, ... color="green", ... ) - >>> mesh.plot(plotter=mpc.plot(plotter=plotter)).show() + >>> mesh.plot(plotter=plotter).show() The mesh is fixed on the left end face and a ramped :class:`~felupe.PointLoad` is applied on the center-point of the :class:`~felupe.MultiPointConstraint`. All items @@ -127,7 +125,7 @@ class MultiPointConstraint: :context: :force_static: - >>> plotter = pv.Plotter() + >>> plotter = mpc.plot() >>> actor_1 = plotter.add_points( ... mesh.points[mpc.points] + displacement.values[mpc.points], ... point_size=16, @@ -138,9 +136,7 @@ class MultiPointConstraint: ... point_size=16, ... color="green", ... ) - >>> field.plot( - ... "Displacement", component=None, plotter=mpc.plot(plotter=plotter) - ... ).show() + >>> field.plot("Displacement", component=None, plotter=plotter).show() See Also -------- From c21538c56adbbf5cd7bcfa87854b2ad22ec6fd87 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 16 Oct 2024 16:10:46 +0200 Subject: [PATCH 041/125] Update _multipoint.py --- src/felupe/mechanics/_multipoint.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/felupe/mechanics/_multipoint.py b/src/felupe/mechanics/_multipoint.py index 8dc0e3ea..c45559be 100644 --- a/src/felupe/mechanics/_multipoint.py +++ b/src/felupe/mechanics/_multipoint.py @@ -83,13 +83,15 @@ class MultiPointConstraint: :context: :force_static: + >>> import pyvista as pv + >>> >>> mpc = fem.MultiPointConstraint( ... field=field, ... points=np.arange(mesh.npoints)[mesh.x == 1], ... centerpoint=-1, ... ) >>> - >>> plotter = mpc.plot() + >>> plotter = pv.Plotter() >>> actor_1 = plotter.add_points( ... mesh.points[mpc.points], ... point_size=16, @@ -100,7 +102,7 @@ class MultiPointConstraint: ... point_size=16, ... color="green", ... ) - >>> mesh.plot(plotter=plotter).show() + >>> mesh.plot(plotter=mpc.plot(plotter=plotter)).show() The mesh is fixed on the left end face and a ramped :class:`~felupe.PointLoad` is applied on the center-point of the :class:`~felupe.MultiPointConstraint`. All items @@ -125,7 +127,8 @@ class MultiPointConstraint: :context: :force_static: - >>> plotter = mpc.plot() + >>> plotter = pv.Plotter() + >>> >>> actor_1 = plotter.add_points( ... mesh.points[mpc.points] + displacement.values[mpc.points], ... point_size=16, @@ -136,7 +139,9 @@ class MultiPointConstraint: ... point_size=16, ... color="green", ... ) - >>> field.plot("Displacement", component=None, plotter=plotter).show() + >>> field.plot( + ... "Displacement", component=None, plotter=mpc.plot(plotter=plotter) + ... ).show() See Also -------- From 6f59bebcd7e4b583ff27394625f9a4f950dc7eba Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 16 Oct 2024 23:02:08 +0200 Subject: [PATCH 042/125] Docs: remove howto/rbe2, now located in docstring of `MultiPointConstraint` --- docs/howto.rst | 1 - docs/howto/rbe2.rst | 47 ----------------------------- src/felupe/mechanics/_multipoint.py | 22 +++++++++----- 3 files changed, 15 insertions(+), 55 deletions(-) delete mode 100644 docs/howto/rbe2.rst diff --git a/docs/howto.rst b/docs/howto.rst index 377fbfec..a3d5609c 100644 --- a/docs/howto.rst +++ b/docs/howto.rst @@ -8,7 +8,6 @@ How-To Guides :caption: How-To: howto/meshgen - howto/rbe2 howto/mixed howto/axi howto/solvers diff --git a/docs/howto/rbe2.rst b/docs/howto/rbe2.rst deleted file mode 100644 index 43c495af..00000000 --- a/docs/howto/rbe2.rst +++ /dev/null @@ -1,47 +0,0 @@ -Multi-Point Constraints ------------------------ - -This How-To demonstrates the usage of multi-point constraints (also called MPC or RBE2 rigid-body-elements) with an independent centerpoint and one or more dependent points. First, a centerpoint has to be added to the mesh. MPC objects are supported as ``items`` of a :class:`~felupe.Step` and within the :func:`~felupe.newtonrhapson` procedure. - -.. pyvista-plot:: - :context: - - import numpy as np - import felupe as fem - - # mesh with one additional rbe2-control point - mesh = fem.Cube(n=11) - mesh.update(points=np.vstack((mesh.points, [2.0, 0.0, 0.0]))) - - # prevent the field-values at the center-point to be treated as dof0 - mesh.points_without_cells = mesh.points_without_cells[:0] - - region = fem.RegionHexahedron(mesh) - displacement = fem.Field(region, dim=3) - field = fem.FieldContainer([displacement]) - -An instance of :class:`~felupe.MultiPointConstraint` defines the multi-point constraint. This instance provides two methods, :meth:`MultiPointConstraint.assemble.vector() ` and :meth:`MultiPointConstraint.assemble.matrix() `. - -.. pyvista-plot:: - :context: - - mpc = fem.MultiPointConstraint( - field=field, - points=np.arange(mesh.npoints)[mesh.points[:, 0] == 1], - centerpoint=mesh.npoints - 1, - skip=(0,1,1), - ) - -Finally, add the results of these methods to the internal force vector or the stiffness matrix. - -.. pyvista-plot:: - :context: - :force_static: - - umat = fem.NeoHooke(mu=1.0, bulk=2.0) - body = fem.SolidBody(umat=umat, field=field) - - K = body.assemble.matrix() + mpc.assemble.matrix() - r = body.assemble.vector(field) + mpc.assemble.vector(field) - - mesh.plot(plotter=mpc.plot()).show() diff --git a/src/felupe/mechanics/_multipoint.py b/src/felupe/mechanics/_multipoint.py index c45559be..258abaca 100644 --- a/src/felupe/mechanics/_multipoint.py +++ b/src/felupe/mechanics/_multipoint.py @@ -43,18 +43,26 @@ class MultiPointConstraint: Notes ----- A :class:`~felupe.MultiPointConstraint` is supported as an item in a - :class:`~felupe.Step`. Rotational degrees-of-freedom of the center-point are - not connected to the points. + :class:`~felupe.Step`. It provides the assemble-methods + :meth:`MultiPointConstraint.assemble.vector() ` + and :meth:`MultiPointConstraint.assemble.matrix() `. + + .. note:: + + Rotational degrees-of-freedom of the center-point are not connected to the + points. Examples -------- This example shows how to use a :class:`~felupe.MultiPointConstraint`. An additional center-point is added to a mesh. By default, all *hanging* points are - collected in the mesh-attribute :attr:`~felupe.Mesh.points_without_cells`. The - degrees of freedom of these points are considered as fixed, i.e. they are ignored. - The center-point is not connected to any cell and is added to the points-without- - cells list. Hence, we have to remove the center-point. + collected in the mesh-attribute + :attr:`Mesh.points_without_cells `. The degrees of + freedom of these points are considered as fixed, i.e. they are ignored. The center- + point is not connected to any cell and is added to the points-without-cells array + on :meth:`Mesh.update `. Hence, center-point has to be removed + manually. .. pyvista-plot:: :context: @@ -106,7 +114,7 @@ class MultiPointConstraint: The mesh is fixed on the left end face and a ramped :class:`~felupe.PointLoad` is applied on the center-point of the :class:`~felupe.MultiPointConstraint`. All items - are added to a step and a job is evaluated. + are added to a :class:`~felupe.Step` and a :class:`~felupe.Job` is evaluated. .. pyvista-plot:: :context: From ecc22c1f3ac7d07937cc7575937e4de82c4e3e93 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 18 Oct 2024 15:32:42 +0200 Subject: [PATCH 043/125] Add docstring for `MultiPointContact` --- src/felupe/mechanics/_multipoint.py | 139 +++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/src/felupe/mechanics/_multipoint.py b/src/felupe/mechanics/_multipoint.py index 258abaca..089d2832 100644 --- a/src/felupe/mechanics/_multipoint.py +++ b/src/felupe/mechanics/_multipoint.py @@ -227,11 +227,146 @@ def _matrix(self, field=None, parallel=False): class MultiPointContact: + """A frictionless point-to-rigid (wall) contact which connects a center-point to a + list of points. + + Parameters + ---------- + field : FieldContainer + A field container with the displacement field as first field. + points : (n,) ndarray + An array with indices of points to be connected to the center-point. + centerpoint : int + The index of the centerpoint. + skip : 3-tuple of bool, optional + A tuple with boolean values for each axis to skip. If True, the respective axis + is not connected. Default is (False, False, False). + multiplier : float, optional + A multiplier to penalize the relative displacements between the center-point and + the points in contact. Default is 1e-6. + + Notes + ----- + A :class:`~felupe.MultiPointContact` is supported as an item in a + :class:`~felupe.Step`. It provides the assemble-methods + :meth:`MultiPointContact.assemble.vector() ` + and :meth:`MultiPointContact.assemble.matrix() `. + + Examples + -------- + This example shows how to use a :class:`~felupe.MultiPointContact`. + + An additional center-point is added to a mesh. By default, all *hanging* points are + collected in the mesh-attribute + :attr:`Mesh.points_without_cells `. The degrees of + freedom of these points are considered as fixed, i.e. they are ignored. The center- + point is not connected to any cell and is added to the points-without-cells array + on :meth:`Mesh.update `. Hence, center-point has to be removed + manually. + + .. pyvista-plot:: + :context: + + >>> import numpy as np + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> mesh.update(points=np.vstack([mesh.points, [2.0, 0.5, 0.5]])) + >>> + >>> # prevent the field-values at the center-point to be treated as dof0 + >>> mesh.points_without_cells = mesh.points_without_cells[:-1] + >>> + >>> region = fem.RegionHexahedron(mesh) + >>> displacement = fem.Field(region, dim=3) + >>> field = fem.FieldContainer([displacement]) + >>> + >>> umat = fem.NeoHooke(mu=1.0, bulk=2.0) + >>> solid = fem.SolidBody(umat=umat, field=field) + + A :class:`~felupe.MultiPointContact` defines the multi-point contact which + connects the displacement degrees of freedom of the center-point with the dofs of + points located at :math:`x=1` if they are in contact. Only the :math:`x`-component + is considered in this example. + + .. pyvista-plot:: + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> contact = fem.MultiPointContact( + ... field=field, + ... points=np.arange(mesh.npoints)[mesh.x == 1], + ... centerpoint=-1, + ... skip=(False, True, True) + ... ) + >>> + >>> plotter = pv.Plotter() + >>> actor_1 = plotter.add_points( + ... mesh.points[mpc.points], + ... point_size=16, + ... color="red", + ... ) + >>> actor_2 = plotter.add_points( + ... mesh.points[[mpc.centerpoint]], + ... point_size=16, + ... color="green", + ... ) + >>> mesh.plot(plotter=contact.plot(plotter=plotter)).show() + + The mesh is fixed on the left end face and a ramped :class:`~felupe.PointLoad` is + applied on the center-point of the :class:`~felupe.MultiPointContact`. All items + are added to a :class:`~felupe.Step` and a :class:`~felupe.Job` is evaluated. + + .. pyvista-plot:: + :context: + + >>> boundaries = { + ... "fixed": fem.Boundary(displacement, fx=0), + ... "control": fem.Boundary(displacement, fx=2, skip=(1, 0, 0)), + ... "move": fem.Boundary(displacement, fx=2, skip=(0, 1, 1)), + ... } + >>> load = fem.PointLoad(field, points=[-1]) + >>> table = fem.math.linsteps([0, -1, -1.5], num=5) + >>> + >>> step = fem.Step( + ... [solid, contact], boundaries=boundaries, ramp={boundaries["move"]: table} + ... ) + >>> job = fem.Job([step]).evaluate() + + A view on the deformed mesh including the :class:`~felupe.MultiPointContact` is + plotted. + + .. pyvista-plot:: + :context: + :force_static: + + >>> plotter = pv.Plotter() + >>> + >>> actor_1 = plotter.add_points( + ... mesh.points[contact.points] + displacement.values[contact.points], + ... point_size=16, + ... color="red", + ... ) + >>> actor_2 = plotter.add_points( + ... mesh.points[[contact.centerpoint]] + displacement.values[[contact.centerpoint]], + ... point_size=16, + ... color="green", + ... ) + >>> field.plot( + ... "Displacement", component=None, plotter=contact.plot(plotter=plotter) + ... ).show() + + See Also + -------- + felupe.MultiPointConstraint : A Multi-point-constraint which connects a center-point + to a list of points. + + """ + def __init__( self, field, points, centerpoint, skip=(False, False, False), multiplier=1e6 ): - "A frictionless point-to-rigid (wall) contact." - self.field = field self.mesh = field.region.mesh self.points = np.asarray(points) From 90db4e82d4b78630aa5ab3308621fd262c2aed97 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 18 Oct 2024 15:34:30 +0200 Subject: [PATCH 044/125] Update _multipoint.py --- src/felupe/mechanics/_multipoint.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/felupe/mechanics/_multipoint.py b/src/felupe/mechanics/_multipoint.py index 089d2832..867e3c1a 100644 --- a/src/felupe/mechanics/_multipoint.py +++ b/src/felupe/mechanics/_multipoint.py @@ -314,7 +314,7 @@ class MultiPointContact: ... ) >>> mesh.plot(plotter=contact.plot(plotter=plotter)).show() - The mesh is fixed on the left end face and a ramped :class:`~felupe.PointLoad` is + The mesh is fixed on the left end face and a ramped :class:`~felupe.Boundary` is applied on the center-point of the :class:`~felupe.MultiPointContact`. All items are added to a :class:`~felupe.Step` and a :class:`~felupe.Job` is evaluated. @@ -326,11 +326,11 @@ class MultiPointContact: ... "control": fem.Boundary(displacement, fx=2, skip=(1, 0, 0)), ... "move": fem.Boundary(displacement, fx=2, skip=(0, 1, 1)), ... } - >>> load = fem.PointLoad(field, points=[-1]) >>> table = fem.math.linsteps([0, -1, -1.5], num=5) - >>> >>> step = fem.Step( - ... [solid, contact], boundaries=boundaries, ramp={boundaries["move"]: table} + ... [solid, contact], + ... boundaries=boundaries, + ... ramp={boundaries["move"]: table}, ... ) >>> job = fem.Job([step]).evaluate() From c55db1fc613d0043c4ea3b95523e62d2a80e14ec Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 18 Oct 2024 23:28:44 +0200 Subject: [PATCH 045/125] Add an optional multiplier in `Laplace(multiplier=1.0)` (#864) --- CHANGELOG.md | 1 + src/felupe/constitution/poisson/_laplace.py | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ded64c9..32f6c804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. The format ### Added - Add the hessian of the element shape functions for a quadratic quad element `QuadraticQuad.hessian()`. - Add the `order`-argument to `FieldContainer.extract(order="C")` as well as for `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` to return C-contiguous arrays by default. +- Add an optional multiplier to `Laplace(multiplier=1.0)`. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/src/felupe/constitution/poisson/_laplace.py b/src/felupe/constitution/poisson/_laplace.py index f5a8ba03..44b44c93 100644 --- a/src/felupe/constitution/poisson/_laplace.py +++ b/src/felupe/constitution/poisson/_laplace.py @@ -26,6 +26,11 @@ class Laplace(ConstitutiveMaterial): r"""Laplace equation as hessian of one half of the second main invariant of the field gradient. + Parameters + ---------- + multiplier : float, optional + A multiplier which scales the potential (default is 1.0). + Notes ----- The potential is given by the second main invariant of the field gradient w.r.t. @@ -64,8 +69,9 @@ class Laplace(ConstitutiveMaterial): """ - def __init__(self): - self.kwargs = {} + def __init__(self, multiplier=1.0): + self.multiplier = multiplier + self.kwargs = {"multiplier": self.multiplier} # aliases for gradient and hessian self.stress = self.gradient @@ -93,7 +99,7 @@ def function(self, x): F = x[0] H = F - identity(F) - return [ddot(H, H) / 2] + return [self.multiplier * ddot(H, H) / 2] def gradient(self, x): r"""Evaluate the stress tensor. @@ -113,7 +119,7 @@ def gradient(self, x): F, statevars = x[0], x[-1] H = F - identity(F) - return [H, statevars] + return [self.multiplier * H, statevars] def hessian(self, x): r"""Evaluate the elasticity tensor. @@ -122,8 +128,6 @@ def hessian(self, x): ---------- x : list of ndarray List with Deformation gradient :math:`\boldsymbol{F}` as first item. - shape : tuple of int, optional - Tuple with shape of the trailing axes (default is (1, 1)). Returns ------- @@ -136,4 +140,6 @@ def hessian(self, x): ntrax = len(x[0].shape) - 2 ones = np.ones(ntrax, dtype=int) - return [cdya_ik(np.eye(n), np.eye(m)).reshape(n, m, n, m, *ones)] + return [ + self.multiplier * cdya_ik(np.eye(n), np.eye(m)).reshape(n, m, n, m, *ones) + ] From e04456a7e6e3c1e858e2e9cbd9a8eb294469dbe9 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 21 Oct 2024 13:54:59 +0200 Subject: [PATCH 046/125] Add optional kwargs in `math.transpose(**kwargs)` (#865) * Add optional kwargs in `math.transpose(**kwargs)` * format black --- CHANGELOG.md | 1 + src/felupe/math/_tensor.py | 6 +++--- src/felupe/mesh/_dual.py | 2 +- src/felupe/mesh/_geometry.py | 6 +++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f6c804..5e2be686 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. The format - Add the hessian of the element shape functions for a quadratic quad element `QuadraticQuad.hessian()`. - Add the `order`-argument to `FieldContainer.extract(order="C")` as well as for `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` to return C-contiguous arrays by default. - Add an optional multiplier to `Laplace(multiplier=1.0)`. +- Add optional keyword-arguments to `math.transpose(**kwargs)` to support optional `out` and `order`-keywords. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/src/felupe/math/_tensor.py b/src/felupe/math/_tensor.py index 35e63fef..b5fd9edf 100644 --- a/src/felupe/math/_tensor.py +++ b/src/felupe/math/_tensor.py @@ -819,12 +819,12 @@ def eigvalsh(A, shear=False): return eigvals(A, shear=shear, eigvals=np.linalg.eigvalsh) -def transpose(A, mode=1): +def transpose(A, mode=1, **kwargs): "Transpose (mode=1) or major-transpose (mode=2) of matrix A." if mode == 1: - return np.einsum("ij...->ji...", A) + return np.einsum("ij...->ji...", A, **kwargs) elif mode == 2: - return np.einsum("ijkl...->klij...", A) + return np.einsum("ijkl...->klij...", A, **kwargs) else: raise ValueError("Unknown value of mode.") diff --git a/src/felupe/mesh/_dual.py b/src/felupe/mesh/_dual.py index ae039e8d..3650ae4d 100644 --- a/src/felupe/mesh/_dual.py +++ b/src/felupe/mesh/_dual.py @@ -75,7 +75,7 @@ def dual( Examples -------- .. pyvista-plot:: - + >>> import felupe as fem >>> >>> mesh = fem.Rectangle(n=5).add_midpoints_edges() diff --git a/src/felupe/mesh/_geometry.py b/src/felupe/mesh/_geometry.py index 3079da27..6c550ec6 100644 --- a/src/felupe/mesh/_geometry.py +++ b/src/felupe/mesh/_geometry.py @@ -35,7 +35,7 @@ class Point(Mesh): Examples -------- .. pyvista-plot:: - + >>> import felupe as fem >>> >>> mesh = fem.Point(a=-2.1) @@ -44,10 +44,10 @@ class Point(Mesh): Number of points: 1 Number of cells: vertex: 1 - + >>> mesh.points array([[-2.1]]) - + >>> mesh.cells array([[0]]) """ From c07d0a9fd1700cf25b25ec765367137e98dab6b1 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 21 Oct 2024 17:18:26 +0200 Subject: [PATCH 047/125] Fix the number of points for non-disconnected dual-meshes (#867) --- CHANGELOG.md | 1 + src/felupe/mesh/_dual.py | 20 ++++++++++++++------ tests/test_mesh.py | 6 ++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e2be686..35ffbfb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. The format ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. +- Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. ## [9.0.0] - 2024-09-06 diff --git a/src/felupe/mesh/_dual.py b/src/felupe/mesh/_dual.py index 3650ae4d..a1411376 100644 --- a/src/felupe/mesh/_dual.py +++ b/src/felupe/mesh/_dual.py @@ -106,15 +106,23 @@ def dual( if disconnect: cells_new = np.arange(ncells * points_per_cell).reshape(ncells, points_per_cell) + + if calc_points: + points_new = points[cells[:, :points_per_cell]].reshape(-1, dim) + else: + points_new = np.broadcast_to( + np.zeros((1, dim), dtype=int), (ncells * points_per_cell, dim) + ) + else: cells_new = cells[:, :points_per_cell] - if calc_points: - points_new = points[cells[:, :points_per_cell]].reshape(-1, dim) - else: - points_new = np.broadcast_to( - np.zeros((1, dim), dtype=int), (ncells * points_per_cell, dim) - ) + if calc_points: + points_new = points[: 1 + cells_new.max()] + else: + points_new = np.broadcast_to( + np.zeros((1, dim), dtype=int), (1 + cells_new.max(), dim) + ) if offset > 0: cells_new += offset diff --git a/tests/test_mesh.py b/tests/test_mesh.py index 61105393..4c66604c 100644 --- a/tests/test_mesh.py +++ b/tests/test_mesh.py @@ -61,8 +61,10 @@ def test_meshes(): ) m.dual() - fem.mesh.dual(m, disconnect=False) - fem.mesh.dual(m, calc_points=True) + fem.mesh.dual(m, disconnect=False, calc_points=False) + fem.mesh.dual(m, disconnect=False, calc_points=True) + fem.mesh.dual(m, disconnect=True, calc_points=False) + fem.mesh.dual(m, disconnect=True, calc_points=True) rect = fem.Rectangle(n=5).add_midpoints_edges() rect_dual = rect.dual(points_per_cell=1, disconnect=False) From 6704ed0d038c35d5fefde4e2b03662df812fb34c Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 24 Oct 2024 08:53:14 +0200 Subject: [PATCH 048/125] Enhance the docstring of the linear-elastic material add a warning on large-strain analyses --- .../linear_elasticity/_linear_elastic.py | 26 +++++++++++++++++-- .../_linear_elastic_large_strain.py | 2 +- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/felupe/constitution/linear_elasticity/_linear_elastic.py b/src/felupe/constitution/linear_elasticity/_linear_elastic.py index a671d75b..3821858b 100644 --- a/src/felupe/constitution/linear_elasticity/_linear_elastic.py +++ b/src/felupe/constitution/linear_elasticity/_linear_elastic.py @@ -35,7 +35,11 @@ class LinearElastic(ConstitutiveMaterial): Notes ----- + The stress-strain relation of the linear-elastic material formulation is given in + Eq. :eq:`linear-elastic` + .. math:: + :label: linear-elastic \begin{bmatrix} \sigma_{11} \\ @@ -60,14 +64,24 @@ class LinearElastic(ConstitutiveMaterial): 2 \varepsilon_{31} \end{bmatrix} - with the strain tensor + with the small-strain tensor from Eq. :eq:`linear-elastic-strain`. .. math:: + :label: linear-elastic-strain \boldsymbol{\varepsilon} = \frac{1}{2} \left( \frac{\partial \boldsymbol{u}} {\partial \boldsymbol{X}} + \left( \frac{\partial \boldsymbol{u}} {\partial \boldsymbol{X}} \right)^T \right) + .. warning:: + + This material formulation must not be used in analyses where large rotations, + large displacements or large strains occur. In this case, consider using a + :class:`~felupe.Hyperelastic` material formulation instead. + :class:`~felupe.LinearElasticLargeStrain` is based on a compressible version + of the Neo-Hookean material formulation and is safe to use for large rotations, + large displacements and large strains. + Examples -------- .. pyvista-plot:: @@ -88,7 +102,15 @@ class LinearElastic(ConstitutiveMaterial): >>> fig = ax.get_figure() >>> chart = pv.ChartMPL(fig) >>> chart.show() - + + See Also + -------- + felupe.LinearElasticLargeStrain : Linear-elastic material formulation suitable for + large-strain analyses based on the compressible Neo-Hookean material + formulation. + felupe.Hyperelastic : A hyperelastic material definition with a given function for + the strain energy density function per unit undeformed volume with automatic + differentiation. """ def __init__(self, E, nu): diff --git a/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py b/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py index e0903d88..beae898e 100644 --- a/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py +++ b/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py @@ -24,7 +24,7 @@ class LinearElasticLargeStrain(ConstitutiveMaterial): - r"""Linear-elastic material formulation suitable for large-rotation analyses based + r"""Linear-elastic material formulation suitable for large-strain analyses based on the compressible Neo-Hookean material formulation. Parameters From 9e07aa8d419693da585c9048728ba7e6f4e0f9bb Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 25 Oct 2024 13:36:47 +0200 Subject: [PATCH 049/125] Fix wrong result of `ConstitutiveMaterial.plot()` if any stretch <= 0 (#872) this raises an error now to avoid the wrong results --- CHANGELOG.md | 3 +++ src/felupe/constitution/_view.py | 22 ++++++++++++++++++++++ tests/test_constitution.py | 16 ++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35ffbfb7..ab3e74e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ All notable changes to this project will be documented in this file. The format - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. - Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. +### Fixed +- Fix wrong results of `ConstitutiveMaterial.plot()` if any stretch is non-physical, i.e. lower or equal zero. This raises an error now. + ## [9.0.0] - 2024-09-06 ### Added diff --git a/src/felupe/constitution/_view.py b/src/felupe/constitution/_view.py index 194a1744..a4070df4 100644 --- a/src/felupe/constitution/_view.py +++ b/src/felupe/constitution/_view.py @@ -24,6 +24,15 @@ from ..math import det, linsteps +def check_stretches(stretches): + "Check if any stretch is lower or equal zero." + + if np.any(stretches <= 0.0): + raise ValueError("All stretches must greater than 0.") + + return + + class PlotMaterial: "Plot force-stretch curves of constitutive material formulations." @@ -203,7 +212,10 @@ def uniaxial(self, stretches=None): if stretches is None: stretches = self.ux + check_stretches(stretches) + λ1 = stretches + λ2 = λ3 = 1 / np.sqrt(λ1) eye = np.eye(3).reshape(3, 3, 1, 1) @@ -265,6 +277,8 @@ def planar(self, stretches=None): if stretches is None: stretches = self.ps + check_stretches(stretches) + λ1 = stretches λ2 = np.ones_like(λ1) λ3 = 1 / λ1 @@ -327,6 +341,8 @@ def biaxial(self, stretches=None): if stretches is None: stretches = self.bx + check_stretches(stretches) + λ1 = λ2 = stretches λ3 = 1 / λ1**2 eye = np.eye(3).reshape(3, 3, 1, 1) @@ -475,6 +491,8 @@ def uniaxial(self, stretches=None): if stretches is None: stretches = self.ux + check_stretches(stretches) + λ1 = stretches λ2 = λ3 = 1 / np.sqrt(λ1) eye = np.eye(3).reshape(3, 3, 1, 1) @@ -512,6 +530,8 @@ def planar(self, stretches=None): if stretches is None: stretches = self.ps + check_stretches(stretches) + λ1 = stretches λ2 = np.ones_like(λ1) λ3 = 1 / λ1 @@ -554,6 +574,8 @@ def biaxial(self, stretches=None): if stretches is None: stretches = self.bx + check_stretches(stretches) + λ1 = λ2 = stretches λ3 = 1 / λ1**2 eye = np.eye(3).reshape(3, 3, 1, 1) diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 3d209f2b..660dab08 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -707,6 +707,21 @@ def test_laplace(): assert A[0].shape == (3, 3, 3, 3, 1, 1) +def test_plot_negative_stretches(): + stretches = np.linspace(-0.5, 1, 16) + umat = fem.NeoHooke(mu=1.0, bulk=2.0) + + for incompressible in [False, True]: + with pytest.raises(ValueError): + umat.plot(ux=stretches, incompressible=incompressible) + + with pytest.raises(ValueError): + umat.plot(bx=stretches, incompressible=incompressible) + + with pytest.raises(ValueError): + umat.plot(ps=stretches, incompressible=incompressible) + + if __name__ == "__main__": test_nh() test_linear() @@ -728,3 +743,4 @@ def test_laplace(): test_lagrange() test_lagrange_statevars() test_laplace() + test_plot_negative_stretches() From 85b54aadee0d07c078443b12fdc84e1c168a1088 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 25 Oct 2024 13:40:40 +0200 Subject: [PATCH 050/125] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab3e74e7..0bf975b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,9 @@ All notable changes to this project will be documented in this file. The format ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. -- Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. ### Fixed +- Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. - Fix wrong results of `ConstitutiveMaterial.plot()` if any stretch is non-physical, i.e. lower or equal zero. This raises an error now. ## [9.0.0] - 2024-09-06 From 03d6506c0a77980e3f46af63ede05d53da201f2c Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 28 Oct 2024 14:54:36 +0100 Subject: [PATCH 051/125] Add `RegionBoundary.tangents` and `math.inplane()` (#873) * Add `RegionBoundary.tangents` attribute * Add `math.inplane(A, vectors)` * Update CHANGELOG.md --- CHANGELOG.md | 2 ++ docs/felupe/math.rst | 3 +- src/felupe/math/__init__.py | 2 ++ src/felupe/math/_tensor.py | 52 ++++++++++++++++++++++++++++++++++ src/felupe/region/_boundary.py | 11 +++++-- tests/test_math.py | 11 +++++++ 6 files changed, 78 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bf975b3..4e046d5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. The format - Add the `order`-argument to `FieldContainer.extract(order="C")` as well as for `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` to return C-contiguous arrays by default. - Add an optional multiplier to `Laplace(multiplier=1.0)`. - Add optional keyword-arguments to `math.transpose(**kwargs)` to support optional `out` and `order`-keywords. +- Add the attribute `RegionBoundary.tangents`, which contains a list of tangent unit vectors. For `quad` cell-types the length of this list is one and for `hexahedron` cell-types it is of length two. +- Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/docs/felupe/math.rst b/docs/felupe/math.rst index 25af760e..ed3ff944 100644 --- a/docs/felupe/math.rst +++ b/docs/felupe/math.rst @@ -34,6 +34,7 @@ This module contains math functions. math.identity math.sym math.dya + math.inplane math.inv math.det math.dev @@ -65,4 +66,4 @@ This module contains math functions. **Detailed API Reference** .. automodule:: felupe.math - :members: linsteps, rotation_matrix, deformation_gradient, strain, strain_stretch_1d, extract, values, norm, interpolate, grad, identity, sym, dya, inv, det, dev,cof, eig, eigh, eigvals, eigvalsh, equivalent_von_mises, transpose, majortranspose, trace, cdya_ik, cdya_il, cdya, cross, dot, ddot, tovoigt, reshape, ravel, solve_2d + :members: linsteps, rotation_matrix, deformation_gradient, strain, strain_stretch_1d, extract, values, norm, interpolate, grad, identity, sym, dya, inplane, inv, det, dev,cof, eig, eigh, eigvals, eigvalsh, equivalent_von_mises, transpose, majortranspose, trace, cdya_ik, cdya_il, cdya, cross, dot, ddot, tovoigt, reshape, ravel, solve_2d diff --git a/src/felupe/math/__init__.py b/src/felupe/math/__init__.py index b4e4434d..bdc3599e 100644 --- a/src/felupe/math/__init__.py +++ b/src/felupe/math/__init__.py @@ -33,6 +33,7 @@ eigvalsh, equivalent_von_mises, identity, + inplane, inv, majortranspose, ravel, @@ -74,6 +75,7 @@ "eigvalsh", "equivalent_von_mises", "identity", + "inplane", "inv", "majortranspose", "ravel", diff --git a/src/felupe/math/_tensor.py b/src/felupe/math/_tensor.py index b5fd9edf..f59fce48 100644 --- a/src/felupe/math/_tensor.py +++ b/src/felupe/math/_tensor.py @@ -1481,3 +1481,55 @@ def equivalent_von_mises(A): devA = dev(A) return np.sqrt(3 / 2 * ddot(devA, devA)) + + +def inplane(A, vectors, **kwargs): + r"""Return the in-plane components of symmetric 2x2 or 3x3 tensors, where the planes + are defined by their standard unit vectors. + + Parameters + ---------- + A : ndarray of shape (N, N, ...) + Symmetric second-order tensors. + vectors : list of ndarray of shape (N, ...) + List of standard unit vectors of the planes. + **kwargs : dict, optional + Optional keyword-arguments for :func:`numpy.einsum`. + + Notes + ----- + The first two axes of the tensor and the first axis of each vector are the + tensor/vector dimensions and all remaining trailing axes are treated as batch + dimensions. + + .. math:: + + \boldsymbol{A}_{N-1} = \sum_{\alpha, \beta} + \left( \boldsymbol{E}_\alpha^T \boldsymbol{A} \boldsymbol{E}_\beta\right) + \boldsymbol{E}_\alpha \otimes \boldsymbol{E}_\beta + + Returns + ------- + ndarray of shape (N - 1, N - 1, ...) + The in-plane components of symmetric (N, N) tensors. + + Examples + -------- + >>> import felupe as fem + >>> + >>> A = np.array([[0, 3, 5], [3, 1, 4], [5, 4, 2]]) + >>> vectors = [[1, 0, 0], [0, 1, 0]] + >>> + >>> A_inplane = fem.math.inplane(A, vectors) + >>> A_inplane + array([[0, 3], + [3, 1]]) + """ + + vectors = np.array(vectors) + + i, j = np.triu_indices(len(vectors)) + ij = np.zeros((len(vectors), len(vectors)), dtype=int) + ij[i, j] = ij[j, i] = np.arange(len(i), dtype=int) + + return np.einsum("ij...,ai...,aj...->a...", A, vectors[i], vectors[j], **kwargs)[ij] diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index 26def48c..367c51cd 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -435,11 +435,13 @@ def __init__( super().__init__(mesh_boundary_cells, element, quadrature, grad=grad) if grad: - self.dA, self.dV, self.normals = self._init_faces() + self.dA, self.dV, self.normals, self.tangents = self._init_faces() def _init_faces(self): "Initialize (norm of) face normals of cells." + tangents = [] + if ( self.mesh.cell_type == "quad" or self.mesh.cell_type == "quad8" @@ -448,6 +450,8 @@ def _init_faces(self): dA_1 = self.dXdr[:, 0][::-1] dA_1[0] = -dA_1[0] + tangents.append(self.dXdr[:, 0] / np.linalg.norm(self.dXdr[:, 0], axis=0)) + elif ( self.mesh.cell_type == "hexahedron" or self.mesh.cell_type == "hexahedron20" @@ -455,6 +459,9 @@ def _init_faces(self): ): dA_1 = cross(self.dXdr[:, 0], self.dXdr[:, 1]) + tangents.append(self.dXdr[:, 0] / np.linalg.norm(self.dXdr[:, 0], axis=0)) + tangents.append(self.dXdr[:, 1] / np.linalg.norm(self.dXdr[:, 1], axis=0)) + dA = -dA_1 * self.quadrature.weights.reshape(-1, 1) # norm and unit normal vector @@ -466,7 +473,7 @@ def _init_faces(self): dA = np.pad(dA, ((0, 1), (0, 0), (0, 0))) normals = np.pad(normals, ((0, 1), (0, 0), (0, 0))) - return dA, dV, normals + return dA, dV, normals, tangents def mesh_faces(self): "Return a Mesh with face-cells on the selected boundary." diff --git a/tests/test_math.py b/tests/test_math.py index 8e8bbb19..281201d7 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -185,7 +185,18 @@ def test_math_linsteps(): assert np.allclose(steps[-1], (0, 5)) +def test_inplane(): + import felupe as fem + + A = np.array([[0, 3, 5], [3, 1, 4], [5, 4, 2]], dtype=float) + vectors = [[1, 0, 0], [0, 1, 0]] + + A_inplane = fem.math.inplane(A, vectors) + assert np.allclose(A_inplane.ravel(), [0, 3, 3, 1]) + + if __name__ == "__main__": test_math() test_math_field() test_math_linsteps() + test_inplane() From 359e7ce3fe8f154423b2bff516002b49b4603143 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 28 Oct 2024 16:06:28 +0100 Subject: [PATCH 052/125] fix tangents for quads --- src/felupe/region/_boundary.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index 367c51cd..0cfc2bc2 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -449,8 +449,11 @@ def _init_faces(self): ): dA_1 = self.dXdr[:, 0][::-1] dA_1[0] = -dA_1[0] + + dX_1 = -self.dXdr[:, 0] + dX_1[0] = -dX_1[0] - tangents.append(self.dXdr[:, 0] / np.linalg.norm(self.dXdr[:, 0], axis=0)) + tangents.append(dX_1 / np.linalg.norm(dX_1, axis=0)) elif ( self.mesh.cell_type == "hexahedron" From d132aa9b8d0c13a48a6b75b8c11c66db756fd7e3 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 28 Oct 2024 16:12:42 +0100 Subject: [PATCH 053/125] fix tangents on hexahedrons --- src/felupe/region/_boundary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index 0cfc2bc2..f1bfb56d 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -462,7 +462,7 @@ def _init_faces(self): ): dA_1 = cross(self.dXdr[:, 0], self.dXdr[:, 1]) - tangents.append(self.dXdr[:, 0] / np.linalg.norm(self.dXdr[:, 0], axis=0)) + tangents.append(-self.dXdr[:, 0] / np.linalg.norm(self.dXdr[:, 0], axis=0)) tangents.append(self.dXdr[:, 1] / np.linalg.norm(self.dXdr[:, 1], axis=0)) dA = -dA_1 * self.quadrature.weights.reshape(-1, 1) From e942040f4d7af02c50ea6598b51288e4fb58292d Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 28 Oct 2024 22:26:44 +0100 Subject: [PATCH 054/125] Enhance the docstring for `RegionBoundary` --- src/felupe/region/_boundary.py | 115 ++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index f1bfb56d..0e9fd384 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -243,9 +243,8 @@ def boundary_cells_hexahedron27(mesh): class RegionBoundary(Region): - r""" - A numeric boundary-region as a combination of a mesh, an element and a - numeric integration scheme (quadrature rule). + r"""A numeric boundary-region as a combination of a mesh, an element and a numeric + integration scheme (quadrature rule). Parameters ---------- @@ -291,6 +290,8 @@ class RegionBoundary(Region): Numeric *Differential area vectors*. normals : ndarray Area unit normal vectors. + tangents : list of ndarray + List of standard unit vectors. dV : ndarray Numeric *Differential volume element* as norm of *Differential area vectors*. dhdX : ndarray @@ -318,11 +319,11 @@ class RegionBoundary(Region): Examples -------- >>> import felupe as fem - + >>> >>> mesh = fem.Rectangle(n=(3, 2)) >>> element = fem.Quad() >>> quadrature = fem.GaussLegendreBoundary(order=1, dim=2) - + >>> >>> region = fem.RegionBoundary(mesh, element, quadrature) >>> region @@ -361,11 +362,109 @@ class RegionBoundary(Region): [-1., -0., -1., -0., 1., 1.]]]) The partial derivative of the first element shape function w.r.t. the undeformed - coordinates evaluated at the second integration point of the last element of the - region: + coordinates, evaluated at the second integration point of the last element of the + region, is obtained by: >>> region.dhdX[0, :, 1, -1] array([2. , 0.21132487]) + + The faces-cells may be used to create a mesh on the boundary. + + >>> fem.Mesh(points=mesh.points, cells=region.mesh.cells_faces, cell_type="line") + + Number of points: 6 + Number of cells: + line: 6 + + A second example shows the standard unit vectors and the area normals, located at + the quadrature points for all edges of a quadrilateral. + + .. pyvista-plot:: + :force_static: + + >>> import felupe as fem + >>> import numpy as np + >>> import pyvista as pv + >>> + >>> m = fem.Rectangle(n=2) + >>> mesh = m.copy() + >>> mesh.points[-1, 0] += 0.5 + >>> edges = fem.RegionQuadBoundary(mesh) + >>> + >>> start = fem.Field(edges, values=mesh.points).interpolate() + >>> (direction,) = edges.tangents + >>> + >>> # 3d-data required for plotting + >>> start = np.insert(start, len(start), 0, axis=0) + >>> direction = np.insert(direction, len(direction), 0, axis=0) + >>> normal = np.insert(edges.normals, len(edges.normals), 0, axis=0) + >>> + >>> plotter = pv.Plotter() + ... actor = plotter.add_arrows( + ... start.reshape(3, -1).T, + ... direction.reshape(3, -1).T, + ... show_scalar_bar=False, + ... mag=1 / 7, + ... color="red", + ... label="tangents", + ... ) + >>> actor = plotter.add_arrows( + ... start.reshape(3, -1).T, + ... normal.reshape(3, -1).T, + ... show_scalar_bar=False, + ... mag=1 / 7, + ... color="green", + ... label="normals", + ... ) + >>> actor = plotter.add_legend() + >>> mesh.plot(plotter=plotter, style="wireframe").show() + + A third example shows the standard unit vectors and the area normals, located at the + quadrature points for one face of a hexahedron. + + .. pyvista-plot:: + :force_static: + + >>> import felupe as fem + >>> import numpy as np + >>> import pyvista as pv + >>> + >>> m = fem.Cube(n=2) + >>> mesh = m.copy() + >>> mesh.points[-1, 0] += 0.5 + >>> faces = fem.RegionHexahedronBoundary(mesh, mask=m.x == m.x.max()) + >>> + >>> start = fem.Field(faces, values=mesh.points).interpolate() + >>> direction, direction_2 = faces.tangents + >>> + >>> plotter = pv.Plotter() + >>> actor = plotter.add_arrows( + ... start.reshape(3, -1).T, + ... direction.reshape(3, -1).T, + ... show_scalar_bar=False, + ... mag=1 / 7, + ... color="red", + ... label="tangents (1)", + ... ) + >>> actor = plotter.add_arrows( + ... start.reshape(3, -1).T, + ... direction_2.reshape(3, -1).T, + ... show_scalar_bar=False, + ... mag=1 / 7, + ... color="green", + ... label="tangents (2)", + ... ) + >>> actor = plotter.add_arrows( + ... start.reshape(3, -1).T, + ... faces.normals.reshape(3, -1).T, + ... show_scalar_bar=False, + ... mag=1 / 7, + ... color="blue", + ... label="normals", + ... ) + >>> plotter.add_legend() + >>> mesh.plot(plotter=plotter, style="wireframe").show() + """ def __init__( @@ -449,7 +548,7 @@ def _init_faces(self): ): dA_1 = self.dXdr[:, 0][::-1] dA_1[0] = -dA_1[0] - + dX_1 = -self.dXdr[:, 0] dX_1[0] = -dX_1[0] From 9d8718f68d7caaea1b62f00ec5d1d943864f4f36 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 28 Oct 2024 22:29:11 +0100 Subject: [PATCH 055/125] Update _templates.py --- src/felupe/region/_templates.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/felupe/region/_templates.py b/src/felupe/region/_templates.py index f06444a2..1f0daf43 100644 --- a/src/felupe/region/_templates.py +++ b/src/felupe/region/_templates.py @@ -180,6 +180,11 @@ class RegionQuadBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() + + See Also + -------- + felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an + element and a numeric integration scheme (quadrature rule). """ def __init__( @@ -228,6 +233,11 @@ class RegionQuadraticQuadBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() + + See Also + -------- + felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an + element and a numeric integration scheme (quadrature rule). """ def __init__( @@ -276,6 +286,11 @@ class RegionBiQuadraticQuadBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() + + See Also + -------- + felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an + element and a numeric integration scheme (quadrature rule). """ def __init__( @@ -373,6 +388,11 @@ class RegionHexahedronBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() + + See Also + -------- + felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an + element and a numeric integration scheme (quadrature rule). """ def __init__( @@ -453,6 +473,11 @@ class RegionQuadraticHexahedronBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() + + See Also + -------- + felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an + element and a numeric integration scheme (quadrature rule). """ def __init__( @@ -531,6 +556,11 @@ class RegionTriQuadraticHexahedronBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() + + See Also + -------- + felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an + element and a numeric integration scheme (quadrature rule). """ def __init__( From bc00b22b814d035b754253760730b05d7b12e17b Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 28 Oct 2024 22:29:55 +0100 Subject: [PATCH 056/125] Update _templates.py --- src/felupe/region/_templates.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/felupe/region/_templates.py b/src/felupe/region/_templates.py index 1f0daf43..a316fdc4 100644 --- a/src/felupe/region/_templates.py +++ b/src/felupe/region/_templates.py @@ -180,7 +180,7 @@ class RegionQuadBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() - + See Also -------- felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an @@ -233,7 +233,7 @@ class RegionQuadraticQuadBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() - + See Also -------- felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an @@ -286,7 +286,7 @@ class RegionBiQuadraticQuadBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() - + See Also -------- felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an @@ -388,7 +388,7 @@ class RegionHexahedronBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() - + See Also -------- felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an @@ -473,7 +473,7 @@ class RegionQuadraticHexahedronBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() - + See Also -------- felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an @@ -556,7 +556,7 @@ class RegionTriQuadraticHexahedronBoundary(RegionBoundary): Hessian evaluated: False >>> region.plot().show() - + See Also -------- felupe.RegionBoundary : A numeric boundary-region as a combination of a mesh, an From f9fec84540f9713abe9d1121ad620bcedb492613 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 29 Oct 2024 09:20:34 +0100 Subject: [PATCH 057/125] Generalize `math.inplane()` to non-symmetric tensors --- src/felupe/math/_tensor.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/felupe/math/_tensor.py b/src/felupe/math/_tensor.py index f59fce48..2d4cd151 100644 --- a/src/felupe/math/_tensor.py +++ b/src/felupe/math/_tensor.py @@ -1484,13 +1484,13 @@ def equivalent_von_mises(A): def inplane(A, vectors, **kwargs): - r"""Return the in-plane components of symmetric 2x2 or 3x3 tensors, where the planes - are defined by their standard unit vectors. + r"""Return the in-plane components of 2d or 3d second order tensors, where the + planes are defined by their standard unit vectors. Parameters ---------- A : ndarray of shape (N, N, ...) - Symmetric second-order tensors. + Second-order tensors. vectors : list of ndarray of shape (N, ...) List of standard unit vectors of the planes. **kwargs : dict, optional @@ -1498,6 +1498,10 @@ def inplane(A, vectors, **kwargs): Notes ----- + .. note:: + + Out-of-plane tensor components are ignored. + The first two axes of the tensor and the first axis of each vector are the tensor/vector dimensions and all remaining trailing axes are treated as batch dimensions. @@ -1511,7 +1515,7 @@ def inplane(A, vectors, **kwargs): Returns ------- ndarray of shape (N - 1, N - 1, ...) - The in-plane components of symmetric (N, N) tensors. + In-plane components. Examples -------- @@ -1528,8 +1532,4 @@ def inplane(A, vectors, **kwargs): vectors = np.array(vectors) - i, j = np.triu_indices(len(vectors)) - ij = np.zeros((len(vectors), len(vectors)), dtype=int) - ij[i, j] = ij[j, i] = np.arange(len(i), dtype=int) - - return np.einsum("ij...,ai...,aj...->a...", A, vectors[i], vectors[j], **kwargs)[ij] + return np.einsum("ij...,ai...,bj...->ab...", A, vectors, vectors, **kwargs) From ffe4c44233c31156787bbad94b70e9896d62b24f Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 29 Oct 2024 11:33:34 +0100 Subject: [PATCH 058/125] Update _boundary.py --- src/felupe/region/_boundary.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index 0e9fd384..0e62523f 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -553,6 +553,12 @@ def _init_faces(self): dX_1[0] = -dX_1[0] tangents.append(dX_1 / np.linalg.norm(dX_1, axis=0)) + + if self.ensure_3d: + tangents[0] = np.insert(tangents[0], len(tangents[0]), 0, axis=0) + other_tangent = np.zeros_like(tangents[0]) + other_tangent[2] = 1.0 + tangents.append(other_tangent) elif ( self.mesh.cell_type == "hexahedron" From ac460a9de24943e69545ec361e4ddd4b87626618 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 31 Oct 2024 14:32:42 +0100 Subject: [PATCH 059/125] Add `constitution.jax.Hyperelastic` (#876) * Add `constitution.jax.Hyperelastic` * Update test_constitution_jax.py * Update test_constitution_jax.py * Update test_constitution_jax.py * Update _hyperelastic.py --- CHANGELOG.md | 1 + docs/felupe/constitution.rst | 1 + docs/felupe/constitution/jax.rst | 21 ++ pyproject.toml | 5 +- src/felupe/constitution/__init__.py | 2 + src/felupe/constitution/jax/__init__.py | 3 + src/felupe/constitution/jax/_hyperelastic.py | 282 +++++++++++++++++++ src/felupe/region/_boundary.py | 2 +- tests/test_constitution_jax.py | 127 +++++++++ 9 files changed, 441 insertions(+), 3 deletions(-) create mode 100644 docs/felupe/constitution/jax.rst create mode 100644 src/felupe/constitution/jax/__init__.py create mode 100644 src/felupe/constitution/jax/_hyperelastic.py create mode 100644 tests/test_constitution_jax.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e046d5a..d89b05f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. The format - Add optional keyword-arguments to `math.transpose(**kwargs)` to support optional `out` and `order`-keywords. - Add the attribute `RegionBoundary.tangents`, which contains a list of tangent unit vectors. For `quad` cell-types the length of this list is one and for `hexahedron` cell-types it is of length two. - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. +- Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/docs/felupe/constitution.rst b/docs/felupe/constitution.rst index db103d84..bdeca712 100644 --- a/docs/felupe/constitution.rst +++ b/docs/felupe/constitution.rst @@ -13,6 +13,7 @@ This module provides :class:`constitutive material constitution/hyperelasticity constitution/lagrange constitution/tools + constitution/jax There are many different pre-defined constitutive material formulations available, including definitions for linear-elasticity, small-strain plasticity, hyperelasticity or pseudo-elasticity. The generation of user materials may be simplified when using frameworks for user-defined functions, like hyperelasticity (with automatic differentiation) or a small-strain based framework with state variables. However, the most general case is given by a framework with functions for the evaluation of stress and elasticity tensors in terms of the deformation gradient. diff --git a/docs/felupe/constitution/jax.rst b/docs/felupe/constitution/jax.rst new file mode 100644 index 00000000..1b80817c --- /dev/null +++ b/docs/felupe/constitution/jax.rst @@ -0,0 +1,21 @@ +.. _felupe-api-constitution-jax: + +JAX-based Materials +~~~~~~~~~~~~~~~~~~~ + +This page contains hyperelastic material model formulations with automatic differentiation using :mod:`jax`. These material model formulations are defined by a strain energy density function. + +**Frameworks** + +.. currentmodule:: felupe + +.. autosummary:: + + constitution.jax.Hyperelastic + +**Detailed API Reference** + +.. autoclass:: felupe.constitution.jax.Hyperelastic + :members: + :undoc-members: + :inherited-members: diff --git a/pyproject.toml b/pyproject.toml index d2f43251..f1bac0f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,7 @@ docs = [ "sphinx-gallery", "pypandoc", ] +constitution = ["jax"] examples = [ "contique", "imageio", @@ -81,8 +82,8 @@ progress = ["tqdm"] plot = ["matplotlib"] view = ["pyvista[jupyter]"] -test = ["felupe[io,plot]"] -all = ["felupe[io,parallel,plot,progress,view]"] +test = ["felupe[io,constitution,plot]"] +all = ["felupe[io,constitution,parallel,plot,progress,view]"] [tool.setuptools.dynamic] version = {attr = "felupe.__about__.__version__"} diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index 1fa185f3..bd04cff7 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -1,3 +1,4 @@ +from . import jax from ._base import CompositeMaterial, ConstitutiveMaterial, constitutive_material from ._kinematics import AreaChange, LineChange, VolumeChange from ._material import Material @@ -97,4 +98,5 @@ "constitutive_material", "CompositeMaterial", "Volumetric", + "jax", ] diff --git a/src/felupe/constitution/jax/__init__.py b/src/felupe/constitution/jax/__init__.py new file mode 100644 index 00000000..2d63f424 --- /dev/null +++ b/src/felupe/constitution/jax/__init__.py @@ -0,0 +1,3 @@ +from ._hyperelastic import Hyperelastic, vmap + +__all__ = ["Hyperelastic", "vmap"] diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py new file mode 100644 index 00000000..b0d79573 --- /dev/null +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" + +import inspect +import warnings +from functools import wraps + +import numpy as np + +from .._material import Material + + +def vmap(fun, in_axes=0, out_axes=0, **kwargs): + """Vectorizing map. Creates a function which maps ``fun`` over argument axes. This + decorator treats all non-specified arguments and keyword-arguments as static. + + See Also + -------- + jax.vmap : Vectorizing map. Creates a function which maps ``fun`` over argument + axes. + """ + + import jax + + @wraps(fun) + def vmap_with_static_kwargs(*args, **keywordargs): + # sorted list of all parameter keys, including kwargs with default values + sig = inspect.signature(fun) + keys = [ + key + for key, value in sig.parameters.items() + if not (key in ["args", "kwargs"] and value.default == inspect._empty) + ] + + if not ( + "kwargs" in sig.parameters.keys() + and sig.parameters["kwargs"].default == inspect._empty + ): + # check if unexpected keyword-argument is given + for key in keywordargs.keys(): + if key not in keys: + raise TypeError( + f"{fun.__name__}() got an unexpected keyword argument '{key}'" + ) + + # dict with default values for all parameters + parameters = dict( + [(key, value.default) for key, value in sig.parameters.items()] + ) + + # merge dict of default values with custom keyword arguments + items = {**parameters, **keywordargs} + + # create sorted list of values of keyword-arguments, including default kwargs + keyword_args = [items[key] for key in keys[len(args) :]] + + # don't map non-given arguments and keyword-arguments + if not hasattr(in_axes, "__len__"): + in_axes_tuple = (in_axes,) + else: + in_axes_tuple = in_axes + + static_argnums = len(args) + len(keyword_args) - len(in_axes_tuple) + in_axes_new = (*in_axes_tuple, *([None] * static_argnums)) + + vfun = jax.vmap(fun, in_axes=in_axes_new, out_axes=out_axes, **kwargs) + + return vfun(*args, *keyword_args) + + return vmap_with_static_kwargs + + +def vmap2(fun, in_axes=0, out_axes=0, **kwargs): + "Nested vectorizing map." + return vmap( + vmap(fun, in_axes=in_axes, out_axes=out_axes, **kwargs), + in_axes=in_axes, + out_axes=out_axes, + **kwargs, + ) + + +def total_lagrange(fun): + @wraps(fun) + def evaluate(F, *args, **kwargs): + C = F.T @ F + return fun(C, *args, **kwargs) + + return evaluate + + +class Hyperelastic(Material): + r"""A hyperelastic material definition with a given function for the strain energy + density function per unit undeformed volume with Automatic Differentiation provided + by :mod:`jax`. + + Parameters + ---------- + fun : callable + A strain energy density function in terms of the right Cauchy-Green deformation + tensor :math:`\boldsymbol{C}`. Function signature must be + ``fun = lambda C, **kwargs: psi`` for functions without state variables and + ``fun = lambda C, statevars, **kwargs: [psi, statevars_new]`` for functions + with state variables. It is important to only use differentiable math-functions + from :mod:`jax`. + nstatevars : int, optional + Number of state variables (default is 0). + jit : bool, optional + A flag to invoke just-in-time compilation (default is True). + parallel : bool, optional + A flag to invoke threaded strain energy density function evaluations (default + is False). Not implemented. + **kwargs : dict, optional + Optional keyword-arguments for the strain energy density function. + + Notes + ----- + The strain energy density function :math:`\psi` must be given in terms of the right + Cauchy-Green deformation tensor + :math:`\boldsymbol{C} = \boldsymbol{F}^T \boldsymbol{F}`. + + .. warning:: + It is important to only use differentiable math-functions from :mod:`jax`! + + Take this minimal code-block as template + + .. math:: + + \psi = \psi(\boldsymbol{C}) + + .. code-block:: + + import felupe as fem + import jax.numpy as jnp + + def neo_hooke(C, mu): + "Strain energy function of the Neo-Hookean material formulation." + return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) + + umat = fem.constitution.jax.Hyperelastic(neo_hooke, mu=1) + + and this code-block for material formulations with state variables. + + .. math:: + + \psi = \psi(\boldsymbol{C}, \boldsymbol{\zeta}) + + .. code-block:: + + import felupe as fem + import jax.numpy as np + + def viscoelastic(C, Cin, mu, eta, dtime): + "Finite strain viscoelastic material formulation." + + # unimodular part of the right Cauchy-Green deformation tensor + Cu = jnp.linalg.det(C) ** (-1 / 3) * C + + # update of state variables by evolution equation + Ci = Cin.reshape(3, 3) + mu / eta * dtime * Cu + Ci = jnp.linalg.det(Ci) ** (-1 / 3) * Ci + + # first invariant of elastic part of right Cauchy-Green deformation tensor + I1 = jnp.trace(Cu @ jnp.linalg.inv(Ci)) + + # strain energy function and state variable + return mu / 2 * (I1 - 3), Ci.ravel() + + umat = fem.constitution.jax.Hyperelastic( + viscoelastic, mu=1, eta=1, dtime=1, nstatevars=9 + ) + + .. note:: + See the `documentation of JAX `_ for further + details. JAX uses single-precision (32bit) data types by default. This requires + to relax the tolerance of :func:`~felupe.newtonrhapson` to ``tol=1e-4``. If + required, JAX may be enforced to use double-precision at startup with + ``jax.config.update("jax_enable_x64", True)``. + + Examples + -------- + View force-stretch curves on elementary incompressible deformations. + + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> import jax.numpy as jnp + >>> + >>> def neo_hooke(C, mu): + ... "Strain energy function of the Neo-Hookean material formulation." + ... return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) + >>> + >>> umat = fem.constitution.jax.Hyperelastic(neo_hooke, mu=1) + >>> ax = umat.plot(incompressible=True) + + .. pyvista-plot:: + :include-source: False + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> fig = ax.get_figure() + >>> chart = pv.ChartMPL(fig) + >>> chart.show() + + """ + + def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): + import jax + + has_aux = nstatevars > 0 + self.fun = total_lagrange(fun) + + if parallel: + warnings.warn("Parallel execution is not implemented.") + + keyword_args = kwargs + if hasattr(fun, "kwargs"): + keyword_args = {**fun.kwargs, **keyword_args} + + super().__init__( + stress=self._stress, + elasticity=self._elasticity, + nstatevars=nstatevars, + **keyword_args, + ) + + kwargs_jax = dict(in_axes=-1, out_axes=-1) + if nstatevars > 0: + kwargs_jax["in_axes"] = (-1, -1) + + self._grad = vmap2(jax.grad(self.fun, has_aux=has_aux), **kwargs_jax) + self._hess = vmap2( + jax.jacfwd(jax.grad(self.fun, has_aux=has_aux), has_aux=has_aux), + **kwargs_jax, + ) + + if jit: + self._grad = jax.jit(self._grad) + self._hess = jax.jit(self._hess) + + def _stress(self, x, **kwargs): + if self.nstatevars > 0: + statevars = x[1] + + F = x[0] + if self.nstatevars > 0: + dWdF, statevars_new = self._grad(F, statevars, **kwargs) + statevars_new = np.array(statevars_new) + else: + dWdF = self._grad(F, **kwargs) + statevars_new = None + + return [np.array(dWdF), statevars_new] + + def _elasticity(self, x, **kwargs): + if self.nstatevars > 0: + statevars = x[1] + + F = x[0] + if self.nstatevars > 0: + d2WdFdF, statevars_new = self._hess(F, statevars, **kwargs) + else: + d2WdFdF = self._hess(F, **kwargs) + return [np.array(d2WdFdF)] diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index 0e62523f..39622e72 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -553,7 +553,7 @@ def _init_faces(self): dX_1[0] = -dX_1[0] tangents.append(dX_1 / np.linalg.norm(dX_1, axis=0)) - + if self.ensure_3d: tangents[0] = np.insert(tangents[0], len(tangents[0]), 0, axis=0) other_tangent = np.zeros_like(tangents[0]) diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py new file mode 100644 index 00000000..c0310e5e --- /dev/null +++ b/tests/test_constitution_jax.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +""" + _______ _______ ___ __ __ _______ _______ +| || || | | | | || || | +| ___|| ___|| | | | | || _ || ___| +| |___ | |___ | | | |_| || |_| || |___ +| ___|| ___|| |___ | || ___|| ___| +| | | |___ | || || | | |___ +|___| |_______||_______||_______||___| |_______| + +This file is part of felupe. + +Felupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Felupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Felupe. If not, see . + +""" +import numpy as np +import pytest + +import felupe as fem + + +def test_vmap(): + try: + + def f(x, a=1.0): + return x + + def g(x, y, a=1.0, **kwargs): + return x + + vf = fem.constitution.jax.vmap(f) + vg = fem.constitution.jax.vmap(g) + + x = np.eye(3).reshape(1, 3, 3) * np.ones((10, 1, 1)) + + z = vf(x, a=1.0) + + assert np.allclose(z, vf(x, 1.0)) + assert np.allclose(z, vf(a=1.0, x=x)) + + with pytest.raises(TypeError): + vf(x, a=1.0, b=2.0) + + # does not raise an error because of `g(..., **kwargs)` + assert np.allclose(z, vg(x, a=1.0, b=2.0)) + + except ModuleNotFoundError: + pass + + +def test_hyperelastic_jax(): + try: + import jax.numpy as jnp + + def W(C, C10, K): + I3 = jnp.linalg.det(C) + J = jnp.sqrt(I3) + I1 = I3 ** (-1 / 3) * jnp.trace(C) + return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2 + + umat = fem.constitution.jax.Hyperelastic(W, C10=0.5, K=2.0, parallel=True) + umat = fem.constitution.jax.Hyperelastic(W, C10=0.5, K=2.0, jit=True) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + solid = fem.SolidBody(umat=umat, field=field) + + move = fem.math.linsteps([0, 1], num=3) + ramp = {boundaries["move"]: move} + step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) + job = fem.Job(steps=[step]) + job.evaluate(tol=1e-4) + + except ModuleNotFoundError: + pass + + +def test_hyperelastic_jax_statevars(): + try: + import jax.numpy as jnp + + def W(C, statevars, C10, K): + I3 = jnp.linalg.det(C) + J = jnp.sqrt(I3) + I1 = I3 ** (-1 / 3) * jnp.trace(C) + statevars_new = I1 + return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2, statevars_new + + W.kwargs = {"C10": 0.5} + + umat = fem.constitution.jax.Hyperelastic( + W, C10=0.5, K=2.0, nstatevars=1, jit=True + ) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + solid = fem.SolidBody(umat=umat, field=field) + + move = fem.math.linsteps([0, 1], num=3) + ramp = {boundaries["move"]: move} + step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) + job = fem.Job(steps=[step]) + job.evaluate(tol=1e-4) + + except ModuleNotFoundError: + pass + + +if __name__ == "__main__": + test_vmap() + test_hyperelastic_jax() + test_hyperelastic_jax_statevars() From 4d86eeca37d9a5ac65545bd40f68ea3ce1093567 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 1 Nov 2024 23:37:08 +0100 Subject: [PATCH 060/125] Create `constitution/autodiff/[backend]` (#878) --- docs/felupe/constitution/jax.rst | 4 +-- src/felupe/constitution/__init__.py | 18 ++++-------- src/felupe/constitution/autodiff/__init__.py | 10 +++++++ .../{ => autodiff}/jax/__init__.py | 0 .../{ => autodiff}/jax/_hyperelastic.py | 8 +++-- .../autodiff/tensortrax/__init__.py | 13 +++++++++ .../tensortrax}/_hyperelastic.py | 4 +-- .../tensortrax/_material.py} | 4 +-- .../tensortrax}/_total_lagrange.py | 0 .../tensortrax}/_updated_lagrange.py | 0 .../autodiff/tensortrax/models/__init__.py | 3 ++ .../models/hyperelastic}/__init__.py | 0 .../models/hyperelastic}/_alexander.py | 0 .../hyperelastic}/_anssari_benam_bucchi.py | 0 .../models/hyperelastic}/_arruda_boyce.py | 0 .../models/hyperelastic}/_extended_tube.py | 0 .../_finite_strain_viscoelastic.py | 0 .../models/hyperelastic}/_helpers.py | 0 .../models/hyperelastic}/_lopez_pamies.py | 0 .../hyperelastic}/_miehe_goektepe_lulei.py | 0 .../models/hyperelastic}/_mooney_rivlin.py | 0 .../_morph_representative_directions.py | 5 ++-- .../models/hyperelastic}/_neo_hooke.py | 0 .../tensortrax/models/hyperelastic}/_ogden.py | 0 .../models/hyperelastic}/_ogden_roxburgh.py | 0 .../hyperelastic}/_saint_venant_kirchhoff.py | 0 .../hyperelastic}/_third_order_deformation.py | 0 .../models/hyperelastic}/_van_der_waals.py | 0 .../tensortrax/models/hyperelastic}/_yeoh.py | 0 .../hyperelastic}/microsphere/__init__.py | 0 .../hyperelastic}/microsphere/_chain.py | 0 .../microsphere/_framework_affine.py | 2 +- .../microsphere/_framework_nonaffine.py | 2 +- .../tensortrax/models/lagrange}/__init__.py | 0 .../tensortrax/models/lagrange}/_morph.py | 2 +- .../_morph_representative_directions.py | 0 .../models/lagrange}/_morph_uniaxial.py | 0 .../models/lagrange}/microsphere/__init__.py | 0 .../microsphere/_framework_affine.py | 4 +-- .../constitution/hyperelasticity/__init__.py | 29 ++++++++++--------- .../{core => }/_neo_hooke_compressible.py | 4 +-- .../_neo_hooke_nearly_incompressible.py | 4 +-- .../{core => }/_ogden_roxburgh.py | 4 +-- .../hyperelasticity/{core => }/_volumetric.py | 0 .../hyperelasticity/core/__init__.py | 20 ------------- src/felupe/constitution/lagrange/__init__.py | 16 ---------- .../_linear_elastic_large_strain.py | 2 +- tests/test_constitution.py | 3 +- tests/test_constitution_jax.py | 12 ++++---- 49 files changed, 83 insertions(+), 90 deletions(-) create mode 100644 src/felupe/constitution/autodiff/__init__.py rename src/felupe/constitution/{ => autodiff}/jax/__init__.py (100%) rename src/felupe/constitution/{ => autodiff}/jax/_hyperelastic.py (97%) create mode 100644 src/felupe/constitution/autodiff/tensortrax/__init__.py rename src/felupe/constitution/{hyperelasticity => autodiff/tensortrax}/_hyperelastic.py (98%) rename src/felupe/constitution/{lagrange/_material_ad.py => autodiff/tensortrax/_material.py} (98%) rename src/felupe/constitution/{lagrange => autodiff/tensortrax}/_total_lagrange.py (100%) rename src/felupe/constitution/{lagrange => autodiff/tensortrax}/_updated_lagrange.py (100%) create mode 100644 src/felupe/constitution/autodiff/tensortrax/models/__init__.py rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/__init__.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_alexander.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_anssari_benam_bucchi.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_arruda_boyce.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_extended_tube.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_finite_strain_viscoelastic.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_helpers.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_lopez_pamies.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_miehe_goektepe_lulei.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_mooney_rivlin.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_morph_representative_directions.py (95%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_neo_hooke.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_ogden.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_ogden_roxburgh.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_saint_venant_kirchhoff.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_third_order_deformation.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_van_der_waals.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/_yeoh.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/microsphere/__init__.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/microsphere/_chain.py (100%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/microsphere/_framework_affine.py (97%) rename src/felupe/constitution/{hyperelasticity/models => autodiff/tensortrax/models/hyperelastic}/microsphere/_framework_nonaffine.py (95%) rename src/felupe/constitution/{lagrange/models => autodiff/tensortrax/models/lagrange}/__init__.py (100%) rename src/felupe/constitution/{lagrange/models => autodiff/tensortrax/models/lagrange}/_morph.py (99%) rename src/felupe/constitution/{lagrange/models => autodiff/tensortrax/models/lagrange}/_morph_representative_directions.py (100%) rename src/felupe/constitution/{lagrange/models => autodiff/tensortrax/models/lagrange}/_morph_uniaxial.py (100%) rename src/felupe/constitution/{lagrange/models => autodiff/tensortrax/models/lagrange}/microsphere/__init__.py (100%) rename src/felupe/constitution/{lagrange/models => autodiff/tensortrax/models/lagrange}/microsphere/_framework_affine.py (89%) rename src/felupe/constitution/hyperelasticity/{core => }/_neo_hooke_compressible.py (97%) rename src/felupe/constitution/hyperelasticity/{core => }/_neo_hooke_nearly_incompressible.py (98%) rename src/felupe/constitution/hyperelasticity/{core => }/_ogden_roxburgh.py (98%) rename src/felupe/constitution/hyperelasticity/{core => }/_volumetric.py (100%) delete mode 100644 src/felupe/constitution/hyperelasticity/core/__init__.py delete mode 100644 src/felupe/constitution/lagrange/__init__.py diff --git a/docs/felupe/constitution/jax.rst b/docs/felupe/constitution/jax.rst index 1b80817c..5dcf13c7 100644 --- a/docs/felupe/constitution/jax.rst +++ b/docs/felupe/constitution/jax.rst @@ -11,11 +11,11 @@ This page contains hyperelastic material model formulations with automatic diffe .. autosummary:: - constitution.jax.Hyperelastic + constitution.autodiff.jax.Hyperelastic **Detailed API Reference** -.. autoclass:: felupe.constitution.jax.Hyperelastic +.. autoclass:: felupe.constitution.autodiff.jax.Hyperelastic :members: :undoc-members: :inherited-members: diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index bd04cff7..fa97ca70 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -1,17 +1,12 @@ -from . import jax from ._base import CompositeMaterial, ConstitutiveMaterial, constitutive_material from ._kinematics import AreaChange, LineChange, VolumeChange from ._material import Material from ._mixed import NearlyIncompressible, ThreeFieldVariation from ._view import ViewMaterial, ViewMaterialIncompressible -from .hyperelasticity import Hyperelastic -from .hyperelasticity.core import ( - NeoHooke, - NeoHookeCompressible, - OgdenRoxburgh, - Volumetric, -) -from .hyperelasticity.models import ( +from .autodiff.tensortrax import Hyperelastic +from .autodiff.tensortrax import Material as MaterialAD +from .autodiff.tensortrax import total_lagrange, updated_lagrange +from .autodiff.tensortrax.models.hyperelastic import ( alexander, anssari_benam_bucchi, arruda_boyce, @@ -29,8 +24,8 @@ van_der_waals, yeoh, ) -from .lagrange import MaterialAD, total_lagrange, updated_lagrange -from .lagrange.models import morph, morph_representative_directions +from .autodiff.tensortrax.models.lagrange import morph, morph_representative_directions +from .hyperelasticity import NeoHooke, NeoHookeCompressible, OgdenRoxburgh, Volumetric from .linear_elasticity import ( LinearElastic, LinearElasticLargeStrain, @@ -98,5 +93,4 @@ "constitutive_material", "CompositeMaterial", "Volumetric", - "jax", ] diff --git a/src/felupe/constitution/autodiff/__init__.py b/src/felupe/constitution/autodiff/__init__.py new file mode 100644 index 00000000..844e505e --- /dev/null +++ b/src/felupe/constitution/autodiff/__init__.py @@ -0,0 +1,10 @@ +""" +felupe.constitution.autodiff +============================ +This module contains constitutive material classes and models for several backends. The +primary used backend in FElupe is based on :mod:`tensortrax`. +""" + +from . import jax, tensortrax + +__all__ = ["jax", "tensortrax"] diff --git a/src/felupe/constitution/jax/__init__.py b/src/felupe/constitution/autodiff/jax/__init__.py similarity index 100% rename from src/felupe/constitution/jax/__init__.py rename to src/felupe/constitution/autodiff/jax/__init__.py diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/autodiff/jax/_hyperelastic.py similarity index 97% rename from src/felupe/constitution/jax/_hyperelastic.py rename to src/felupe/constitution/autodiff/jax/_hyperelastic.py index b0d79573..77b4052e 100644 --- a/src/felupe/constitution/jax/_hyperelastic.py +++ b/src/felupe/constitution/autodiff/jax/_hyperelastic.py @@ -22,7 +22,7 @@ import numpy as np -from .._material import Material +from ..._material import Material def vmap(fun, in_axes=0, out_axes=0, **kwargs): @@ -96,9 +96,13 @@ def vmap2(fun, in_axes=0, out_axes=0, **kwargs): def total_lagrange(fun): + import jax.numpy as jnp + @wraps(fun) def evaluate(F, *args, **kwargs): - C = F.T @ F + i, j = jnp.triu_indices(3) + C_triu = jnp.einsum("ia,ia->a", F[:, i], F[:, j]) + C = C_triu[jnp.array([[0, 1, 2], [1, 3, 4], [2, 4, 5]])] return fun(C, *args, **kwargs) return evaluate diff --git a/src/felupe/constitution/autodiff/tensortrax/__init__.py b/src/felupe/constitution/autodiff/tensortrax/__init__.py new file mode 100644 index 00000000..c95b71e6 --- /dev/null +++ b/src/felupe/constitution/autodiff/tensortrax/__init__.py @@ -0,0 +1,13 @@ +from . import models +from ._hyperelastic import Hyperelastic +from ._material import Material +from ._total_lagrange import total_lagrange +from ._updated_lagrange import updated_lagrange + +__all__ = [ + "Hyperelastic", + "models", + "total_lagrange", + "updated_lagrange", + "Material", +] diff --git a/src/felupe/constitution/hyperelasticity/_hyperelastic.py b/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py similarity index 98% rename from src/felupe/constitution/hyperelasticity/_hyperelastic.py rename to src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py index 4c03076d..a39ecd2c 100644 --- a/src/felupe/constitution/hyperelasticity/_hyperelastic.py +++ b/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py @@ -19,8 +19,8 @@ import numpy as np import tensortrax as tr -from ...math import cdya_ik, dot, transpose -from .._material import Material +from ....math import cdya_ik, dot, transpose +from ..._material import Material class Hyperelastic(Material): diff --git a/src/felupe/constitution/lagrange/_material_ad.py b/src/felupe/constitution/autodiff/tensortrax/_material.py similarity index 98% rename from src/felupe/constitution/lagrange/_material_ad.py rename to src/felupe/constitution/autodiff/tensortrax/_material.py index 21b8add2..41a78f3d 100644 --- a/src/felupe/constitution/lagrange/_material_ad.py +++ b/src/felupe/constitution/autodiff/tensortrax/_material.py @@ -19,10 +19,10 @@ import numpy as np import tensortrax as tr -from .._material import Material +from ..._material import Material as MaterialDefault -class MaterialAD(Material): +class Material(MaterialDefault): r"""A material definition with a given function for the partial derivative of the strain energy function w.r.t. the deformation gradient tensor with Automatic Differentiation provided by `tensortrax `_. diff --git a/src/felupe/constitution/lagrange/_total_lagrange.py b/src/felupe/constitution/autodiff/tensortrax/_total_lagrange.py similarity index 100% rename from src/felupe/constitution/lagrange/_total_lagrange.py rename to src/felupe/constitution/autodiff/tensortrax/_total_lagrange.py diff --git a/src/felupe/constitution/lagrange/_updated_lagrange.py b/src/felupe/constitution/autodiff/tensortrax/_updated_lagrange.py similarity index 100% rename from src/felupe/constitution/lagrange/_updated_lagrange.py rename to src/felupe/constitution/autodiff/tensortrax/_updated_lagrange.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/__init__.py b/src/felupe/constitution/autodiff/tensortrax/models/__init__.py new file mode 100644 index 00000000..b317792b --- /dev/null +++ b/src/felupe/constitution/autodiff/tensortrax/models/__init__.py @@ -0,0 +1,3 @@ +from . import hyperelastic, lagrange + +__all__ = ["hyperelastic", "lagrange"] diff --git a/src/felupe/constitution/hyperelasticity/models/__init__.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/__init__.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/__init__.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/__init__.py diff --git a/src/felupe/constitution/hyperelasticity/models/_alexander.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_alexander.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_alexander.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_alexander.py diff --git a/src/felupe/constitution/hyperelasticity/models/_anssari_benam_bucchi.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_anssari_benam_bucchi.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py diff --git a/src/felupe/constitution/hyperelasticity/models/_arruda_boyce.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_arruda_boyce.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_arruda_boyce.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_arruda_boyce.py diff --git a/src/felupe/constitution/hyperelasticity/models/_extended_tube.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_extended_tube.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_extended_tube.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_extended_tube.py diff --git a/src/felupe/constitution/hyperelasticity/models/_finite_strain_viscoelastic.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_finite_strain_viscoelastic.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py diff --git a/src/felupe/constitution/hyperelasticity/models/_helpers.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_helpers.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_helpers.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_helpers.py diff --git a/src/felupe/constitution/hyperelasticity/models/_lopez_pamies.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_lopez_pamies.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_lopez_pamies.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_lopez_pamies.py diff --git a/src/felupe/constitution/hyperelasticity/models/_miehe_goektepe_lulei.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_miehe_goektepe_lulei.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py diff --git a/src/felupe/constitution/hyperelasticity/models/_mooney_rivlin.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_mooney_rivlin.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_mooney_rivlin.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_mooney_rivlin.py diff --git a/src/felupe/constitution/hyperelasticity/models/_morph_representative_directions.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_morph_representative_directions.py similarity index 95% rename from src/felupe/constitution/hyperelasticity/models/_morph_representative_directions.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_morph_representative_directions.py index e1988149..064dfc8b 100644 --- a/src/felupe/constitution/hyperelasticity/models/_morph_representative_directions.py +++ b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_morph_representative_directions.py @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with FElupe. If not, see . """ -from ...lagrange.models import morph_uniaxial +from ..lagrange import morph_uniaxial from .microsphere import affine_stretch_statevars @@ -43,9 +43,10 @@ def morph_representative_directions(C, statevars, p, ε=1e-8): :context: >>> import felupe as fem + >>> import felupe.constitution.autodiff.tensortrax.models as models >>> >>> umat = fem.Hyperelastic( - ... fem.constitution.hyperelasticity.models.morph_representative_directions, + ... models.hyperelastic.morph_representative_directions, ... p=[0.011, 0.408, 0.421, 6.85, 0.0056, 5.54, 5.84, 0.117], ... nstatevars=84, ... ) diff --git a/src/felupe/constitution/hyperelasticity/models/_neo_hooke.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_neo_hooke.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_neo_hooke.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_neo_hooke.py diff --git a/src/felupe/constitution/hyperelasticity/models/_ogden.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_ogden.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden.py diff --git a/src/felupe/constitution/hyperelasticity/models/_ogden_roxburgh.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden_roxburgh.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_ogden_roxburgh.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden_roxburgh.py diff --git a/src/felupe/constitution/hyperelasticity/models/_saint_venant_kirchhoff.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_saint_venant_kirchhoff.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py diff --git a/src/felupe/constitution/hyperelasticity/models/_third_order_deformation.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_third_order_deformation.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_third_order_deformation.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_third_order_deformation.py diff --git a/src/felupe/constitution/hyperelasticity/models/_van_der_waals.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_van_der_waals.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_van_der_waals.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_van_der_waals.py diff --git a/src/felupe/constitution/hyperelasticity/models/_yeoh.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_yeoh.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/_yeoh.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_yeoh.py diff --git a/src/felupe/constitution/hyperelasticity/models/microsphere/__init__.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/__init__.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/microsphere/__init__.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/__init__.py diff --git a/src/felupe/constitution/hyperelasticity/models/microsphere/_chain.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_chain.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/models/microsphere/_chain.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_chain.py diff --git a/src/felupe/constitution/hyperelasticity/models/microsphere/_framework_affine.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_affine.py similarity index 97% rename from src/felupe/constitution/hyperelasticity/models/microsphere/_framework_affine.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_affine.py index 1753cbc9..ae3053f4 100644 --- a/src/felupe/constitution/hyperelasticity/models/microsphere/_framework_affine.py +++ b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_affine.py @@ -1,7 +1,7 @@ from tensortrax.math import einsum, sqrt from tensortrax.math.linalg import det, inv -from .....quadrature import BazantOh +from .......quadrature import BazantOh def affine_stretch(C, f, kwargs, quadrature=BazantOh(n=21)): diff --git a/src/felupe/constitution/hyperelasticity/models/microsphere/_framework_nonaffine.py b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py similarity index 95% rename from src/felupe/constitution/hyperelasticity/models/microsphere/_framework_nonaffine.py rename to src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py index b6f9dfd3..7fd122e6 100644 --- a/src/felupe/constitution/hyperelasticity/models/microsphere/_framework_nonaffine.py +++ b/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py @@ -1,7 +1,7 @@ from tensortrax.math import einsum, sqrt from tensortrax.math.linalg import det, inv -from .....quadrature import BazantOh +from .......quadrature import BazantOh def nonaffine_stretch(C, p, f, kwargs, quadrature=BazantOh(n=21)): diff --git a/src/felupe/constitution/lagrange/models/__init__.py b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/__init__.py similarity index 100% rename from src/felupe/constitution/lagrange/models/__init__.py rename to src/felupe/constitution/autodiff/tensortrax/models/lagrange/__init__.py diff --git a/src/felupe/constitution/lagrange/models/_morph.py b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph.py similarity index 99% rename from src/felupe/constitution/lagrange/models/_morph.py rename to src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph.py index e8262a90..b17250b0 100644 --- a/src/felupe/constitution/lagrange/models/_morph.py +++ b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph.py @@ -19,7 +19,7 @@ from tensortrax.math.linalg import det, eigvalsh, expm, inv from tensortrax.math.special import dev, from_triu_1d, sym, triu_1d, try_stack -from .._total_lagrange import total_lagrange +from ..._total_lagrange import total_lagrange @total_lagrange diff --git a/src/felupe/constitution/lagrange/models/_morph_representative_directions.py b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_representative_directions.py similarity index 100% rename from src/felupe/constitution/lagrange/models/_morph_representative_directions.py rename to src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_representative_directions.py diff --git a/src/felupe/constitution/lagrange/models/_morph_uniaxial.py b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_uniaxial.py similarity index 100% rename from src/felupe/constitution/lagrange/models/_morph_uniaxial.py rename to src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_uniaxial.py diff --git a/src/felupe/constitution/lagrange/models/microsphere/__init__.py b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/__init__.py similarity index 100% rename from src/felupe/constitution/lagrange/models/microsphere/__init__.py rename to src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/__init__.py diff --git a/src/felupe/constitution/lagrange/models/microsphere/_framework_affine.py b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/_framework_affine.py similarity index 89% rename from src/felupe/constitution/lagrange/models/microsphere/_framework_affine.py rename to src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/_framework_affine.py index 8cb1d524..b9ae90bb 100644 --- a/src/felupe/constitution/lagrange/models/microsphere/_framework_affine.py +++ b/src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/_framework_affine.py @@ -1,8 +1,8 @@ from tensortrax.math import einsum, sqrt, trace from tensortrax.math.linalg import det, inv -from .....quadrature import BazantOh -from ..._total_lagrange import total_lagrange +from .......quadrature import BazantOh +from ...._total_lagrange import total_lagrange @total_lagrange diff --git a/src/felupe/constitution/hyperelasticity/__init__.py b/src/felupe/constitution/hyperelasticity/__init__.py index a1e516dc..9a686e02 100644 --- a/src/felupe/constitution/hyperelasticity/__init__.py +++ b/src/felupe/constitution/hyperelasticity/__init__.py @@ -1,19 +1,20 @@ """ -Hyperelastic material model formulations. - -This module contains automatic-differentiation (ad) and non-ad based hyperelastic -material model formulations: - -a) :class:`~felupe.Hyperelastic` to be used with strain energy density functions for - material model formulations from :mod:`constitution.hyperelasticity.models` which are - implemented with automatic differentiation using - `tensortrax `_ and - -b) manually-defined hyperelastic material model formulations (no automatic - differentation) :mod:`constitution.hyperelasticity.core`. +constitution.hyperelasticity +============================ +This module contains manually (no automatic differentiation) defined isotropic +hyperelastic constitutive material formulations with gradients and hessians of strain +energy density functions. For more sophisticated material model formulations see +:class:`~felupe.Hyperelastic`. """ -from ._hyperelastic import Hyperelastic + +from ._neo_hooke_compressible import NeoHookeCompressible +from ._neo_hooke_nearly_incompressible import NeoHooke +from ._ogden_roxburgh import OgdenRoxburgh +from ._volumetric import Volumetric __all__ = [ - "Hyperelastic", + "NeoHooke", + "NeoHookeCompressible", + "OgdenRoxburgh", + "Volumetric", ] diff --git a/src/felupe/constitution/hyperelasticity/core/_neo_hooke_compressible.py b/src/felupe/constitution/hyperelasticity/_neo_hooke_compressible.py similarity index 97% rename from src/felupe/constitution/hyperelasticity/core/_neo_hooke_compressible.py rename to src/felupe/constitution/hyperelasticity/_neo_hooke_compressible.py index 26b0bf08..5f84971d 100644 --- a/src/felupe/constitution/hyperelasticity/core/_neo_hooke_compressible.py +++ b/src/felupe/constitution/hyperelasticity/_neo_hooke_compressible.py @@ -18,8 +18,8 @@ import numpy as np -from ....math import cdya_ik, cdya_il, det, dot, dya, identity, inv, trace, transpose -from ..._base import ConstitutiveMaterial +from ...math import cdya_ik, cdya_il, det, dot, dya, identity, inv, trace, transpose +from .._base import ConstitutiveMaterial class NeoHookeCompressible(ConstitutiveMaterial): diff --git a/src/felupe/constitution/hyperelasticity/core/_neo_hooke_nearly_incompressible.py b/src/felupe/constitution/hyperelasticity/_neo_hooke_nearly_incompressible.py similarity index 98% rename from src/felupe/constitution/hyperelasticity/core/_neo_hooke_nearly_incompressible.py rename to src/felupe/constitution/hyperelasticity/_neo_hooke_nearly_incompressible.py index 8b0a739a..3e0bdca5 100644 --- a/src/felupe/constitution/hyperelasticity/core/_neo_hooke_nearly_incompressible.py +++ b/src/felupe/constitution/hyperelasticity/_neo_hooke_nearly_incompressible.py @@ -18,8 +18,8 @@ import numpy as np -from ....math import cdya_ik, ddot, det, dot, dya, identity, inv, trace, transpose -from ..._base import ConstitutiveMaterial +from ...math import cdya_ik, ddot, det, dot, dya, identity, inv, trace, transpose +from .._base import ConstitutiveMaterial class NeoHooke(ConstitutiveMaterial): diff --git a/src/felupe/constitution/hyperelasticity/core/_ogden_roxburgh.py b/src/felupe/constitution/hyperelasticity/_ogden_roxburgh.py similarity index 98% rename from src/felupe/constitution/hyperelasticity/core/_ogden_roxburgh.py rename to src/felupe/constitution/hyperelasticity/_ogden_roxburgh.py index 1ad8781a..9fcefd02 100644 --- a/src/felupe/constitution/hyperelasticity/core/_ogden_roxburgh.py +++ b/src/felupe/constitution/hyperelasticity/_ogden_roxburgh.py @@ -19,8 +19,8 @@ import numpy as np from scipy.special import erf -from ....math import dya -from ..._base import ConstitutiveMaterial +from ...math import dya +from .._base import ConstitutiveMaterial class OgdenRoxburgh(ConstitutiveMaterial): diff --git a/src/felupe/constitution/hyperelasticity/core/_volumetric.py b/src/felupe/constitution/hyperelasticity/_volumetric.py similarity index 100% rename from src/felupe/constitution/hyperelasticity/core/_volumetric.py rename to src/felupe/constitution/hyperelasticity/_volumetric.py diff --git a/src/felupe/constitution/hyperelasticity/core/__init__.py b/src/felupe/constitution/hyperelasticity/core/__init__.py deleted file mode 100644 index 6d03c8ff..00000000 --- a/src/felupe/constitution/hyperelasticity/core/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -constitution.hyperelasticity.core -================================= -This module contains manually (no automatic differentiation) defined isotropic -hyperelastic constitutive material formulations with gradients and hessians of strain -energy density functions. For more sophisticated material model formulations see -:class:`~felupe.Hyperelastic`. -""" - -from ._neo_hooke_compressible import NeoHookeCompressible -from ._neo_hooke_nearly_incompressible import NeoHooke -from ._ogden_roxburgh import OgdenRoxburgh -from ._volumetric import Volumetric - -__all__ = [ - "NeoHooke", - "NeoHookeCompressible", - "OgdenRoxburgh", - "Volumetric", -] diff --git a/src/felupe/constitution/lagrange/__init__.py b/src/felupe/constitution/lagrange/__init__.py deleted file mode 100644 index f72e200e..00000000 --- a/src/felupe/constitution/lagrange/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -Total Lagrange and Updated Lagrange material model formulations. - -This module contains automatic-differentiation (ad) material model formulations which -have to be defined by the first Piola-Kirchhoff stress tensor in terms of the -deformation gradient. Total Lagrange and Updated Lagrange formulations are available -via function decorators. -""" -from ._material_ad import MaterialAD -from ._total_lagrange import total_lagrange -from ._updated_lagrange import updated_lagrange - -__all__ = [ - "total_lagrange", - "updated_lagrange", -] diff --git a/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py b/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py index beae898e..a7b80ef8 100644 --- a/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py +++ b/src/felupe/constitution/linear_elasticity/_linear_elastic_large_strain.py @@ -19,7 +19,7 @@ import numpy as np from .._base import ConstitutiveMaterial -from ..hyperelasticity.core import NeoHookeCompressible +from ..hyperelasticity import NeoHookeCompressible from ._lame_converter import lame_converter diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 660dab08..94f7a5e8 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -29,6 +29,7 @@ import pytest import felupe as fem +import felupe.constitution.autodiff.tensortrax.models as models def pre(sym, add_identity, add_random=False): @@ -312,7 +313,7 @@ def test_umat_hyperelastic_statevars(): True, ), ( - fem.constitution.hyperelasticity.models.morph_representative_directions, + models.hyperelastic.morph_representative_directions, dict( p=[0.011, 0.408, 0.421, 6.85, 0.0056, 5.54, 5.84, 0.117], nstatevars=84 ), diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index c0310e5e..7c517e29 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -39,8 +39,8 @@ def f(x, a=1.0): def g(x, y, a=1.0, **kwargs): return x - vf = fem.constitution.jax.vmap(f) - vg = fem.constitution.jax.vmap(g) + vf = fem.constitution.autodiff.jax.vmap(f) + vg = fem.constitution.autodiff.jax.vmap(g) x = np.eye(3).reshape(1, 3, 3) * np.ones((10, 1, 1)) @@ -69,8 +69,10 @@ def W(C, C10, K): I1 = I3 ** (-1 / 3) * jnp.trace(C) return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2 - umat = fem.constitution.jax.Hyperelastic(W, C10=0.5, K=2.0, parallel=True) - umat = fem.constitution.jax.Hyperelastic(W, C10=0.5, K=2.0, jit=True) + umat = fem.constitution.autodiff.jax.Hyperelastic( + W, C10=0.5, K=2.0, parallel=True + ) + umat = fem.constitution.autodiff.jax.Hyperelastic(W, C10=0.5, K=2.0, jit=True) mesh = fem.Cube(n=2) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) @@ -101,7 +103,7 @@ def W(C, statevars, C10, K): W.kwargs = {"C10": 0.5} - umat = fem.constitution.jax.Hyperelastic( + umat = fem.constitution.autodiff.jax.Hyperelastic( W, C10=0.5, K=2.0, nstatevars=1, jit=True ) mesh = fem.Cube(n=2) From 4811b2666f47e3335f00b487bc1b0a6d646c560f Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 00:31:26 +0100 Subject: [PATCH 061/125] Add `felupe.constitution.autodiff.jax.Material` (#879) * Add `felupe.constitution.autodiff.jax.Material` as an alternative for `MaterialAD` (`felupe.constitution.autodiff.tensortrax.Material`) * test new material class for jax --- docs/conf.py | 3 +- docs/felupe/constitution/jax.rst | 16 +- .../examples/extut03_building_blocks.py | 2 +- .../constitution/autodiff/jax/__init__.py | 6 +- .../autodiff/jax/_hyperelastic.py | 96 +------- .../constitution/autodiff/jax/_material.py | 206 ++++++++++++++++++ .../constitution/autodiff/jax/_tools.py | 103 +++++++++ .../autodiff/tensortrax/_hyperelastic.py | 4 +- .../autodiff/tensortrax/_material.py | 6 +- tests/test_constitution_jax.py | 72 ++++++ 10 files changed, 415 insertions(+), 99 deletions(-) create mode 100644 src/felupe/constitution/autodiff/jax/_material.py create mode 100644 src/felupe/constitution/autodiff/jax/_tools.py diff --git a/docs/conf.py b/docs/conf.py index fa53d6a4..14f1da2b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -79,11 +79,12 @@ "within_subsection_order": FileNameSortKey, } intersphinx_mapping = { + "jax": ("https://jax.readthedocs.io/en/stable", None), "matplotlib": ("https://matplotlib.org/stable/", None), "numpy": ("https://numpy.org/doc/stable/", None), - "scipy": ("https://docs.scipy.org/doc/scipy/", None), "python": ("https://docs.python.org/3/", None), "pyvista": ("https://docs.pyvista.org/version/stable/", None), + "scipy": ("https://docs.scipy.org/doc/scipy/", None), "tensortrax": ("https://tensortrax.readthedocs.io/en/latest/", None), } diff --git a/docs/felupe/constitution/jax.rst b/docs/felupe/constitution/jax.rst index 5dcf13c7..b3d9642c 100644 --- a/docs/felupe/constitution/jax.rst +++ b/docs/felupe/constitution/jax.rst @@ -3,7 +3,7 @@ JAX-based Materials ~~~~~~~~~~~~~~~~~~~ -This page contains hyperelastic material model formulations with automatic differentiation using :mod:`jax`. These material model formulations are defined by a strain energy density function. +This page contains material model formulations with automatic differentiation using :mod:`jax`. **Frameworks** @@ -12,6 +12,13 @@ This page contains hyperelastic material model formulations with automatic diffe .. autosummary:: constitution.autodiff.jax.Hyperelastic + constitution.autodiff.jax.Material + +**Tools** + +.. autosummary:: + + constitution.autodiff.jax.vmap **Detailed API Reference** @@ -19,3 +26,10 @@ This page contains hyperelastic material model formulations with automatic diffe :members: :undoc-members: :inherited-members: + +.. autoclass:: felupe.constitution.autodiff.jax.Material + :members: + :undoc-members: + :inherited-members: + +.. autofunction:: felupe.constitution.autodiff.jax.vmap diff --git a/docs/tutorial/examples/extut03_building_blocks.py b/docs/tutorial/examples/extut03_building_blocks.py index 658f5d49..e03e43ad 100644 --- a/docs/tutorial/examples/extut03_building_blocks.py +++ b/docs/tutorial/examples/extut03_building_blocks.py @@ -126,7 +126,7 @@ # incompressible version of the Neo-Hookean material model formulation. # # .. note:: -# It is important to only use automatic-differentiable math-functions from the +# It is important to use only automatic-differentiable math-functions from the # NumPy-like modules `tensortrax.math `_, # `tensortrax.math.linalg `_ or # `tensortrax.math.special `_. TensorTRAX is a diff --git a/src/felupe/constitution/autodiff/jax/__init__.py b/src/felupe/constitution/autodiff/jax/__init__.py index 2d63f424..20911309 100644 --- a/src/felupe/constitution/autodiff/jax/__init__.py +++ b/src/felupe/constitution/autodiff/jax/__init__.py @@ -1,3 +1,5 @@ -from ._hyperelastic import Hyperelastic, vmap +from ._hyperelastic import Hyperelastic +from ._material import Material +from ._tools import vmap -__all__ = ["Hyperelastic", "vmap"] +__all__ = ["Hyperelastic", "Material", "vmap"] diff --git a/src/felupe/constitution/autodiff/jax/_hyperelastic.py b/src/felupe/constitution/autodiff/jax/_hyperelastic.py index 77b4052e..b4a99527 100644 --- a/src/felupe/constitution/autodiff/jax/_hyperelastic.py +++ b/src/felupe/constitution/autodiff/jax/_hyperelastic.py @@ -16,96 +16,12 @@ along with FElupe. If not, see . """ -import inspect import warnings -from functools import wraps import numpy as np from ..._material import Material - - -def vmap(fun, in_axes=0, out_axes=0, **kwargs): - """Vectorizing map. Creates a function which maps ``fun`` over argument axes. This - decorator treats all non-specified arguments and keyword-arguments as static. - - See Also - -------- - jax.vmap : Vectorizing map. Creates a function which maps ``fun`` over argument - axes. - """ - - import jax - - @wraps(fun) - def vmap_with_static_kwargs(*args, **keywordargs): - # sorted list of all parameter keys, including kwargs with default values - sig = inspect.signature(fun) - keys = [ - key - for key, value in sig.parameters.items() - if not (key in ["args", "kwargs"] and value.default == inspect._empty) - ] - - if not ( - "kwargs" in sig.parameters.keys() - and sig.parameters["kwargs"].default == inspect._empty - ): - # check if unexpected keyword-argument is given - for key in keywordargs.keys(): - if key not in keys: - raise TypeError( - f"{fun.__name__}() got an unexpected keyword argument '{key}'" - ) - - # dict with default values for all parameters - parameters = dict( - [(key, value.default) for key, value in sig.parameters.items()] - ) - - # merge dict of default values with custom keyword arguments - items = {**parameters, **keywordargs} - - # create sorted list of values of keyword-arguments, including default kwargs - keyword_args = [items[key] for key in keys[len(args) :]] - - # don't map non-given arguments and keyword-arguments - if not hasattr(in_axes, "__len__"): - in_axes_tuple = (in_axes,) - else: - in_axes_tuple = in_axes - - static_argnums = len(args) + len(keyword_args) - len(in_axes_tuple) - in_axes_new = (*in_axes_tuple, *([None] * static_argnums)) - - vfun = jax.vmap(fun, in_axes=in_axes_new, out_axes=out_axes, **kwargs) - - return vfun(*args, *keyword_args) - - return vmap_with_static_kwargs - - -def vmap2(fun, in_axes=0, out_axes=0, **kwargs): - "Nested vectorizing map." - return vmap( - vmap(fun, in_axes=in_axes, out_axes=out_axes, **kwargs), - in_axes=in_axes, - out_axes=out_axes, - **kwargs, - ) - - -def total_lagrange(fun): - import jax.numpy as jnp - - @wraps(fun) - def evaluate(F, *args, **kwargs): - i, j = jnp.triu_indices(3) - C_triu = jnp.einsum("ia,ia->a", F[:, i], F[:, j]) - C = C_triu[jnp.array([[0, 1, 2], [1, 3, 4], [2, 4, 5]])] - return fun(C, *args, **kwargs) - - return evaluate +from ._tools import total_lagrange, vmap2 class Hyperelastic(Material): @@ -120,7 +36,7 @@ class Hyperelastic(Material): tensor :math:`\boldsymbol{C}`. Function signature must be ``fun = lambda C, **kwargs: psi`` for functions without state variables and ``fun = lambda C, statevars, **kwargs: [psi, statevars_new]`` for functions - with state variables. It is important to only use differentiable math-functions + with state variables. It is important to use only differentiable math-functions from :mod:`jax`. nstatevars : int, optional Number of state variables (default is 0). @@ -139,7 +55,7 @@ class Hyperelastic(Material): :math:`\boldsymbol{C} = \boldsymbol{F}^T \boldsymbol{F}`. .. warning:: - It is important to only use differentiable math-functions from :mod:`jax`! + It is important to use only differentiable math-functions from :mod:`jax`! Take this minimal code-block as template @@ -156,7 +72,7 @@ def neo_hooke(C, mu): "Strain energy function of the Neo-Hookean material formulation." return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) - umat = fem.constitution.jax.Hyperelastic(neo_hooke, mu=1) + umat = fem.constitution.autodiff.jax.Hyperelastic(neo_hooke, mu=1) and this code-block for material formulations with state variables. @@ -185,7 +101,7 @@ def viscoelastic(C, Cin, mu, eta, dtime): # strain energy function and state variable return mu / 2 * (I1 - 3), Ci.ravel() - umat = fem.constitution.jax.Hyperelastic( + umat = fem.constitution.autodiff.jax.Hyperelastic( viscoelastic, mu=1, eta=1, dtime=1, nstatevars=9 ) @@ -210,7 +126,7 @@ def viscoelastic(C, Cin, mu, eta, dtime): ... "Strain energy function of the Neo-Hookean material formulation." ... return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) >>> - >>> umat = fem.constitution.jax.Hyperelastic(neo_hooke, mu=1) + >>> umat = fem.constitution.autodiff.jax.Hyperelastic(neo_hooke, mu=1) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/autodiff/jax/_material.py b/src/felupe/constitution/autodiff/jax/_material.py new file mode 100644 index 00000000..abad689d --- /dev/null +++ b/src/felupe/constitution/autodiff/jax/_material.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" + +import warnings + +import numpy as np + +from ..._material import Material as MaterialDefault +from ._tools import vmap2 + + +class Material(MaterialDefault): + r"""A material definition with a given function for the partial derivative of the + strain energy function w.r.t. the deformation gradient tensor with Automatic + Differentiation provided by :mod:`jax`. + + Parameters + ---------- + fun : callable + A gradient of the strain energy density function w.r.t. the deformation gradient + tensor :math:`\boldsymbol{F}`. Function signature must be + ``fun = lambda F, **kwargs: P`` for functions without state variables and + ``fun = lambda F, statevars, **kwargs: [P, statevars_new]`` for functions + with state variables. It is important to use only differentiable math-functions + from :mod:`jax`. + nstatevars : int, optional + Number of state variables (default is 0). + jit : bool, optional + A flag to invoke just-in-time compilation (default is True). + parallel : bool, optional + A flag to invoke threaded function evaluations (defaultnis False). Not + implemented. + **kwargs : dict, optional + Optional keyword-arguments for the gradient of the strain energy density + function. + + Notes + ----- + The gradient of the strain energy density function + :math:`\frac{\partial \psi}{\partial \boldsymbol{F}}` must be given in terms of the + deformation gradient tensor :math:`\boldsymbol{F}`. + + .. warning:: + It is important to use only differentiable math-functions from :mod:`jax`! + + Take this code-block as template + + .. code-block:: + + import felupe as fem + import jax.numpy as jnp + + def neo_hooke(F, mu): + "First Piola-Kirchhoff stress of the Neo-Hookean material formulation." + + C = F.T @ F + Cu = jnp.linalg.det(C) ** (-1/3) * C + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + + return mu * F @ dev(Cu) @ jnp.linalg.inv(C) + + umat = fem.constitution.autodiff.jax.Material(neo_hooke, mu=1) + + and this code-block for material formulations with state variables: + + .. code-block:: + + import felupe as fem + import jax.numpy as jnp + + def viscoelastic(F, Cin, mu, eta, dtime): + "Finite strain viscoelastic material formulation." + + # unimodular part of the right Cauchy-Green deformation tensor + C = F.T @ F + Cu = jnp.linalg.det(C) ** (-1 / 3) * C + + # update of state variables by evolution equation + from_triu = lambda C: C[jnp.array([[0, 1, 2], [1, 3, 4], [2, 4, 5]])] + Ci = from_triu(Cin) + mu / eta * dtime * Cu + Ci = jnp.linalg.det(Ci) ** (-1 / 3) * Ci + + # second Piola-Kirchhoff stress tensor + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + S = mu * dev(Cu @ jnp.linalg.inv(Ci)) @ jnp.linalg.inv(C) + + # first Piola-Kirchhoff stress tensor and state variable + to_triu = lambda C: C[*jnp.triu_indices(3)] + return F @ S, to_triu(Ci) + + umat = fem.constitution.autodiff.jax.Material( + viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6 + ) + + .. note:: + See the `documentation of JAX `_ for further + details. JAX uses single-precision (32bit) data types by default. This requires + to relax the tolerance of :func:`~felupe.newtonrhapson` to ``tol=1e-4``. If + required, JAX may be enforced to use double-precision at startup with + ``jax.config.update("jax_enable_x64", True)``. + + Examples + -------- + View force-stretch curves on elementary incompressible deformations. + + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> import jax.numpy as jnp + >>> + >>> def neo_hooke(F, mu): + ... "First Piola-Kirchhoff stress of the Neo-Hookean material formulation." + ... + ... C = F.T @ F + ... Cu = jnp.linalg.det(C) ** (-1/3) * C + ... dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + ... + ... return mu * F @ dev(Cu) @ jnp.linalg.inv(C) + >>> + >>> umat = fem.constitution.autodiff.jax.Material(neo_hooke, mu=1) + >>> ax = umat.plot(incompressible=True) + + .. pyvista-plot:: + :include-source: False + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> fig = ax.get_figure() + >>> chart = pv.ChartMPL(fig) + >>> chart.show() + + """ + + def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): + import jax + + has_aux = nstatevars > 0 + self.fun = fun + + if parallel: + warnings.warn("Parallel execution is not implemented.") + + keyword_args = kwargs + if hasattr(fun, "kwargs"): + keyword_args = {**fun.kwargs, **keyword_args} + + super().__init__( + stress=self._stress, + elasticity=self._elasticity, + nstatevars=nstatevars, + **keyword_args, + ) + + kwargs_jax = dict(in_axes=-1, out_axes=-1) + if nstatevars > 0: + kwargs_jax["in_axes"] = (-1, -1) + + self._grad = vmap2(self.fun, **kwargs_jax) + self._hess = vmap2(jax.jacfwd(self.fun, has_aux=has_aux), **kwargs_jax) + + if jit: + self._grad = jax.jit(self._grad) + self._hess = jax.jit(self._hess) + + def _stress(self, x, **kwargs): + if self.nstatevars > 0: + statevars = x[1] + + F = x[0] + if self.nstatevars > 0: + dWdF, statevars_new = self._grad(F, statevars, **kwargs) + statevars_new = np.array(statevars_new) + else: + dWdF = self._grad(F, **kwargs) + statevars_new = None + + return [np.array(dWdF), statevars_new] + + def _elasticity(self, x, **kwargs): + if self.nstatevars > 0: + statevars = x[1] + + F = x[0] + if self.nstatevars > 0: + d2WdFdF, statevars_new = self._hess(F, statevars, **kwargs) + else: + d2WdFdF = self._hess(F, **kwargs) + return [np.array(d2WdFdF)] diff --git a/src/felupe/constitution/autodiff/jax/_tools.py b/src/felupe/constitution/autodiff/jax/_tools.py new file mode 100644 index 00000000..6a54ae3c --- /dev/null +++ b/src/felupe/constitution/autodiff/jax/_tools.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" + +import inspect +from functools import wraps + + +def vmap(fun, in_axes=0, out_axes=0, **kwargs): + """Vectorizing map. Creates a function which maps ``fun`` over argument axes. This + decorator treats all non-specified arguments and keyword-arguments as static. + + See Also + -------- + jax.vmap : Vectorizing map. Creates a function which maps ``fun`` over argument + axes. + """ + + import jax + + @wraps(fun) + def vmap_with_static_kwargs(*args, **keywordargs): + # sorted list of all parameter keys, including kwargs with default values + sig = inspect.signature(fun) + keys = [ + key + for key, value in sig.parameters.items() + if not (key in ["args", "kwargs"] and value.default == inspect._empty) + ] + + if not ( + "kwargs" in sig.parameters.keys() + and sig.parameters["kwargs"].default == inspect._empty + ): + # check if unexpected keyword-argument is given + for key in keywordargs.keys(): + if key not in keys: + raise TypeError( + f"{fun.__name__}() got an unexpected keyword argument '{key}'" + ) + + # dict with default values for all parameters + parameters = dict( + [(key, value.default) for key, value in sig.parameters.items()] + ) + + # merge dict of default values with custom keyword arguments + items = {**parameters, **keywordargs} + + # create sorted list of values of keyword-arguments, including default kwargs + keyword_args = [items[key] for key in keys[len(args) :]] + + # don't map non-given arguments and keyword-arguments + if not hasattr(in_axes, "__len__"): + in_axes_tuple = (in_axes,) + else: + in_axes_tuple = in_axes + + static_argnums = len(args) + len(keyword_args) - len(in_axes_tuple) + in_axes_new = (*in_axes_tuple, *([None] * static_argnums)) + + vfun = jax.vmap(fun, in_axes=in_axes_new, out_axes=out_axes, **kwargs) + + return vfun(*args, *keyword_args) + + return vmap_with_static_kwargs + + +def vmap2(fun, in_axes=0, out_axes=0, **kwargs): + "Nested vectorizing map." + return vmap( + vmap(fun, in_axes=in_axes, out_axes=out_axes, **kwargs), + in_axes=in_axes, + out_axes=out_axes, + **kwargs, + ) + + +def total_lagrange(fun): + import jax.numpy as jnp + + @wraps(fun) + def evaluate(F, *args, **kwargs): + i, j = jnp.triu_indices(3) + C_triu = jnp.einsum("ia,ia->a", F[:, i], F[:, j]) + C = C_triu[jnp.array([[0, 1, 2], [1, 3, 4], [2, 4, 5]])] + return fun(C, *args, **kwargs) + + return evaluate diff --git a/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py b/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py index a39ecd2c..6687034d 100644 --- a/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py +++ b/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py @@ -37,7 +37,7 @@ class Hyperelastic(Material): ``fun = lambda C, statevars, **kwargs: [psi, statevars_new]`` for functions with state variables. The right Cauchy-Green deformation tensor will be a :class:`tensortrax.Tensor` when the function is evaluated. It is important to - only use differentiable math-functions from :mod:`tensortrax.math`. + use only differentiable math-functions from :mod:`tensortrax.math`. nstatevars : int, optional Number of state variables (default is 0). parallel : bool, optional @@ -53,7 +53,7 @@ class Hyperelastic(Material): :math:`\boldsymbol{C} = \boldsymbol{F}^T \boldsymbol{F}`. .. warning:: - It is important to only use differentiable math-functions from + It is important to use only differentiable math-functions from :mod:`tensortrax.math`! Take this minimal code-block as template diff --git a/src/felupe/constitution/autodiff/tensortrax/_material.py b/src/felupe/constitution/autodiff/tensortrax/_material.py index 41a78f3d..3592404f 100644 --- a/src/felupe/constitution/autodiff/tensortrax/_material.py +++ b/src/felupe/constitution/autodiff/tensortrax/_material.py @@ -36,7 +36,7 @@ class Material(MaterialDefault): ``fun = lambda F, statevars, **kwargs: [P, statevars_new]`` for functions with state variables. The deformation gradient tensor will be a :class:`tensortrax.Tensor` when the function is evaluated. It is important to - only use differentiable math-functions from ``tensortrax.math``! + use only differentiable math-functions from ``tensortrax.math``! nstatevars : int, optional Number of state variables (default is 0). parallel : bool, optional @@ -53,7 +53,7 @@ class Material(MaterialDefault): deformation gradient tensor :math:`\boldsymbol{F}`. .. warning:: - It is important to only use differentiable math-functions from + It is important to use only differentiable math-functions from ``tensortrax.math``! .. math:: @@ -65,6 +65,7 @@ class Material(MaterialDefault): .. code-block:: + import felupe as fem import tensortrax.math as tm def neo_hooke(F, mu): @@ -81,6 +82,7 @@ def neo_hooke(F, mu): .. code-block:: + import felupe as fem import tensortrax.math as tm def viscoelastic(F, Cin, mu, eta, dtime): diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 7c517e29..f6572eb3 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -123,7 +123,79 @@ def W(C, statevars, C10, K): pass +def test_material_jax(): + try: + import jax.numpy as jnp + + def dWdF(F, C10, K): + J = jnp.linalg.det(F) + C = F.T @ F + Cu = J ** (-2 / 3) * C + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + + P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) + return P + K * (J - 1) * J * jnp.linalg.inv(C) + + umat = fem.constitution.autodiff.jax.Material( + dWdF, C10=0.5, K=2.0, parallel=True + ) + umat = fem.constitution.autodiff.jax.Material(dWdF, C10=0.5, K=2.0, jit=True) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + solid = fem.SolidBody(umat=umat, field=field) + + move = fem.math.linsteps([0, 1], num=3) + ramp = {boundaries["move"]: move} + step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) + job = fem.Job(steps=[step]) + job.evaluate(tol=1e-4) + + except ModuleNotFoundError: + pass + + +def test_material_jax_statevars(): + try: + import jax.numpy as jnp + + def dWdF(F, statevars, C10, K): + J = jnp.linalg.det(F) + C = F.T @ F + Cu = J ** (-2 / 3) * C + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + + P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) + statevars_new = J + return P + K * (J - 1) * J * jnp.linalg.inv(C), statevars_new + + dWdF.kwargs = {"C10": 0.5} + + umat = fem.constitution.autodiff.jax.Material( + dWdF, C10=0.5, K=2.0, nstatevars=1, jit=True + ) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + solid = fem.SolidBody(umat=umat, field=field) + + move = fem.math.linsteps([0, 1], num=3) + ramp = {boundaries["move"]: move} + step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) + job = fem.Job(steps=[step]) + job.evaluate(tol=1e-4) + + except ModuleNotFoundError: + pass + + if __name__ == "__main__": test_vmap() test_hyperelastic_jax() test_hyperelastic_jax_statevars() + test_material_jax() + test_material_jax_statevars() From 85835a8ae92fb98ed90ee0d4069951e4d16f6c68 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 00:45:33 +0100 Subject: [PATCH 062/125] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d89b05f1..25b5aa9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ All notable changes to this project will be documented in this file. The format - Add optional keyword-arguments to `math.transpose(**kwargs)` to support optional `out` and `order`-keywords. - Add the attribute `RegionBoundary.tangents`, which contains a list of tangent unit vectors. For `quad` cell-types the length of this list is one and for `hexahedron` cell-types it is of length two. - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. -- Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. +- Add `constitution.autodiff.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. +- Add `constitution.autodiff.jax.Material` as a feature-equivalent alternative to `MaterialAD` with `jax` as backend. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. From b87862a510406052932bd3e2b211c0cdf3770405 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 00:45:36 +0100 Subject: [PATCH 063/125] Update lagrange.rst --- docs/felupe/constitution/lagrange.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/felupe/constitution/lagrange.rst b/docs/felupe/constitution/lagrange.rst index ab7b2077..7a1de9e0 100644 --- a/docs/felupe/constitution/lagrange.rst +++ b/docs/felupe/constitution/lagrange.rst @@ -34,6 +34,11 @@ This page contains Total- and Updated-Lagrange material formulations with automa :undoc-members: :inherited-members: +.. autoclass:: felupe.constitution.autodiff.tensortrax.Material + :members: + :undoc-members: + :inherited-members: + .. autofunction:: felupe.morph .. autofunction:: felupe.morph_representative_directions From 39738ea84513671891daccdfac81e39ad757fbc0 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 01:54:25 +0100 Subject: [PATCH 064/125] Add `morph()` for JAX-based `Material` (#880) * Add `morph()` for JAX-based `Material` * remove Python 3.9 support (EOL) * Update index.rst * update to Python 3.9+ (docs) * Update _morph.py * Update _morph.py * Update _material.py * Create .gitkeep * Update CHANGELOG.md * Delete .gitkeep * Create __init__.py --- .github/workflows/upload-codecov.yml | 2 +- CHANGELOG.md | 2 + README.md | 2 +- docs/felupe/constitution/jax.rst | 8 + docs/index.rst | 3 +- pyproject.toml | 3 +- .../constitution/autodiff/jax/__init__.py | 3 +- .../constitution/autodiff/jax/_material.py | 3 +- .../autodiff/jax/models/__init__.py | 3 + .../jax/models/hyperelastic/__init__.py | 0 .../autodiff/jax/models/lagrange/__init__.py | 8 + .../autodiff/jax/models/lagrange/_morph.py | 228 ++++++++++++++++++ tests/test_constitution_jax.py | 25 ++ 13 files changed, 283 insertions(+), 7 deletions(-) create mode 100644 src/felupe/constitution/autodiff/jax/models/__init__.py create mode 100644 src/felupe/constitution/autodiff/jax/models/hyperelastic/__init__.py create mode 100644 src/felupe/constitution/autodiff/jax/models/lagrange/__init__.py create mode 100644 src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py diff --git a/.github/workflows/upload-codecov.yml b/.github/workflows/upload-codecov.yml index 27acf711..ea8d2e3d 100644 --- a/.github/workflows/upload-codecov.yml +++ b/.github/workflows/upload-codecov.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/setup-python@v4 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 25b5aa9b..dc32106d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,9 +12,11 @@ All notable changes to this project will be documented in this file. The format - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. - Add `constitution.autodiff.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.autodiff.jax.Material` as a feature-equivalent alternative to `MaterialAD` with `jax` as backend. +- Add the MORPH-material formulation for a JAX-based material `felupe.constitution.autodiff.jax.models.lagrange.morph()`. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. +- Change supported Python versions to 3.9 - 3.12. ### Fixed - Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. diff --git a/README.md b/README.md index 30fd43fa..01cd19e5 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![FElupe](https://img.shields.io/badge/%F0%9F%94%8D-FElupe-white)](https://felupe.readthedocs.io) [![PyPI version shields.io](https://img.shields.io/pypi/v/felupe.svg)](https://pypi.python.org/pypi/felupe/) [![Documentation Status](https://readthedocs.org/projects/felupe/badge/?version=latest)](https://felupe.readthedocs.io/en/latest/?badge=latest) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![codecov](https://codecov.io/gh/adtzlr/felupe/branch/main/graph/badge.svg?token=J2QP6Y6LVH)](https://codecov.io/gh/adtzlr/felupe) [![DOI](https://zenodo.org/badge/360657894.svg)](https://zenodo.org/badge/latestdoi/360657894) ![Codestyle black](https://img.shields.io/badge/code%20style-black-black) ![PyPI - Downloads](https://img.shields.io/pypi/dm/felupe) [![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://adtzlr.github.io/felupe-web/lab?path=01_Getting-Started.ipynb) Open In Colab -FElupe is a Python 3.8+ 🐍 finite element analysis package 📦 focusing on the formulation and numerical solution of nonlinear problems in continuum mechanics of solid bodies 🔧. This package is intended for scientific research 💻, but is also suitable for running nonlinear simulations 🚂 in general 🏎️. In addition to the transformation of general weak forms into sparse vectors and matrices, FElupe provides an efficient high-level abstraction layer for the simulation of the deformation of solid bodies. +FElupe is a Python 3.9+ 🐍 finite element analysis package 📦 focusing on the formulation and numerical solution of nonlinear problems in continuum mechanics of solid bodies 🔧. This package is intended for scientific research 💻, but is also suitable for running nonlinear simulations 🚂 in general 🏎️. In addition to the transformation of general weak forms into sparse vectors and matrices, FElupe provides an efficient high-level abstraction layer for the simulation of the deformation of solid bodies.

`_ for parallel (threaded) assembly +* `jax `_ for JAX-based material formulations * `h5py `_ for writing XDMF result files * `matplotlib `_ for plotting graphs * `meshio `_ for mesh-related I/O diff --git a/pyproject.toml b/pyproject.toml index f1bac0f5..cdc15bde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ authors = [ {email = "a.dutzler@gmail.com"}, ] -requires-python = ">=3.8" +requires-python = ">=3.9" license = {file = "LICENSE"} keywords = [ "computational-mechanics", @@ -38,7 +38,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/src/felupe/constitution/autodiff/jax/__init__.py b/src/felupe/constitution/autodiff/jax/__init__.py index 20911309..c1b91f02 100644 --- a/src/felupe/constitution/autodiff/jax/__init__.py +++ b/src/felupe/constitution/autodiff/jax/__init__.py @@ -1,5 +1,6 @@ +from . import models from ._hyperelastic import Hyperelastic from ._material import Material from ._tools import vmap -__all__ = ["Hyperelastic", "Material", "vmap"] +__all__ = ["Hyperelastic", "Material", "models", "vmap"] diff --git a/src/felupe/constitution/autodiff/jax/_material.py b/src/felupe/constitution/autodiff/jax/_material.py index abad689d..5fe604bf 100644 --- a/src/felupe/constitution/autodiff/jax/_material.py +++ b/src/felupe/constitution/autodiff/jax/_material.py @@ -100,7 +100,8 @@ def viscoelastic(F, Cin, mu, eta, dtime): S = mu * dev(Cu @ jnp.linalg.inv(Ci)) @ jnp.linalg.inv(C) # first Piola-Kirchhoff stress tensor and state variable - to_triu = lambda C: C[*jnp.triu_indices(3)] + i, j = triu_indices(3) + to_triu = lambda C: C[i, j] return F @ S, to_triu(Ci) umat = fem.constitution.autodiff.jax.Material( diff --git a/src/felupe/constitution/autodiff/jax/models/__init__.py b/src/felupe/constitution/autodiff/jax/models/__init__.py new file mode 100644 index 00000000..b317792b --- /dev/null +++ b/src/felupe/constitution/autodiff/jax/models/__init__.py @@ -0,0 +1,3 @@ +from . import hyperelastic, lagrange + +__all__ = ["hyperelastic", "lagrange"] diff --git a/src/felupe/constitution/autodiff/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/autodiff/jax/models/hyperelastic/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/felupe/constitution/autodiff/jax/models/lagrange/__init__.py b/src/felupe/constitution/autodiff/jax/models/lagrange/__init__.py new file mode 100644 index 00000000..8d3461ae --- /dev/null +++ b/src/felupe/constitution/autodiff/jax/models/lagrange/__init__.py @@ -0,0 +1,8 @@ +from ._morph import morph + +__all__ = [ + "morph", +] + +# default (stable) material parameters +morph.kwargs = dict(p=[0, 0, 0, 0, 0, 1, 0, 0]) diff --git a/src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py b/src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py new file mode 100644 index 00000000..4166133f --- /dev/null +++ b/src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" + + +def morph(F, statevars, p): + r"""Second Piola-Kirchhoff stress tensor of the + `MORPH `_ model formulation [1]_. + + Parameters + ---------- + C : tensortrax.Tensor + Right Cauchy-Green deformation tensor. + statevars : array + Vector of stacked state variables (CTS, C, SA). + p : list of float + A list which contains the 8 material parameters. + + Notes + ----- + The MORPH material model is implemented as a second Piola-Kirchhoff stress-based + formulation with automatic differentiation. The Tresca invariant of the distortional + part of the right Cauchy-Green deformation tensor is used as internal state + variable, see Eq. :eq:`morph-state`. + + .. warning:: + While the `MORPH `_-material + formulation captures the Mullins effect and quasi-static hysteresis effects of + rubber mixtures very nicely, it has been observed to be unstable for medium- to + highly-distorted states of deformation. + + .. math:: + :label: morph-state + + \boldsymbol{C} &= \boldsymbol{F}^T \boldsymbol{F} + + I_3 &= \det (\boldsymbol{C}) + + \hat{\boldsymbol{C}} &= I_3^{-1/3} \boldsymbol{C} + + \hat{\lambda}^2_\alpha &= \text{eigvals}(\hat{\boldsymbol{C}}) + + \hat{C}_T &= \max \left( \hat{\lambda}^2_\alpha - \hat{\lambda}^2_\beta \right) + + \hat{C}_T^S &= \max \left( \hat{C}_T, \hat{C}_{T,n}^S \right) + + A sigmoid-function is used inside the deformation-dependent variables + :math:`\alpha`, :math:`\beta` and :math:`\gamma`, see Eq. :eq:`morph-sigmoid`. + + .. math:: + :label: morph-sigmoid + + f(x) &= \frac{1}{\sqrt{1 + x^2}} + + \alpha &= p_1 + p_2 \ f(p_3\ C_T^S) + + \beta &= p_4\ f(p_3\ C_T^S) + + \gamma &= p_5\ C_T^S\ \left( 1 - f\left(\frac{C_T^S}{p_6}\right) \right) + + The rate of deformation is described by the Lagrangian tensor and its Tresca- + invariant, see Eq. :eq:`morph-rate-of-deformation`. + + .. note:: + It is important to evaluate the incremental right Cauchy-Green tensor by the + difference of the final and the previous state of deformation, not by its + variation with respect to the deformation gradient tensor. + + .. math:: + :label: morph-rate-of-deformation + + \hat{\boldsymbol{L}} &= \text{sym}\left( + \text{dev}(\boldsymbol{C}^{-1} \Delta\boldsymbol{C}) + \right) \hat{\boldsymbol{C}} + + \lambda_{\hat{\boldsymbol{L}}, \alpha} &= \text{eigvals}(\hat{\boldsymbol{L}}) + + \hat{L}_T &= \max \left( + \lambda_{\hat{\boldsymbol{L}}, \alpha}-\lambda_{\hat{\boldsymbol{L}}, \beta} + \right) + + \Delta\boldsymbol{C} &= \boldsymbol{C} - \boldsymbol{C}_n + + The additional stresses evolve between the limiting stresses, see Eq. + :eq:`morph-stresses`. The additional deviatoric-enforcement terms [1]_ are neglected + in this implementation. + + .. math:: + :label: morph-stresses + + \boldsymbol{S}_L &= \left( + \gamma \exp \left(p_7 \frac{\hat{\boldsymbol{L}}}{\hat{L}_T} + \frac{\hat{C}_T}{\hat{C}_T^S} \right) + + p8 \frac{\hat{\boldsymbol{L}}}{\hat{L}_T} + \right) \boldsymbol{C}^{-1} + + \boldsymbol{S}_A &= \frac{ + \boldsymbol{S}_{A,n} + \beta\ \hat{L}_T\ \boldsymbol{S}_L + }{1 + \beta\ \hat{L}_T} + + \boldsymbol{S} &= 2 \alpha\ \text{dev}( \hat{\boldsymbol{C}} ) + \boldsymbol{C}^{-1}+\text{dev}\left(\boldsymbol{S}_A\ \boldsymbol{C}\right) + \boldsymbol{C}^{-1} + + Examples + -------- + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> + >>> umat = fem.constitution.autodiff.jax.Material( + ... fem.constitution.autodiff.jax.models.lagrange.morph, + ... p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], + ... nstatevars=13, + ... ) + >>> ax = umat.plot( + ... incompressible=True, + ... ux=fem.math.linsteps( + ... # [1, 2, 1, 2.75, 1, 3.5, 1, 4.2, 1, 4.8, 1, 4.8, 1], + ... [1, 2.75, 1, 2.75], + ... num=20, + ... ), + ... ps=None, + ... bx=None, + ... ) + + .. pyvista-plot:: + :include-source: False + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> fig = ax.get_figure() + >>> chart = pv.ChartMPL(fig) + >>> chart.show() + + References + ---------- + .. [1] D. Besdo and J. Ihlemann, "A phenomenological constitutive model for + rubberlike materials and its numerical applications", International Journal + of Plasticity, vol. 19, no. 7. Elsevier BV, pp. 1019–1036, Jul. 2003. doi: + `10.1016/s0749-6419(02)00091-8 `_. + """ + + from jax.numpy import ( + array, + concatenate, + diag, + eye, + maximum, + sqrt, + trace, + triu_indices, + ) + from jax.numpy.linalg import det, eigvalsh, inv + from jax.scipy.linalg import expm + + # right Cauchy-Green deformation tensor + C = F.T @ F + + # extract old state variables + CTSn = statevars[0] + from_triu = lambda C: C[array([[0, 1, 2], [1, 3, 4], [2, 4, 5]])] + Cn = from_triu(statevars[1:7]) + SAn = from_triu(statevars[7:13]) + + # distortional part of right Cauchy-Green deformation tensor + I3 = det(C) + CG = C * I3 ** (-1 / 3) + + # inverse of and incremental right Cauchy-Green deformation tensor + invC = inv(C) + dC = C - Cn + + # eigenvalues of right Cauchy-Green deformation tensor (sorted in ascending order) + eigvalsh2 = lambda C: eigvalsh(C + diag(array([1e-4, -1e-4, 0]))) + λCG = eigvalsh2(CG) + + # Tresca invariant of distortional part of right Cauchy-Green deformation tensor + CTG = λCG[-1] - λCG[0] + + # maximum Tresca invariant in load history + CTS = maximum(CTG, CTSn) + + def sigmoid(x): + "Algebraic sigmoid function." + return 1 / sqrt(1 + x**2) + + # material parameters + α = p[0] + p[1] * sigmoid(p[2] * CTS) + β = p[3] * sigmoid(p[2] * CTS) + γ = p[4] * CTS * (1 - sigmoid(CTS / p[5])) + + dev = lambda C: C - trace(C) / 3 * eye(3) + sym = lambda C: (C + C.T) / 2 + + LG = sym(dev(invC @ dC)) @ CG + λLG = eigvalsh2(LG) + LTG = λLG[-1] - λLG[0] + + # limiting stresses "L" and additional stresses "A" + SL = (γ * expm(p[6] * LG / LTG * CTG / CTS) + p[7] * LG / LTG) @ invC + SA = (SAn + β * LTG * SL) / (1 + β * LTG) + + # second Piola-Kirchhoff stress tensor + S = 2 * α * dev(CG) @ invC + dev(SA @ C) @ invC + + i, j = triu_indices(3) + to_triu = lambda C: C[i, j] + statevars_new = concatenate([array([CTS]), to_triu(C), to_triu(SA)]) + + return F @ S, statevars_new diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index f6572eb3..d58bd901 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -193,9 +193,34 @@ def dWdF(F, statevars, C10, K): pass +def test_material_included_jax_statevars(): + try: + umat = fem.constitution.autodiff.jax.Material( + fem.constitution.autodiff.jax.models.lagrange.morph, + p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], + nstatevars=13, + ) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + solid = fem.SolidBody(umat=umat, field=field) + + move = fem.math.linsteps([0, 1], num=3) + ramp = {boundaries["move"]: move} + step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) + job = fem.Job(steps=[step]) + job.evaluate(tol=1e-4) + + except ModuleNotFoundError: + pass + + if __name__ == "__main__": test_vmap() test_hyperelastic_jax() test_hyperelastic_jax_statevars() test_material_jax() test_material_jax_statevars() + test_material_included_jax_statevars() From bd1bf633d70d71dcd490fc359cf02e80e5e939e0 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 08:56:14 +0100 Subject: [PATCH 065/125] Simplify constitution (#881) --- CHANGELOG.md | 6 +-- docs/felupe/constitution/jax.rst | 18 ++++---- docs/felupe/constitution/lagrange.rst | 2 +- src/felupe/constitution/__init__.py | 44 +++++++++---------- src/felupe/constitution/autodiff/__init__.py | 10 ----- .../{autodiff => }/jax/__init__.py | 0 .../{autodiff => }/jax/_hyperelastic.py | 12 ++--- .../{autodiff => }/jax/_material.py | 13 +++--- .../constitution/{autodiff => }/jax/_tools.py | 0 .../{autodiff => }/jax/models/__init__.py | 0 .../jax/models/hyperelastic/__init__.py | 0 .../jax/models/lagrange/__init__.py | 0 .../jax/models/lagrange/_morph.py | 5 ++- .../{autodiff => }/tensortrax/__init__.py | 0 .../tensortrax/_hyperelastic.py | 4 +- .../{autodiff => }/tensortrax/_material.py | 13 +++--- .../tensortrax/_total_lagrange.py | 0 .../tensortrax/_updated_lagrange.py | 0 .../tensortrax/models/__init__.py | 0 .../models/hyperelastic/__init__.py | 0 .../models/hyperelastic/_alexander.py | 0 .../hyperelastic/_anssari_benam_bucchi.py | 0 .../models/hyperelastic/_arruda_boyce.py | 0 .../models/hyperelastic/_extended_tube.py | 0 .../_finite_strain_viscoelastic.py | 0 .../models/hyperelastic/_helpers.py | 0 .../models/hyperelastic/_lopez_pamies.py | 0 .../hyperelastic/_miehe_goektepe_lulei.py | 0 .../models/hyperelastic/_mooney_rivlin.py | 0 .../_morph_representative_directions.py | 2 +- .../models/hyperelastic/_neo_hooke.py | 0 .../tensortrax/models/hyperelastic/_ogden.py | 0 .../models/hyperelastic/_ogden_roxburgh.py | 0 .../hyperelastic/_saint_venant_kirchhoff.py | 0 .../hyperelastic/_third_order_deformation.py | 0 .../models/hyperelastic/_van_der_waals.py | 0 .../tensortrax/models/hyperelastic/_yeoh.py | 0 .../hyperelastic/microsphere/__init__.py | 0 .../models/hyperelastic/microsphere/_chain.py | 0 .../microsphere/_framework_affine.py | 2 +- .../microsphere/_framework_nonaffine.py | 2 +- .../tensortrax/models/lagrange/__init__.py | 0 .../tensortrax/models/lagrange/_morph.py | 0 .../_morph_representative_directions.py | 0 .../models/lagrange/_morph_uniaxial.py | 0 .../models/lagrange/microsphere/__init__.py | 0 .../lagrange/microsphere/_framework_affine.py | 2 +- tests/test_constitution.py | 2 +- tests/test_constitution_jax.py | 29 +++++------- 49 files changed, 76 insertions(+), 90 deletions(-) delete mode 100644 src/felupe/constitution/autodiff/__init__.py rename src/felupe/constitution/{autodiff => }/jax/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/jax/_hyperelastic.py (95%) rename src/felupe/constitution/{autodiff => }/jax/_material.py (94%) rename src/felupe/constitution/{autodiff => }/jax/_tools.py (100%) rename src/felupe/constitution/{autodiff => }/jax/models/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/jax/models/hyperelastic/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/jax/models/lagrange/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/jax/models/lagrange/_morph.py (98%) rename src/felupe/constitution/{autodiff => }/tensortrax/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/_hyperelastic.py (98%) rename src/felupe/constitution/{autodiff => }/tensortrax/_material.py (93%) rename src/felupe/constitution/{autodiff => }/tensortrax/_total_lagrange.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/_updated_lagrange.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_alexander.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_arruda_boyce.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_extended_tube.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_helpers.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_lopez_pamies.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_mooney_rivlin.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_morph_representative_directions.py (98%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_neo_hooke.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_ogden.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_ogden_roxburgh.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_third_order_deformation.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_van_der_waals.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/_yeoh.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/microsphere/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/microsphere/_chain.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/microsphere/_framework_affine.py (97%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py (95%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/lagrange/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/lagrange/_morph.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/lagrange/_morph_representative_directions.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/lagrange/_morph_uniaxial.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/lagrange/microsphere/__init__.py (100%) rename src/felupe/constitution/{autodiff => }/tensortrax/models/lagrange/microsphere/_framework_affine.py (95%) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc32106d..9c87e698 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,9 @@ All notable changes to this project will be documented in this file. The format - Add optional keyword-arguments to `math.transpose(**kwargs)` to support optional `out` and `order`-keywords. - Add the attribute `RegionBoundary.tangents`, which contains a list of tangent unit vectors. For `quad` cell-types the length of this list is one and for `hexahedron` cell-types it is of length two. - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. -- Add `constitution.autodiff.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. -- Add `constitution.autodiff.jax.Material` as a feature-equivalent alternative to `MaterialAD` with `jax` as backend. -- Add the MORPH-material formulation for a JAX-based material `felupe.constitution.autodiff.jax.models.lagrange.morph()`. +- Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. +- Add `constitution.jax.Material` as a feature-equivalent alternative to `MaterialAD` with `jax` as backend. +- Add the MORPH-material formulation for a JAX-based material `felupe.constitution.jax.models.lagrange.morph()`. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/docs/felupe/constitution/jax.rst b/docs/felupe/constitution/jax.rst index f79bc215..0024beae 100644 --- a/docs/felupe/constitution/jax.rst +++ b/docs/felupe/constitution/jax.rst @@ -11,33 +11,33 @@ This page contains material model formulations with automatic differentiation us .. autosummary:: - constitution.autodiff.jax.Hyperelastic - constitution.autodiff.jax.Material + constitution.jax.Hyperelastic + constitution.jax.Material -**Material Models for** :class:`felupe.constitution.autodiff.jax.Material` +**Material Models for** :class:`felupe.constitution.jax.Material` .. autosummary:: - felupe.constitution.autodiff.jax.models.lagrange.morph + felupe.constitution.jax.models.lagrange.morph **Tools** .. autosummary:: - constitution.autodiff.jax.vmap + constitution.jax.vmap **Detailed API Reference** -.. autoclass:: felupe.constitution.autodiff.jax.Hyperelastic +.. autoclass:: felupe.constitution.jax.Hyperelastic :members: :undoc-members: :inherited-members: -.. autoclass:: felupe.constitution.autodiff.jax.Material +.. autoclass:: felupe.constitution.jax.Material :members: :undoc-members: :inherited-members: -.. autofunction:: felupe.constitution.autodiff.jax.models.lagrange.morph +.. autofunction:: felupe.constitution.jax.models.lagrange.morph -.. autofunction:: felupe.constitution.autodiff.jax.vmap +.. autofunction:: felupe.constitution.jax.vmap diff --git a/docs/felupe/constitution/lagrange.rst b/docs/felupe/constitution/lagrange.rst index 7a1de9e0..29470667 100644 --- a/docs/felupe/constitution/lagrange.rst +++ b/docs/felupe/constitution/lagrange.rst @@ -34,7 +34,7 @@ This page contains Total- and Updated-Lagrange material formulations with automa :undoc-members: :inherited-members: -.. autoclass:: felupe.constitution.autodiff.tensortrax.Material +.. autoclass:: felupe.constitution.tensortrax.Material :members: :undoc-members: :inherited-members: diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index fa97ca70..852c25a4 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -3,28 +3,6 @@ from ._material import Material from ._mixed import NearlyIncompressible, ThreeFieldVariation from ._view import ViewMaterial, ViewMaterialIncompressible -from .autodiff.tensortrax import Hyperelastic -from .autodiff.tensortrax import Material as MaterialAD -from .autodiff.tensortrax import total_lagrange, updated_lagrange -from .autodiff.tensortrax.models.hyperelastic import ( - alexander, - anssari_benam_bucchi, - arruda_boyce, - extended_tube, - finite_strain_viscoelastic, - isochoric_volumetric_split, - lopez_pamies, - miehe_goektepe_lulei, - mooney_rivlin, - neo_hooke, - ogden, - ogden_roxburgh, - saint_venant_kirchhoff, - third_order_deformation, - van_der_waals, - yeoh, -) -from .autodiff.tensortrax.models.lagrange import morph, morph_representative_directions from .hyperelasticity import NeoHooke, NeoHookeCompressible, OgdenRoxburgh, Volumetric from .linear_elasticity import ( LinearElastic, @@ -42,6 +20,28 @@ linear_elastic, linear_elastic_plastic_isotropic_hardening, ) +from .tensortrax import Hyperelastic +from .tensortrax import Material as MaterialAD +from .tensortrax import total_lagrange, updated_lagrange +from .tensortrax.models.hyperelastic import ( + alexander, + anssari_benam_bucchi, + arruda_boyce, + extended_tube, + finite_strain_viscoelastic, + isochoric_volumetric_split, + lopez_pamies, + miehe_goektepe_lulei, + mooney_rivlin, + neo_hooke, + ogden, + ogden_roxburgh, + saint_venant_kirchhoff, + third_order_deformation, + van_der_waals, + yeoh, +) +from .tensortrax.models.lagrange import morph, morph_representative_directions __all__ = [ "alexander", diff --git a/src/felupe/constitution/autodiff/__init__.py b/src/felupe/constitution/autodiff/__init__.py deleted file mode 100644 index 844e505e..00000000 --- a/src/felupe/constitution/autodiff/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -""" -felupe.constitution.autodiff -============================ -This module contains constitutive material classes and models for several backends. The -primary used backend in FElupe is based on :mod:`tensortrax`. -""" - -from . import jax, tensortrax - -__all__ = ["jax", "tensortrax"] diff --git a/src/felupe/constitution/autodiff/jax/__init__.py b/src/felupe/constitution/jax/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/jax/__init__.py rename to src/felupe/constitution/jax/__init__.py diff --git a/src/felupe/constitution/autodiff/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py similarity index 95% rename from src/felupe/constitution/autodiff/jax/_hyperelastic.py rename to src/felupe/constitution/jax/_hyperelastic.py index b4a99527..2af44e63 100644 --- a/src/felupe/constitution/autodiff/jax/_hyperelastic.py +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -20,7 +20,7 @@ import numpy as np -from ..._material import Material +from .._material import Material from ._tools import total_lagrange, vmap2 @@ -72,7 +72,7 @@ def neo_hooke(C, mu): "Strain energy function of the Neo-Hookean material formulation." return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) - umat = fem.constitution.autodiff.jax.Hyperelastic(neo_hooke, mu=1) + umat = fem.constitution.jax.Hyperelastic(neo_hooke, mu=1) and this code-block for material formulations with state variables. @@ -83,6 +83,7 @@ def neo_hooke(C, mu): .. code-block:: import felupe as fem + import felupe.constitution.jax as mat import jax.numpy as np def viscoelastic(C, Cin, mu, eta, dtime): @@ -101,9 +102,7 @@ def viscoelastic(C, Cin, mu, eta, dtime): # strain energy function and state variable return mu / 2 * (I1 - 3), Ci.ravel() - umat = fem.constitution.autodiff.jax.Hyperelastic( - viscoelastic, mu=1, eta=1, dtime=1, nstatevars=9 - ) + umat = mat.Hyperelastic(viscoelastic, mu=1, eta=1, dtime=1, nstatevars=9) .. note:: See the `documentation of JAX `_ for further @@ -120,13 +119,14 @@ def viscoelastic(C, Cin, mu, eta, dtime): :context: >>> import felupe as fem + >>> import felupe.constitution.jax as mat >>> import jax.numpy as jnp >>> >>> def neo_hooke(C, mu): ... "Strain energy function of the Neo-Hookean material formulation." ... return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) >>> - >>> umat = fem.constitution.autodiff.jax.Hyperelastic(neo_hooke, mu=1) + >>> umat = mat.Hyperelastic(neo_hooke, mu=1) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/autodiff/jax/_material.py b/src/felupe/constitution/jax/_material.py similarity index 94% rename from src/felupe/constitution/autodiff/jax/_material.py rename to src/felupe/constitution/jax/_material.py index 5fe604bf..6504d400 100644 --- a/src/felupe/constitution/autodiff/jax/_material.py +++ b/src/felupe/constitution/jax/_material.py @@ -20,7 +20,7 @@ import numpy as np -from ..._material import Material as MaterialDefault +from .._material import Material as MaterialDefault from ._tools import vmap2 @@ -63,6 +63,7 @@ class Material(MaterialDefault): .. code-block:: import felupe as fem + import felupe.constitution.jax as mat import jax.numpy as jnp def neo_hooke(F, mu): @@ -74,13 +75,14 @@ def neo_hooke(F, mu): return mu * F @ dev(Cu) @ jnp.linalg.inv(C) - umat = fem.constitution.autodiff.jax.Material(neo_hooke, mu=1) + umat = mat.Material(neo_hooke, mu=1) and this code-block for material formulations with state variables: .. code-block:: import felupe as fem + import felupe.constitution.jax as mat import jax.numpy as jnp def viscoelastic(F, Cin, mu, eta, dtime): @@ -104,9 +106,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): to_triu = lambda C: C[i, j] return F @ S, to_triu(Ci) - umat = fem.constitution.autodiff.jax.Material( - viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6 - ) + umat = mat.Material(viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6) .. note:: See the `documentation of JAX `_ for further @@ -123,6 +123,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): :context: >>> import felupe as fem + >>> import felupe.constitution.jax as mat >>> import jax.numpy as jnp >>> >>> def neo_hooke(F, mu): @@ -134,7 +135,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): ... ... return mu * F @ dev(Cu) @ jnp.linalg.inv(C) >>> - >>> umat = fem.constitution.autodiff.jax.Material(neo_hooke, mu=1) + >>> umat = mat.Material(neo_hooke, mu=1) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/autodiff/jax/_tools.py b/src/felupe/constitution/jax/_tools.py similarity index 100% rename from src/felupe/constitution/autodiff/jax/_tools.py rename to src/felupe/constitution/jax/_tools.py diff --git a/src/felupe/constitution/autodiff/jax/models/__init__.py b/src/felupe/constitution/jax/models/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/jax/models/__init__.py rename to src/felupe/constitution/jax/models/__init__.py diff --git a/src/felupe/constitution/autodiff/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/jax/models/hyperelastic/__init__.py rename to src/felupe/constitution/jax/models/hyperelastic/__init__.py diff --git a/src/felupe/constitution/autodiff/jax/models/lagrange/__init__.py b/src/felupe/constitution/jax/models/lagrange/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/jax/models/lagrange/__init__.py rename to src/felupe/constitution/jax/models/lagrange/__init__.py diff --git a/src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py b/src/felupe/constitution/jax/models/lagrange/_morph.py similarity index 98% rename from src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py rename to src/felupe/constitution/jax/models/lagrange/_morph.py index 4166133f..b7e242f7 100644 --- a/src/felupe/constitution/autodiff/jax/models/lagrange/_morph.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph.py @@ -122,9 +122,10 @@ def morph(F, statevars, p): :context: >>> import felupe as fem + >>> import felupe.constitution.jax as mat >>> - >>> umat = fem.constitution.autodiff.jax.Material( - ... fem.constitution.autodiff.jax.models.lagrange.morph, + >>> umat = mat.Material( + ... mat.models.lagrange.morph, ... p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], ... nstatevars=13, ... ) diff --git a/src/felupe/constitution/autodiff/tensortrax/__init__.py b/src/felupe/constitution/tensortrax/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/__init__.py rename to src/felupe/constitution/tensortrax/__init__.py diff --git a/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py b/src/felupe/constitution/tensortrax/_hyperelastic.py similarity index 98% rename from src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py rename to src/felupe/constitution/tensortrax/_hyperelastic.py index 6687034d..95ed7a85 100644 --- a/src/felupe/constitution/autodiff/tensortrax/_hyperelastic.py +++ b/src/felupe/constitution/tensortrax/_hyperelastic.py @@ -19,8 +19,8 @@ import numpy as np import tensortrax as tr -from ....math import cdya_ik, dot, transpose -from ..._material import Material +from ...math import cdya_ik, dot, transpose +from .._material import Material class Hyperelastic(Material): diff --git a/src/felupe/constitution/autodiff/tensortrax/_material.py b/src/felupe/constitution/tensortrax/_material.py similarity index 93% rename from src/felupe/constitution/autodiff/tensortrax/_material.py rename to src/felupe/constitution/tensortrax/_material.py index 3592404f..4b6e2368 100644 --- a/src/felupe/constitution/autodiff/tensortrax/_material.py +++ b/src/felupe/constitution/tensortrax/_material.py @@ -19,7 +19,7 @@ import numpy as np import tensortrax as tr -from ..._material import Material as MaterialDefault +from .._material import Material as MaterialDefault class Material(MaterialDefault): @@ -66,6 +66,7 @@ class Material(MaterialDefault): .. code-block:: import felupe as fem + import felupe.constitution.tensortrax as mat import tensortrax.math as tm def neo_hooke(F, mu): @@ -76,13 +77,14 @@ def neo_hooke(F, mu): return mu * F @ tm.special.dev(Cu) @ tm.linalg.inv(C) - umat = fem.MaterialAD(neo_hooke, mu=1) + umat = mat.Material(neo_hooke, mu=1) and this code-block for material formulations with state variables: .. code-block:: import felupe as fem + import felupe.constitution.tensortrax as mat import tensortrax.math as tm def viscoelastic(F, Cin, mu, eta, dtime): @@ -102,9 +104,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): # first Piola-Kirchhoff stress tensor and state variable return F @ S, tm.special.triu_1d(Ci) - umat = fem.MaterialAD( - viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6 - ) + umat = mat.Material(viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6) .. note:: See the `documentation of tensortrax `_ @@ -116,6 +116,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): :context: >>> import felupe as fem + >>> import felupe.constitution.tensortrax as mat >>> import tensortrax.math as tm >>> >>> def neo_hooke(F, mu): @@ -123,7 +124,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): ... S = mu * tm.special.dev(tm.linalg.det(C)**(-1/3) * C) @ tm.linalg.inv(C) ... return F @ S >>> - >>> umat = fem.MaterialAD(neo_hooke, mu=1) + >>> umat = mat.Material(neo_hooke, mu=1) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/autodiff/tensortrax/_total_lagrange.py b/src/felupe/constitution/tensortrax/_total_lagrange.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/_total_lagrange.py rename to src/felupe/constitution/tensortrax/_total_lagrange.py diff --git a/src/felupe/constitution/autodiff/tensortrax/_updated_lagrange.py b/src/felupe/constitution/tensortrax/_updated_lagrange.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/_updated_lagrange.py rename to src/felupe/constitution/tensortrax/_updated_lagrange.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/__init__.py b/src/felupe/constitution/tensortrax/models/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/__init__.py rename to src/felupe/constitution/tensortrax/models/__init__.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/__init__.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_alexander.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_alexander.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_alexander.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_alexander.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_anssari_benam_bucchi.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_arruda_boyce.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_arruda_boyce.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_arruda_boyce.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_arruda_boyce.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_extended_tube.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_extended_tube.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_extended_tube.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_extended_tube.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_finite_strain_viscoelastic.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_helpers.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_helpers.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_helpers.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_helpers.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_lopez_pamies.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_lopez_pamies.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_lopez_pamies.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_lopez_pamies.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_mooney_rivlin.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_mooney_rivlin.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_mooney_rivlin.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_mooney_rivlin.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_morph_representative_directions.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_morph_representative_directions.py similarity index 98% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_morph_representative_directions.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_morph_representative_directions.py index 064dfc8b..c9ca837e 100644 --- a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_morph_representative_directions.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_morph_representative_directions.py @@ -43,7 +43,7 @@ def morph_representative_directions(C, statevars, p, ε=1e-8): :context: >>> import felupe as fem - >>> import felupe.constitution.autodiff.tensortrax.models as models + >>> import felupe.constitution.tensortrax.models as models >>> >>> umat = fem.Hyperelastic( ... models.hyperelastic.morph_representative_directions, diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_neo_hooke.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_neo_hooke.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_neo_hooke.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_neo_hooke.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_ogden.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_ogden.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden_roxburgh.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_ogden_roxburgh.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_ogden_roxburgh.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_ogden_roxburgh.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_third_order_deformation.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_third_order_deformation.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_third_order_deformation.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_third_order_deformation.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_van_der_waals.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_van_der_waals.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_yeoh.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_yeoh.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/_yeoh.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/_yeoh.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/__init__.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/__init__.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_chain.py b/src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_chain.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_chain.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_chain.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_affine.py b/src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_framework_affine.py similarity index 97% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_affine.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_framework_affine.py index ae3053f4..2afe444e 100644 --- a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_affine.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_framework_affine.py @@ -1,7 +1,7 @@ from tensortrax.math import einsum, sqrt from tensortrax.math.linalg import det, inv -from .......quadrature import BazantOh +from ......quadrature import BazantOh def affine_stretch(C, f, kwargs, quadrature=BazantOh(n=21)): diff --git a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py b/src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py similarity index 95% rename from src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py rename to src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py index 7fd122e6..7f781324 100644 --- a/src/felupe/constitution/autodiff/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/microsphere/_framework_nonaffine.py @@ -1,7 +1,7 @@ from tensortrax.math import einsum, sqrt from tensortrax.math.linalg import det, inv -from .......quadrature import BazantOh +from ......quadrature import BazantOh def nonaffine_stretch(C, p, f, kwargs, quadrature=BazantOh(n=21)): diff --git a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/__init__.py b/src/felupe/constitution/tensortrax/models/lagrange/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/lagrange/__init__.py rename to src/felupe/constitution/tensortrax/models/lagrange/__init__.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph.py rename to src/felupe/constitution/tensortrax/models/lagrange/_morph.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_representative_directions.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_representative_directions.py rename to src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_uniaxial.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph_uniaxial.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/lagrange/_morph_uniaxial.py rename to src/felupe/constitution/tensortrax/models/lagrange/_morph_uniaxial.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/__init__.py b/src/felupe/constitution/tensortrax/models/lagrange/microsphere/__init__.py similarity index 100% rename from src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/__init__.py rename to src/felupe/constitution/tensortrax/models/lagrange/microsphere/__init__.py diff --git a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/_framework_affine.py b/src/felupe/constitution/tensortrax/models/lagrange/microsphere/_framework_affine.py similarity index 95% rename from src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/_framework_affine.py rename to src/felupe/constitution/tensortrax/models/lagrange/microsphere/_framework_affine.py index b9ae90bb..1864e5e5 100644 --- a/src/felupe/constitution/autodiff/tensortrax/models/lagrange/microsphere/_framework_affine.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/microsphere/_framework_affine.py @@ -1,7 +1,7 @@ from tensortrax.math import einsum, sqrt, trace from tensortrax.math.linalg import det, inv -from .......quadrature import BazantOh +from ......quadrature import BazantOh from ...._total_lagrange import total_lagrange diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 94f7a5e8..4e436101 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -29,7 +29,7 @@ import pytest import felupe as fem -import felupe.constitution.autodiff.tensortrax.models as models +import felupe.constitution.tensortrax.models as models def pre(sym, add_identity, add_random=False): diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index d58bd901..97321173 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -28,6 +28,7 @@ import pytest import felupe as fem +import felupe.constitution.jax as mat def test_vmap(): @@ -39,8 +40,8 @@ def f(x, a=1.0): def g(x, y, a=1.0, **kwargs): return x - vf = fem.constitution.autodiff.jax.vmap(f) - vg = fem.constitution.autodiff.jax.vmap(g) + vf = fem.constitution.jax.vmap(f) + vg = fem.constitution.jax.vmap(g) x = np.eye(3).reshape(1, 3, 3) * np.ones((10, 1, 1)) @@ -69,10 +70,8 @@ def W(C, C10, K): I1 = I3 ** (-1 / 3) * jnp.trace(C) return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2 - umat = fem.constitution.autodiff.jax.Hyperelastic( - W, C10=0.5, K=2.0, parallel=True - ) - umat = fem.constitution.autodiff.jax.Hyperelastic(W, C10=0.5, K=2.0, jit=True) + umat = fem.constitution.jax.Hyperelastic(W, C10=0.5, K=2.0, parallel=True) + umat = mat.Hyperelastic(W, C10=0.5, K=2.0, jit=True) mesh = fem.Cube(n=2) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) @@ -103,9 +102,7 @@ def W(C, statevars, C10, K): W.kwargs = {"C10": 0.5} - umat = fem.constitution.autodiff.jax.Hyperelastic( - W, C10=0.5, K=2.0, nstatevars=1, jit=True - ) + umat = mat.Hyperelastic(W, C10=0.5, K=2.0, nstatevars=1, jit=True) mesh = fem.Cube(n=2) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) @@ -136,10 +133,8 @@ def dWdF(F, C10, K): P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) return P + K * (J - 1) * J * jnp.linalg.inv(C) - umat = fem.constitution.autodiff.jax.Material( - dWdF, C10=0.5, K=2.0, parallel=True - ) - umat = fem.constitution.autodiff.jax.Material(dWdF, C10=0.5, K=2.0, jit=True) + umat = mat.Material(dWdF, C10=0.5, K=2.0, parallel=True) + umat = fem.constitution.jax.Material(dWdF, C10=0.5, K=2.0, jit=True) mesh = fem.Cube(n=2) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) @@ -173,9 +168,7 @@ def dWdF(F, statevars, C10, K): dWdF.kwargs = {"C10": 0.5} - umat = fem.constitution.autodiff.jax.Material( - dWdF, C10=0.5, K=2.0, nstatevars=1, jit=True - ) + umat = mat.Material(dWdF, C10=0.5, K=2.0, nstatevars=1, jit=True) mesh = fem.Cube(n=2) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) @@ -195,8 +188,8 @@ def dWdF(F, statevars, C10, K): def test_material_included_jax_statevars(): try: - umat = fem.constitution.autodiff.jax.Material( - fem.constitution.autodiff.jax.models.lagrange.morph, + umat = mat.Material( + fem.constitution.jax.models.lagrange.morph, p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], nstatevars=13, ) From 5c0eba8ce58f5de2a35aef1373077a29b6319f14 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:15:29 +0100 Subject: [PATCH 066/125] remove deprecated aliases --- src/felupe/__init__.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/felupe/__init__.py b/src/felupe/__init__.py index 4c679413..e6200f28 100644 --- a/src/felupe/__init__.py +++ b/src/felupe/__init__.py @@ -141,10 +141,6 @@ from .view import ViewSolid as View from .view import ViewXdmf -UserMaterial = Material # alias to be removed in v8.0.0 -UserMaterialStrain = MaterialStrain # alias to be removed in v8.0.0 -UserMaterialHyperelastic = Hyperelastic # alias to be removed in v8.0.0 - __all__ = [ "__version__", "constitution", @@ -289,7 +285,4 @@ "ViewXdmf", "ViewSolid", "runs_on", - "UserMaterial", # to be removed in v8.0.0 - "UserMaterialStrain", # to be removed in v8.0.0 - "UserMaterialHyperelastic", # to be removed in v8.0.0 ] From 26c204396c52f157759e2aa22df1674e9f66c192 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:17:21 +0100 Subject: [PATCH 067/125] Enhance the docs on automatic differentiation --- docs/felupe/constitution.rst | 8 +- docs/felupe/constitution/autodiff.rst | 47 ++++++++ .../constitution/{ => autodiff}/jax.rst | 6 +- .../constitution/autodiff/tensortrax.rst | 105 ++++++++++++++++++ docs/felupe/constitution/core.rst | 2 +- docs/felupe/constitution/hyperelasticity.rst | 76 ------------- docs/felupe/constitution/lagrange.rst | 48 -------- docs/howto/umat_hyperelasticity.rst | 2 +- docs/index.rst | 2 +- .../examples/extut03_building_blocks.py | 25 +++-- src/felupe/constitution/_view.py | 18 +-- src/felupe/constitution/jax/_hyperelastic.py | 3 +- .../constitution/tensortrax/_hyperelastic.py | 13 ++- .../tensortrax/_total_lagrange.py | 3 +- .../tensortrax/_updated_lagrange.py | 3 +- 15 files changed, 199 insertions(+), 162 deletions(-) create mode 100644 docs/felupe/constitution/autodiff.rst rename docs/felupe/constitution/{ => autodiff}/jax.rst (85%) create mode 100644 docs/felupe/constitution/autodiff/tensortrax.rst delete mode 100644 docs/felupe/constitution/hyperelasticity.rst delete mode 100644 docs/felupe/constitution/lagrange.rst diff --git a/docs/felupe/constitution.rst b/docs/felupe/constitution.rst index bdeca712..83db3487 100644 --- a/docs/felupe/constitution.rst +++ b/docs/felupe/constitution.rst @@ -10,14 +10,12 @@ This module provides :class:`constitutive material :caption: Constitution: constitution/core - constitution/hyperelasticity - constitution/lagrange + constitution/autodiff constitution/tools - constitution/jax There are many different pre-defined constitutive material formulations available, including definitions for linear-elasticity, small-strain plasticity, hyperelasticity or pseudo-elasticity. The generation of user materials may be simplified when using frameworks for user-defined functions, like hyperelasticity (with automatic differentiation) or a small-strain based framework with state variables. However, the most general case is given by a framework with functions for the evaluation of stress and elasticity tensors in terms of the deformation gradient. -**Constitutive material formulation** +**Constitutive Material Formulation** .. currentmodule:: felupe @@ -26,7 +24,7 @@ There are many different pre-defined constitutive material formulations availabl ConstitutiveMaterial constitutive_material -**Deformation Gradient-based User Materials** +**Deformation Gradient-based Materials** .. autosummary:: diff --git a/docs/felupe/constitution/autodiff.rst b/docs/felupe/constitution/autodiff.rst new file mode 100644 index 00000000..78045c99 --- /dev/null +++ b/docs/felupe/constitution/autodiff.rst @@ -0,0 +1,47 @@ +.. _felupe-api-constitution-autodiff: + +Automatic Differentiation +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + :caption: Constitution: + + constitution/autodiff/tensortrax + constitution/autodiff/jax + +FElupe supports multiple backends for constitutive material formulations with +automatic differentiation. The default backend is based on :mod:`tensortrax` which ships +with FElupe. For more computationally expensive material formulations, :mod:`jax` may +be the preferred option. + +It is straightforward to switch between these backends. + +.. tab:: tensortrax + + .. code-block:: + + import felupe as fem + import felupe.constitution.tensortrax as mat + import tensortrax.math as tm + + def neo_hooke(C, mu): + "Strain energy function of the Neo-Hookean material formulation." + return mu / 2 * (tm.linalg.det(C) ** (-1/3) * tm.trace(C) - 3) + + umat = mat.Hyperelastic(neo_hooke, mu=1.0) + + +.. tab:: JAX + + .. code-block:: + + import felupe as fem + import felupe.constitution.jax as mat + import jax.numpy as jnp + + def neo_hooke(C, mu): + "Strain energy function of the Neo-Hookean material formulation." + return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) + + umat = mat.Hyperelastic(neo_hooke, mu=1.0) \ No newline at end of file diff --git a/docs/felupe/constitution/jax.rst b/docs/felupe/constitution/autodiff/jax.rst similarity index 85% rename from docs/felupe/constitution/jax.rst rename to docs/felupe/constitution/autodiff/jax.rst index 0024beae..9e7a1d80 100644 --- a/docs/felupe/constitution/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -1,7 +1,7 @@ -.. _felupe-api-constitution-jax: +.. _felupe-api-constitution-autodiff-jax: -JAX-based Materials -~~~~~~~~~~~~~~~~~~~ +Materials with Automatic Differentiation (JAX) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This page contains material model formulations with automatic differentiation using :mod:`jax`. diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst new file mode 100644 index 00000000..7754e1cd --- /dev/null +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -0,0 +1,105 @@ +.. _felupe-api-constitution-autodiff-tensortrax: + +Materials with Automatic Differentiation (tensortrax) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This page contains hyperelastic material model formulations with automatic differentiation using :mod:`tensortrax.math`. + +.. figure:: /_static/logo_tensortrax.png + :align: center + + Differentiable Tensors based on NumPy Arrays. + +**Frameworks** + +.. currentmodule:: felupe + +.. autosummary:: + + constitution.tensortrax.Hyperelastic + constitution.tensortrax.Material + constitution.tensortrax.total_lagrange + constitution.tensortrax.updated_lagrange + +**Material Models for** :class:`felupe.constitution.tensortrax.Hyperelastic` + +These material model formulations are defined by a strain energy density function. + +.. autosummary:: + + alexander + anssari_benam_bucchi + arruda_boyce + extended_tube + finite_strain_viscoelastic + lopez_pamies + miehe_goektepe_lulei + mooney_rivlin + neo_hooke + ogden + ogden_roxburgh + saint_venant_kirchhoff + third_order_deformation + van_der_waals + yeoh + +**Material Models for** :class:`~felupe.constitution.tensortrax.Material` + +The material model formulations are defined by the first Piola-Kirchhoff stress tensor. +Function-decorators are available to use Total-Lagrange and Updated-Lagrange material +formulations in :class:`~felupe.constitution.tensortrax.Material`. + +.. autosummary:: + + morph + morph_representative_directions + +**Detailed API Reference** + +.. autoclass:: constitution.tensortrax.Hyperelastic + :members: + :undoc-members: + :inherited-members: + +.. autoclass:: constitution.tensortrax.Material + :members: + :undoc-members: + :inherited-members: + +.. autofunction:: felupe.total_lagrange + +.. autofunction:: felupe.updated_lagrange + +.. autofunction:: felupe.alexander + +.. autofunction:: felupe.anssari_benam_bucchi + +.. autofunction:: felupe.arruda_boyce + +.. autofunction:: felupe.extended_tube + +.. autofunction:: felupe.finite_strain_viscoelastic + +.. autofunction:: felupe.lopez_pamies + +.. autofunction:: felupe.miehe_goektepe_lulei + +.. autofunction:: felupe.mooney_rivlin + +.. autofunction:: felupe.neo_hooke + +.. autofunction:: felupe.ogden + +.. autofunction:: felupe.ogden_roxburgh + +.. autofunction:: felupe.saint_venant_kirchhoff + +.. autofunction:: felupe.third_order_deformation + +.. autofunction:: felupe.van_der_waals + +.. autofunction:: felupe.yeoh + +.. autofunction:: felupe.morph + +.. autofunction:: felupe.morph_representative_directions \ No newline at end of file diff --git a/docs/felupe/constitution/core.rst b/docs/felupe/constitution/core.rst index 7cd91dd3..e3246c4b 100644 --- a/docs/felupe/constitution/core.rst +++ b/docs/felupe/constitution/core.rst @@ -45,7 +45,7 @@ This page contains the core (hard-coded) constitutive material model formulation ThreeFieldVariation NearlyIncompressible -**Small Strain-based User Materials** +**Small Strain-based Materials** .. autosummary:: diff --git a/docs/felupe/constitution/hyperelasticity.rst b/docs/felupe/constitution/hyperelasticity.rst deleted file mode 100644 index f929ff05..00000000 --- a/docs/felupe/constitution/hyperelasticity.rst +++ /dev/null @@ -1,76 +0,0 @@ -.. _felupe-api-constitution-hyperelasticity: - -Hyperelasticity -~~~~~~~~~~~~~~~ - -This page contains hyperelastic material model formulations with automatic differentiation using :mod:`tensortrax.math`. These material model formulations are defined by a strain energy density function. - -.. figure:: /_static/logo_tensortrax.png - :align: center - - Differentiable Tensors based on NumPy Arrays. - -**Frameworks** - -.. currentmodule:: felupe - -.. autosummary:: - - Hyperelastic - -**Material Models (Strain Energy Functions) for** :class:`~felupe.Hyperelastic` - -.. autosummary:: - - alexander - anssari_benam_bucchi - arruda_boyce - extended_tube - finite_strain_viscoelastic - lopez_pamies - miehe_goektepe_lulei - mooney_rivlin - neo_hooke - ogden - ogden_roxburgh - saint_venant_kirchhoff - third_order_deformation - van_der_waals - yeoh - -**Detailed API Reference** - -.. autoclass:: felupe.Hyperelastic - :members: - :undoc-members: - :inherited-members: - -.. autofunction:: felupe.alexander - -.. autofunction:: felupe.anssari_benam_bucchi - -.. autofunction:: felupe.arruda_boyce - -.. autofunction:: felupe.extended_tube - -.. autofunction:: felupe.finite_strain_viscoelastic - -.. autofunction:: felupe.lopez_pamies - -.. autofunction:: felupe.miehe_goektepe_lulei - -.. autofunction:: felupe.mooney_rivlin - -.. autofunction:: felupe.neo_hooke - -.. autofunction:: felupe.ogden - -.. autofunction:: felupe.ogden_roxburgh - -.. autofunction:: felupe.saint_venant_kirchhoff - -.. autofunction:: felupe.third_order_deformation - -.. autofunction:: felupe.van_der_waals - -.. autofunction:: felupe.yeoh diff --git a/docs/felupe/constitution/lagrange.rst b/docs/felupe/constitution/lagrange.rst deleted file mode 100644 index 29470667..00000000 --- a/docs/felupe/constitution/lagrange.rst +++ /dev/null @@ -1,48 +0,0 @@ -.. _felupe-api-constitution-lagrange: - -Total- & Updated-Lagrange -~~~~~~~~~~~~~~~~~~~~~~~~ - -This page contains Total- and Updated-Lagrange material formulations with automatic differentiation using :mod:`tensortrax.math`. The material model formulations are defined by the first Piola-Kirchhoff stress tensor. Function-decorators are available to use Total-Lagrange and Updated-Lagrange material formulations in :class:`~felupe.MaterialAD`. - -.. figure:: /_static/logo_tensortrax.png - :align: center - - Differentiable Tensors based on NumPy Arrays. - -**Frameworks** - -.. currentmodule:: felupe - -.. autosummary:: - - MaterialAD - total_lagrange - updated_lagrange - -**Material Models for** :class:`~felupe.MaterialAD` - -.. autosummary:: - - morph - morph_representative_directions - -**Detailed API Reference** - -.. autoclass:: felupe.MaterialAD - :members: - :undoc-members: - :inherited-members: - -.. autoclass:: felupe.constitution.tensortrax.Material - :members: - :undoc-members: - :inherited-members: - -.. autofunction:: felupe.morph - -.. autofunction:: felupe.morph_representative_directions - -.. autofunction:: felupe.total_lagrange - -.. autofunction:: felupe.updated_lagrange diff --git a/docs/howto/umat_hyperelasticity.rst b/docs/howto/umat_hyperelasticity.rst index 31ce6074..af5eab1c 100644 --- a/docs/howto/umat_hyperelasticity.rst +++ b/docs/howto/umat_hyperelasticity.rst @@ -33,4 +33,4 @@ FElupe contains several reference implementations of hyperelastic user material * :func:`~felupe.yeoh` or * :func:`~felupe.ogden`. -A complete list of all available model formulations is available in the :ref:`hyperelasticity ` section of the API reference. +A complete list of all available model formulations is available in the :ref:`hyperelasticity ` section of the API reference. diff --git a/docs/index.rst b/docs/index.rst index ba1266b0..1e37d496 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -47,7 +47,7 @@ FElupe is a Python 3.9+ 🐍 finite element analysis package 📦 focusing on th + cartesian, axisymmetric, plane strain and mixed fields - + :ref:`hyperelastic material models ` + + :ref:`hyperelastic material models ` + strain energy density functions with :class:`automatic differentiation ` diff --git a/docs/tutorial/examples/extut03_building_blocks.py b/docs/tutorial/examples/extut03_building_blocks.py index e03e43ad..b164577e 100644 --- a/docs/tutorial/examples/extut03_building_blocks.py +++ b/docs/tutorial/examples/extut03_building_blocks.py @@ -120,18 +120,21 @@ # library (see :ref:`felupe-api-constitution`) including :class:`~felupe.NeoHooke`, # :class:`~felupe.LinearElastic` and a generalized Hu-Washizu (u,p,J) # :class:`~felupe.ThreeFieldVariation`. By alternative, an isotropic material -# formulation :class:`~felupe.Hyperelastic` is defined by a strain energy density -# function where both variation (stress) and linearization (elasticity) are carried out -# by automatic differentiation. The latter one is demonstrated here with a nearly- -# incompressible version of the Neo-Hookean material model formulation. +# formulation :class:`~felupe.constitution.tensortrax.Hyperelastic` is defined by a +# strain energy density function where both variation (stress) and linearization +# (elasticity) are carried out by automatic differentiation. The latter one is +# demonstrated here with a nearly-incompressible version of the Neo-Hookean material +# model formulation. # # .. note:: -# It is important to use only automatic-differentiable math-functions from the +# FElupe supports different backends for automatic differentiation and uses +# `tensortrax `_ by default. It is important to +# use only differentiable math-functions from the backend, e.g. # NumPy-like modules `tensortrax.math `_, # `tensortrax.math.linalg `_ or -# `tensortrax.math.special `_. TensorTRAX is a -# dependency of FElupe and hence, is installed along with -# `FElupe `_. +# `tensortrax.math.special `_. +# `tensortrax `_ is a dependency of FElupe and +# hence, is installed along with `FElupe `_. # # .. math:: # @@ -139,16 +142,18 @@ # + \frac{K}{2} \left( J - 1 \right)^2 import tensortrax.math as tm +import felupe.constitution.tensortrax as mat + def W(C, mu, bulk): - "Neo-Hooke" + "Isotropic hyperelastic Neo-Hookean material formulation." J = tm.sqrt(tm.linalg.det(C)) return mu / 2 * (J ** (-2 / 3) * tm.trace(C) - 3) + bulk * (J - 1) ** 2 / 2 -umat = fem.Hyperelastic(W, mu=1.0, bulk=2.0) +umat = mat.Hyperelastic(W, mu=1.0, bulk=2.0) P = umat.gradient A = umat.hessian diff --git a/src/felupe/constitution/_view.py b/src/felupe/constitution/_view.py index a4070df4..6c93419f 100644 --- a/src/felupe/constitution/_view.py +++ b/src/felupe/constitution/_view.py @@ -37,7 +37,7 @@ class PlotMaterial: "Plot force-stretch curves of constitutive material formulations." def evaluate(self): - """Evaluate normal force per undeformed area vs. stretch curves for the + """Evaluate normal force per undeformed area vs stretch curves for the elementary homogeneous incompressible deformations uniaxial tension/compression, planar shear and biaxial tension. A load case is not included if its array of stretches (attribute ``ux``, ``ps`` or ``bx``) is None. @@ -67,7 +67,7 @@ def evaluate(self): return data def plot(self, ax=None, show_title=True, show_kwargs=True, **kwargs): - """Plot normal force per undeformed area vs. stretch curves for the elementary + """Plot normal force per undeformed area vs stretch curves for the elementary homogeneous incompressible deformations uniaxial tension/compression, planar shear and biaxial tension.""" @@ -126,7 +126,7 @@ def plot(self, ax=None, show_title=True, show_kwargs=True, **kwargs): class ViewMaterial(PlotMaterial): - """Create views on normal force per undeformed area vs. stretch curves for the + """Create views on normal force per undeformed area vs stretch curves for the elementary homogeneous deformations uniaxial tension/compression, planar shear and biaxial tension of a given isotropic material formulation. @@ -259,7 +259,7 @@ def fun(λ3): return λ1, P[0, 0].ravel(), "Uniaxial" def planar(self, stretches=None): - """Normal force per undeformed area vs. stretch curve for a planar shear + """Normal force per undeformed area vs stretch curve for a planar shear incompressible deformation. Parameters @@ -323,7 +323,7 @@ def fun(λ3): return λ1, P[0, 0].ravel(), "Planar Shear" def biaxial(self, stretches=None): - """Normal force per undeformed area vs. stretch curve for a equi-biaxial + """Normal force per undeformed area vs stretch curve for a equi-biaxial incompressible deformation. Parameters @@ -387,7 +387,7 @@ def fun(λ3): class ViewMaterialIncompressible(PlotMaterial): - """Create views on normal force per undeformed area vs. stretch curves for the + """Create views on normal force per undeformed area vs stretch curves for the elementary homogeneous incompressible deformations uniaxial tension/compression, planar shear and biaxial tension of a given isotropic material formulation. @@ -473,7 +473,7 @@ def __init__( self.statevars = statevars def uniaxial(self, stretches=None): - """Normal force per undeformed area vs. stretch curve for a uniaxial + """Normal force per undeformed area vs stretch curve for a uniaxial incompressible deformation. Parameters @@ -512,7 +512,7 @@ def uniaxial(self, stretches=None): return λ1, (P[0, 0] - λ3 / λ1 * P[2, 2]).ravel(), "Uniaxial (Incompressible)" def planar(self, stretches=None): - """Normal force per undeformed area vs. stretch curve for a planar shear + """Normal force per undeformed area vs stretch curve for a planar shear incompressible deformation. Parameters @@ -556,7 +556,7 @@ def planar(self, stretches=None): ) def biaxial(self, stretches=None): - """Normal force per undeformed area vs. stretch curve for a equi-biaxial + """Normal force per undeformed area vs stretch curve for a equi-biaxial incompressible deformation. Parameters diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py index 2af44e63..0deb6fc9 100644 --- a/src/felupe/constitution/jax/_hyperelastic.py +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -66,13 +66,14 @@ class Hyperelastic(Material): .. code-block:: import felupe as fem + import felupe.constitution.jax as mat import jax.numpy as jnp def neo_hooke(C, mu): "Strain energy function of the Neo-Hookean material formulation." return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) - umat = fem.constitution.jax.Hyperelastic(neo_hooke, mu=1) + umat = mat.Hyperelastic(neo_hooke, mu=1) and this code-block for material formulations with state variables. diff --git a/src/felupe/constitution/tensortrax/_hyperelastic.py b/src/felupe/constitution/tensortrax/_hyperelastic.py index 95ed7a85..abfd5e33 100644 --- a/src/felupe/constitution/tensortrax/_hyperelastic.py +++ b/src/felupe/constitution/tensortrax/_hyperelastic.py @@ -64,13 +64,15 @@ class Hyperelastic(Material): .. code-block:: + import felupe as fem + import felupe.constitution.tensortrax as mat import tensortrax.math as tm def neo_hooke(C, mu): "Strain energy function of the Neo-Hookean material formulation." return mu / 2 * (tm.linalg.det(C) ** (-1/3) * tm.trace(C) - 3) - umat = fem.Hyperelastic(neo_hooke, mu=1) + umat = mat.Hyperelastic(neo_hooke, mu=1) and this code-block for material formulations with state variables. @@ -80,6 +82,8 @@ def neo_hooke(C, mu): .. code-block:: + import felupe as fem + import felupe.constitution.tensortrax as mat import tensortrax.math as tm def viscoelastic(C, Cin, mu, eta, dtime): @@ -98,9 +102,7 @@ def viscoelastic(C, Cin, mu, eta, dtime): # strain energy function and state variable return mu / 2 * (I1 - 3), tm.special.triu_1d(Ci) - umat = fem.Hyperelastic( - viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6 - ) + umat = mat.Hyperelastic(viscoelastic, mu=1, eta=1, dtime=1, nstatevars=6) .. note:: See the `documentation of tensortrax `_ @@ -114,13 +116,14 @@ def viscoelastic(C, Cin, mu, eta, dtime): :context: >>> import felupe as fem + >>> import felupe.constitution.jax as mat >>> import tensortrax.math as tm >>> >>> def neo_hooke(C, mu): ... "Strain energy function of the Neo-Hookean material formulation." ... return mu / 2 * (tm.linalg.det(C) ** (-1/3) * tm.trace(C) - 3) >>> - >>> umat = fem.Hyperelastic(neo_hooke, mu=1) + >>> umat = mat.Hyperelastic(neo_hooke, mu=1) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/tensortrax/_total_lagrange.py b/src/felupe/constitution/tensortrax/_total_lagrange.py index 69247544..4c708f4c 100644 --- a/src/felupe/constitution/tensortrax/_total_lagrange.py +++ b/src/felupe/constitution/tensortrax/_total_lagrange.py @@ -33,6 +33,7 @@ def total_lagrange(material): Examples -------- >>> import felupe as fem + >>> import felupe.constitution.tensortrax as mat >>> import tensortrax.math as tm >>> >>> @fem.total_lagrange @@ -41,7 +42,7 @@ def total_lagrange(material): >>> S = mu * tm.special.dev(tm.linalg.det(C)**(-1/3) * C) @ tm.linalg.inv(C) >>> return S >>> - >>> umat = fem.MaterialAD(neo_hooke_total_lagrange, mu=1) + >>> umat = mat.Material(neo_hooke_total_lagrange, mu=1) See Also -------- diff --git a/src/felupe/constitution/tensortrax/_updated_lagrange.py b/src/felupe/constitution/tensortrax/_updated_lagrange.py index 25ea2dff..03886979 100644 --- a/src/felupe/constitution/tensortrax/_updated_lagrange.py +++ b/src/felupe/constitution/tensortrax/_updated_lagrange.py @@ -34,6 +34,7 @@ def updated_lagrange(material): Examples -------- >>> import felupe as fem + >>> import felupe.constitution.tensortrax as mat >>> import tensortrax.math as tm >>> >>> @fem.updated_lagrange @@ -43,7 +44,7 @@ def updated_lagrange(material): >>> σ = mu * tm.special.dev(J**(-2/3) * b) / J >>> return σ >>> - >>> umat = fem.MaterialAD(neo_hooke_updated_lagrange, mu=1) + >>> umat = mat.Material(neo_hooke_updated_lagrange, mu=1) See Also -------- From bf5e7be32777231f9742f2d6d139f4f89993be17 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:19:16 +0100 Subject: [PATCH 068/125] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c87e698..2e5ce6e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,9 @@ All notable changes to this project will be documented in this file. The format - Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. - Fix wrong results of `ConstitutiveMaterial.plot()` if any stretch is non-physical, i.e. lower or equal zero. This raises an error now. +# Removed +- Remove the unused, deprecated aliases `UserMaterial`, `UserMaterialStrain` and `UserMaterialHyperelastic`. + ## [9.0.0] - 2024-09-06 ### Added From b319d4e0b401fbe0991815d6f584727b1dc0de2f Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:21:37 +0100 Subject: [PATCH 069/125] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 01cd19e5..babb6a70 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ FElupe is a Python 3.9+ 🐍 finite element analysis package 📦 focusing on th - [x] interactive views on meshes, fields and solid bodies (using [PyVista](https://pyvista.org/)) - [x] typical [finite elements](https://felupe.readthedocs.io/en/latest/felupe/element.html) - [x] cartesian, axisymmetric, plane strain and mixed fields -- [x] [hyperelastic material models](https://felupe.readthedocs.io/en/latest/felupe/constitution/hyperelasticity.html) -- [x] strain energy density functions with [automatic differentiation](https://felupe.readthedocs.io/en/latest/felupe/constitution/hyperelasticity.html#felupe.Hyperelastic) +- [x] [hyperelastic material models](https://felupe.readthedocs.io/en/latest/felupe/constitution.html) +- [x] strain energy density functions with automatic differentiation Efficient [NumPy](https://numpy.org/)-based math is realized by element-wise operating *trailing axes* [[1]](https://doi.org/10.21105/joss.02369). The finite element method, as used in FElupe, is based on [[2]](https://doi.org/10.1017/cbo9780511755446), [[3]]() and [[4]](https://doi.org/10.1016/c2009-0-24909-9). Related scientific articles are listed in the sections of the [API reference](https://felupe.readthedocs.io/en/latest/felupe.html). From 3cb72c3eec22d4bcc089a80214e27ccf79b9b7e2 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:22:35 +0100 Subject: [PATCH 070/125] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index babb6a70..4031d26f 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,7 @@ FElupe is a Python 3.9+ 🐍 finite element analysis package 📦 focusing on th - [x] interactive views on meshes, fields and solid bodies (using [PyVista](https://pyvista.org/)) - [x] typical [finite elements](https://felupe.readthedocs.io/en/latest/felupe/element.html) - [x] cartesian, axisymmetric, plane strain and mixed fields -- [x] [hyperelastic material models](https://felupe.readthedocs.io/en/latest/felupe/constitution.html) -- [x] strain energy density functions with automatic differentiation +- [x] [hyperelastic material models](https://felupe.readthedocs.io/en/latest/felupe/constitution.html) with automatic differentiation Efficient [NumPy](https://numpy.org/)-based math is realized by element-wise operating *trailing axes* [[1]](https://doi.org/10.21105/joss.02369). The finite element method, as used in FElupe, is based on [[2]](https://doi.org/10.1017/cbo9780511755446), [[3]]() and [[4]](https://doi.org/10.1016/c2009-0-24909-9). Related scientific articles are listed in the sections of the [API reference](https://felupe.readthedocs.io/en/latest/felupe.html). From 4cfec76b92ef88514f672892a428caee482c5ef1 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:23:03 +0100 Subject: [PATCH 071/125] Update index.rst --- docs/index.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 1e37d496..02571a89 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -47,9 +47,7 @@ FElupe is a Python 3.9+ 🐍 finite element analysis package 📦 focusing on th + cartesian, axisymmetric, plane strain and mixed fields - + :ref:`hyperelastic material models ` - - + strain energy density functions with :class:`automatic differentiation ` + + :ref:`hyperelastic material models ` with :class:`automatic differentiation ` Installation From b42871ddcb9a1548c801201c8665a1ad5523e051 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:24:27 +0100 Subject: [PATCH 072/125] Update tensortrax.rst --- docs/felupe/constitution/autodiff/tensortrax.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index 7754e1cd..fede9bd4 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -56,12 +56,22 @@ formulations in :class:`~felupe.constitution.tensortrax.Material`. **Detailed API Reference** -.. autoclass:: constitution.tensortrax.Hyperelastic +.. autoclass:: felupe.constitution.tensortrax.Hyperelastic :members: :undoc-members: :inherited-members: -.. autoclass:: constitution.tensortrax.Material +.. autoclass:: felupe.constitution.tensortrax.Material + :members: + :undoc-members: + :inherited-members: + +.. autoclass:: felupe.Hyperelastic + :members: + :undoc-members: + :inherited-members: + +.. autoclass:: felupe.MaterialAD :members: :undoc-members: :inherited-members: From dddca3999eaa519a1b9f9caf78411dd5620db398 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:43:20 +0100 Subject: [PATCH 073/125] Update autodiff.rst --- docs/felupe/constitution/autodiff.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/felupe/constitution/autodiff.rst b/docs/felupe/constitution/autodiff.rst index 78045c99..48ca8d38 100644 --- a/docs/felupe/constitution/autodiff.rst +++ b/docs/felupe/constitution/autodiff.rst @@ -5,10 +5,10 @@ Automatic Differentiation .. toctree:: :maxdepth: 1 - :caption: Constitution: + :caption: Automatic Differentiation: - constitution/autodiff/tensortrax - constitution/autodiff/jax + autodiff/tensortrax + autodiff/jax FElupe supports multiple backends for constitutive material formulations with automatic differentiation. The default backend is based on :mod:`tensortrax` which ships From 9e75104268e07f96c6bbeab705338cd38ccb7fa6 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:45:15 +0100 Subject: [PATCH 074/125] Update tensortrax.rst --- docs/felupe/constitution/autodiff/tensortrax.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index fede9bd4..213fd5e3 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -43,7 +43,7 @@ These material model formulations are defined by a strain energy density functio van_der_waals yeoh -**Material Models for** :class:`~felupe.constitution.tensortrax.Material` +**Material Models for** :class:`felupe.constitution.tensortrax.Material` The material model formulations are defined by the first Piola-Kirchhoff stress tensor. Function-decorators are available to use Total-Lagrange and Updated-Lagrange material From 64e5e68252748d9c29d2489861afa348a72f1ae3 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 10:45:56 +0100 Subject: [PATCH 075/125] Update autodiff.rst --- docs/felupe/constitution/autodiff.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/felupe/constitution/autodiff.rst b/docs/felupe/constitution/autodiff.rst index 48ca8d38..fb8cc96a 100644 --- a/docs/felupe/constitution/autodiff.rst +++ b/docs/felupe/constitution/autodiff.rst @@ -17,7 +17,7 @@ be the preferred option. It is straightforward to switch between these backends. -.. tab:: tensortrax +.. tab:: tensortrax (default) .. code-block:: From 6d921e81d2ee927ce2b1f8ae963b7328c7f8b2f6 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 11:00:56 +0100 Subject: [PATCH 076/125] Update conf.py --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 14f1da2b..75d8e0f6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -79,7 +79,7 @@ "within_subsection_order": FileNameSortKey, } intersphinx_mapping = { - "jax": ("https://jax.readthedocs.io/en/stable", None), + "jax": ("https://jax.readthedocs.io/en/stable/", None), "matplotlib": ("https://matplotlib.org/stable/", None), "numpy": ("https://numpy.org/doc/stable/", None), "python": ("https://docs.python.org/3/", None), From d8e470383e6412c9ada6a717679bc07b72724318 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 11:13:37 +0100 Subject: [PATCH 077/125] Update tensortrax.rst --- docs/felupe/constitution/autodiff/tensortrax.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index 213fd5e3..f3c46044 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -76,6 +76,10 @@ formulations in :class:`~felupe.constitution.tensortrax.Material`. :undoc-members: :inherited-members: +.. autofunction:: felupe.constitution.tensortrax.total_lagrange + +.. autofunction:: felupe.constitution.tensortrax.updated_lagrange + .. autofunction:: felupe.total_lagrange .. autofunction:: felupe.updated_lagrange From 9b57af1fc7f9c8511cab7e232847fbedd4e6e349 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 2 Nov 2024 18:13:38 +0100 Subject: [PATCH 078/125] Update ex13_morph-rubber-wheel.py switch to JAX backend --- examples/ex13_morph-rubber-wheel.py | 75 +++++++++++++++-------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/examples/ex13_morph-rubber-wheel.py b/examples/ex13_morph-rubber-wheel.py index e8652c3d..f8fbffaa 100644 --- a/examples/ex13_morph-rubber-wheel.py +++ b/examples/ex13_morph-rubber-wheel.py @@ -6,9 +6,9 @@ [1]_. While the rotation is increased, a constant vertical compression is applied to the rubber wheel by a frictionless contact on the bottom. The vertical reaction force is then carried out for the rotation angles. The MORPH material model is implemented as a -second Piola-Kirchhoff stress-based formulation with automatic differentiation. The -Tresca invariant of the distortional part of the right Cauchy-Green deformation tensor -is used as internal state variable, see Eq. :eq:`morph-state`. +second Piola-Kirchhoff stress-based formulation with automatic differentiation (JAX). +The Tresca invariant of the distortional part of the right Cauchy-Green deformation +tensor is used as internal state variable, see Eq. :eq:`morph-state`. .. warning:: While the `MORPH `_-material @@ -99,86 +99,87 @@ """ # sphinx_gallery_thumbnail_number = -1 import numpy as np -import tensortrax.math as tm - import felupe as fem +import felupe.constitution.jax as mat +from jax.scipy.linalg import expm +import jax.numpy as jnp -@fem.total_lagrange -def morph(F, statevars_old, p): +def morph(F, statevars, p): "MORPH material model formulation." # right Cauchy-Green deformation tensor C = F.T @ F # extract old state variables - CTSn = tm.array(statevars_old[0], like=C[0, 0]) - Cn = tm.special.from_triu_1d(statevars_old[1:7], like=C) - SAn = tm.special.from_triu_1d(statevars_old[7:13], like=C) + CTSn = statevars[0] + from_triu = lambda C: C[jnp.array([[0, 1, 2], [1, 3, 4], [2, 4, 5]])] + Cn = from_triu(statevars[1:7]) + SAn = from_triu(statevars[7:13]) # distortional part of right Cauchy-Green deformation tensor - I3 = tm.linalg.det(C) + I3 = jnp.linalg.det(C) CG = C * I3 ** (-1 / 3) # inverse of and incremental right Cauchy-Green deformation tensor - invC = tm.linalg.inv(C) + invC = jnp.linalg.inv(C) dC = C - Cn # eigenvalues of right Cauchy-Green deformation tensor (sorted in ascending order) - λCG = tm.linalg.eigvalsh(CG) + ε = jnp.diag(jnp.array([1e-4, -1e-4, 0])) + eigvalsh_ε = lambda C: jnp.linalg.eigvalsh(C + ε) + λCG = eigvalsh_ε(CG) # Tresca invariant of distortional part of right Cauchy-Green deformation tensor CTG = λCG[-1] - λCG[0] # maximum Tresca invariant in load history - CTS = tm.maximum(CTG, CTSn) + CTS = jnp.maximum(CTG, CTSn) - def f(x): + def sigmoid(x): "Algebraic sigmoid function." - return 1 / tm.sqrt(1 + x**2) + return 1 / jnp.sqrt(1 + x**2) # material parameters - α = p[0] + p[1] * f(p[2] * CTS) - β = p[3] * f(p[2] * CTS) - γ = p[4] * CTS * (1 - f(CTS / p[5])) + α = p[0] + p[1] * sigmoid(p[2] * CTS) + β = p[3] * sigmoid(p[2] * CTS) + γ = p[4] * CTS * (1 - sigmoid(CTS / p[5])) + + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + sym = lambda C: (C + C.T) / 2 - LG = tm.special.sym(tm.special.dev(invC @ dC)) @ CG - λLG = tm.linalg.eigvalsh(LG) + LG = sym(dev(invC @ dC)) @ CG + λLG = eigvalsh_ε(LG) LTG = λLG[-1] - λLG[0] - LG_LTG = tm.if_else(LTG > 0, LG / LTG, LG) # limiting stresses "L" and additional stresses "A" - SL = (γ * tm.linalg.expm(p[6] * LG_LTG * CTG / CTS) + p[7] * LG_LTG) @ invC + SL = (γ * expm(p[6] * LG / LTG * CTG / CTS) + p[7] * LG / LTG) @ invC SA = (SAn + β * LTG * SL) / (1 + β * LTG) # second Piola-Kirchhoff stress tensor - S = 2 * α * tm.special.dev(CG) @ invC + tm.special.dev(SA @ C) @ invC + S = 2 * α * dev(CG) @ invC + dev(SA @ C) @ invC - try: # update state variables - statevars_new = np.stack( - [CTS.x, *tm.special.triu_1d(C).x, *tm.special.triu_1d(SA).x] - ) - except: - # not possible (and not necessary) during AD-based hessian evaluation - statevars_new = statevars_old + # update the state variables + i, j = jnp.triu_indices(3) + to_triu = lambda C: C[i, j] + statevars_new = jnp.concatenate([jnp.array([CTS]), to_triu(C), to_triu(SA)]) - return S, statevars_new + return F @ S, statevars_new -umat = fem.MaterialAD( +umat = mat.Material( morph, p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], nstatevars=13, - # parallel=True, ) # %% # .. note:: # The MORPH material model formulation is also available in FElupe, see -# :class:`~felupe.morph`. +# :class:`~felupe.constitution.jax.models.lagrange.morph`. # # The force-stress curves are shown for uniaxial incompressible tension cycles. -ux = fem.math.linsteps([1, 1.5, 1, 2, 1, 2.5, 1, 2.5], num=(10, 10, 20, 20, 30, 30, 30)) +ux = fem.math.linsteps([1, 1.5, 1, 2, 1, 2.5, 1, 2.5], num=(5, 5, 10, 10, 15, 15, 15)) ax = umat.plot( ux=ux, bx=None, @@ -214,7 +215,7 @@ def f(x): "bottom-y": fem.dof.Boundary(field[0], fy=-1.1, value=0.2, skip=(1, 0)), } -angles_deg = fem.math.linsteps([0, 120], num=6) +angles_deg = fem.math.linsteps([0, 180], num=9) move = [] for phi in angles_deg: center = mesh.points[boundaries["move"].points] From 0947f51f57256e4d3005c92b5cb79d1f5ba010ec Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 3 Nov 2024 00:11:21 +0100 Subject: [PATCH 079/125] Fix JAX intersphinx switch from stable to latest --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 75d8e0f6..4626c7d7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -79,7 +79,7 @@ "within_subsection_order": FileNameSortKey, } intersphinx_mapping = { - "jax": ("https://jax.readthedocs.io/en/stable/", None), + "jax": ("https://jax.readthedocs.io/en/latest/", None), "matplotlib": ("https://matplotlib.org/stable/", None), "numpy": ("https://numpy.org/doc/stable/", None), "python": ("https://docs.python.org/3/", None), From 6d097421932c60e4de351700d2f627d01cb911bc Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 3 Nov 2024 00:11:46 +0100 Subject: [PATCH 080/125] enhance the examples --- examples/ex12_foot-bone.py | 12 ++-------- examples/ex13_morph-rubber-wheel.py | 35 ++++++++++++++++------------- examples/ex14_hyperelasticity.py | 2 +- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/examples/ex12_foot-bone.py b/examples/ex12_foot-bone.py index bbee8aac..d726689f 100644 --- a/examples/ex12_foot-bone.py +++ b/examples/ex12_foot-bone.py @@ -3,24 +3,16 @@ ------------------- A :class:`~felupe.Region` on a voxel-based mesh with uniform hexahedrons should be created with ``uniform=True`` to enhance performance. - -.. admonition:: This example requires external packages. - :class: hint - - .. code-block:: - - pip install pypardiso """ import numpy as np -import pypardiso import pyvista as pv from pyvista import examples import felupe as fem surface = examples.download_foot_bones() -voxels = pv.voxelize(surface, density=surface.length / 50) +voxels = pv.voxelize(surface, density=0.6) mesh = fem.Mesh( points=voxels.points, @@ -42,7 +34,7 @@ ) step = fem.Step(items=[solid, gravity, bottom], boundaries=boundaries) -job = fem.Job(steps=[step]).evaluate(solver=pypardiso.spsolve, parallel=True) +job = fem.Job(steps=[step]).evaluate() plotter = solid.plot( "Principal Values of Cauchy Stress", show_edges=False, diff --git a/examples/ex13_morph-rubber-wheel.py b/examples/ex13_morph-rubber-wheel.py index f8fbffaa..48a65019 100644 --- a/examples/ex13_morph-rubber-wheel.py +++ b/examples/ex13_morph-rubber-wheel.py @@ -8,7 +8,7 @@ then carried out for the rotation angles. The MORPH material model is implemented as a second Piola-Kirchhoff stress-based formulation with automatic differentiation (JAX). The Tresca invariant of the distortional part of the right Cauchy-Green deformation -tensor is used as internal state variable, see Eq. :eq:`morph-state`. +tensor is used as internal state variable, see Eq. :eq:`morph-state-ex`. .. warning:: While the `MORPH `_-material @@ -19,7 +19,7 @@ provides better stability but is computationally more costly [2]_, [3]_. .. math:: - :label: morph-state + :label: morph-state-ex \boldsymbol{C} &= \boldsymbol{F}^T \boldsymbol{F} @@ -34,10 +34,10 @@ \hat{C}_T^S &= \max \left( \hat{C}_T, \hat{C}_{T,n}^S \right) A sigmoid-function is used inside the deformation-dependent variables :math:`\alpha`, -:math:`\beta` and :math:`\gamma`, see Eq. :eq:`morph-sigmoid`. +:math:`\beta` and :math:`\gamma`, see Eq. :eq:`morph-sigmoid-ex`. .. math:: - :label: morph-sigmoid + :label: morph-sigmoid-ex f(x) &= \frac{1}{\sqrt{1 + x^2}} @@ -48,7 +48,7 @@ \gamma &= p_5\ C_T^S\ \left( 1 - f\left(\frac{C_T^S}{p_6}\right) \right) The rate of deformation is described by the Lagrangian tensor and its Tresca-invariant, -see Eq. :eq:`morph-rate-of-deformation`. +see Eq. :eq:`morph-rate-of-deformation-ex`. .. note:: It is important to evaluate the incremental right Cauchy-Green tensor by the @@ -56,7 +56,7 @@ with respect to the deformation gradient tensor. .. math:: - :label: morph-rate-of-deformation + :label: morph-rate-of-deformation-ex \hat{\boldsymbol{L}} &= \text{sym}\left( \text{dev}(\boldsymbol{C}^{-1} \Delta\boldsymbol{C}) @@ -71,11 +71,11 @@ \Delta\boldsymbol{C} &= \boldsymbol{C} - \boldsymbol{C}_n The additional stresses evolve between the limiting stresses, see Eq. -:eq:`morph-stresses`. The additional deviatoric-enforcement terms [1]_ are neglected in +:eq:`morph-stresses-ex`. The additional deviatoric-enforcement terms [1]_ are neglected in this example. .. math:: - :label: morph-stresses + :label: morph-stresses-ex \boldsymbol{S}_L &= \left( \gamma \exp \left(p_7 \frac{\hat{\boldsymbol{L}}}{\hat{L}_T} @@ -93,16 +93,20 @@ .. note:: Only the upper-triangle entries of the symmetric stress-tensor state - variables are stored in the solid body. Hence, it is necessary to extract such - variables with :func:`tm.special.from_triu_1d` and export them as - :func:`tm.special.triu_1d`. + variables are stored in the solid body. + """ # sphinx_gallery_thumbnail_number = -1 +# sphinx_gallery_start_ignore +PYVISTA_GALLERY_FORCE_STATIC_IN_DOCUMENT = True +# sphinx_gallery_end_ignore + +import jax.numpy as jnp import numpy as np +from jax.scipy.linalg import expm + import felupe as fem import felupe.constitution.jax as mat -from jax.scipy.linalg import expm -import jax.numpy as jnp def morph(F, statevars, p): @@ -176,7 +180,8 @@ def sigmoid(x): # %% # .. note:: # The MORPH material model formulation is also available in FElupe, see -# :class:`~felupe.constitution.jax.models.lagrange.morph`. +# :class:`~felupe.morph` (tensortrax) and +# :class:`~felupe.constitution.jax.models.lagrange.morph` (JAX). # # The force-stress curves are shown for uniaxial incompressible tension cycles. ux = fem.math.linsteps([1, 1.5, 1, 2, 1, 2.5, 1, 2.5], num=(5, 5, 10, 10, 15, 15, 15)) @@ -215,7 +220,7 @@ def sigmoid(x): "bottom-y": fem.dof.Boundary(field[0], fy=-1.1, value=0.2, skip=(1, 0)), } -angles_deg = fem.math.linsteps([0, 180], num=9) +angles_deg = fem.math.linsteps([0, 120], num=6) move = [] for phi in angles_deg: center = mesh.points[boundaries["move"].points] diff --git a/examples/ex14_hyperelasticity.py b/examples/ex14_hyperelasticity.py index 5ccd86df..9c06ef44 100644 --- a/examples/ex14_hyperelasticity.py +++ b/examples/ex14_hyperelasticity.py @@ -107,7 +107,7 @@ # .. note:: # This material formulation is also available in FElupe as # :func:`~felupe.extended_tube` among other -# :ref:`hyperelastic material models `. +# :ref:`hyperelastic material models `. def extended_tube(C, Gc, δ, Ge, β): "Strain energy density function of the Extended Tube material formulation." From c2dc5d9f0cdc895cd231f2ab20c7b9d4a41c1989 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 3 Nov 2024 00:12:21 +0100 Subject: [PATCH 081/125] force static plots in docstrings try to make readthedocs run faster --- .../jax/models/lagrange/_morph.py | 10 +++++++--- .../constitution/tensortrax/_hyperelastic.py | 2 +- src/felupe/mesh/_container.py | 1 + src/felupe/mesh/_convert.py | 5 +++-- src/felupe/mesh/_discrete_geometry.py | 20 ++++++++++--------- src/felupe/mesh/_geometry.py | 5 ----- src/felupe/mesh/_tools.py | 16 ++++++++------- 7 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/felupe/constitution/jax/models/lagrange/_morph.py b/src/felupe/constitution/jax/models/lagrange/_morph.py index b7e242f7..3ec6eca4 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph.py @@ -18,12 +18,12 @@ def morph(F, statevars, p): - r"""Second Piola-Kirchhoff stress tensor of the + r"""First Piola-Kirchhoff stress tensor of the `MORPH `_ model formulation [1]_. Parameters ---------- - C : tensortrax.Tensor + F : jax.array Right Cauchy-Green deformation tensor. statevars : array Vector of stacked state variables (CTS, C, SA). @@ -32,7 +32,7 @@ def morph(F, statevars, p): Notes ----- - The MORPH material model is implemented as a second Piola-Kirchhoff stress-based + The MORPH material model is implemented as a first Piola-Kirchhoff stress-based formulation with automatic differentiation. The Tresca invariant of the distortional part of the right Cauchy-Green deformation tensor is used as internal state variable, see Eq. :eq:`morph-state`. @@ -157,6 +157,10 @@ def morph(F, statevars, p): rubberlike materials and its numerical applications", International Journal of Plasticity, vol. 19, no. 7. Elsevier BV, pp. 1019–1036, Jul. 2003. doi: `10.1016/s0749-6419(02)00091-8 `_. + + See Also + -------- + felupe.constitution.tensortrax.models.lagrange.morph : MORPH model (tensortrax) """ from jax.numpy import ( diff --git a/src/felupe/constitution/tensortrax/_hyperelastic.py b/src/felupe/constitution/tensortrax/_hyperelastic.py index abfd5e33..46c2b5fe 100644 --- a/src/felupe/constitution/tensortrax/_hyperelastic.py +++ b/src/felupe/constitution/tensortrax/_hyperelastic.py @@ -116,7 +116,7 @@ def viscoelastic(C, Cin, mu, eta, dtime): :context: >>> import felupe as fem - >>> import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat >>> import tensortrax.math as tm >>> >>> def neo_hooke(C, mu): diff --git a/src/felupe/mesh/_container.py b/src/felupe/mesh/_container.py index 29ff3d95..17baa2ad 100644 --- a/src/felupe/mesh/_container.py +++ b/src/felupe/mesh/_container.py @@ -51,6 +51,7 @@ class MeshContainer: -------- .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> diff --git a/src/felupe/mesh/_convert.py b/src/felupe/mesh/_convert.py index b52040b2..4b978647 100644 --- a/src/felupe/mesh/_convert.py +++ b/src/felupe/mesh/_convert.py @@ -396,6 +396,7 @@ def add_midpoints_edges(points, cells, cell_type, cell_type_new=None): .. pyvista-plot:: :include-source: True + :force_static: >>> import felupe as fem >>> @@ -474,7 +475,7 @@ def add_midpoints_faces(points, cells, cell_type, cell_type_new=None): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -558,7 +559,7 @@ def add_midpoints_volumes(points, cells, cell_type, cell_type_new=None): Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> import pyvista as pv diff --git a/src/felupe/mesh/_discrete_geometry.py b/src/felupe/mesh/_discrete_geometry.py index 90096914..6bc657be 100644 --- a/src/felupe/mesh/_discrete_geometry.py +++ b/src/felupe/mesh/_discrete_geometry.py @@ -102,15 +102,17 @@ def update(self, points=None, cells=None, cell_type=None, callback=None): If the points of a mesh are modified and a region was already created with the mesh, it is important to re-evaluate (reload) the :class:`~felupe.Region`. - - >>> import felupe as fem - >>> - >>> mesh = fem.Cube(n=6) - >>> region = fem.RegionHexahedron(mesh) - >>> field = fem.FieldContainer([fem.Field(region, dim=3)]) - >>> - >>> new_points = mesh.rotate(angle_deg=-90, axis=2).points - >>> mesh.update(points=new_points, callback=region.reload) + + .. pyvista-plot:: + + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=6) + >>> region = fem.RegionHexahedron(mesh) + >>> field = fem.FieldContainer([fem.Field(region, dim=3)]) + >>> + >>> new_points = mesh.rotate(angle_deg=-90, axis=2).points + >>> mesh.update(points=new_points, callback=region.reload) See Also -------- diff --git a/src/felupe/mesh/_geometry.py b/src/felupe/mesh/_geometry.py index 6c550ec6..f78bf24b 100644 --- a/src/felupe/mesh/_geometry.py +++ b/src/felupe/mesh/_geometry.py @@ -77,7 +77,6 @@ class Line(Mesh): Examples -------- .. pyvista-plot:: - :include-source: True :force_static: >>> import felupe as fem @@ -127,7 +126,6 @@ class Rectangle(Mesh): Examples -------- .. pyvista-plot:: - :include-source: True :force_static: >>> import felupe as fem @@ -185,7 +183,6 @@ class Cube(Mesh): Examples -------- .. pyvista-plot:: - :include-source: True :force_static: >>> import felupe as fem @@ -240,7 +237,6 @@ class Grid(Mesh): Examples -------- .. pyvista-plot:: - :include-source: True :force_static: >>> import numpy as np @@ -482,7 +478,6 @@ class Triangle(Mesh): Examples -------- .. pyvista-plot:: - :include-source: True :force_static: >>> import felupe as fem diff --git a/src/felupe/mesh/_tools.py b/src/felupe/mesh/_tools.py index b0449266..5c6d1769 100644 --- a/src/felupe/mesh/_tools.py +++ b/src/felupe/mesh/_tools.py @@ -411,6 +411,7 @@ def merge_duplicate_points(points, cells, cell_type, decimals=None): .. pyvista-plot:: :context: + :force_static: >>> import felupe as fem >>> @@ -553,6 +554,7 @@ def merge_duplicate_cells(points, cells, cell_type): .. pyvista-plot:: :context: + :force_static: >>> import felupe as fem >>> @@ -823,7 +825,7 @@ def mirror( Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -831,7 +833,7 @@ def mirror( >>> mesh.plot().show() .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -960,7 +962,7 @@ def stack(meshes): Two quad meshes with identical point arrays should be stacked into a single mesh. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1022,7 +1024,7 @@ def triangulate(points, cells, cell_type, mode=3): Use ``mode=0`` to convert a mesh of hexahedrons into tetrahedrons [1]_. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1033,7 +1035,7 @@ def triangulate(points, cells, cell_type, mode=3): Use ``mode=3`` to convert a mesh of hexahedrons into tetrahedrons [1]_. .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1152,7 +1154,7 @@ def runouts( Examples -------- .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> @@ -1162,7 +1164,7 @@ def runouts( >>> mesh.plot().show() .. pyvista-plot:: - :include-source: True + :force_static: >>> import felupe as fem >>> From eed4ece78e216eeda99a02dec1148fea347bc17f Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 4 Nov 2024 00:10:33 +0100 Subject: [PATCH 082/125] Add Total-Lagrange and Updated-Lagrange decorators for JAX (#883) * Add Total- and Updated-Lagrange for JAX * Add Mooney-Rivlin material for JAX * JAX-based MORPH material as Total-Lagrange * Update _morph_representative_directions.py enhance docstring example * format black * Update jax.rst * Update test_constitution_jax.py * Add TOD and YEOH for JAX * Update test_constitution_jax.py * Update test_constitution_jax.py * Update jax.rst * Update test_constitution_jax.py --- CHANGELOG.md | 3 +- docs/felupe/constitution/autodiff/jax.rst | 22 +++++ .../examples/extut01_getting_started.py | 1 + docs/tutorial/examples/extut02_job.py | 1 + .../examples/extut03_building_blocks.py | 1 + examples/ex02_plate-with-hole.py | 1 + examples/ex03_plasticity.py | 1 + examples/ex04_balloon.py | 1 + examples/ex05_rubber-metal-bushing.py | 1 + examples/ex06_rubber-metal-spring.py | 1 + examples/ex07_engine-mount.py | 1 + examples/ex08_shear.py | 1 + examples/ex11_notch-stress.py | 1 + examples/ex13_morph-rubber-wheel.py | 1 + examples/ex14_hyperelasticity.py | 1 + examples/ex15_hexmesh-metacone.py | 1 + examples/ex16_deeplearning-torch.py | 1 + examples/ex20_third-medium-contact.py | 1 + src/felupe/constitution/jax/__init__.py | 11 ++- .../constitution/jax/_total_lagrange.py | 78 +++++++++++++++++ .../constitution/jax/_updated_lagrange.py | 81 +++++++++++++++++ .../jax/models/hyperelastic/__init__.py | 9 ++ .../jax/models/hyperelastic/_mooney_rivlin.py | 31 +++++++ .../hyperelastic/_third_order_deformation.py | 37 ++++++++ .../jax/models/hyperelastic/_yeoh.py | 29 +++++++ .../jax/models/lagrange/_morph.py | 12 +-- .../models/hyperelastic/_mooney_rivlin.py | 17 +++- .../hyperelastic/_third_order_deformation.py | 22 +++-- .../tensortrax/models/hyperelastic/_yeoh.py | 17 +++- .../tensortrax/models/lagrange/_morph.py | 4 +- .../_morph_representative_directions.py | 7 +- src/felupe/mesh/_discrete_geometry.py | 2 +- tests/test_constitution_jax.py | 87 +++++++------------ 33 files changed, 405 insertions(+), 80 deletions(-) create mode 100644 src/felupe/constitution/jax/_total_lagrange.py create mode 100644 src/felupe/constitution/jax/_updated_lagrange.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_yeoh.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e5ce6e3..00684f3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ All notable changes to this project will be documented in this file. The format - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.jax.Material` as a feature-equivalent alternative to `MaterialAD` with `jax` as backend. -- Add the MORPH-material formulation for a JAX-based material `felupe.constitution.jax.models.lagrange.morph()`. +- Add the material models for JAX-based materials `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()` and `felupe.constitution.jax.models.lagrange.morph()`. +- Add `felupe.constitution.jax.total_lagrange()` and `felupe.constitution.jax.updated_lagrange()` function decorators for JAX materials. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 9e7a1d80..7d92856d 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -13,6 +13,18 @@ This page contains material model formulations with automatic differentiation us constitution.jax.Hyperelastic constitution.jax.Material + constitution.jax.total_lagrange + constitution.jax.updated_lagrange + +**Material Models for** :class:`felupe.constitution.jax.Hyperelastic` + +These material model formulations are defined by a strain energy density function. + +.. autosummary:: + + felupe.constitution.jax.models.hyperelastic.mooney_rivlin + felupe.constitution.jax.models.hyperelastic.third_order_deformation + felupe.constitution.jax.models.hyperelastic.yeoh **Material Models for** :class:`felupe.constitution.jax.Material` @@ -38,6 +50,16 @@ This page contains material model formulations with automatic differentiation us :undoc-members: :inherited-members: +.. autofunction:: felupe.constitution.jax.total_lagrange + +.. autofunction:: felupe.constitution.jax.updated_lagrange + +.. autofunction:: felupe.constitution.jax.models.hyperelastic.mooney_rivlin + +.. autofunction:: felupe.constitution.jax.models.hyperelastic.third_order_deformation + +.. autofunction:: felupe.constitution.jax.models.hyperelastic.yeoh + .. autofunction:: felupe.constitution.jax.models.lagrange.morph .. autofunction:: felupe.constitution.jax.vmap diff --git a/docs/tutorial/examples/extut01_getting_started.py b/docs/tutorial/examples/extut01_getting_started.py index 3fa4f828..1177d563 100644 --- a/docs/tutorial/examples/extut01_getting_started.py +++ b/docs/tutorial/examples/extut01_getting_started.py @@ -24,6 +24,7 @@ created on the mesh. A vector-valued displacement field is initiated on the region. Next, a field container is created on top of the displacement field. """ + import felupe as fem mesh = fem.Cube(n=6) diff --git a/docs/tutorial/examples/extut02_job.py b/docs/tutorial/examples/extut02_job.py index 6658f923..dc7f3993 100644 --- a/docs/tutorial/examples/extut02_job.py +++ b/docs/tutorial/examples/extut02_job.py @@ -22,6 +22,7 @@ argument of the (nearly) incompressible solid body instead of the constitutive Neo-Hookean material definition. """ + import felupe as fem mesh = fem.Cube(n=6) diff --git a/docs/tutorial/examples/extut03_building_blocks.py b/docs/tutorial/examples/extut03_building_blocks.py index b164577e..fb2d23e5 100644 --- a/docs/tutorial/examples/extut03_building_blocks.py +++ b/docs/tutorial/examples/extut03_building_blocks.py @@ -23,6 +23,7 @@ .. image:: examples/extut03_building_blocks_sketch.svg :width: 600px """ + # sphinx_gallery_thumbnail_number = -1 import felupe as fem diff --git a/examples/ex02_plate-with-hole.py b/examples/ex02_plate-with-hole.py index 7bebef32..b7b769ba 100644 --- a/examples/ex02_plate-with-hole.py +++ b/examples/ex02_plate-with-hole.py @@ -21,6 +21,7 @@ .. image:: ../../examples/ex02_plate-with-hole_sketch.svg :width: 400px """ + # sphinx_gallery_thumbnail_number = -2 h = 1 L = 2 diff --git a/examples/ex03_plasticity.py b/examples/ex03_plasticity.py index ac5ae139..e70fd4d5 100644 --- a/examples/ex03_plasticity.py +++ b/examples/ex03_plasticity.py @@ -22,6 +22,7 @@ per axis. A three-dimensional vector-valued displacement field is initiated on the numeric region. """ + import numpy as np import felupe as fem diff --git a/examples/ex04_balloon.py b/examples/ex04_balloon.py index 7854c427..ed92110d 100644 --- a/examples/ex04_balloon.py +++ b/examples/ex04_balloon.py @@ -39,6 +39,7 @@ \text{tr}(\boldsymbol{C}) - \ln(\det(\boldsymbol{C})) \right) """ + # sphinx_gallery_thumbnail_number = -1 import contique import numpy as np diff --git a/examples/ex05_rubber-metal-bushing.py b/examples/ex05_rubber-metal-bushing.py index 9f0db16d..bd7996e6 100644 --- a/examples/ex05_rubber-metal-bushing.py +++ b/examples/ex05_rubber-metal-bushing.py @@ -24,6 +24,7 @@ An elastic bearing is subjected to combined multiaxial radial-torsional-cardanic loading. First the meshes for the rubber and the metal sheet rings are created. """ + # sphinx_gallery_thumbnail_number = -2 import numpy as np import pypardiso diff --git a/examples/ex06_rubber-metal-spring.py b/examples/ex06_rubber-metal-spring.py index 68659698..2c759276 100644 --- a/examples/ex06_rubber-metal-spring.py +++ b/examples/ex06_rubber-metal-spring.py @@ -24,6 +24,7 @@ Simplified elastic-to-rigid contact definitions simulate the end stops caused by steel plates at the bottom and the top in direction :math:`z`. """ + # sphinx_gallery_thumbnail_number = -3 import numpy as np import pypardiso diff --git a/examples/ex07_engine-mount.py b/examples/ex07_engine-mount.py index 5a07fcd7..6ea405a6 100644 --- a/examples/ex07_engine-mount.py +++ b/examples/ex07_engine-mount.py @@ -29,6 +29,7 @@ * a `mesh for the air <../_static/ex07_engine-mount_mesh-air.vtk>`_ inside the engine mount. """ + # sphinx_gallery_thumbnail_number = -1 import numpy as np diff --git a/examples/ex08_shear.py b/examples/ex08_shear.py index 3ac36955..862e6eaf 100644 --- a/examples/ex08_shear.py +++ b/examples/ex08_shear.py @@ -37,6 +37,7 @@ :attr:`Mesh.points_without_cells` and adds them to the list of inactive degrees of freedom. Hence, we have to drop our MPC-centerpoint from that list. """ + # sphinx_gallery_thumbnail_number = -2 import numpy as np diff --git a/examples/ex11_notch-stress.py b/examples/ex11_notch-stress.py index 7f9a64c3..4102fea4 100644 --- a/examples/ex11_notch-stress.py +++ b/examples/ex11_notch-stress.py @@ -26,6 +26,7 @@ implemented and hence, the quadratic wedges in the mesh are converted to quadratic hexahedrons. """ + # sphinx_gallery_thumbnail_number = -1 import numpy as np import pypardiso diff --git a/examples/ex13_morph-rubber-wheel.py b/examples/ex13_morph-rubber-wheel.py index 48a65019..829fd6cb 100644 --- a/examples/ex13_morph-rubber-wheel.py +++ b/examples/ex13_morph-rubber-wheel.py @@ -96,6 +96,7 @@ variables are stored in the solid body. """ + # sphinx_gallery_thumbnail_number = -1 # sphinx_gallery_start_ignore PYVISTA_GALLERY_FORCE_STATIC_IN_DOCUMENT = True diff --git a/examples/ex14_hyperelasticity.py b/examples/ex14_hyperelasticity.py index 9c06ef44..5b50990f 100644 --- a/examples/ex14_hyperelasticity.py +++ b/examples/ex14_hyperelasticity.py @@ -13,6 +13,7 @@ The :func:`Extended Tube ` material model formulation [1]_ is best-fitted on Treloar's uniaxial and biaxial tension data [2]_. """ + import numpy as np import tensortrax.math as tm diff --git a/examples/ex15_hexmesh-metacone.py b/examples/ex15_hexmesh-metacone.py index 12b86858..de1c2709 100644 --- a/examples/ex15_hexmesh-metacone.py +++ b/examples/ex15_hexmesh-metacone.py @@ -8,6 +8,7 @@ * create a :class:`~felupe.MeshContainer` for meshes associated to two materials """ + import numpy as np import felupe as fem diff --git a/examples/ex16_deeplearning-torch.py b/examples/ex16_deeplearning-torch.py index 1aa00a51..6fdeacf5 100644 --- a/examples/ex16_deeplearning-torch.py +++ b/examples/ex16_deeplearning-torch.py @@ -22,6 +22,7 @@ pip install torch """ + # sphinx_gallery_thumbnail_number = -1 import numpy as np diff --git a/examples/ex20_third-medium-contact.py b/examples/ex20_third-medium-contact.py index af43ad3d..352e9f72 100644 --- a/examples/ex20_third-medium-contact.py +++ b/examples/ex20_third-medium-contact.py @@ -15,6 +15,7 @@ body. All sub meshes are merged by stacking the meshes of the :class:`mesh container ` into a :class:`mesh `. """ + import numpy as np import felupe as fem diff --git a/src/felupe/constitution/jax/__init__.py b/src/felupe/constitution/jax/__init__.py index c1b91f02..7e98c94d 100644 --- a/src/felupe/constitution/jax/__init__.py +++ b/src/felupe/constitution/jax/__init__.py @@ -2,5 +2,14 @@ from ._hyperelastic import Hyperelastic from ._material import Material from ._tools import vmap +from ._total_lagrange import total_lagrange +from ._updated_lagrange import updated_lagrange -__all__ = ["Hyperelastic", "Material", "models", "vmap"] +__all__ = [ + "Hyperelastic", + "Material", + "models", + "total_lagrange", + "updated_lagrange", + "vmap", +] diff --git a/src/felupe/constitution/jax/_total_lagrange.py b/src/felupe/constitution/jax/_total_lagrange.py new file mode 100644 index 00000000..ff16a8bf --- /dev/null +++ b/src/felupe/constitution/jax/_total_lagrange.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + + +def total_lagrange(material): + r"""Decorate a second Piola-Kirchhoff stress Total-Lagrange material formulation as + a first Piola-Kirchoff stress function. + + Notes + ----- + .. math:: + + \delta \psi = \boldsymbol{F} \boldsymbol{S} : \delta \boldsymbol{F} + + Examples + -------- + >>> import felupe as fem + >>> import felupe.constitution.jax as mat + >>> import jax.numpy as jnp + >>> + >>> @mat.total_lagrange + >>> def neo_hooke_total_lagrange(F, mu=1): + >>> C = F.T @ F + >>> dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) + >>> S = mu * dev(jnp.linalg.det(C)**(-1/3) * C) @ jnp.linalg.inv(C) + >>> return S + >>> + >>> umat = mat.Material(neo_hooke_total_lagrange, mu=1) + + See Also + -------- + felupe.constitution.jax.Hyperelastic : A hyperelastic material definition with a + given function for the strain energy density function per unit undeformed volume + with Automatic Differentiation provided by jax. + felupe.constitution.jax.Material : A material definition with a given function for + the partial derivative of the strain energy function w.r.t. the deformation + gradient tensor with Automatic Differentiation provided by jax. + """ + from jax import Array + + @wraps(material) + def first_piola_kirchhoff_stress(F, *args, **kwargs): + # evaluate the second Piola-Kirchhoff stress + res = material(F, *args, **kwargs) + + # check if the material formulation returns state variables and extract + # the second Piola-Kirchhoff stress tensor + if isinstance(res, Array): + S = res + statevars_new = None + else: + S, statevars_new = res + + # first Piola-Kirchhoff stress tensor + P = F @ S + + if statevars_new is None: + return P + else: + return P, statevars_new + + return first_piola_kirchhoff_stress diff --git a/src/felupe/constitution/jax/_updated_lagrange.py b/src/felupe/constitution/jax/_updated_lagrange.py new file mode 100644 index 00000000..5614b6f1 --- /dev/null +++ b/src/felupe/constitution/jax/_updated_lagrange.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + + +def updated_lagrange(material): + r"""Decorate a Cauchy-stress Updated-Lagrange material formulation as a first Piola- + Kirchoff stress function. + + Notes + ----- + .. math:: + + \delta \psi = J \boldsymbol{\sigma} \boldsymbol{F}^{-T} : \delta \boldsymbol{F} + + Examples + -------- + >>> import felupe as fem + >>> import felupe.constitution.jax as mat + >>> import jax.numpy as jnp + >>> + >>> @fem.updated_lagrange + >>> def neo_hooke_updated_lagrange(F, mu=1): + >>> J = jnp.linalg.det(F) + >>> b = F @ F.T + >>> dev = lambda b: b - jnp.trace(b) / 3 * jnp.eye(3) + >>> τ = mu * dev(J**(-2/3) * b) + >>> return τ / J + >>> + >>> umat = mat.Material(neo_hooke_updated_lagrange, mu=1) + + See Also + -------- + felupe.constitution.jax.Hyperelastic : A hyperelastic material definition with a + given function for the strain energy density function per unit undeformed volume + with Automatic Differentiation provided by jax. + felupe.constitution.jax.Material : A material definition with a given function for + the partial derivative of the strain energy function w.r.t. the deformation + gradient tensor with Automatic Differentiation provided by jax. + """ + import jax.numpy as jnp + from jax import Array + + @wraps(material) + def first_piola_kirchhoff_stress(F, *args, **kwargs): + # evaluate the Cauchy stress + res = material(F, *args, **kwargs) + + # check if the material formulation returns state variables and extract + # the Cauchy stress tensor + if isinstance(res, Array): + σ = res + statevars_new = None + else: + σ, statevars_new = res + + # first Piola-Kirchhoff stress tensor + J = jnp.linalg.det(F) + P = J * σ @ jnp.linalg.inv(F).T + + if statevars_new is None: + return P + else: + return P, statevars_new + + return first_piola_kirchhoff_stress diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index e69de29b..dcf1252f 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -0,0 +1,9 @@ +from ._mooney_rivlin import mooney_rivlin +from ._third_order_deformation import third_order_deformation +from ._yeoh import yeoh + +__all__ = [ + "mooney_rivlin", + "third_order_deformation", + "yeoh", +] diff --git a/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py b/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py new file mode 100644 index 00000000..aa65c2cf --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from ....tensortrax.models.hyperelastic import mooney_rivlin as mooney_rivlin_docstring + + +@wraps(mooney_rivlin_docstring) +def mooney_rivlin(C, C10, C01): + from jax.numpy import trace + from jax.numpy.linalg import det + + J3 = det(C) ** (-1 / 3) + I1 = J3 * trace(C) + I2 = (I1**2 - J3**2 * trace(C @ C)) / 2 + return C10 * (I1 - 3) + C01 * (I2 - 3) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py b/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py new file mode 100644 index 00000000..c847675b --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from ....tensortrax.models.hyperelastic import third_order_deformation as tod_docstring + + +@wraps(tod_docstring) +def third_order_deformation(C, C10, C01, C11, C20, C30): + from jax.numpy import trace + from jax.numpy.linalg import det + + J3 = det(C) ** (-1 / 3) + I1 = J3 * trace(C) + I2 = (I1**2 - J3**2 * trace(C @ C)) / 2 + return ( + C10 * (I1 - 3) + + C01 * (I2 - 3) + + C11 * (I1 - 3) * (I2 - 3) + + C20 * (I1 - 3) ** 2 + + C30 * (I1 - 3) ** 3 + ) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py b/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py new file mode 100644 index 00000000..43a4db83 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from ....tensortrax.models.hyperelastic import yeoh as yeoh_docstring + + +@wraps(yeoh_docstring) +def yeoh(C, C10, C20, C30): + from jax.numpy import trace + from jax.numpy.linalg import det + + I1 = det(C) ** (-1 / 3) * trace(C) + return C10 * (I1 - 3) + C20 * (I1 - 3) ** 2 + C30 * (I1 - 3) ** 3 diff --git a/src/felupe/constitution/jax/models/lagrange/_morph.py b/src/felupe/constitution/jax/models/lagrange/_morph.py index 3ec6eca4..4d1c2c14 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph.py @@ -15,24 +15,26 @@ You should have received a copy of the GNU General Public License along with FElupe. If not, see . """ +from ..._total_lagrange import total_lagrange +@total_lagrange def morph(F, statevars, p): r"""First Piola-Kirchhoff stress tensor of the `MORPH `_ model formulation [1]_. Parameters ---------- - F : jax.array - Right Cauchy-Green deformation tensor. - statevars : array + F : jax.Array + Deformation gradient tensor. + statevars : jax.Array Vector of stacked state variables (CTS, C, SA). p : list of float A list which contains the 8 material parameters. Notes ----- - The MORPH material model is implemented as a first Piola-Kirchhoff stress-based + The MORPH material model is implemented as a second Piola-Kirchhoff stress-based formulation with automatic differentiation. The Tresca invariant of the distortional part of the right Cauchy-Green deformation tensor is used as internal state variable, see Eq. :eq:`morph-state`. @@ -230,4 +232,4 @@ def sigmoid(x): to_triu = lambda C: C[i, j] statevars_new = concatenate([array([CTS]), to_triu(C), to_triu(SA)]) - return F @ S, statevars_new + return S, statevars_new diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_mooney_rivlin.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_mooney_rivlin.py index d0868ada..21931908 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_mooney_rivlin.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_mooney_rivlin.py @@ -27,7 +27,7 @@ def mooney_rivlin(C, C10, C01): Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. C10 : float First material parameter associated to the first invariant. @@ -66,13 +66,22 @@ def mooney_rivlin(C, C10, C01): Examples -------- + First, choose the desired automatic differentiation backend .. pyvista-plot:: :context: - >>> import felupe as fem - >>> - >>> umat = fem.Hyperelastic(fem.mooney_rivlin, C10=0.3, C01=0.8) + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. + + .. pyvista-plot:: + :context: + + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.mooney_rivlin, C10=0.3, C01=0.8 + ... ) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_third_order_deformation.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_third_order_deformation.py index a2688184..94105265 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_third_order_deformation.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_third_order_deformation.py @@ -27,7 +27,7 @@ def third_order_deformation(C, C10, C01, C11, C20, C30): Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. C10 : float Material parameter associated to the linear term of the first invariant. @@ -78,14 +78,26 @@ def third_order_deformation(C, C10, C01, C11, C20, C30): Examples -------- + First, choose the desired automatic differentiation backend .. pyvista-plot:: :context: - >>> import felupe as fem - >>> - >>> umat = fem.Hyperelastic( - ... fem.third_order_deformation, C10=0.5, C01=0.1, C11=0.01, C20=-0.1, C30=0.02 + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. + + .. pyvista-plot:: + :context: + + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.third_order_deformation, + ... C10=0.5, + ... C01=0.1, + ... C11=0.01, + ... C20=-0.1, + ... C30=0.02, ... ) >>> ax = umat.plot(incompressible=True) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_yeoh.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_yeoh.py index eac9e318..bee80aca 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_yeoh.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_yeoh.py @@ -27,7 +27,7 @@ def yeoh(C, C10, C20, C30): Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. C10 : float Material parameter associated to the linear term of the first invariant. @@ -64,13 +64,22 @@ def yeoh(C, C10, C20, C30): Examples -------- + First, choose the desired automatic differentiation backend .. pyvista-plot:: :context: - >>> import felupe as fem - >>> - >>> umat = fem.Hyperelastic(fem.yeoh, C10=0.5, C20=-0.1, C30=0.02) + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. + + .. pyvista-plot:: + :context: + + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.yeoh, C10=0.5, C20=-0.1, C30=0.02 + ... ) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py index b17250b0..11172820 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py @@ -29,8 +29,8 @@ def morph(F, statevars, p): Parameters ---------- - C : tensortrax.Tensor - Right Cauchy-Green deformation tensor. + F : tensortrax.Tensor + Deformation gradient tensor. statevars : array Vector of stacked state variables (CTS, C, SA). p : list of float diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py index c604aecb..b097a983 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py @@ -28,8 +28,8 @@ def morph_representative_directions(F, statevars, p, ε=1e-8): Parameters ---------- - C : tensortrax.Tensor - Right Cauchy-Green deformation tensor. + F : tensortrax.Tensor + Deformation gradient tensor. statevars : array Vector of stacked state variables (CTS, λ - 1, SA1, SA2). p : list of float @@ -43,8 +43,9 @@ def morph_representative_directions(F, statevars, p, ε=1e-8): :context: >>> import felupe as fem + >>> import felupe.constitution.tensortrax as mat >>> - >>> umat = fem.MaterialAD( + >>> umat = mat.Material( ... fem.morph_representative_directions, ... p=[0.011, 0.408, 0.421, 6.85, 0.0056, 5.54, 5.84, 0.117], ... nstatevars=84, diff --git a/src/felupe/mesh/_discrete_geometry.py b/src/felupe/mesh/_discrete_geometry.py index 6bc657be..51b5be10 100644 --- a/src/felupe/mesh/_discrete_geometry.py +++ b/src/felupe/mesh/_discrete_geometry.py @@ -102,7 +102,7 @@ def update(self, points=None, cells=None, cell_type=None, callback=None): If the points of a mesh are modified and a region was already created with the mesh, it is important to re-evaluate (reload) the :class:`~felupe.Region`. - + .. pyvista-plot:: >>> import felupe as fem diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 97321173..93be8e5c 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -62,28 +62,23 @@ def g(x, y, a=1.0, **kwargs): def test_hyperelastic_jax(): try: - import jax.numpy as jnp - - def W(C, C10, K): - I3 = jnp.linalg.det(C) - J = jnp.sqrt(I3) - I1 = I3 ** (-1 / 3) * jnp.trace(C) - return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2 - - umat = fem.constitution.jax.Hyperelastic(W, C10=0.5, K=2.0, parallel=True) - umat = mat.Hyperelastic(W, C10=0.5, K=2.0, jit=True) mesh = fem.Cube(n=2) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) - boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) - solid = fem.SolidBody(umat=umat, field=field) + md = mat.models.hyperelastic + for W in [ + md.mooney_rivlin, + md.yeoh, + md.third_order_deformation, + ]: + umat = mat.Hyperelastic(W, **W.kwargs) + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() - move = fem.math.linsteps([0, 1], num=3) - ramp = {boundaries["move"]: move} - step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) - job = fem.Job(steps=[step]) - job.evaluate(tol=1e-4) + umat = mat.Hyperelastic(W, **W.kwargs, parallel=True) + umat = mat.Hyperelastic(W, **W.kwargs, jit=True) except ModuleNotFoundError: pass @@ -107,14 +102,9 @@ def W(C, statevars, C10, K): region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) - boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) solid = fem.SolidBody(umat=umat, field=field) - - move = fem.math.linsteps([0, 1], num=3) - ramp = {boundaries["move"]: move} - step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) - job = fem.Job(steps=[step]) - job.evaluate(tol=1e-4) + solid.evaluate.gradient() + solid.evaluate.hessian() except ModuleNotFoundError: pass @@ -134,19 +124,17 @@ def dWdF(F, C10, K): return P + K * (J - 1) * J * jnp.linalg.inv(C) umat = mat.Material(dWdF, C10=0.5, K=2.0, parallel=True) - umat = fem.constitution.jax.Material(dWdF, C10=0.5, K=2.0, jit=True) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) + umat = mat.Material(dWdF, C10=0.5, K=2.0, jit=True) - boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) - solid = fem.SolidBody(umat=umat, field=field) + for fun in [dWdF, mat.updated_lagrange(dWdF), mat.total_lagrange(dWdF)]: + umat = mat.Material(fun, C10=0.5, K=2.0) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) - move = fem.math.linsteps([0, 1], num=3) - ramp = {boundaries["move"]: move} - step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) - job = fem.Job(steps=[step]) - job.evaluate(tol=1e-4) + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() except ModuleNotFoundError: pass @@ -168,19 +156,15 @@ def dWdF(F, statevars, C10, K): dWdF.kwargs = {"C10": 0.5} - umat = mat.Material(dWdF, C10=0.5, K=2.0, nstatevars=1, jit=True) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) - - boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) - solid = fem.SolidBody(umat=umat, field=field) + for fun in [dWdF, mat.updated_lagrange(dWdF), mat.total_lagrange(dWdF)]: + umat = mat.Material(fun, C10=0.5, K=2.0, nstatevars=1, jit=True) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) - move = fem.math.linsteps([0, 1], num=3) - ramp = {boundaries["move"]: move} - step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) - job = fem.Job(steps=[step]) - job.evaluate(tol=1e-4) + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() except ModuleNotFoundError: pass @@ -197,14 +181,9 @@ def test_material_included_jax_statevars(): region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) - boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) solid = fem.SolidBody(umat=umat, field=field) - - move = fem.math.linsteps([0, 1], num=3) - ramp = {boundaries["move"]: move} - step = fem.Step(items=[solid], ramp=ramp, boundaries=boundaries) - job = fem.Job(steps=[step]) - job.evaluate(tol=1e-4) + solid.evaluate.gradient() + solid.evaluate.hessian() except ModuleNotFoundError: pass From 5c713767a01de6900e3dc392753570422dce5b4d Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 5 Nov 2024 13:49:10 +0100 Subject: [PATCH 083/125] Add more JAX-based models (#884) * Add more JAX-based models * Add tests for JAX material * Update _morph_uniaxial.py --- CHANGELOG.md | 4 +- docs/felupe/constitution/autodiff/jax.rst | 7 + src/felupe/constitution/jax/_material.py | 13 +- .../jax/models/lagrange/__init__.py | 15 ++ .../jax/models/lagrange/_morph.py | 149 +----------------- .../_morph_representative_directions.py | 31 ++++ .../jax/models/lagrange/_morph_uniaxial.py | 58 +++++++ .../models/lagrange/microsphere/__init__.py | 5 + .../lagrange/microsphere/_framework_affine.py | 43 +++++ .../tensortrax/models/lagrange/__init__.py | 9 +- .../tensortrax/models/lagrange/_morph.py | 16 +- .../_morph_representative_directions.py | 19 ++- .../models/lagrange/_morph_uniaxial.py | 6 +- tests/test_constitution_jax.py | 31 ++-- 14 files changed, 231 insertions(+), 175 deletions(-) create mode 100644 src/felupe/constitution/jax/models/lagrange/_morph_representative_directions.py create mode 100644 src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py create mode 100644 src/felupe/constitution/jax/models/lagrange/microsphere/__init__.py create mode 100644 src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 00684f3c..77f92426 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,8 @@ All notable changes to this project will be documented in this file. The format - Add the attribute `RegionBoundary.tangents`, which contains a list of tangent unit vectors. For `quad` cell-types the length of this list is one and for `hexahedron` cell-types it is of length two. - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. -- Add `constitution.jax.Material` as a feature-equivalent alternative to `MaterialAD` with `jax` as backend. -- Add the material models for JAX-based materials `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()` and `felupe.constitution.jax.models.lagrange.morph()`. +- Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. +- Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. - Add `felupe.constitution.jax.total_lagrange()` and `felupe.constitution.jax.updated_lagrange()` function decorators for JAX materials. ### Changed diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 7d92856d..8d31bcf1 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -28,9 +28,14 @@ These material model formulations are defined by a strain energy density functio **Material Models for** :class:`felupe.constitution.jax.Material` +The material model formulations are defined by the first Piola-Kirchhoff stress tensor. +Function-decorators are available to use Total-Lagrange and Updated-Lagrange material +formulations in :class:`~felupe.constitution.jax.Material`. + .. autosummary:: felupe.constitution.jax.models.lagrange.morph + felupe.constitution.jax.models.lagrange.morph_representative_directions **Tools** @@ -62,4 +67,6 @@ These material model formulations are defined by a strain energy density functio .. autofunction:: felupe.constitution.jax.models.lagrange.morph +.. autofunction:: felupe.constitution.jax.models.lagrange.morph_representative_directions + .. autofunction:: felupe.constitution.jax.vmap diff --git a/src/felupe/constitution/jax/_material.py b/src/felupe/constitution/jax/_material.py index 6504d400..5c31052a 100644 --- a/src/felupe/constitution/jax/_material.py +++ b/src/felupe/constitution/jax/_material.py @@ -45,6 +45,10 @@ class Material(MaterialDefault): parallel : bool, optional A flag to invoke threaded function evaluations (defaultnis False). Not implemented. + jacobian : callable or None, optional + A callable for the Jacobian. Default is None, where :func:`jax.jacobian` is + used. This may be used to switch to forward-mode differentian + :func:`jax.jacfwd`. **kwargs : dict, optional Optional keyword-arguments for the gradient of the strain energy density function. @@ -151,12 +155,17 @@ def viscoelastic(F, Cin, mu, eta, dtime): """ - def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): + def __init__( + self, fun, nstatevars=0, jit=True, parallel=False, jacobian=None, **kwargs + ): import jax has_aux = nstatevars > 0 self.fun = fun + if jacobian is None: + jacobian = jax.jacobian + if parallel: warnings.warn("Parallel execution is not implemented.") @@ -176,7 +185,7 @@ def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): kwargs_jax["in_axes"] = (-1, -1) self._grad = vmap2(self.fun, **kwargs_jax) - self._hess = vmap2(jax.jacfwd(self.fun, has_aux=has_aux), **kwargs_jax) + self._hess = vmap2(jacobian(self.fun, has_aux=has_aux), **kwargs_jax) if jit: self._grad = jax.jit(self._grad) diff --git a/src/felupe/constitution/jax/models/lagrange/__init__.py b/src/felupe/constitution/jax/models/lagrange/__init__.py index 8d3461ae..ee02dc2a 100644 --- a/src/felupe/constitution/jax/models/lagrange/__init__.py +++ b/src/felupe/constitution/jax/models/lagrange/__init__.py @@ -1,8 +1,23 @@ +""" +Strain-energy density functions for strain energy-gradient (stress) model formulations. + +This module contains material model formulations to be used as the ``fun``-argument in +:func:`~felupe.constitution.jax.Material`. The gradient as well as the hessian of +the strain energy density function is carried out by automatic differentiation using +:mod:`jax`. Hence, all math-functions must be taken from :mod:`jax.numpy`. +""" + from ._morph import morph +from ._morph_representative_directions import morph_representative_directions +from ._morph_uniaxial import morph_uniaxial __all__ = [ "morph", + "morph_representative_directions", + "morph_uniaxial", ] # default (stable) material parameters morph.kwargs = dict(p=[0, 0, 0, 0, 0, 1, 0, 0]) +morph_representative_directions.kwargs = dict(p=[0, 0, 0, 0, 0, 1, 0, 0]) +morph_uniaxial.kwargs = dict(p=[0, 0, 0, 0, 0, 1, 0, 0]) diff --git a/src/felupe/constitution/jax/models/lagrange/_morph.py b/src/felupe/constitution/jax/models/lagrange/_morph.py index 4d1c2c14..25600f03 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph.py @@ -15,156 +15,15 @@ You should have received a copy of the GNU General Public License along with FElupe. If not, see . """ +from functools import wraps + +from ....tensortrax.models.lagrange import morph as morph_docstring from ..._total_lagrange import total_lagrange +@wraps(morph_docstring) @total_lagrange def morph(F, statevars, p): - r"""First Piola-Kirchhoff stress tensor of the - `MORPH `_ model formulation [1]_. - - Parameters - ---------- - F : jax.Array - Deformation gradient tensor. - statevars : jax.Array - Vector of stacked state variables (CTS, C, SA). - p : list of float - A list which contains the 8 material parameters. - - Notes - ----- - The MORPH material model is implemented as a second Piola-Kirchhoff stress-based - formulation with automatic differentiation. The Tresca invariant of the distortional - part of the right Cauchy-Green deformation tensor is used as internal state - variable, see Eq. :eq:`morph-state`. - - .. warning:: - While the `MORPH `_-material - formulation captures the Mullins effect and quasi-static hysteresis effects of - rubber mixtures very nicely, it has been observed to be unstable for medium- to - highly-distorted states of deformation. - - .. math:: - :label: morph-state - - \boldsymbol{C} &= \boldsymbol{F}^T \boldsymbol{F} - - I_3 &= \det (\boldsymbol{C}) - - \hat{\boldsymbol{C}} &= I_3^{-1/3} \boldsymbol{C} - - \hat{\lambda}^2_\alpha &= \text{eigvals}(\hat{\boldsymbol{C}}) - - \hat{C}_T &= \max \left( \hat{\lambda}^2_\alpha - \hat{\lambda}^2_\beta \right) - - \hat{C}_T^S &= \max \left( \hat{C}_T, \hat{C}_{T,n}^S \right) - - A sigmoid-function is used inside the deformation-dependent variables - :math:`\alpha`, :math:`\beta` and :math:`\gamma`, see Eq. :eq:`morph-sigmoid`. - - .. math:: - :label: morph-sigmoid - - f(x) &= \frac{1}{\sqrt{1 + x^2}} - - \alpha &= p_1 + p_2 \ f(p_3\ C_T^S) - - \beta &= p_4\ f(p_3\ C_T^S) - - \gamma &= p_5\ C_T^S\ \left( 1 - f\left(\frac{C_T^S}{p_6}\right) \right) - - The rate of deformation is described by the Lagrangian tensor and its Tresca- - invariant, see Eq. :eq:`morph-rate-of-deformation`. - - .. note:: - It is important to evaluate the incremental right Cauchy-Green tensor by the - difference of the final and the previous state of deformation, not by its - variation with respect to the deformation gradient tensor. - - .. math:: - :label: morph-rate-of-deformation - - \hat{\boldsymbol{L}} &= \text{sym}\left( - \text{dev}(\boldsymbol{C}^{-1} \Delta\boldsymbol{C}) - \right) \hat{\boldsymbol{C}} - - \lambda_{\hat{\boldsymbol{L}}, \alpha} &= \text{eigvals}(\hat{\boldsymbol{L}}) - - \hat{L}_T &= \max \left( - \lambda_{\hat{\boldsymbol{L}}, \alpha}-\lambda_{\hat{\boldsymbol{L}}, \beta} - \right) - - \Delta\boldsymbol{C} &= \boldsymbol{C} - \boldsymbol{C}_n - - The additional stresses evolve between the limiting stresses, see Eq. - :eq:`morph-stresses`. The additional deviatoric-enforcement terms [1]_ are neglected - in this implementation. - - .. math:: - :label: morph-stresses - - \boldsymbol{S}_L &= \left( - \gamma \exp \left(p_7 \frac{\hat{\boldsymbol{L}}}{\hat{L}_T} - \frac{\hat{C}_T}{\hat{C}_T^S} \right) + - p8 \frac{\hat{\boldsymbol{L}}}{\hat{L}_T} - \right) \boldsymbol{C}^{-1} - - \boldsymbol{S}_A &= \frac{ - \boldsymbol{S}_{A,n} + \beta\ \hat{L}_T\ \boldsymbol{S}_L - }{1 + \beta\ \hat{L}_T} - - \boldsymbol{S} &= 2 \alpha\ \text{dev}( \hat{\boldsymbol{C}} ) - \boldsymbol{C}^{-1}+\text{dev}\left(\boldsymbol{S}_A\ \boldsymbol{C}\right) - \boldsymbol{C}^{-1} - - Examples - -------- - .. pyvista-plot:: - :context: - - >>> import felupe as fem - >>> import felupe.constitution.jax as mat - >>> - >>> umat = mat.Material( - ... mat.models.lagrange.morph, - ... p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], - ... nstatevars=13, - ... ) - >>> ax = umat.plot( - ... incompressible=True, - ... ux=fem.math.linsteps( - ... # [1, 2, 1, 2.75, 1, 3.5, 1, 4.2, 1, 4.8, 1, 4.8, 1], - ... [1, 2.75, 1, 2.75], - ... num=20, - ... ), - ... ps=None, - ... bx=None, - ... ) - - .. pyvista-plot:: - :include-source: False - :context: - :force_static: - - >>> import pyvista as pv - >>> - >>> fig = ax.get_figure() - >>> chart = pv.ChartMPL(fig) - >>> chart.show() - - References - ---------- - .. [1] D. Besdo and J. Ihlemann, "A phenomenological constitutive model for - rubberlike materials and its numerical applications", International Journal - of Plasticity, vol. 19, no. 7. Elsevier BV, pp. 1019–1036, Jul. 2003. doi: - `10.1016/s0749-6419(02)00091-8 `_. - - See Also - -------- - felupe.constitution.tensortrax.models.lagrange.morph : MORPH model (tensortrax) - """ - from jax.numpy import ( array, concatenate, diff --git a/src/felupe/constitution/jax/models/lagrange/_morph_representative_directions.py b/src/felupe/constitution/jax/models/lagrange/_morph_representative_directions.py new file mode 100644 index 00000000..72dda6b7 --- /dev/null +++ b/src/felupe/constitution/jax/models/lagrange/_morph_representative_directions.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from ....tensortrax.models.lagrange import morph_representative_directions as morph_repr +from ._morph_uniaxial import morph_uniaxial +from .microsphere import affine_force_statevars + + +@wraps(morph_repr) +def morph_representative_directions(F, statevars, p, ε=1e-6): + def f(λ, statevars, **kwargs): + dψdλ, statevars_new = morph_uniaxial(λ, statevars, **kwargs) + return 5 * dψdλ, statevars_new + + return affine_force_statevars(F, statevars, f=f, kwargs={"p": p, "ε": ε}) diff --git a/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py b/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py new file mode 100644 index 00000000..ffb01a83 --- /dev/null +++ b/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from ....tensortrax.models.lagrange import morph_uniaxial as morph_ux + + +@wraps(morph_ux) +def morph_uniaxial(λ, statevars, p, ε=1e-6): + from jax.numpy import abs as jabs + from jax.numpy import concatenate, exp, maximum, sqrt + + CTSn = statevars[:21] + λn = 1 + statevars[21:42] + SA1n = statevars[42:63] + SA2n = statevars[63:84] + + CT = jabs(λ**2 - 1 / λ) + CTS = maximum(CT, CTSn) + + L1 = 2 * (λ**3 / λn - λn**2) / 3 + L2 = (λn**2 / λ**3 - 1 / λn) / 3 + LT = jabs(L1 - L2) + + sigmoid = lambda x: 1 / sqrt(1 + x**2) + α = p[0] + p[1] * sigmoid(p[2] * CTS) + β = p[3] * sigmoid(p[2] * CTS) + γ = p[4] * CTS * (1 - sigmoid(CTS / p[5])) + + L1_LT = L1 / (ε + LT) + L2_LT = L2 / (ε + LT) + CT_CTS = CT / (ε + CTS) + + SL1 = (γ * exp(p[6] * L1_LT * CT_CTS) + p[7] * L1_LT) / λ**2 + SL2 = (γ * exp(p[6] * L2_LT * CT_CTS) + p[7] * L2_LT) * λ + + SA1 = (SA1n + β * LT * SL1) / (1 + β * LT) + SA2 = (SA2n + β * LT * SL2) / (1 + β * LT) + + dψdλ = (2 * α + SA1) * λ - (2 * α + SA2) / λ**2 + statevars_new = concatenate([CTS, (λ - 1), SA1, SA2]) + + return dψdλ, statevars_new diff --git a/src/felupe/constitution/jax/models/lagrange/microsphere/__init__.py b/src/felupe/constitution/jax/models/lagrange/microsphere/__init__.py new file mode 100644 index 00000000..132fb9a6 --- /dev/null +++ b/src/felupe/constitution/jax/models/lagrange/microsphere/__init__.py @@ -0,0 +1,5 @@ +from ._framework_affine import affine_force_statevars + +__all__ = [ + "affine_force_statevars", +] diff --git a/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py b/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py new file mode 100644 index 00000000..d95e067f --- /dev/null +++ b/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from ......quadrature import BazantOh +from ...._total_lagrange import total_lagrange + + +@total_lagrange +def affine_force_statevars(F, statevars, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Affine force (stretch) part." + + from jax.numpy import einsum, sqrt, trace + from jax.numpy.linalg import det, inv + + r = quadrature.points + M = einsum("ai,aj->aij", r, r) + Mw = einsum("aij,a->aij", M, quadrature.weights) + + # affine stretches (unimodular part) + J = det(F) + C = F.T @ F + λ = J ** (-1 / 3) * sqrt(einsum("ij...,aij->a...", C, M)) + + dψdλ, statevars_new = f(λ, statevars, **kwargs) + dψdE = einsum("a...,aij->ij...", dψdλ / λ, Mw) + + S = J ** (-2 / 3) * (dψdE - trace(dψdE @ C) / 3 * inv(C)) + + return S, statevars_new diff --git a/src/felupe/constitution/tensortrax/models/lagrange/__init__.py b/src/felupe/constitution/tensortrax/models/lagrange/__init__.py index ce8e5593..ffdeeb39 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/__init__.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/__init__.py @@ -1,9 +1,10 @@ """ -Strain-energy density functions for hyperlastic model formulations. +Strain-energy density functions for strain energy-gradient (stress) model formulations. -This module contains material model formulations to be used as the ``fun``-argument in :func:`~felupe.MaterialAD`. The gradient as well as the hessian of the strain energy -density function is carried out by automatic differentiation using :mod:`tensortrax`. -Hence, all math-functions must be taken from :mod:`tensortrax.math`. +This module contains material model formulations to be used as the ``fun``-argument in +:func:`~felupe.constitution.tensortrax.Material`. The gradient as well as the hessian of +the strain energy density function is carried out by automatic differentiation using +:mod:`tensortrax`. Hence, all math-functions must be taken from :mod:`tensortrax.math`. """ from ._morph import morph diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py index 11172820..c1c4e7bd 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py @@ -29,7 +29,7 @@ def morph(F, statevars, p): Parameters ---------- - F : tensortrax.Tensor + F : tensortrax.Tensor or jax.Array Deformation gradient tensor. statevars : array Vector of stacked state variables (CTS, C, SA). @@ -130,13 +130,23 @@ def morph(F, statevars, p): Examples -------- + First, choose the desired automatic differentiation backend + .. pyvista-plot:: :context: >>> import felupe as fem >>> - >>> umat = fem.MaterialAD( - ... fem.morph, + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the material. + + .. pyvista-plot:: + :context: + + >>> umat = mat.Material( + ... mat.models.lagrange.morph, ... p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], ... nstatevars=13, ... ) diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py index b097a983..a1b8fa16 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py @@ -19,7 +19,7 @@ from .microsphere import affine_force_statevars -def morph_representative_directions(F, statevars, p, ε=1e-8): +def morph_representative_directions(F, statevars, p, ε=1e-6): """First Piola-Kirchhoff stress tensor of the `MORPH `_ model formulation [1]_, implemented by the concept of @@ -28,25 +28,34 @@ def morph_representative_directions(F, statevars, p, ε=1e-8): Parameters ---------- - F : tensortrax.Tensor + F : tensortrax.Tensor or jax.Array Deformation gradient tensor. statevars : array Vector of stacked state variables (CTS, λ - 1, SA1, SA2). p : list of float A list which contains the 8 material parameters. ε : float, optional - A small stabilization parameter (default is 1e-8). + A small stabilization parameter (default is 1e-6). Examples -------- + First, choose the desired automatic differentiation backend + .. pyvista-plot:: :context: >>> import felupe as fem - >>> import felupe.constitution.tensortrax as mat >>> + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the material. + + .. pyvista-plot:: + :context: + >>> umat = mat.Material( - ... fem.morph_representative_directions, + ... mat.models.lagrange.morph_representative_directions, ... p=[0.011, 0.408, 0.421, 6.85, 0.0056, 5.54, 5.84, 0.117], ... nstatevars=84, ... ) diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph_uniaxial.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph_uniaxial.py index 522435ce..0e40cfa5 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph_uniaxial.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph_uniaxial.py @@ -20,21 +20,21 @@ from tensortrax.math.special import try_stack -def morph_uniaxial(λ, statevars, p, ε=1e-8): +def morph_uniaxial(λ, statevars, p, ε=1e-6): """Return the force (per undeformed area) for a given longitudinal stretch in uniaxial incompressible tension or compression for the MORPH material formulation [1]_, [2]_. Parameters ---------- - λ : tensortrax.Tensor + λ : tensortrax.Tensor or jax.Array Longitudinal stretch of uniaxial incompressible deformation. statevars : array Vector of stacked state variables (CTS, λ - 1, SA1, SA2). p : list of float A list which contains the 8 material parameters. ε : float, optional - A small stabilization parameter (default is 1e-8). + A small stabilization parameter (default is 1e-6). References ---------- diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 93be8e5c..eba982ff 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -172,18 +172,27 @@ def dWdF(F, statevars, C10, K): def test_material_included_jax_statevars(): try: - umat = mat.Material( - fem.constitution.jax.models.lagrange.morph, - p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244], - nstatevars=13, - ) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) + import felupe.constitution.jax as mat + + for fun, nstatevars in zip( + [ + mat.models.lagrange.morph, + mat.models.lagrange.morph_representative_directions, + ], + [13, 84], + ): + umat = mat.Material( + fun, + **fun.kwargs, + nstatevars=nstatevars, + ) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) - solid = fem.SolidBody(umat=umat, field=field) - solid.evaluate.gradient() - solid.evaluate.hessian() + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() except ModuleNotFoundError: pass From eb32eddc659fe7c629b0d1c2e342eb213fc64bff Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 5 Nov 2024 16:31:52 +0100 Subject: [PATCH 084/125] Add `isochoric_volumetric_split()` for JAX-hyperelastic material (#885) --- CHANGELOG.md | 2 +- .../jax/models/hyperelastic/__init__.py | 2 + .../jax/models/hyperelastic/_helpers.py | 30 ++++++++ tests/test_constitution_newton.py | 77 +++++++++++++++++-- 4 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_helpers.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 77f92426..3c148794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file. The format - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. - Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. -- Add `felupe.constitution.jax.total_lagrange()` and `felupe.constitution.jax.updated_lagrange()` function decorators for JAX materials. +- Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.models.hyperelastic.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index dcf1252f..6f45ba48 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -1,8 +1,10 @@ +from ._helpers import isochoric_volumetric_split from ._mooney_rivlin import mooney_rivlin from ._third_order_deformation import third_order_deformation from ._yeoh import yeoh __all__ = [ + "isochoric_volumetric_split", "mooney_rivlin", "third_order_deformation", "yeoh", diff --git a/src/felupe/constitution/jax/models/hyperelastic/_helpers.py b/src/felupe/constitution/jax/models/hyperelastic/_helpers.py new file mode 100644 index 00000000..9dbcb3a5 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_helpers.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + + +def isochoric_volumetric_split(fun): + """Apply the material formulation only on the isochoric part of the + multiplicative split of the deformation gradient.""" + from jax.numpy.linalg import det + + @wraps(fun) + def apply_iso(C, *args, **kwargs): + return fun(det(C) ** (-1 / 3) * C, *args, **kwargs) + + return apply_iso diff --git a/tests/test_constitution_newton.py b/tests/test_constitution_newton.py index 9156812c..053e5289 100644 --- a/tests/test_constitution_newton.py +++ b/tests/test_constitution_newton.py @@ -25,21 +25,24 @@ """ import numpy as np -import tensortrax as tr -from tensortrax.math import trace -from tensortrax.math.linalg import det, inv -from tensortrax.math.special import dev, from_triu_1d, triu_1d import felupe as fem def test_visco_newton(): + import tensortrax as tr + from tensortrax.math import trace + from tensortrax.math.linalg import det, inv + from tensortrax.math.special import from_triu_1d, triu_1d + + import felupe.constitution.tensortrax as mat + mesh = fem.Rectangle(n=3) region = fem.RegionQuad(mesh) field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)]) boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) - @fem.constitution.isochoric_volumetric_split + @mat.models.hyperelastic.isochoric_volumetric_split def finite_strain_viscoelastic_newton(C, Cin, mu, eta, dtime): "Finite Strain Viscoelastic material formulation." @@ -65,11 +68,10 @@ def evolution(Ci, Cin, C, mu, eta, dtime): # strain energy function and state variable return mu / 2 * (I1 - 3), triu_1d(Ci) - umat = fem.Hyperelastic( + umat = mat.Hyperelastic( finite_strain_viscoelastic_newton, mu=1.0, eta=1.0, dtime=0.1, nstatevars=6 ) solid = fem.SolidBodyNearlyIncompressible(umat, field, bulk=5000) - # solid.results.statevars[[0, 3, 5]] += 1 move = fem.math.linsteps([0, 0.3], num=3) step = fem.Step( @@ -79,5 +81,66 @@ def evolution(Ci, Cin, C, mu, eta, dtime): assert np.all([norm[-1] < 1e-7 for norm in job.fnorms]) +def test_visco_newton_jax(): + import jax + from jax.numpy import trace + from jax.numpy.linalg import det, inv + from jax.scipy.optimize import minimize + + import felupe.constitution.jax as mat + + mesh = fem.Rectangle(n=3) + region = fem.RegionQuad(mesh) + field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)]) + boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + + @mat.models.hyperelastic.isochoric_volumetric_split + def finite_strain_viscoelastic_newton(C, statevars, mu, eta, dtime): + "Finite Strain Viscoelastic material formulation." + + def evolution(Ci, Cin, C, mu, eta, dtime): + "Viscoelastic evolution equation." + Ci = Ci.reshape(3, 3) + residuals = mu / eta * C - (Ci - Cin) / dtime + return residuals.ravel() @ residuals.ravel() + + # update of state variables by evolution equation + Cin = statevars[:9].reshape(3, 3) + Ci = minimize( + evolution, + x0=Cin.ravel(), + args=(Cin, jax.lax.stop_gradient(C), mu, eta, dtime), + method="BFGS", + ).x.reshape(3, 3) + Ci *= det(Ci) ** (-1 / 3) + + # first invariant of elastic part of right Cauchy-Green deformation tensor + I1 = trace(C @ inv(Ci)) + + # strain energy function and state variable + statevars_new = Ci.ravel() + return mu / 2 * (I1 - 3), statevars_new + + umat = mat.Hyperelastic( + finite_strain_viscoelastic_newton, + mu=1.0, + eta=1.0, + dtime=0.1, + nstatevars=9, + jit=True, + ) + solid = fem.SolidBodyNearlyIncompressible(umat, field, bulk=5000) + + move = fem.math.linsteps([0, 0.3], num=3) + step = fem.Step( + items=[solid], ramp={boundaries["move"]: move}, boundaries=boundaries + ) + job = fem.CharacteristicCurve(steps=[step], boundary=boundaries["move"]) + job.evaluate(tol=1e-3) + + assert np.all([fnorm[-1] < 1e-3 for fnorm in job.fnorms]) + + if __name__ == "__main__": test_visco_newton() + test_visco_newton_jax() From 461eadc0de2b7a3f4ee5bab69661088ea44ec16b Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 5 Nov 2024 23:07:05 +0100 Subject: [PATCH 085/125] Reduce test matrix to run only on min. and max. supported Python versions --- .github/workflows/upload-codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/upload-codecov.yml b/.github/workflows/upload-codecov.yml index ea8d2e3d..30d1c89b 100644 --- a/.github/workflows/upload-codecov.yml +++ b/.github/workflows/upload-codecov.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.12"] steps: - uses: actions/setup-python@v4 with: From b213099c4b01475d1f7460f7bd8e602bff4546cc Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 5 Nov 2024 23:23:56 +0100 Subject: [PATCH 086/125] Move `constitution.jax.isochoric_volumetric_split()` (#887) from `constitution.jax.models.hyperelastic.isochoric_volumetric_split()`; also for tensortrax --- src/felupe/constitution/__init__.py | 3 +- src/felupe/constitution/jax/__init__.py | 3 +- .../jax/{_tools.py => _helpers.py} | 14 ++++++++- src/felupe/constitution/jax/_hyperelastic.py | 4 +-- src/felupe/constitution/jax/_material.py | 2 +- .../jax/models/hyperelastic/__init__.py | 2 -- .../jax/models/hyperelastic/_helpers.py | 30 ------------------- .../constitution/tensortrax/__init__.py | 2 ++ .../{models/hyperelastic => }/_helpers.py | 0 .../models/hyperelastic/__init__.py | 2 -- tests/test_constitution_newton.py | 4 +-- 11 files changed, 23 insertions(+), 43 deletions(-) rename src/felupe/constitution/jax/{_tools.py => _helpers.py} (90%) delete mode 100644 src/felupe/constitution/jax/models/hyperelastic/_helpers.py rename src/felupe/constitution/tensortrax/{models/hyperelastic => }/_helpers.py (100%) diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index 852c25a4..f1e23bdb 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -22,14 +22,13 @@ ) from .tensortrax import Hyperelastic from .tensortrax import Material as MaterialAD -from .tensortrax import total_lagrange, updated_lagrange +from .tensortrax import isochoric_volumetric_split, total_lagrange, updated_lagrange from .tensortrax.models.hyperelastic import ( alexander, anssari_benam_bucchi, arruda_boyce, extended_tube, finite_strain_viscoelastic, - isochoric_volumetric_split, lopez_pamies, miehe_goektepe_lulei, mooney_rivlin, diff --git a/src/felupe/constitution/jax/__init__.py b/src/felupe/constitution/jax/__init__.py index 7e98c94d..da2d61da 100644 --- a/src/felupe/constitution/jax/__init__.py +++ b/src/felupe/constitution/jax/__init__.py @@ -1,12 +1,13 @@ from . import models +from ._helpers import isochoric_volumetric_split, vmap from ._hyperelastic import Hyperelastic from ._material import Material -from ._tools import vmap from ._total_lagrange import total_lagrange from ._updated_lagrange import updated_lagrange __all__ = [ "Hyperelastic", + "isochoric_volumetric_split", "Material", "models", "total_lagrange", diff --git a/src/felupe/constitution/jax/_tools.py b/src/felupe/constitution/jax/_helpers.py similarity index 90% rename from src/felupe/constitution/jax/_tools.py rename to src/felupe/constitution/jax/_helpers.py index 6a54ae3c..00300cc7 100644 --- a/src/felupe/constitution/jax/_tools.py +++ b/src/felupe/constitution/jax/_helpers.py @@ -90,7 +90,7 @@ def vmap2(fun, in_axes=0, out_axes=0, **kwargs): ) -def total_lagrange(fun): +def as_total_lagrange(fun): import jax.numpy as jnp @wraps(fun) @@ -101,3 +101,15 @@ def evaluate(F, *args, **kwargs): return fun(C, *args, **kwargs) return evaluate + + +def isochoric_volumetric_split(fun): + """Apply the material formulation only on the isochoric part of the + multiplicative split of the deformation gradient.""" + from jax.numpy.linalg import det + + @wraps(fun) + def apply_iso(C, *args, **kwargs): + return fun(det(C) ** (-1 / 3) * C, *args, **kwargs) + + return apply_iso diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py index 0deb6fc9..5d060d48 100644 --- a/src/felupe/constitution/jax/_hyperelastic.py +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -21,7 +21,7 @@ import numpy as np from .._material import Material -from ._tools import total_lagrange, vmap2 +from ._helpers import as_total_lagrange, vmap2 class Hyperelastic(Material): @@ -147,7 +147,7 @@ def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): import jax has_aux = nstatevars > 0 - self.fun = total_lagrange(fun) + self.fun = as_total_lagrange(fun) if parallel: warnings.warn("Parallel execution is not implemented.") diff --git a/src/felupe/constitution/jax/_material.py b/src/felupe/constitution/jax/_material.py index 5c31052a..a16b5428 100644 --- a/src/felupe/constitution/jax/_material.py +++ b/src/felupe/constitution/jax/_material.py @@ -21,7 +21,7 @@ import numpy as np from .._material import Material as MaterialDefault -from ._tools import vmap2 +from ._helpers import vmap2 class Material(MaterialDefault): diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index 6f45ba48..dcf1252f 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -1,10 +1,8 @@ -from ._helpers import isochoric_volumetric_split from ._mooney_rivlin import mooney_rivlin from ._third_order_deformation import third_order_deformation from ._yeoh import yeoh __all__ = [ - "isochoric_volumetric_split", "mooney_rivlin", "third_order_deformation", "yeoh", diff --git a/src/felupe/constitution/jax/models/hyperelastic/_helpers.py b/src/felupe/constitution/jax/models/hyperelastic/_helpers.py deleted file mode 100644 index 9dbcb3a5..00000000 --- a/src/felupe/constitution/jax/models/hyperelastic/_helpers.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -""" -This file is part of FElupe. - -FElupe is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -FElupe is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with FElupe. If not, see . -""" -from functools import wraps - - -def isochoric_volumetric_split(fun): - """Apply the material formulation only on the isochoric part of the - multiplicative split of the deformation gradient.""" - from jax.numpy.linalg import det - - @wraps(fun) - def apply_iso(C, *args, **kwargs): - return fun(det(C) ** (-1 / 3) * C, *args, **kwargs) - - return apply_iso diff --git a/src/felupe/constitution/tensortrax/__init__.py b/src/felupe/constitution/tensortrax/__init__.py index c95b71e6..0f347ffa 100644 --- a/src/felupe/constitution/tensortrax/__init__.py +++ b/src/felupe/constitution/tensortrax/__init__.py @@ -1,4 +1,5 @@ from . import models +from ._helpers import isochoric_volumetric_split from ._hyperelastic import Hyperelastic from ._material import Material from ._total_lagrange import total_lagrange @@ -6,6 +7,7 @@ __all__ = [ "Hyperelastic", + "isochoric_volumetric_split", "models", "total_lagrange", "updated_lagrange", diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_helpers.py b/src/felupe/constitution/tensortrax/_helpers.py similarity index 100% rename from src/felupe/constitution/tensortrax/models/hyperelastic/_helpers.py rename to src/felupe/constitution/tensortrax/_helpers.py diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py index 275f71af..6b6bbf56 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py @@ -14,7 +14,6 @@ from ._arruda_boyce import arruda_boyce from ._extended_tube import extended_tube from ._finite_strain_viscoelastic import finite_strain_viscoelastic -from ._helpers import isochoric_volumetric_split from ._lopez_pamies import lopez_pamies from ._miehe_goektepe_lulei import miehe_goektepe_lulei from ._mooney_rivlin import mooney_rivlin @@ -33,7 +32,6 @@ "arruda_boyce", "extended_tube", "finite_strain_viscoelastic", - "isochoric_volumetric_split", "lopez_pamies", "miehe_goektepe_lulei", "mooney_rivlin", diff --git a/tests/test_constitution_newton.py b/tests/test_constitution_newton.py index 053e5289..181c7e40 100644 --- a/tests/test_constitution_newton.py +++ b/tests/test_constitution_newton.py @@ -42,7 +42,7 @@ def test_visco_newton(): field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)]) boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) - @mat.models.hyperelastic.isochoric_volumetric_split + @mat.isochoric_volumetric_split def finite_strain_viscoelastic_newton(C, Cin, mu, eta, dtime): "Finite Strain Viscoelastic material formulation." @@ -94,7 +94,7 @@ def test_visco_newton_jax(): field = fem.FieldContainer([fem.FieldPlaneStrain(region, dim=2)]) boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) - @mat.models.hyperelastic.isochoric_volumetric_split + @mat.isochoric_volumetric_split def finite_strain_viscoelastic_newton(C, statevars, mu, eta, dtime): "Finite Strain Viscoelastic material formulation." From da629276816c1c315177c9f39619c056939a228a Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 5 Nov 2024 23:29:51 +0100 Subject: [PATCH 087/125] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c148794..e04dafda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file. The format - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. - Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. -- Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.models.hyperelastic.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. +- Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. From 706a6380ead211542425c79c0730b6d363109c7d Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 6 Nov 2024 23:15:15 +0100 Subject: [PATCH 088/125] Add optional in-place cast `Region.astype(dtype, copy=True)` (#888) * Add optional in-place cast `Region.astype(dtype, copy=True)` * Update test_dtype.py --- CHANGELOG.md | 2 ++ src/felupe/region/_region.py | 21 ++++++++++++++++----- tests/test_dtype.py | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e04dafda..90b8d656 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,12 @@ All notable changes to this project will be documented in this file. The format - Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. - Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. - Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. +- Add an optional keyword-argument `Region.astype(copy=True)` to modify the data types of the arrays of the region in-place if `copy=False`. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. - Change supported Python versions to 3.9 - 3.12. +- Change the `dtype`-argument in `Region.astype(dtype)` from an optional to a required argument. ### Fixed - Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. diff --git a/src/felupe/region/_region.py b/src/felupe/region/_region.py index cc088cc5..dd12b1ea 100644 --- a/src/felupe/region/_region.py +++ b/src/felupe/region/_region.py @@ -149,14 +149,17 @@ def __init__(self, mesh, element, quadrature, grad=True, hess=False, uniform=Fal self.evaluate_hessian = hess self.reload(mesh=mesh, element=element, quadrature=quadrature, uniform=uniform) - def astype(self, dtype=None): + def astype(self, dtype, copy=True): """Copy the region and cast the arrays to a specified type. Parameters ---------- - dtype : data-type or None, optional - The data-type of the arrays of the Region. If None, a copy of the Region is - returned. + dtype : str or dtype + Typecode or data-type to which the arrays of the region are cast. + copy : bool, optional + By default, astype always returns a copy of the region with newly allocated + arrays. If False, the arrays of the input region are modified and the input + region is returned. Default is True. Returns ------- @@ -168,7 +171,11 @@ def astype(self, dtype=None): felupe.region.copy : Return a copy of the region and reload it if necessary. """ - region = self.copy(uniform=self.uniform) + region = self + + if copy: + region = region.copy(uniform=self.uniform) + region.h = region.h.astype(dtype) region.dhdr = region.dhdr.astype(dtype) @@ -178,6 +185,10 @@ def astype(self, dtype=None): region.dhdX = region.dhdX.astype(dtype) region.dV = region.dV.astype(dtype) + if region.evaluate_hessian: + region.d2hdrdr = region.d2hdrdr.astype(dtype) + region.d2hdXdX = region.d2hdXdX.astype(dtype) + return region def copy( diff --git a/tests/test_dtype.py b/tests/test_dtype.py index 273c2126..08ff2862 100644 --- a/tests/test_dtype.py +++ b/tests/test_dtype.py @@ -32,7 +32,7 @@ def test_dtype(dtype=np.float32, tol=1e-3): mesh = fem.Cube(n=3) - region = fem.RegionHexahedron(mesh).astype(dtype) + region = fem.RegionHexahedron(mesh).astype(dtype, copy=False) displacement = fem.Field(region, dim=3, dtype=dtype) field = fem.FieldContainer([displacement]) @@ -62,7 +62,7 @@ def test_dtype_axi(): def test_dtype_planestrain(): mesh = fem.Rectangle(n=3) - region = fem.RegionQuad(mesh).astype(np.float32) + region = fem.RegionQuad(mesh, hess=True).astype(np.float32) displacement = fem.FieldPlaneStrain(region, dtype=np.float32) field = fem.FieldContainer([displacement]) From 51237be68a929c5b17a1b8516194a24eec0e4a0f Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 7 Nov 2024 13:47:08 +0100 Subject: [PATCH 089/125] Make the examples run faster on CI/CD (#890) --- docs/felupe/constitution/autodiff.rst | 11 +++- docs/felupe/constitution/autodiff/jax.rst | 28 ++++++---- .../constitution/autodiff/tensortrax.rst | 53 ++++++++++--------- examples/ex03_plasticity.py | 2 +- examples/ex11_notch-stress.py | 16 +++--- .../constitution/tensortrax/_hyperelastic.py | 32 ++++++----- 6 files changed, 85 insertions(+), 57 deletions(-) diff --git a/docs/felupe/constitution/autodiff.rst b/docs/felupe/constitution/autodiff.rst index fb8cc96a..c1462d04 100644 --- a/docs/felupe/constitution/autodiff.rst +++ b/docs/felupe/constitution/autodiff.rst @@ -44,4 +44,13 @@ It is straightforward to switch between these backends. "Strain energy function of the Neo-Hookean material formulation." return mu / 2 * (jnp.linalg.det(C) ** (-1/3) * jnp.trace(C) - 3) - umat = mat.Hyperelastic(neo_hooke, mu=1.0) \ No newline at end of file + umat = mat.Hyperelastic(neo_hooke, mu=1.0) + + +.. note:: + + The default backend is available in the top-level package namespace, this includes + all models from :mod:`felupe.constitution.tensortrax.models.hyperelastic` and + :mod:`felupe.constitution.tensortrax.models.lagrange` as well as the material + classes :class:`felupe.constitution.tensortrax.Material` and + :class:`felupe.constitution.tensortrax.Hyperelastic`. \ No newline at end of file diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 8d31bcf1..6bd4469b 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -7,24 +7,26 @@ This page contains material model formulations with automatic differentiation us **Frameworks** -.. currentmodule:: felupe +.. currentmodule:: felupe.constitution.jax .. autosummary:: - constitution.jax.Hyperelastic - constitution.jax.Material - constitution.jax.total_lagrange - constitution.jax.updated_lagrange + Hyperelastic + Material + total_lagrange + updated_lagrange **Material Models for** :class:`felupe.constitution.jax.Hyperelastic` These material model formulations are defined by a strain energy density function. +.. currentmodule:: felupe.constitution.jax.models.hyperelastic + .. autosummary:: - felupe.constitution.jax.models.hyperelastic.mooney_rivlin - felupe.constitution.jax.models.hyperelastic.third_order_deformation - felupe.constitution.jax.models.hyperelastic.yeoh + mooney_rivlin + third_order_deformation + yeoh **Material Models for** :class:`felupe.constitution.jax.Material` @@ -32,16 +34,20 @@ The material model formulations are defined by the first Piola-Kirchhoff stress Function-decorators are available to use Total-Lagrange and Updated-Lagrange material formulations in :class:`~felupe.constitution.jax.Material`. +.. currentmodule:: felupe.constitution.jax.models.lagrange + .. autosummary:: - felupe.constitution.jax.models.lagrange.morph - felupe.constitution.jax.models.lagrange.morph_representative_directions + morph + morph_representative_directions **Tools** +.. currentmodule:: felupe.constitution.jax + .. autosummary:: - constitution.jax.vmap + vmap **Detailed API Reference** diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index f3c46044..f3024875 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -12,19 +12,21 @@ This page contains hyperelastic material model formulations with automatic diffe **Frameworks** -.. currentmodule:: felupe +.. currentmodule:: felupe.constitution.tensortrax .. autosummary:: - constitution.tensortrax.Hyperelastic - constitution.tensortrax.Material - constitution.tensortrax.total_lagrange - constitution.tensortrax.updated_lagrange + Hyperelastic + Material + total_lagrange + updated_lagrange **Material Models for** :class:`felupe.constitution.tensortrax.Hyperelastic` These material model formulations are defined by a strain energy density function. +.. currentmodule:: felupe.constitution.tensortrax.models.hyperelastic + .. autosummary:: alexander @@ -46,8 +48,11 @@ These material model formulations are defined by a strain energy density functio **Material Models for** :class:`felupe.constitution.tensortrax.Material` The material model formulations are defined by the first Piola-Kirchhoff stress tensor. -Function-decorators are available to use Total-Lagrange and Updated-Lagrange material -formulations in :class:`~felupe.constitution.tensortrax.Material`. +Function-decorators are available to use :func:`~felupe.constitution.tensortrax.total_lagrange` +and :func:`~felupe.constitution.tensortrax.updated_lagrange` material formulations in +:class:`~felupe.constitution.tensortrax.Material`. + +.. currentmodule:: felupe.constitution.tensortrax.models.lagrange .. autosummary:: @@ -84,36 +89,36 @@ formulations in :class:`~felupe.constitution.tensortrax.Material`. .. autofunction:: felupe.updated_lagrange -.. autofunction:: felupe.alexander +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.alexander -.. autofunction:: felupe.anssari_benam_bucchi +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.anssari_benam_bucchi -.. autofunction:: felupe.arruda_boyce +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.arruda_boyce -.. autofunction:: felupe.extended_tube +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.extended_tube -.. autofunction:: felupe.finite_strain_viscoelastic +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.finite_strain_viscoelastic -.. autofunction:: felupe.lopez_pamies +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.lopez_pamies -.. autofunction:: felupe.miehe_goektepe_lulei +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.miehe_goektepe_lulei -.. autofunction:: felupe.mooney_rivlin +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.mooney_rivlin -.. autofunction:: felupe.neo_hooke +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.neo_hooke -.. autofunction:: felupe.ogden +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.ogden -.. autofunction:: felupe.ogden_roxburgh +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.ogden_roxburgh -.. autofunction:: felupe.saint_venant_kirchhoff +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.saint_venant_kirchhoff -.. autofunction:: felupe.third_order_deformation +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.third_order_deformation -.. autofunction:: felupe.van_der_waals +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.van_der_waals -.. autofunction:: felupe.yeoh +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.yeoh -.. autofunction:: felupe.morph +.. autofunction:: felupe.constitution.tensortrax.models.lagrange.morph -.. autofunction:: felupe.morph_representative_directions \ No newline at end of file +.. autofunction:: felupe.constitution.tensortrax.models.lagrange.morph_representative_directions \ No newline at end of file diff --git a/examples/ex03_plasticity.py b/examples/ex03_plasticity.py index e70fd4d5..13e94871 100644 --- a/examples/ex03_plasticity.py +++ b/examples/ex03_plasticity.py @@ -27,7 +27,7 @@ import felupe as fem -mesh = fem.Cube(b=(3, 1, 1), n=(16, 6, 6)) +mesh = fem.Cube(b=(3, 1, 1), n=(10, 4, 4)) region = fem.RegionHexahedron(mesh) displacement = fem.Field(region, dim=3) field = fem.FieldContainer([displacement]) diff --git a/examples/ex11_notch-stress.py b/examples/ex11_notch-stress.py index 4102fea4..469c3003 100644 --- a/examples/ex11_notch-stress.py +++ b/examples/ex11_notch-stress.py @@ -22,9 +22,9 @@ pip install pypardiso A linear-elastic notched plate is subjected to uniaxial tension. The cell-based mean of -the stress tensor is projected to the mesh-points and its maximum principal value is plotted. FElupe has no quadratic wedge element formulation -implemented and hence, the quadratic wedges in the mesh are converted to quadratic -hexahedrons. +the stress tensor is projected to the mesh-points and its maximum principal value is +plotted. FElupe has no wedge element formulation implemented and hence, the wedges in +the mesh are converted to hexahedrons. """ # sphinx_gallery_thumbnail_number = -1 @@ -36,13 +36,13 @@ m = pv.examples.download_notch_displacement() -hex20 = [0, 2, 1, 1, 3, 5, 4, 4, 8, 7, 1, 6, 11, 10, 4, 9, 12, 14, 13, 13] +hex8 = [0, 2, 1, 1, 3, 5, 4, 4] mesh = fem.Mesh( m.points * 250, - np.vstack([m.cells_dict[25], m.cells_dict[26][:, hex20]]), - "hexahedron20", + np.vstack([m.cells_dict[25][:, :8], m.cells_dict[26][:, hex8]]), + "hexahedron", ) -region = fem.RegionQuadraticHexahedron(mesh) +region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) boundaries, loadcase = fem.dof.uniaxial(field, clamped=True, sym=False, move=0.02) @@ -64,7 +64,7 @@ # principal value of the Cauchy stress tensor is used to evaluate the fatigue life. # For simplicity, the stress is evaluated for the total solid body. To consider only # stresses on points which lie on the surface of the solid body, the cells on faces -# :meth:`~felupe.RegionQuadraticHexahedronBoundary.mesh.cells_faces` must be determined +# :meth:`~felupe.RegionHexahedronBoundary.mesh.cells_faces` must be determined # first. # # .. math:: diff --git a/src/felupe/constitution/tensortrax/_hyperelastic.py b/src/felupe/constitution/tensortrax/_hyperelastic.py index 46c2b5fe..0fbd179b 100644 --- a/src/felupe/constitution/tensortrax/_hyperelastic.py +++ b/src/felupe/constitution/tensortrax/_hyperelastic.py @@ -139,18 +139,26 @@ def viscoelastic(C, Cin, mu, eta, dtime): See Also -------- - saint_venant_kirchhoff : Strain energy function of the Saint - Venant-Kirchhoff material formulation. - neo_hooke : Strain energy function of the Neo-Hookean material formulation. - mooney_rivlin : Strain energy function of the Mooney-Rivlin material formulation. - yeoh : "Strain energy function of the Yeoh material formulation. - third_order_deformation : Strain energy function of the - Third-Order-Deformation material formulation. - ogden : Strain energy function of the Ogden material formulation. - arruda_boyce : Strain energy function of the Arruda-Boyce material formulation. - extended_tube : Strain energy function of the Extended-Tube material formulation. - van_der_waals : Strain energy function of the Van der Waals material formulation. - finite_strain_viscoelastic : Finite strain viscoelastic material formulation. + felupe.constitution.tensortrax.models.hyperelastic.saint_venant_kirchhoff : Strain + energy function of the Saint Venant-Kirchhoff material formulation. + felupe.constitution.tensortrax.models.hyperelastic.neo_hooke : Strain energy + function of the Neo-Hookean material formulation. + felupe.constitution.tensortrax.models.hyperelastic.mooney_rivlin : Strain energy + function of the Mooney-Rivlin material formulation. + felupe.constitution.tensortrax.models.hyperelastic.yeoh : "Strain energy function of + the Yeoh material formulation. + felupe.constitution.tensortrax.models.hyperelastic.third_order_deformation : Strain + energy function of the Third-Order-Deformation material formulation. + felupe.constitution.tensortrax.models.hyperelastic.ogden : Strain energy function of + the Ogden material formulation. + felupe.constitution.tensortrax.models.hyperelastic.arruda_boyce : Strain energy + function of the Arruda-Boyce material formulation. + felupe.constitution.tensortrax.models.hyperelastic.extended_tube : Strain energy + function of the Extended-Tube material formulation. + felupe.constitution.tensortrax.models.hyperelastic.van_der_waals : Strain energy + function of the Van der Waals material formulation. + felupe.constitution.tensortrax.models.hyperelastic.finite_strain_viscoelastic : + Finite strain viscoelastic material formulation. """ From 59ab5951c4b12961fc7e79a85db6087009219a73 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 7 Nov 2024 15:12:56 +0100 Subject: [PATCH 090/125] Update ex11_notch-stress.py use only mesh-points with connected cells --- examples/ex11_notch-stress.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/ex11_notch-stress.py b/examples/ex11_notch-stress.py index 469c3003..a0a9c53b 100644 --- a/examples/ex11_notch-stress.py +++ b/examples/ex11_notch-stress.py @@ -42,6 +42,10 @@ np.vstack([m.cells_dict[25][:, :8], m.cells_dict[26][:, hex8]]), "hexahedron", ) +point_ids = np.zeros(mesh.npoints, dtype=int) +point_ids[mesh.points_with_cells] = np.arange(len(mesh.points_with_cells)) +mesh.update(points=mesh.points[mesh.points_with_cells], cells=point_ids[mesh.cells]) + region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) From b08e2006b4d472b9b03b147854b3be34585bc0be Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 8 Nov 2024 13:53:37 +0100 Subject: [PATCH 091/125] Update ex09_numeric-continuation.py use less substeps --- examples/ex09_numeric-continuation.py | 46 ++++++++++----------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/examples/ex09_numeric-continuation.py b/examples/ex09_numeric-continuation.py index bca9d748..c5d25931 100644 --- a/examples/ex09_numeric-continuation.py +++ b/examples/ex09_numeric-continuation.py @@ -2,7 +2,12 @@ Numeric Continuation -------------------- -With the help of `contique `_ (install with ``pip install contique``) it is possible to apply a numerical parameter continuation algorithm on any system of equilibrium equations. This example demonstrates the usage of FElupe in conjunction with contique. An unstable isotropic hyperelastic material formulation is applied on a single hexahedron. The model will be visualized by the XDMF-output (of meshio) and the resulting force - displacement curve will be plotted. +With the help of `contique `_ (install with +``pip install contique``) it is possible to apply a numerical parameter continuation +algorithm on any system of equilibrium equations. This example demonstrates the usage of +FElupe in conjunction with contique. An unstable isotropic hyperelastic material +formulation is applied on a single hexahedron. The model will be visualized and the +resulting force - displacement curve will be plotted. .. topic:: Numeric continuation of a hyperelastic cube. @@ -10,24 +15,17 @@ * on-the-fly XDMF-file export - * plot force-displacement curve - -.. admonition:: This example requires external packages. - :class: hint - - .. code-block:: - - pip install contique matadi + * plot a force-displacement curve """ # sphinx_gallery_thumbnail_number = -1 import contique -import matadi as mat import matplotlib.pyplot as plt import meshio import numpy as np import felupe as fem +import felupe.constitution.tensortrax as mat # %% # First, setup a problem as usual (mesh, region, field, boundaries and umat). For the @@ -46,20 +44,9 @@ dof0, dof1 = fem.dof.partition(field, bounds) # constitutive isotropic hyperelastic material formulation -yeoh = mat.MaterialHyperelastic(mat.models.yeoh, C10=0.5, C20=-0.25, C30=0.025, bulk=5) - -lab = mat.Lab(yeoh) -data = lab.run( - ux=True, - bx=False, - ps=False, - shear=False, - stretch_min=1, - stretch_max=2.75, - num=100, -) -lab.plot(data) -body = fem.SolidBody(yeoh, field) +yeoh = mat.Hyperelastic(mat.models.hyperelastic.yeoh, C10=0.5, C20=-0.25, C30=0.025) +ax = yeoh.plot(incompressible=True, ux=np.linspace(1, 2.76), bx=None, ps=None) +body = fem.SolidBodyNearlyIncompressible(yeoh, field, bulk=5000) # %% # An external normal force is applied at :math:`x=1` on a quarter model of a cube with @@ -131,23 +118,24 @@ def step_to_xdmf(step, res): jac=[dfundx, dfundl], x0=field[0][dof1], lpf0=0, - dxmax=0.05, - dlpfmax=0.5, - maxsteps=80, + dxmax=0.06, + dlpfmax=2, + maxsteps=35, rebalance=True, overshoot=1.05, callback=step_to_xdmf, + tol=1e-2, ) X = np.array([res.x for res in Res]) # check the final lpf value -assert np.isclose(X[-1, -1], 11.759) +assert np.isclose(X[-1, 1], -0.3982995) # %% # Finally, the force-displacement curve is plotted. It can be seen that the resulting # (unstable) force-controlled equilibrium path is equal to the displacement-controlled -# load case of matADi's lab. +# load case. plt.figure() plt.plot(X[:, 0], X[:, -1], "x-") From 5a3586236c6fb0940d56e3caf4983a1fa4c72692 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 8 Nov 2024 22:37:32 +0100 Subject: [PATCH 092/125] Update ex09_numeric-continuation.py --- examples/ex09_numeric-continuation.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/ex09_numeric-continuation.py b/examples/ex09_numeric-continuation.py index c5d25931..c0491e3c 100644 --- a/examples/ex09_numeric-continuation.py +++ b/examples/ex09_numeric-continuation.py @@ -28,9 +28,8 @@ import felupe.constitution.tensortrax as mat # %% -# First, setup a problem as usual (mesh, region, field, boundaries and umat). For the -# material definition we use matADi (``pip install madati``). We utilize matADi's lab- -# capability to visualize the unstable material behavior in uniaxial tension. +# First, setup a problem as usual (mesh, region, field, boundaries and umat). The +# unstable material behavior is plotted for uniaxial incompressible tension. # setup a numeric region on a cube mesh = fem.Cube(n=2) @@ -56,7 +55,7 @@ # external force vector at x=1 right = region.mesh.points[:, 0] == 1 -v = 0.01 * region.mesh.cells_per_point[right] +v = region.mesh.cells_per_point[right] values_load = np.vstack([v, np.zeros_like(v), np.zeros_like(v)]).T load = fem.PointLoad(field, right, values_load) @@ -119,7 +118,7 @@ def step_to_xdmf(step, res): x0=field[0][dof1], lpf0=0, dxmax=0.06, - dlpfmax=2, + dlpfmax=0.02, maxsteps=35, rebalance=True, overshoot=1.05, From 6d31e79994ac389f7fd76a61936434ec776791de Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 8 Nov 2024 22:56:53 +0100 Subject: [PATCH 093/125] Ex.04: Add y-symmetry and use less continuation steps --- examples/ex04_balloon.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/ex04_balloon.py b/examples/ex04_balloon.py index ed92110d..f22911fc 100644 --- a/examples/ex04_balloon.py +++ b/examples/ex04_balloon.py @@ -46,11 +46,12 @@ import felupe as fem -mesh = fem.Rectangle(b=(1, 25), n=(2, 6)) +mesh = fem.Rectangle(b=(1, 25), n=(2, 4)) region = fem.RegionQuad(mesh) field = fem.FieldContainer([fem.FieldAxisymmetric(region, dim=2)]) -bounds = {"fix-y": fem.Boundary(field[0], fy=mesh.y.max(), mode="or", skip=(0, 1))} -dof0, dof1 = fem.dof.partition(field, bounds) +boundaries = fem.dof.symmetry(field[0], axes=(0, 1)) +boundaries["fix-y"] = fem.Boundary(field[0], fy=mesh.y.max(), mode="or", skip=(0, 1)) +dof0, dof1 = fem.dof.partition(field, boundaries) umat = fem.NeoHookeCompressible(mu=1) solid = fem.SolidBodyNearlyIncompressible(umat, field, bulk=5000) @@ -103,9 +104,13 @@ def dfundl(x, lpf, *args): x0=field[0][dof1], lpf0=0, control0=(0, 1), - maxsteps=150, + dxmax=1.0, + dlpfmax=0.0075, + maxsteps=65, rebalance=True, - tol=1e-2, + tol=1e-3, + decrease=1.2, + increase=0.4, ) X = np.array([res.x for res in Res]) From e232e53a99442f05f30fd9a0eefef59ee334079c Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 8 Nov 2024 23:31:00 +0100 Subject: [PATCH 094/125] Add the `miehe_goektepe_lulei` model for JAX (#892) --- docs/felupe/constitution/autodiff/jax.rst | 3 + .../jax/models/hyperelastic/__init__.py | 8 +++ .../hyperelastic/_miehe_goektepe_lulei.py | 31 ++++++++++ .../hyperelastic/microsphere/__init__.py | 19 ++++++ .../models/hyperelastic/microsphere/_chain.py | 18 ++++++ .../microsphere/_framework_affine.py | 59 +++++++++++++++++++ .../microsphere/_framework_nonaffine.py | 35 +++++++++++ .../hyperelastic/_miehe_goektepe_lulei.py | 15 ++++- tests/test_constitution_jax.py | 1 + 9 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_miehe_goektepe_lulei.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/microsphere/__init__.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 6bd4469b..3c14a8db 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -24,6 +24,7 @@ These material model formulations are defined by a strain energy density functio .. autosummary:: + miehe_goektepe_lulei mooney_rivlin third_order_deformation yeoh @@ -65,6 +66,8 @@ formulations in :class:`~felupe.constitution.jax.Material`. .. autofunction:: felupe.constitution.jax.updated_lagrange +.. autofunction:: felupe.constitution.jax.models.hyperelastic.miehe_goektepe_lulei + .. autofunction:: felupe.constitution.jax.models.hyperelastic.mooney_rivlin .. autofunction:: felupe.constitution.jax.models.hyperelastic.third_order_deformation diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index dcf1252f..e9515fad 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -1,9 +1,17 @@ +from ._miehe_goektepe_lulei import miehe_goektepe_lulei from ._mooney_rivlin import mooney_rivlin from ._third_order_deformation import third_order_deformation from ._yeoh import yeoh __all__ = [ + "miehe_goektepe_lulei", "mooney_rivlin", "third_order_deformation", "yeoh", ] + +# default (stable) material parameters +miehe_goektepe_lulei.kwargs = dict(mu=0, N=100, U=0, p=2, q=2) +mooney_rivlin.kwargs = dict(C10=0, C01=0) +third_order_deformation.kwargs = dict(C10=0, C01=0, C11=0, C20=0, C30=0) +yeoh.kwargs = dict(C10=0, C20=0, C30=0) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_miehe_goektepe_lulei.py b/src/felupe/constitution/jax/models/hyperelastic/_miehe_goektepe_lulei.py new file mode 100644 index 00000000..7f3836ab --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_miehe_goektepe_lulei.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from ....tensortrax.models.hyperelastic import miehe_goektepe_lulei as mgl_docstring +from .microsphere import langevin, linear, nonaffine_stretch, nonaffine_tube + + +@wraps(mgl_docstring) +def miehe_goektepe_lulei(C, mu, N, U, p, q): + kwargs_stretch = {"mu": mu, "N": N} + kwargs_tube = {"mu": mu * N * U} + + return nonaffine_stretch( + C, p=p, f=langevin, kwargs=kwargs_stretch + ) + nonaffine_tube(C, q=q, f=linear, kwargs=kwargs_tube) diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/__init__.py new file mode 100644 index 00000000..b6a181f8 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/__init__.py @@ -0,0 +1,19 @@ +from ._chain import langevin, linear +from ._framework_affine import ( + affine_stretch, + affine_stretch_statevars, + affine_tube, + affine_tube_statevars, +) +from ._framework_nonaffine import nonaffine_stretch, nonaffine_tube + +__all__ = [ + "affine_stretch", + "affine_stretch_statevars", + "affine_tube", + "affine_tube_statevars", + "linear", + "langevin", + "nonaffine_stretch", + "nonaffine_tube", +] diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py new file mode 100644 index 00000000..9808a886 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py @@ -0,0 +1,18 @@ +def langevin(stretch, mu, N): + """Langevin model given by the free energy of a single chain as a function of the + stretch (assuming a complex valued logarithm). The inverse Langevin function is + defined by a Padé approximation. + """ + from jax.numpy import log, sinh, sqrt + + x = stretch / sqrt(N) + L = x * (3 - x**2) / (1 - x**2) + + return mu * N * (x * L + log(L / sinh(L))) + + +def linear(stretch, mu): + """Linear model given by the free energy + of a single chain as a function of the stretch.""" + + return mu * (stretch - 1) diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py new file mode 100644 index 00000000..13b13a4e --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py @@ -0,0 +1,59 @@ +from ......quadrature import BazantOh + + +def affine_stretch(C, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Affine stretch part." + from jax.numpy import einsum, sqrt + from jax.numpy.linalg import det + + r = quadrature.points + w = quadrature.weights + + # affine stretches (distortional part) + λ = det(C) ** (-1 / 6) * sqrt(einsum("ai,ij...,aj->a...", r, C, r)) + + return einsum("a...,a->...", f(λ, **kwargs), w) + + +def affine_stretch_statevars(C, statevars, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Affine stretch part." + from jax.numpy import einsum, sqrt + from jax.numpy.linalg import det + + r = quadrature.points + w = quadrature.weights + + # affine stretches (distortional part) + λ = det(C) ** (-1 / 6) * sqrt(einsum("ai,ij...,aj->a...", r, C, r)) + ψ, statevars_new = f(λ, statevars, **kwargs) + + return einsum("a...,a->...", ψ, w), statevars_new + + +def affine_tube(C, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Affine area-stretch part." + from jax.numpy import einsum, sqrt + from jax.numpy.linalg import det, inv + + r = quadrature.points + w = quadrature.weights + + # affine area-stretches (distortional part) + λa = det(C) ** (1 / 6) * sqrt(einsum("ai,ij...,aj->a...", r, inv(C), r)) + + return einsum("a...,a->...", f(λa, **kwargs), w) + + +def affine_tube_statevars(C, statevars, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Affine area-stretch part." + from jax.numpy import einsum, sqrt + from jax.numpy.linalg import det, inv + + r = quadrature.points + w = quadrature.weights + + # affine area-stretches (distortional part) + λa = det(C) ** (1 / 6) * sqrt(einsum("ai,ij...,aj->a...", r, inv(C), r)) + ψa, statevars_new = f(λa, statevars, **kwargs) + + return einsum("a...,a->...", ψa, w), statevars_new diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py new file mode 100644 index 00000000..7cdfe83c --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py @@ -0,0 +1,35 @@ +from ......quadrature import BazantOh + + +def nonaffine_stretch(C, p, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Non-affine stretch part." + from jax.numpy import einsum, sqrt + from jax.numpy.linalg import det + + r = quadrature.points + w = quadrature.weights + + # affine stretches + λ = sqrt(einsum("ai,ij...,aj->a...", r, C, r)) + + # non-affine stretch (distortional part) + Λ = det(C) ** (-1 / 6) * einsum("a...,a->...", λ**p, w) ** (1 / p) + + return f(Λ, **kwargs) + + +def nonaffine_tube(C, q, f, kwargs, quadrature=BazantOh(n=21)): + "Micro-sphere model: Non-affine tube part." + from jax.numpy import einsum, sqrt + from jax.numpy.linalg import det, inv + + r = quadrature.points + w = quadrature.weights + + # affine area-stretches + λa = sqrt(einsum("ai,ij...,aj->a...", r, inv(C), r)) + + # non-affine tube contraction (distortional part) + Λt = det(C) ** (q / 6) * einsum("a...,a->...", λa**q, w) + + return f(Λt, **kwargs) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py index 07df3d1d..ce710994 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_miehe_goektepe_lulei.py @@ -24,7 +24,7 @@ def miehe_goektepe_lulei(C, mu, N, U, p, q): Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. mu : float Shear modulus (ground state stifness). @@ -39,14 +39,23 @@ def miehe_goektepe_lulei(C, mu, N, U, p, q): Examples -------- + First, choose the desired automatic differentiation backend + + .. pyvista-plot:: + :context: + + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. .. pyvista-plot:: :context: >>> import felupe as fem >>> - >>> umat = fem.Hyperelastic( - ... fem.miehe_goektepe_lulei, + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.miehe_goektepe_lulei, ... mu=0.1475, ... N=3.273, ... p=9.31, diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index eba982ff..d2574cfc 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -71,6 +71,7 @@ def test_hyperelastic_jax(): md.mooney_rivlin, md.yeoh, md.third_order_deformation, + md.miehe_goektepe_lulei, ]: umat = mat.Hyperelastic(W, **W.kwargs) solid = fem.SolidBody(umat=umat, field=field) From 29571c1f8247efb799312f03f107c06b692c1ef4 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Fri, 8 Nov 2024 23:57:23 +0100 Subject: [PATCH 095/125] Ex. 08: Switch from matADI to JAX --- CHANGELOG.md | 2 +- examples/ex08_shear.py | 24 ++++++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90b8d656..2866a373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. The format - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. -- Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. +- Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.miehe_goektepe_lulei()`, `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. - Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. - Add an optional keyword-argument `Region.astype(copy=True)` to modify the data types of the arrays of the region in-place if `copy=False`. diff --git a/examples/ex08_shear.py b/examples/ex08_shear.py index 862e6eaf..5df6e5bc 100644 --- a/examples/ex08_shear.py +++ b/examples/ex08_shear.py @@ -16,13 +16,6 @@ * plot force - displacement curves -.. admonition:: This example requires external packages. - :class: hint - - .. code-block:: - - pip install matadi - Two rubber blocks of height :math:`H` and length :math:`L`, both glued to a rigid plate on their top and bottom faces, are subjected to a displacement controlled non-homogeneous shear deformation by :math:`u_{ext}` in combination @@ -74,23 +67,22 @@ # %% # The micro-sphere material formulation is used for the rubber. It is defined -# as a hyperelastic material in `matADi `_. The -# material formulation is finally applied on the plane-strain field, resulting in a -# hyperelastic solid body. +# as a :class:`~felupe.constitution.jax.Hyperelastic` JAX-based material. The material +# formulation is finally applied on the plane-strain field, resulting in a hyperelastic +# solid body. -import matadi as mat +import felupe.constitution.jax as mat -umat = mat.MaterialHyperelastic( - mat.models.miehe_goektepe_lulei, +umat = mat.Hyperelastic( + mat.models.hyperelastic.miehe_goektepe_lulei, mu=0.1475, N=3.273, p=9.31, U=9.94, q=0.567, - bulk=5000.0, ) -rubber = fem.SolidBody(umat=mat.ThreeFieldVariation(umat), field=field) +rubber = fem.SolidBody(umat=fem.NearlyIncompressible(umat, bulk=5000), field=field) # %% # At the centerpoint of a multi-point constraint (MPC) the external shear @@ -133,7 +125,7 @@ def callback(stepnumber, substepnumber, substep): items=[rubber, mpc], ramp={boundaries["control"]: UX}, boundaries=boundaries ) job = fem.Job(steps=[step], callback=callback) -res = job.evaluate() +res = job.evaluate(tol=1e-4) # %% # The principal stretches are evaluated for the maximum deformed configuration. This may From 7d0ed640fa083fe35cc93a39d1b0063b50b77ef7 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 9 Nov 2024 08:15:46 +0100 Subject: [PATCH 096/125] Update ex08_shear.py --- examples/ex08_shear.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex08_shear.py b/examples/ex08_shear.py index 5df6e5bc..6ee843d5 100644 --- a/examples/ex08_shear.py +++ b/examples/ex08_shear.py @@ -125,7 +125,7 @@ def callback(stepnumber, substepnumber, substep): items=[rubber, mpc], ramp={boundaries["control"]: UX}, boundaries=boundaries ) job = fem.Job(steps=[step], callback=callback) -res = job.evaluate(tol=1e-4) +res = job.evaluate(tol=1e-2) # %% # The principal stretches are evaluated for the maximum deformed configuration. This may From 15c9668acb8abfbe0282769432602507f5eba6c2 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 9 Nov 2024 10:07:31 +0100 Subject: [PATCH 097/125] Update ex08_shear.py --- examples/ex08_shear.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/ex08_shear.py b/examples/ex08_shear.py index 6ee843d5..87f8000a 100644 --- a/examples/ex08_shear.py +++ b/examples/ex08_shear.py @@ -67,11 +67,12 @@ # %% # The micro-sphere material formulation is used for the rubber. It is defined -# as a :class:`~felupe.constitution.jax.Hyperelastic` JAX-based material. The material +# as a :class:`~felupe.Hyperelastic` material. The material # formulation is finally applied on the plane-strain field, resulting in a hyperelastic # solid body. -import felupe.constitution.jax as mat +import felupe.constitution.tensortrax as mat +# import felupe.constitution.jax as mat umat = mat.Hyperelastic( mat.models.hyperelastic.miehe_goektepe_lulei, @@ -125,7 +126,7 @@ def callback(stepnumber, substepnumber, substep): items=[rubber, mpc], ramp={boundaries["control"]: UX}, boundaries=boundaries ) job = fem.Job(steps=[step], callback=callback) -res = job.evaluate(tol=1e-2) +res = job.evaluate() # %% # The principal stretches are evaluated for the maximum deformed configuration. This may From 2721c1bb93a2800ff7f37162ab4af62bb0f704b5 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 9 Nov 2024 22:23:40 +0100 Subject: [PATCH 098/125] Make `tensortrax` optional (#894) * Make `tensortrax` optional * remove docstring of test-files * Update test_constitution_jax.py --- CHANGELOG.md | 1 + docs/index.rst | 4 +- pyproject.toml | 9 +- src/felupe/__init__.py | 100 ++++---- src/felupe/constitution/__init__.py | 94 ++++---- src/felupe/constitution/jax/__init__.py | 34 +-- src/felupe/constitution/jax/_helpers.py | 9 +- src/felupe/constitution/jax/_hyperelastic.py | 2 +- src/felupe/constitution/jax/_material.py | 2 +- .../constitution/jax/_total_lagrange.py | 5 +- .../constitution/jax/_updated_lagrange.py | 7 +- .../jax/models/hyperelastic/_mooney_rivlin.py | 5 +- .../hyperelastic/_third_order_deformation.py | 5 +- .../jax/models/hyperelastic/_yeoh.py | 5 +- .../models/hyperelastic/microsphere/_chain.py | 4 +- .../microsphere/_framework_affine.py | 11 +- .../microsphere/_framework_nonaffine.py | 7 +- .../jax/models/lagrange/_morph.py | 16 +- .../jax/models/lagrange/_morph_uniaxial.py | 5 +- .../lagrange/microsphere/_framework_affine.py | 6 +- .../constitution/tensortrax/__init__.py | 31 +-- tests/test_composite.py | 7 - tests/test_constitution_jax.py | 228 ++++++++---------- tests/test_job.py | 6 - 24 files changed, 290 insertions(+), 313 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2866a373..f372865a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. The format - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. - Change supported Python versions to 3.9 - 3.12. - Change the `dtype`-argument in `Region.astype(dtype)` from an optional to a required argument. +- Make `tensortrax` an optional dependency (again). Now FElupe does only depend on NumPy and SciPy, all other extras are optional. ### Fixed - Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. diff --git a/docs/index.rst b/docs/index.rst index 02571a89..04b00ad3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -65,16 +65,16 @@ where ``[all]`` is a combination of ``[io,parallel,plot,progress,view]`` and ins * `numpy `_ for array operations * `scipy `_ for sparse matrices -* `tensortrax `_ for automatic differentiation In order to make use of all features of FElupe 💎💰💍👑💎, it is suggested to install all optional dependencies. * `einsumt `_ for parallel (threaded) assembly -* `jax `_ for JAX-based material formulations +* `jax `_ for automatic differentiation in material formulations (JAX-based) * `h5py `_ for writing XDMF result files * `matplotlib `_ for plotting graphs * `meshio `_ for mesh-related I/O * `pyvista `_ for interactive visualizations +* `tensortrax `_ for automatic differentiation in material formulations (NumPy-based) * `tqdm `_ for showing progress bars during job evaluations The development version may contain not yet released bug fixes and features. Consider using the ``--user`` option to install the package into your home directory (see `pip documentation `_ for more details). To install FElupe from the latest development branch, use diff --git a/pyproject.toml b/pyproject.toml index cdc15bde..7bf99962 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,6 @@ dynamic = ["version"] dependencies = [ "numpy", "scipy", - "tensortrax>=0.25.2", ] [project.optional-dependencies] @@ -64,11 +63,11 @@ docs = [ "sphinx-gallery", "pypandoc", ] -constitution = ["jax"] +autodiff = ["tensortrax", "jax"] examples = [ "contique", "imageio", - "matadi>=0.2.2", + "matadi", "pypardiso", "torch", ] @@ -81,8 +80,8 @@ progress = ["tqdm"] plot = ["matplotlib"] view = ["pyvista[jupyter]"] -test = ["felupe[io,constitution,plot]"] -all = ["felupe[io,constitution,parallel,plot,progress,view]"] +test = ["felupe[io,autodiff,plot]"] +all = ["felupe[io,autodiff,parallel,plot,progress,view]"] [tool.setuptools.dynamic] version = {attr = "felupe.__about__.__version__"} diff --git a/src/felupe/__init__.py b/src/felupe/__init__.py index e6200f28..2e9e9e0a 100644 --- a/src/felupe/__init__.py +++ b/src/felupe/__init__.py @@ -19,7 +19,6 @@ AreaChange, CompositeMaterial, ConstitutiveMaterial, - Hyperelastic, Laplace, LinearElastic, LinearElasticLargeStrain, @@ -28,7 +27,6 @@ LinearElasticPlasticIsotropicHardening, LineChange, Material, - MaterialAD, MaterialStrain, NearlyIncompressible, NeoHooke, @@ -39,29 +37,8 @@ ViewMaterialIncompressible, VolumeChange, Volumetric, - alexander, - anssari_benam_bucchi, - arruda_boyce, - constitutive_material, - extended_tube, - finite_strain_viscoelastic, - isochoric_volumetric_split, linear_elastic, linear_elastic_plastic_isotropic_hardening, - lopez_pamies, - miehe_goektepe_lulei, - mooney_rivlin, - morph, - morph_representative_directions, - neo_hooke, - ogden, - ogden_roxburgh, - saint_venant_kirchhoff, - third_order_deformation, - total_lagrange, - updated_lagrange, - van_der_waals, - yeoh, ) from .dof import Boundary from .element import ArbitraryOrderLagrange as ArbitraryOrderLagrangeElement @@ -181,10 +158,6 @@ "NearlyIncompressible", "Material", "MaterialStrain", - "Hyperelastic", - "total_lagrange", - "updated_lagrange", - "MaterialAD", "ViewMaterial", "ViewMaterialIncompressible", "ConstitutiveMaterial", @@ -192,24 +165,6 @@ "VolumeChange", "linear_elastic", "linear_elastic_plastic_isotropic_hardening", - "alexander", - "anssari_benam_bucchi", - "arruda_boyce", - "extended_tube", - "finite_strain_viscoelastic", - "isochoric_volumetric_split", - "lopez_pamies", - "miehe_goektepe_lulei", - "mooney_rivlin", - "morph", - "morph_representative_directions", - "neo_hooke", - "ogden", - "ogden_roxburgh", - "saint_venant_kirchhoff", - "third_order_deformation", - "van_der_waals", - "yeoh", "Boundary", "ArbitraryOrderLagrangeElement", "BiQuadraticQuad", @@ -286,3 +241,58 @@ "ViewSolid", "runs_on", ] + +try: + from .constitution import ( + Hyperelastic, + MaterialAD, + alexander, + anssari_benam_bucchi, + arruda_boyce, + constitutive_material, + extended_tube, + finite_strain_viscoelastic, + isochoric_volumetric_split, + lopez_pamies, + miehe_goektepe_lulei, + mooney_rivlin, + morph, + morph_representative_directions, + neo_hooke, + ogden, + ogden_roxburgh, + saint_venant_kirchhoff, + third_order_deformation, + total_lagrange, + updated_lagrange, + van_der_waals, + yeoh, + ) + + __all_tensortrax = [ + "Hyperelastic", + "total_lagrange", + "updated_lagrange", + "MaterialAD", + "alexander", + "anssari_benam_bucchi", + "arruda_boyce", + "extended_tube", + "finite_strain_viscoelastic", + "isochoric_volumetric_split", + "lopez_pamies", + "miehe_goektepe_lulei", + "mooney_rivlin", + "morph", + "morph_representative_directions", + "neo_hooke", + "ogden", + "ogden_roxburgh", + "saint_venant_kirchhoff", + "third_order_deformation", + "van_der_waals", + "yeoh", + ] + __all__.extend(__all_tensortrax) +except ImportError: + pass diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index f1e23bdb..91fdb417 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -20,47 +20,8 @@ linear_elastic, linear_elastic_plastic_isotropic_hardening, ) -from .tensortrax import Hyperelastic -from .tensortrax import Material as MaterialAD -from .tensortrax import isochoric_volumetric_split, total_lagrange, updated_lagrange -from .tensortrax.models.hyperelastic import ( - alexander, - anssari_benam_bucchi, - arruda_boyce, - extended_tube, - finite_strain_viscoelastic, - lopez_pamies, - miehe_goektepe_lulei, - mooney_rivlin, - neo_hooke, - ogden, - ogden_roxburgh, - saint_venant_kirchhoff, - third_order_deformation, - van_der_waals, - yeoh, -) -from .tensortrax.models.lagrange import morph, morph_representative_directions __all__ = [ - "alexander", - "anssari_benam_bucchi", - "arruda_boyce", - "extended_tube", - "finite_strain_viscoelastic", - "isochoric_volumetric_split", - "lopez_pamies", - "miehe_goektepe_lulei", - "mooney_rivlin", - "morph", - "morph_representative_directions", - "neo_hooke", - "ogden", - "ogden_roxburgh", - "saint_venant_kirchhoff", - "third_order_deformation", - "van_der_waals", - "yeoh", "NeoHooke", "NeoHookeCompressible", "Laplace", @@ -75,10 +36,6 @@ "LinearElasticPlasticIsotropicHardening", "Material", "MaterialStrain", - "MaterialAD", - "Hyperelastic", - "total_lagrange", - "updated_lagrange", "AreaChange", "LineChange", "VolumeChange", @@ -93,3 +50,54 @@ "CompositeMaterial", "Volumetric", ] +try: + from .tensortrax import Hyperelastic + from .tensortrax import Material as MaterialAD + from .tensortrax import isochoric_volumetric_split, total_lagrange, updated_lagrange + from .tensortrax.models.hyperelastic import ( + alexander, + anssari_benam_bucchi, + arruda_boyce, + extended_tube, + finite_strain_viscoelastic, + lopez_pamies, + miehe_goektepe_lulei, + mooney_rivlin, + neo_hooke, + ogden, + ogden_roxburgh, + saint_venant_kirchhoff, + third_order_deformation, + van_der_waals, + yeoh, + ) + from .tensortrax.models.lagrange import morph, morph_representative_directions + + __all_tensortrax = [ + "alexander", + "anssari_benam_bucchi", + "arruda_boyce", + "extended_tube", + "finite_strain_viscoelastic", + "isochoric_volumetric_split", + "lopez_pamies", + "miehe_goektepe_lulei", + "mooney_rivlin", + "morph", + "morph_representative_directions", + "neo_hooke", + "ogden", + "ogden_roxburgh", + "saint_venant_kirchhoff", + "third_order_deformation", + "van_der_waals", + "yeoh", + "MaterialAD", + "Hyperelastic", + "total_lagrange", + "updated_lagrange", + ] + __all__.extend(__all_tensortrax) + +except ImportError: + pass diff --git a/src/felupe/constitution/jax/__init__.py b/src/felupe/constitution/jax/__init__.py index da2d61da..788ff064 100644 --- a/src/felupe/constitution/jax/__init__.py +++ b/src/felupe/constitution/jax/__init__.py @@ -1,16 +1,20 @@ -from . import models -from ._helpers import isochoric_volumetric_split, vmap -from ._hyperelastic import Hyperelastic -from ._material import Material -from ._total_lagrange import total_lagrange -from ._updated_lagrange import updated_lagrange +try: + from . import models + from ._helpers import isochoric_volumetric_split, vmap + from ._hyperelastic import Hyperelastic + from ._material import Material + from ._total_lagrange import total_lagrange + from ._updated_lagrange import updated_lagrange -__all__ = [ - "Hyperelastic", - "isochoric_volumetric_split", - "Material", - "models", - "total_lagrange", - "updated_lagrange", - "vmap", -] + __all__ = [ + "Hyperelastic", + "isochoric_volumetric_split", + "Material", + "models", + "total_lagrange", + "updated_lagrange", + "vmap", + ] + +except ModuleNotFoundError: + __all__ = [] diff --git a/src/felupe/constitution/jax/_helpers.py b/src/felupe/constitution/jax/_helpers.py index 00300cc7..fe9a4c8d 100644 --- a/src/felupe/constitution/jax/_helpers.py +++ b/src/felupe/constitution/jax/_helpers.py @@ -15,10 +15,13 @@ You should have received a copy of the GNU General Public License along with FElupe. If not, see . """ - import inspect from functools import wraps +import jax +import jax.numpy as jnp +from jax.numpy.linalg import det + def vmap(fun, in_axes=0, out_axes=0, **kwargs): """Vectorizing map. Creates a function which maps ``fun`` over argument axes. This @@ -30,8 +33,6 @@ def vmap(fun, in_axes=0, out_axes=0, **kwargs): axes. """ - import jax - @wraps(fun) def vmap_with_static_kwargs(*args, **keywordargs): # sorted list of all parameter keys, including kwargs with default values @@ -91,7 +92,6 @@ def vmap2(fun, in_axes=0, out_axes=0, **kwargs): def as_total_lagrange(fun): - import jax.numpy as jnp @wraps(fun) def evaluate(F, *args, **kwargs): @@ -106,7 +106,6 @@ def evaluate(F, *args, **kwargs): def isochoric_volumetric_split(fun): """Apply the material formulation only on the isochoric part of the multiplicative split of the deformation gradient.""" - from jax.numpy.linalg import det @wraps(fun) def apply_iso(C, *args, **kwargs): diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py index 5d060d48..dd2020b6 100644 --- a/src/felupe/constitution/jax/_hyperelastic.py +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -18,6 +18,7 @@ import warnings +import jax import numpy as np from .._material import Material @@ -144,7 +145,6 @@ def viscoelastic(C, Cin, mu, eta, dtime): """ def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): - import jax has_aux = nstatevars > 0 self.fun = as_total_lagrange(fun) diff --git a/src/felupe/constitution/jax/_material.py b/src/felupe/constitution/jax/_material.py index a16b5428..fa31a882 100644 --- a/src/felupe/constitution/jax/_material.py +++ b/src/felupe/constitution/jax/_material.py @@ -18,6 +18,7 @@ import warnings +import jax import numpy as np from .._material import Material as MaterialDefault @@ -158,7 +159,6 @@ def viscoelastic(F, Cin, mu, eta, dtime): def __init__( self, fun, nstatevars=0, jit=True, parallel=False, jacobian=None, **kwargs ): - import jax has_aux = nstatevars > 0 self.fun = fun diff --git a/src/felupe/constitution/jax/_total_lagrange.py b/src/felupe/constitution/jax/_total_lagrange.py index ff16a8bf..eee31d26 100644 --- a/src/felupe/constitution/jax/_total_lagrange.py +++ b/src/felupe/constitution/jax/_total_lagrange.py @@ -17,6 +17,8 @@ """ from functools import wraps +import jax + def total_lagrange(material): r"""Decorate a second Piola-Kirchhoff stress Total-Lagrange material formulation as @@ -52,7 +54,6 @@ def total_lagrange(material): the partial derivative of the strain energy function w.r.t. the deformation gradient tensor with Automatic Differentiation provided by jax. """ - from jax import Array @wraps(material) def first_piola_kirchhoff_stress(F, *args, **kwargs): @@ -61,7 +62,7 @@ def first_piola_kirchhoff_stress(F, *args, **kwargs): # check if the material formulation returns state variables and extract # the second Piola-Kirchhoff stress tensor - if isinstance(res, Array): + if isinstance(res, jax.Array): S = res statevars_new = None else: diff --git a/src/felupe/constitution/jax/_updated_lagrange.py b/src/felupe/constitution/jax/_updated_lagrange.py index 5614b6f1..7624c0a2 100644 --- a/src/felupe/constitution/jax/_updated_lagrange.py +++ b/src/felupe/constitution/jax/_updated_lagrange.py @@ -17,6 +17,9 @@ """ from functools import wraps +import jax +import jax.numpy as jnp + def updated_lagrange(material): r"""Decorate a Cauchy-stress Updated-Lagrange material formulation as a first Piola- @@ -53,8 +56,6 @@ def updated_lagrange(material): the partial derivative of the strain energy function w.r.t. the deformation gradient tensor with Automatic Differentiation provided by jax. """ - import jax.numpy as jnp - from jax import Array @wraps(material) def first_piola_kirchhoff_stress(F, *args, **kwargs): @@ -63,7 +64,7 @@ def first_piola_kirchhoff_stress(F, *args, **kwargs): # check if the material formulation returns state variables and extract # the Cauchy stress tensor - if isinstance(res, Array): + if isinstance(res, jax.Array): σ = res statevars_new = None else: diff --git a/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py b/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py index aa65c2cf..fd04eddc 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py @@ -17,13 +17,14 @@ """ from functools import wraps +from jax.numpy import trace +from jax.numpy.linalg import det + from ....tensortrax.models.hyperelastic import mooney_rivlin as mooney_rivlin_docstring @wraps(mooney_rivlin_docstring) def mooney_rivlin(C, C10, C01): - from jax.numpy import trace - from jax.numpy.linalg import det J3 = det(C) ** (-1 / 3) I1 = J3 * trace(C) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py b/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py index c847675b..429ce33f 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py @@ -17,13 +17,14 @@ """ from functools import wraps +from jax.numpy import trace +from jax.numpy.linalg import det + from ....tensortrax.models.hyperelastic import third_order_deformation as tod_docstring @wraps(tod_docstring) def third_order_deformation(C, C10, C01, C11, C20, C30): - from jax.numpy import trace - from jax.numpy.linalg import det J3 = det(C) ** (-1 / 3) I1 = J3 * trace(C) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py b/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py index 43a4db83..6ac3236a 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py @@ -17,13 +17,14 @@ """ from functools import wraps +from jax.numpy import trace +from jax.numpy.linalg import det + from ....tensortrax.models.hyperelastic import yeoh as yeoh_docstring @wraps(yeoh_docstring) def yeoh(C, C10, C20, C30): - from jax.numpy import trace - from jax.numpy.linalg import det I1 = det(C) ** (-1 / 3) * trace(C) return C10 * (I1 - 3) + C20 * (I1 - 3) ** 2 + C30 * (I1 - 3) ** 3 diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py index 9808a886..02299f8d 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_chain.py @@ -1,9 +1,11 @@ +from jax.numpy import log, sinh, sqrt + + def langevin(stretch, mu, N): """Langevin model given by the free energy of a single chain as a function of the stretch (assuming a complex valued logarithm). The inverse Langevin function is defined by a Padé approximation. """ - from jax.numpy import log, sinh, sqrt x = stretch / sqrt(N) L = x * (3 - x**2) / (1 - x**2) diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py index 13b13a4e..fc275274 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_affine.py @@ -1,10 +1,11 @@ +from jax.numpy import einsum, sqrt +from jax.numpy.linalg import det, inv + from ......quadrature import BazantOh def affine_stretch(C, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Affine stretch part." - from jax.numpy import einsum, sqrt - from jax.numpy.linalg import det r = quadrature.points w = quadrature.weights @@ -17,8 +18,6 @@ def affine_stretch(C, f, kwargs, quadrature=BazantOh(n=21)): def affine_stretch_statevars(C, statevars, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Affine stretch part." - from jax.numpy import einsum, sqrt - from jax.numpy.linalg import det r = quadrature.points w = quadrature.weights @@ -32,8 +31,6 @@ def affine_stretch_statevars(C, statevars, f, kwargs, quadrature=BazantOh(n=21)) def affine_tube(C, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Affine area-stretch part." - from jax.numpy import einsum, sqrt - from jax.numpy.linalg import det, inv r = quadrature.points w = quadrature.weights @@ -46,8 +43,6 @@ def affine_tube(C, f, kwargs, quadrature=BazantOh(n=21)): def affine_tube_statevars(C, statevars, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Affine area-stretch part." - from jax.numpy import einsum, sqrt - from jax.numpy.linalg import det, inv r = quadrature.points w = quadrature.weights diff --git a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py index 7cdfe83c..043ef274 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py +++ b/src/felupe/constitution/jax/models/hyperelastic/microsphere/_framework_nonaffine.py @@ -1,10 +1,11 @@ +from jax.numpy import einsum, sqrt +from jax.numpy.linalg import det, inv + from ......quadrature import BazantOh def nonaffine_stretch(C, p, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Non-affine stretch part." - from jax.numpy import einsum, sqrt - from jax.numpy.linalg import det r = quadrature.points w = quadrature.weights @@ -20,8 +21,6 @@ def nonaffine_stretch(C, p, f, kwargs, quadrature=BazantOh(n=21)): def nonaffine_tube(C, q, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Non-affine tube part." - from jax.numpy import einsum, sqrt - from jax.numpy.linalg import det, inv r = quadrature.points w = quadrature.weights diff --git a/src/felupe/constitution/jax/models/lagrange/_morph.py b/src/felupe/constitution/jax/models/lagrange/_morph.py index 25600f03..47c1b213 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph.py @@ -17,6 +17,10 @@ """ from functools import wraps +from jax.numpy import array, concatenate, diag, eye, maximum, sqrt, trace, triu_indices +from jax.numpy.linalg import det, eigvalsh, inv +from jax.scipy.linalg import expm + from ....tensortrax.models.lagrange import morph as morph_docstring from ..._total_lagrange import total_lagrange @@ -24,18 +28,6 @@ @wraps(morph_docstring) @total_lagrange def morph(F, statevars, p): - from jax.numpy import ( - array, - concatenate, - diag, - eye, - maximum, - sqrt, - trace, - triu_indices, - ) - from jax.numpy.linalg import det, eigvalsh, inv - from jax.scipy.linalg import expm # right Cauchy-Green deformation tensor C = F.T @ F diff --git a/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py b/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py index ffb01a83..b168539c 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py @@ -17,13 +17,14 @@ """ from functools import wraps +from jax.numpy import abs as jabs +from jax.numpy import concatenate, exp, maximum, sqrt + from ....tensortrax.models.lagrange import morph_uniaxial as morph_ux @wraps(morph_ux) def morph_uniaxial(λ, statevars, p, ε=1e-6): - from jax.numpy import abs as jabs - from jax.numpy import concatenate, exp, maximum, sqrt CTSn = statevars[:21] λn = 1 + statevars[21:42] diff --git a/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py b/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py index d95e067f..540a8069 100644 --- a/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py +++ b/src/felupe/constitution/jax/models/lagrange/microsphere/_framework_affine.py @@ -15,6 +15,9 @@ You should have received a copy of the GNU General Public License along with FElupe. If not, see . """ +from jax.numpy import einsum, sqrt, trace +from jax.numpy.linalg import det, inv + from ......quadrature import BazantOh from ...._total_lagrange import total_lagrange @@ -23,9 +26,6 @@ def affine_force_statevars(F, statevars, f, kwargs, quadrature=BazantOh(n=21)): "Micro-sphere model: Affine force (stretch) part." - from jax.numpy import einsum, sqrt, trace - from jax.numpy.linalg import det, inv - r = quadrature.points M = einsum("ai,aj->aij", r, r) Mw = einsum("aij,a->aij", M, quadrature.weights) diff --git a/src/felupe/constitution/tensortrax/__init__.py b/src/felupe/constitution/tensortrax/__init__.py index 0f347ffa..e9c1752e 100644 --- a/src/felupe/constitution/tensortrax/__init__.py +++ b/src/felupe/constitution/tensortrax/__init__.py @@ -1,15 +1,18 @@ -from . import models -from ._helpers import isochoric_volumetric_split -from ._hyperelastic import Hyperelastic -from ._material import Material -from ._total_lagrange import total_lagrange -from ._updated_lagrange import updated_lagrange +try: + from . import models + from ._helpers import isochoric_volumetric_split + from ._hyperelastic import Hyperelastic + from ._material import Material + from ._total_lagrange import total_lagrange + from ._updated_lagrange import updated_lagrange -__all__ = [ - "Hyperelastic", - "isochoric_volumetric_split", - "models", - "total_lagrange", - "updated_lagrange", - "Material", -] + __all__ = [ + "Hyperelastic", + "isochoric_volumetric_split", + "models", + "total_lagrange", + "updated_lagrange", + "Material", + ] +except ModuleNotFoundError: + __all__ = [] diff --git a/tests/test_composite.py b/tests/test_composite.py index 900e3d3a..3634c1f2 100644 --- a/tests/test_composite.py +++ b/tests/test_composite.py @@ -1,10 +1,3 @@ -# -*- coding: utf-8 -*- -""" -Created on Tue Aug 9 01:40:56 2022 - -@author: z0039mte -""" - import numpy as np import felupe as fem diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index d2574cfc..02918ccf 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -24,6 +24,7 @@ along with Felupe. If not, see . """ +import jax.numpy as jnp import numpy as np import pytest @@ -32,171 +33,142 @@ def test_vmap(): - try: + def f(x, a=1.0): + return x - def f(x, a=1.0): - return x + def g(x, y, a=1.0, **kwargs): + return x - def g(x, y, a=1.0, **kwargs): - return x + vf = fem.constitution.jax.vmap(f) + vg = fem.constitution.jax.vmap(g) - vf = fem.constitution.jax.vmap(f) - vg = fem.constitution.jax.vmap(g) + x = np.eye(3).reshape(1, 3, 3) * np.ones((10, 1, 1)) - x = np.eye(3).reshape(1, 3, 3) * np.ones((10, 1, 1)) + z = vf(x, a=1.0) - z = vf(x, a=1.0) + assert np.allclose(z, vf(x, 1.0)) + assert np.allclose(z, vf(a=1.0, x=x)) - assert np.allclose(z, vf(x, 1.0)) - assert np.allclose(z, vf(a=1.0, x=x)) + with pytest.raises(TypeError): + vf(x, a=1.0, b=2.0) - with pytest.raises(TypeError): - vf(x, a=1.0, b=2.0) - - # does not raise an error because of `g(..., **kwargs)` - assert np.allclose(z, vg(x, a=1.0, b=2.0)) - - except ModuleNotFoundError: - pass + # does not raise an error because of `g(..., **kwargs)` + assert np.allclose(z, vg(x, a=1.0, b=2.0)) def test_hyperelastic_jax(): - try: - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) - - md = mat.models.hyperelastic - for W in [ - md.mooney_rivlin, - md.yeoh, - md.third_order_deformation, - md.miehe_goektepe_lulei, - ]: - umat = mat.Hyperelastic(W, **W.kwargs) - solid = fem.SolidBody(umat=umat, field=field) - solid.evaluate.gradient() - solid.evaluate.hessian() - - umat = mat.Hyperelastic(W, **W.kwargs, parallel=True) - umat = mat.Hyperelastic(W, **W.kwargs, jit=True) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + md = mat.models.hyperelastic + for W in [ + md.mooney_rivlin, + md.yeoh, + md.third_order_deformation, + md.miehe_goektepe_lulei, + ]: + umat = mat.Hyperelastic(W, **W.kwargs) + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() - except ModuleNotFoundError: - pass + umat = mat.Hyperelastic(W, **W.kwargs, parallel=True) + umat = mat.Hyperelastic(W, **W.kwargs, jit=True) def test_hyperelastic_jax_statevars(): - try: - import jax.numpy as jnp - def W(C, statevars, C10, K): - I3 = jnp.linalg.det(C) - J = jnp.sqrt(I3) - I1 = I3 ** (-1 / 3) * jnp.trace(C) - statevars_new = I1 - return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2, statevars_new + def W(C, statevars, C10, K): + I3 = jnp.linalg.det(C) + J = jnp.sqrt(I3) + I1 = I3 ** (-1 / 3) * jnp.trace(C) + statevars_new = I1 + return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2, statevars_new - W.kwargs = {"C10": 0.5} + W.kwargs = {"C10": 0.5} - umat = mat.Hyperelastic(W, C10=0.5, K=2.0, nstatevars=1, jit=True) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) - - solid = fem.SolidBody(umat=umat, field=field) - solid.evaluate.gradient() - solid.evaluate.hessian() + umat = mat.Hyperelastic(W, C10=0.5, K=2.0, nstatevars=1, jit=True) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) - except ModuleNotFoundError: - pass + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() def test_material_jax(): - try: - import jax.numpy as jnp - - def dWdF(F, C10, K): - J = jnp.linalg.det(F) - C = F.T @ F - Cu = J ** (-2 / 3) * C - dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) - P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) - return P + K * (J - 1) * J * jnp.linalg.inv(C) + def dWdF(F, C10, K): + J = jnp.linalg.det(F) + C = F.T @ F + Cu = J ** (-2 / 3) * C + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) - umat = mat.Material(dWdF, C10=0.5, K=2.0, parallel=True) - umat = mat.Material(dWdF, C10=0.5, K=2.0, jit=True) + P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) + return P + K * (J - 1) * J * jnp.linalg.inv(C) - for fun in [dWdF, mat.updated_lagrange(dWdF), mat.total_lagrange(dWdF)]: - umat = mat.Material(fun, C10=0.5, K=2.0) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) + umat = mat.Material(dWdF, C10=0.5, K=2.0, parallel=True) + umat = mat.Material(dWdF, C10=0.5, K=2.0, jit=True) - solid = fem.SolidBody(umat=umat, field=field) - solid.evaluate.gradient() - solid.evaluate.hessian() + for fun in [dWdF, mat.updated_lagrange(dWdF), mat.total_lagrange(dWdF)]: + umat = mat.Material(fun, C10=0.5, K=2.0) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) - except ModuleNotFoundError: - pass + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() def test_material_jax_statevars(): - try: - import jax.numpy as jnp - - def dWdF(F, statevars, C10, K): - J = jnp.linalg.det(F) - C = F.T @ F - Cu = J ** (-2 / 3) * C - dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) - P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) - statevars_new = J - return P + K * (J - 1) * J * jnp.linalg.inv(C), statevars_new + def dWdF(F, statevars, C10, K): + J = jnp.linalg.det(F) + C = F.T @ F + Cu = J ** (-2 / 3) * C + dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) - dWdF.kwargs = {"C10": 0.5} + P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) + statevars_new = J + return P + K * (J - 1) * J * jnp.linalg.inv(C), statevars_new - for fun in [dWdF, mat.updated_lagrange(dWdF), mat.total_lagrange(dWdF)]: - umat = mat.Material(fun, C10=0.5, K=2.0, nstatevars=1, jit=True) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) + dWdF.kwargs = {"C10": 0.5} - solid = fem.SolidBody(umat=umat, field=field) - solid.evaluate.gradient() - solid.evaluate.hessian() + for fun in [dWdF, mat.updated_lagrange(dWdF), mat.total_lagrange(dWdF)]: + umat = mat.Material(fun, C10=0.5, K=2.0, nstatevars=1, jit=True) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) - except ModuleNotFoundError: - pass + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() def test_material_included_jax_statevars(): - try: - import felupe.constitution.jax as mat - - for fun, nstatevars in zip( - [ - mat.models.lagrange.morph, - mat.models.lagrange.morph_representative_directions, - ], - [13, 84], - ): - umat = mat.Material( - fun, - **fun.kwargs, - nstatevars=nstatevars, - ) - mesh = fem.Cube(n=2) - region = fem.RegionHexahedron(mesh) - field = fem.FieldContainer([fem.Field(region, dim=3)]) - - solid = fem.SolidBody(umat=umat, field=field) - solid.evaluate.gradient() - solid.evaluate.hessian() - - except ModuleNotFoundError: - pass + + for fun, nstatevars in zip( + [ + mat.models.lagrange.morph, + mat.models.lagrange.morph_representative_directions, + ], + [13, 84], + ): + umat = mat.Material( + fun, + **fun.kwargs, + nstatevars=nstatevars, + ) + mesh = fem.Cube(n=2) + region = fem.RegionHexahedron(mesh) + field = fem.FieldContainer([fem.Field(region, dim=3)]) + + solid = fem.SolidBody(umat=umat, field=field) + solid.evaluate.gradient() + solid.evaluate.hessian() if __name__ == "__main__": diff --git a/tests/test_job.py b/tests/test_job.py index c331e3d6..854be430 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -1,9 +1,3 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Aug 21 00:27:38 2022 - -@author: z0039mte -""" import os import numpy as np From a32469d63b1d8c8eeff85838d070df3df77fac28 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 9 Nov 2024 22:52:38 +0100 Subject: [PATCH 099/125] Test the import in an environment with no autodiff-backend present (#895) * Test the import in an env with no autodiff * Update pyproject.toml * Update tox.ini * Update tox.ini * Update pyproject.toml --- pyproject.toml | 2 -- tests/test_import.py | 8 ++++++++ tox.ini | 7 ++++--- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 tests/test_import.py diff --git a/pyproject.toml b/pyproject.toml index 7bf99962..ab922c14 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,8 +79,6 @@ parallel = ["einsumt"] progress = ["tqdm"] plot = ["matplotlib"] view = ["pyvista[jupyter]"] - -test = ["felupe[io,autodiff,plot]"] all = ["felupe[io,autodiff,parallel,plot,progress,view]"] [tool.setuptools.dynamic] diff --git a/tests/test_import.py b/tests/test_import.py new file mode 100644 index 00000000..6958382c --- /dev/null +++ b/tests/test_import.py @@ -0,0 +1,8 @@ +def test_import(): + import felupe as fem + + assert hasattr(fem, "constitution") + + +if __name__ == "__main__": + test_import() diff --git a/tox.ini b/tox.ini index 1f9e505c..d41b6ff1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py3 +envlist = core, py3 isolated_build = True [tool:pytest] @@ -13,5 +13,6 @@ extras = all commands = pytest tests {posargs} -[testenv:test] -extras = test +[testenv:core] +commands = + pytest tests/test_import.py {posargs} From 90d0c22175b51d9a2823e9ce2e223a69e7cb3dd3 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 9 Nov 2024 22:54:12 +0100 Subject: [PATCH 100/125] update install-description --- docs/index.rst | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 04b00ad3..1dbcdcc1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -61,7 +61,7 @@ Install Python, fire up 🔥 a terminal and run 🏃 pip install felupe[all] -where ``[all]`` is a combination of ``[io,parallel,plot,progress,view]`` and installs all optional dependencies. FElupe has minimal requirements, all available at PyPI supporting all platforms. +where ``[all]`` is a combination of ``[autodiff,io,parallel,plot,progress,view]`` and installs all optional dependencies. FElupe has minimal requirements, all available at PyPI supporting all platforms. * `numpy `_ for array operations * `scipy `_ for sparse matrices diff --git a/pyproject.toml b/pyproject.toml index ab922c14..36e1eede 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,7 @@ parallel = ["einsumt"] progress = ["tqdm"] plot = ["matplotlib"] view = ["pyvista[jupyter]"] -all = ["felupe[io,autodiff,parallel,plot,progress,view]"] +all = ["felupe[autodiff,io,parallel,plot,progress,view]"] [tool.setuptools.dynamic] version = {attr = "felupe.__about__.__version__"} From 3358876e110e926c00c290792e5f5c2ccfaa7ccc Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 9 Nov 2024 23:55:17 +0100 Subject: [PATCH 101/125] Remove matadi from examples in docstrings --- pyproject.toml | 1 - src/felupe/constitution/_base.py | 31 +++++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 36e1eede..5f96496a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,6 @@ autodiff = ["tensortrax", "jax"] examples = [ "contique", "imageio", - "matadi", "pypardiso", "torch", ] diff --git a/src/felupe/constitution/_base.py b/src/felupe/constitution/_base.py index a7738648..361014c3 100644 --- a/src/felupe/constitution/_base.py +++ b/src/felupe/constitution/_base.py @@ -445,24 +445,31 @@ def constitutive_material(Material, name=None): Examples -------- This example shows how to create a derived user material class to enable the - methods from :class:`~felupe.ConstitutiveMaterial` on an externally defined user - material. - - .. admonition:: This example requires external packages. - :class: hint - - .. code-block:: - - pip install matadi + methods from :class:`~felupe.ConstitutiveMaterial` on any (external) material. .. pyvista-plot:: :context: >>> import felupe as fem - >>> import matadi as mat + >>> import numpy as np + >>> + >>> class MyMaterialFormulation: + ... def __init__(self, a=5): + ... self.x = [np.zeros((3, 3))] + ... self.kwargs = {"a": a} + ... + ... def gradient(self, x): + ... F, statevars = x[0], x[-1] + ... dWdF = self.kwargs["a"] * fem.math.identity(F) + ... return [dWdF, statevars] + ... + ... def hessian(self, x, **kwargs): + ... F, statevars = x[0], x[-1] + ... d2WdFdF = self.kwargs["a"] * np.zeros((3, 3, 3, 3, *F.shape[2:])) + ... return [d2WdFdF] >>> - >>> MaterialHyperelastic = fem.constitutive_material(mat.MaterialHyperelastic) - >>> umat = MaterialHyperelastic(mat.models.neo_hooke, C10=0.5) + >>> MyMaterial = fem.constitutive_material(MyMaterialFormulation) + >>> umat = MyMaterial(a=0.5) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: From b70320e11ce59250a85d2b214bfc7fdbb434d2ef Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 10 Nov 2024 00:04:24 +0100 Subject: [PATCH 102/125] Update _base.py --- src/felupe/constitution/_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/felupe/constitution/_base.py b/src/felupe/constitution/_base.py index 361014c3..f7bc9a77 100644 --- a/src/felupe/constitution/_base.py +++ b/src/felupe/constitution/_base.py @@ -460,12 +460,12 @@ def constitutive_material(Material, name=None): ... ... def gradient(self, x): ... F, statevars = x[0], x[-1] - ... dWdF = self.kwargs["a"] * fem.math.identity(F) + ... dWdF = self.kwargs["a"] * np.eye(3).reshape(3, 3, 1, 1) ... return [dWdF, statevars] ... ... def hessian(self, x, **kwargs): ... F, statevars = x[0], x[-1] - ... d2WdFdF = self.kwargs["a"] * np.zeros((3, 3, 3, 3, *F.shape[2:])) + ... d2WdFdF = self.kwargs["a"] * np.zeros((3, 3, 3, 3, 1, 1)) ... return [d2WdFdF] >>> >>> MyMaterial = fem.constitutive_material(MyMaterialFormulation) From a21a5d5d48dfb7d6cf3abdbe3db4533f2b108323 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 10 Nov 2024 10:23:50 +0100 Subject: [PATCH 103/125] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f372865a..8a225b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ All notable changes to this project will be documented in this file. The format - Fix the number of points for non-disconnected dual meshes. This reduces the assembled (sparse) vector- and matrix-shapes, which are defined on mixed-fields. - Fix wrong results of `ConstitutiveMaterial.plot()` if any stretch is non-physical, i.e. lower or equal zero. This raises an error now. -# Removed +### Removed - Remove the unused, deprecated aliases `UserMaterial`, `UserMaterialStrain` and `UserMaterialHyperelastic`. ## [9.0.0] - 2024-09-06 From 4ee3496f0c7f768172480f4ea7f0c5a4acb4b9a5 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 10 Nov 2024 10:23:52 +0100 Subject: [PATCH 104/125] Update autodiff.rst --- docs/felupe/constitution/autodiff.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/felupe/constitution/autodiff.rst b/docs/felupe/constitution/autodiff.rst index c1462d04..66b3d1a8 100644 --- a/docs/felupe/constitution/autodiff.rst +++ b/docs/felupe/constitution/autodiff.rst @@ -15,6 +15,12 @@ automatic differentiation. The default backend is based on :mod:`tensortrax` whi with FElupe. For more computationally expensive material formulations, :mod:`jax` may be the preferred option. +.. note:: + JAX uses single-precision (32bit) data types by default. This requires to relax the + tolerance of :func:`~felupe.newtonrhapson` to ``tol=1e-4``. If required, JAX may be + enforced to use double-precision at startup with + ``jax.config.update("jax_enable_x64", True)``. + It is straightforward to switch between these backends. .. tab:: tensortrax (default) @@ -53,4 +59,4 @@ It is straightforward to switch between these backends. all models from :mod:`felupe.constitution.tensortrax.models.hyperelastic` and :mod:`felupe.constitution.tensortrax.models.lagrange` as well as the material classes :class:`felupe.constitution.tensortrax.Material` and - :class:`felupe.constitution.tensortrax.Hyperelastic`. \ No newline at end of file + :class:`felupe.constitution.tensortrax.Hyperelastic`. From c8bb5dfd6314b4832e32d432ee5c076c9d313108 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 10 Nov 2024 21:58:52 +0100 Subject: [PATCH 105/125] Enable `jax.Hyperelastic(..., parallel=True)` with `jax.pmap` on quadrature-points axis (#896) * Attempt to enable `jax.Hyperelastic(..., parallel=True)` with `jax.pmap` * Enhance the docs on `parallel=True` with JAX * Update test_constitution_jax.py --- docs/felupe/constitution/autodiff.rst | 6 ---- docs/felupe/constitution/autodiff/jax.rst | 25 +++++++++++++- src/felupe/constitution/jax/_helpers.py | 15 +++++---- src/felupe/constitution/jax/_hyperelastic.py | 34 ++++++++++++++------ src/felupe/constitution/jax/_material.py | 34 ++++++++++++++------ tests/test_constitution_jax.py | 6 ++-- 6 files changed, 84 insertions(+), 36 deletions(-) diff --git a/docs/felupe/constitution/autodiff.rst b/docs/felupe/constitution/autodiff.rst index 66b3d1a8..9e79c6b1 100644 --- a/docs/felupe/constitution/autodiff.rst +++ b/docs/felupe/constitution/autodiff.rst @@ -15,12 +15,6 @@ automatic differentiation. The default backend is based on :mod:`tensortrax` whi with FElupe. For more computationally expensive material formulations, :mod:`jax` may be the preferred option. -.. note:: - JAX uses single-precision (32bit) data types by default. This requires to relax the - tolerance of :func:`~felupe.newtonrhapson` to ``tol=1e-4``. If required, JAX may be - enforced to use double-precision at startup with - ``jax.config.update("jax_enable_x64", True)``. - It is straightforward to switch between these backends. .. tab:: tensortrax (default) diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 3c14a8db..e57b0f48 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -3,7 +3,30 @@ Materials with Automatic Differentiation (JAX) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This page contains material model formulations with automatic differentiation using :mod:`jax`. +This page contains material model formulations with automatic differentiation using +:mod:`jax`. + +.. note:: + + JAX uses single-precision (32bit) data types by default. This requires to relax the + tolerance of :func:`~felupe.newtonrhapson` to ``tol=1e-4``. If required, JAX may be + enforced to use double-precision at startup with + ``jax.config.update("jax_enable_x64", True)``. + +.. note:: + + The number of local XLA devices available must be greater or equal the number of the + parallel-mapped axis, i.e. the number of quadrature points per cell when used in + :class:`~felupe.constitution.jax.Material` and + :class:`~felupe.constitution.jax.Hyperelastic` along with ``parallel=True``. To use + the multiple cores of a CPU device as multiple local XLA devices, the XLA device + count must be defined at startup. + + .. code-block:: python + + import os + + os.environ["XLA_FLAGS"] = "--xla_force_host_platform_device_count=4" **Frameworks** diff --git a/src/felupe/constitution/jax/_helpers.py b/src/felupe/constitution/jax/_helpers.py index fe9a4c8d..bd362070 100644 --- a/src/felupe/constitution/jax/_helpers.py +++ b/src/felupe/constitution/jax/_helpers.py @@ -23,7 +23,7 @@ from jax.numpy.linalg import det -def vmap(fun, in_axes=0, out_axes=0, **kwargs): +def vmap(fun, in_axes=0, out_axes=0, method=jax.vmap, **kwargs): """Vectorizing map. Creates a function which maps ``fun`` over argument axes. This decorator treats all non-specified arguments and keyword-arguments as static. @@ -74,19 +74,22 @@ def vmap_with_static_kwargs(*args, **keywordargs): static_argnums = len(args) + len(keyword_args) - len(in_axes_tuple) in_axes_new = (*in_axes_tuple, *([None] * static_argnums)) - vfun = jax.vmap(fun, in_axes=in_axes_new, out_axes=out_axes, **kwargs) + vfun = method(fun, in_axes=in_axes_new, out_axes=out_axes, **kwargs) return vfun(*args, *keyword_args) return vmap_with_static_kwargs -def vmap2(fun, in_axes=0, out_axes=0, **kwargs): +def vmap2(fun, in_axes=[0, 0], out_axes=[0, 0], methods=[jax.vmap, jax.vmap], **kwargs): "Nested vectorizing map." return vmap( - vmap(fun, in_axes=in_axes, out_axes=out_axes, **kwargs), - in_axes=in_axes, - out_axes=out_axes, + vmap( + fun, in_axes=in_axes[0], out_axes=out_axes[0], method=methods[0], **kwargs + ), + in_axes=in_axes[1], + out_axes=out_axes[1], + method=methods[1], **kwargs, ) diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py index dd2020b6..f18d83f9 100644 --- a/src/felupe/constitution/jax/_hyperelastic.py +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -44,8 +44,9 @@ class Hyperelastic(Material): jit : bool, optional A flag to invoke just-in-time compilation (default is True). parallel : bool, optional - A flag to invoke threaded strain energy density function evaluations (default - is False). Not implemented. + A flag to invoke parallel strain energy density function evaluations (default + is False). If True, the quadrature points are executed in parallel. The number + of devices must be greater or equal the number of quadrature points per cell. **kwargs : dict, optional Optional keyword-arguments for the strain energy density function. @@ -86,7 +87,7 @@ def neo_hooke(C, mu): import felupe as fem import felupe.constitution.jax as mat - import jax.numpy as np + import jax.numpy as jnp def viscoelastic(C, Cin, mu, eta, dtime): "Finite strain viscoelastic material formulation." @@ -149,9 +150,6 @@ def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): has_aux = nstatevars > 0 self.fun = as_total_lagrange(fun) - if parallel: - warnings.warn("Parallel execution is not implemented.") - keyword_args = kwargs if hasattr(fun, "kwargs"): keyword_args = {**fun.kwargs, **keyword_args} @@ -163,14 +161,30 @@ def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): **keyword_args, ) - kwargs_jax = dict(in_axes=-1, out_axes=-1) + in_axes = out_axes_grad = [2, 3] if nstatevars > 0: - kwargs_jax["in_axes"] = (-1, -1) + in_axes = out_axes_grad = [(2, 1), (3, 2)] - self._grad = vmap2(jax.grad(self.fun, has_aux=has_aux), **kwargs_jax) + out_axes_hess = [4, 5] + if nstatevars > 0: + out_axes_hess = [(4, 1), (5, 2)] + + methods = [jax.vmap, jax.vmap] + if parallel: + methods[0] = jax.pmap # apply on quadrature-points + jit = False # pmap uses jit + + self._grad = vmap2( + jax.grad(self.fun, has_aux=has_aux), + in_axes=in_axes, + out_axes=out_axes_grad, + methods=methods, + ) self._hess = vmap2( jax.jacfwd(jax.grad(self.fun, has_aux=has_aux), has_aux=has_aux), - **kwargs_jax, + in_axes=in_axes, + out_axes=out_axes_hess, + methods=methods, ) if jit: diff --git a/src/felupe/constitution/jax/_material.py b/src/felupe/constitution/jax/_material.py index fa31a882..44317b3e 100644 --- a/src/felupe/constitution/jax/_material.py +++ b/src/felupe/constitution/jax/_material.py @@ -44,8 +44,9 @@ class Material(MaterialDefault): jit : bool, optional A flag to invoke just-in-time compilation (default is True). parallel : bool, optional - A flag to invoke threaded function evaluations (defaultnis False). Not - implemented. + A flag to invoke parallel function evaluations (default is False). If True, the + quadrature points are executed in parallel. The number of devices must be + greater or equal the number of quadrature points per cell. jacobian : callable or None, optional A callable for the Jacobian. Default is None, where :func:`jax.jacobian` is used. This may be used to switch to forward-mode differentian @@ -107,7 +108,7 @@ def viscoelastic(F, Cin, mu, eta, dtime): S = mu * dev(Cu @ jnp.linalg.inv(Ci)) @ jnp.linalg.inv(C) # first Piola-Kirchhoff stress tensor and state variable - i, j = triu_indices(3) + i, j = jnp.triu_indices(3) to_triu = lambda C: C[i, j] return F @ S, to_triu(Ci) @@ -166,9 +167,6 @@ def __init__( if jacobian is None: jacobian = jax.jacobian - if parallel: - warnings.warn("Parallel execution is not implemented.") - keyword_args = kwargs if hasattr(fun, "kwargs"): keyword_args = {**fun.kwargs, **keyword_args} @@ -180,12 +178,28 @@ def __init__( **keyword_args, ) - kwargs_jax = dict(in_axes=-1, out_axes=-1) + in_axes = out_axes_grad = [2, 3] + if nstatevars > 0: + in_axes = out_axes_grad = [(2, 1), (3, 2)] + + out_axes_hess = [4, 5] if nstatevars > 0: - kwargs_jax["in_axes"] = (-1, -1) + out_axes_hess = [(4, 1), (5, 2)] - self._grad = vmap2(self.fun, **kwargs_jax) - self._hess = vmap2(jacobian(self.fun, has_aux=has_aux), **kwargs_jax) + methods = [jax.vmap, jax.vmap] + if parallel: + methods[0] = jax.pmap # apply on quadrature-points + jit = False # pmap uses jit + + self._grad = vmap2( + self.fun, in_axes=in_axes, out_axes=out_axes_grad, methods=methods + ) + self._hess = vmap2( + jacobian(self.fun, has_aux=has_aux), + in_axes=in_axes, + out_axes=out_axes_hess, + methods=methods, + ) if jit: self._grad = jax.jit(self._grad) diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 02918ccf..32c066a7 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -42,7 +42,7 @@ def g(x, y, a=1.0, **kwargs): vf = fem.constitution.jax.vmap(f) vg = fem.constitution.jax.vmap(g) - x = np.eye(3).reshape(1, 3, 3) * np.ones((10, 1, 1)) + x = (np.eye(3).reshape(1, 1, 3, 3) * np.ones((10, 2, 1, 1))).T z = vf(x, a=1.0) @@ -83,7 +83,7 @@ def W(C, statevars, C10, K): I3 = jnp.linalg.det(C) J = jnp.sqrt(I3) I1 = I3 ** (-1 / 3) * jnp.trace(C) - statevars_new = I1 + statevars_new = statevars.at[0].set(I1) return C10 * (I1 - 3) + K * (J - 1) ** 2 / 2, statevars_new W.kwargs = {"C10": 0.5} @@ -132,7 +132,7 @@ def dWdF(F, statevars, C10, K): dev = lambda C: C - jnp.trace(C) / 3 * jnp.eye(3) P = 2 * C10 * F @ dev(Cu) @ jnp.linalg.inv(C) - statevars_new = J + statevars_new = statevars.at[0].set(J) return P + K * (J - 1) * J * jnp.linalg.inv(C), statevars_new dWdF.kwargs = {"C10": 0.5} From 8c46cdff93f5f7bbe1ba6d205edad7478e6b13cd Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 12 Nov 2024 22:35:03 +0100 Subject: [PATCH 106/125] Update GitHub-Actions (#897) --- .github/workflows/publish-to-pypi.yml | 6 +++--- .github/workflows/upload-codecov.yml | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index d833e112..b5384cbf 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -8,9 +8,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' architecture: 'x64' @@ -32,4 +32,4 @@ jobs: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@release/v1 with: - password: ${{ secrets.PYPI_API_TOKEN }} \ No newline at end of file + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/upload-codecov.yml b/.github/workflows/upload-codecov.yml index 30d1c89b..87c0570a 100644 --- a/.github/workflows/upload-codecov.yml +++ b/.github/workflows/upload-codecov.yml @@ -16,16 +16,16 @@ jobs: matrix: python-version: ["3.9", "3.12"] steps: - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Test with tox run: | pip install tox tox -- --cov felupe --cov-report xml --cov-report term - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 if: ${{ matrix.python-version == '3.12' }} - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} From e6135d0eafb677ee49d3623e375dbf2f77fa80ed Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 13 Nov 2024 16:07:46 +0100 Subject: [PATCH 107/125] Add math-function for the right Cauchy-Green deformation tensor (#898) * Add `math.right_cauchy_green_deformation()` * format black * Update CHANGELOG.md --- CHANGELOG.md | 2 ++ src/felupe/constitution/jax/_helpers.py | 1 - src/felupe/constitution/jax/_hyperelastic.py | 1 - src/felupe/constitution/jax/_material.py | 1 - .../jax/models/hyperelastic/_mooney_rivlin.py | 1 - .../hyperelastic/_third_order_deformation.py | 1 - .../jax/models/hyperelastic/_yeoh.py | 1 - .../jax/models/lagrange/_morph.py | 1 - .../jax/models/lagrange/_morph_uniaxial.py | 1 - src/felupe/field/_evaluate.py | 17 +++++++++ src/felupe/math/__init__.py | 2 ++ src/felupe/math/_field.py | 24 ++++++++++--- src/felupe/region/_boundary.py | 35 +++++++++++++++++++ tests/test_constitution_jax.py | 4 --- tests/test_field.py | 1 + 15 files changed, 76 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a225b7e..342e4d94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ All notable changes to this project will be documented in this file. The format - Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.miehe_goektepe_lulei()`, `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. - Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. - Add an optional keyword-argument `Region.astype(copy=True)` to modify the data types of the arrays of the region in-place if `copy=False`. +- Add `FieldContainer.evaluate.right_cauchy_green_deformation()` and `math.right_cauchy_green_deformation(field)` to evaluate the right Cauchy-Green deformation tensor. +- Add `math.strain(field, C=None, ..., **kwargs)` to use a given right Cauchy-Green deformation tensor for the evaluation of the strain tensor. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/src/felupe/constitution/jax/_helpers.py b/src/felupe/constitution/jax/_helpers.py index bd362070..fba57c7c 100644 --- a/src/felupe/constitution/jax/_helpers.py +++ b/src/felupe/constitution/jax/_helpers.py @@ -95,7 +95,6 @@ def vmap2(fun, in_axes=[0, 0], out_axes=[0, 0], methods=[jax.vmap, jax.vmap], ** def as_total_lagrange(fun): - @wraps(fun) def evaluate(F, *args, **kwargs): i, j = jnp.triu_indices(3) diff --git a/src/felupe/constitution/jax/_hyperelastic.py b/src/felupe/constitution/jax/_hyperelastic.py index f18d83f9..8460d8cc 100644 --- a/src/felupe/constitution/jax/_hyperelastic.py +++ b/src/felupe/constitution/jax/_hyperelastic.py @@ -146,7 +146,6 @@ def viscoelastic(C, Cin, mu, eta, dtime): """ def __init__(self, fun, nstatevars=0, jit=True, parallel=False, **kwargs): - has_aux = nstatevars > 0 self.fun = as_total_lagrange(fun) diff --git a/src/felupe/constitution/jax/_material.py b/src/felupe/constitution/jax/_material.py index 44317b3e..722979db 100644 --- a/src/felupe/constitution/jax/_material.py +++ b/src/felupe/constitution/jax/_material.py @@ -160,7 +160,6 @@ def viscoelastic(F, Cin, mu, eta, dtime): def __init__( self, fun, nstatevars=0, jit=True, parallel=False, jacobian=None, **kwargs ): - has_aux = nstatevars > 0 self.fun = fun diff --git a/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py b/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py index fd04eddc..9f28837c 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_mooney_rivlin.py @@ -25,7 +25,6 @@ @wraps(mooney_rivlin_docstring) def mooney_rivlin(C, C10, C01): - J3 = det(C) ** (-1 / 3) I1 = J3 * trace(C) I2 = (I1**2 - J3**2 * trace(C @ C)) / 2 diff --git a/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py b/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py index 429ce33f..b1fe2ce7 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_third_order_deformation.py @@ -25,7 +25,6 @@ @wraps(tod_docstring) def third_order_deformation(C, C10, C01, C11, C20, C30): - J3 = det(C) ** (-1 / 3) I1 = J3 * trace(C) I2 = (I1**2 - J3**2 * trace(C @ C)) / 2 diff --git a/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py b/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py index 6ac3236a..010bec7f 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_yeoh.py @@ -25,6 +25,5 @@ @wraps(yeoh_docstring) def yeoh(C, C10, C20, C30): - I1 = det(C) ** (-1 / 3) * trace(C) return C10 * (I1 - 3) + C20 * (I1 - 3) ** 2 + C30 * (I1 - 3) ** 3 diff --git a/src/felupe/constitution/jax/models/lagrange/_morph.py b/src/felupe/constitution/jax/models/lagrange/_morph.py index 47c1b213..cf7d8c3c 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph.py @@ -28,7 +28,6 @@ @wraps(morph_docstring) @total_lagrange def morph(F, statevars, p): - # right Cauchy-Green deformation tensor C = F.T @ F diff --git a/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py b/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py index b168539c..dd176f39 100644 --- a/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py +++ b/src/felupe/constitution/jax/models/lagrange/_morph_uniaxial.py @@ -25,7 +25,6 @@ @wraps(morph_ux) def morph_uniaxial(λ, statevars, p, ε=1e-6): - CTSn = statevars[:21] λn = 1 + statevars[21:42] SA1n = statevars[42:63] diff --git a/src/felupe/field/_evaluate.py b/src/felupe/field/_evaluate.py index 3250e918..7aa5c482 100644 --- a/src/felupe/field/_evaluate.py +++ b/src/felupe/field/_evaluate.py @@ -16,6 +16,7 @@ along with FElupe. If not, see . """ +from ..math import right_cauchy_green_deformation as right_cauchy_green from ..math import strain, strain_stretch_1d @@ -71,6 +72,22 @@ def deformation_gradient(self): """ return self.field[0].extract() + def right_cauchy_green_deformation(self): + r"""Return the right Cauchy-Green deformation tensor. + + .. math:: + :label:right-cauchy-green-deformation-tensor + + \boldsymbol{F} &= \frac{\partial \boldsymbol{x}}{\partial \boldsymbol{X}} + + \boldsymbol{C} &= \boldsymbol{F}^T \boldsymbol{F} + + \boldsymbol{C} &= \sum_\alpha \lambda^2_\alpha + \ \boldsymbol{N}_\alpha \otimes \boldsymbol{N}_\alpha + + """ + return right_cauchy_green(self.field) + def strain(self, fun=strain_stretch_1d, tensor=True, asvoigt=False, n=0, **kwargs): r"""Return the Lagrangian strain tensor or its principal values. diff --git a/src/felupe/math/__init__.py b/src/felupe/math/__init__.py index bdc3599e..2eefa61a 100644 --- a/src/felupe/math/__init__.py +++ b/src/felupe/math/__init__.py @@ -8,6 +8,7 @@ hess, interpolate, norm, + right_cauchy_green_deformation, strain, strain_stretch_1d, values, @@ -80,6 +81,7 @@ "majortranspose", "ravel", "reshape", + "right_cauchy_green_deformation", "sym", "tovoigt", "trace", diff --git a/src/felupe/math/_field.py b/src/felupe/math/_field.py index dd9fb8d3..ab05ca00 100644 --- a/src/felupe/math/_field.py +++ b/src/felupe/math/_field.py @@ -35,6 +35,12 @@ def deformation_gradient(field, n=0): return field[n].extract(grad=True, sym=False, add_identity=True) +def right_cauchy_green_deformation(field, n=0): + "Return the right Cauchy-Green deformation tensor of the n-th field." + F = deformation_gradient(field, n=n) + return dot(transpose(F), F) + + def strain_stretch_1d(stretch, k=0): r"""Compute the Seth-Hill strains. @@ -66,13 +72,20 @@ def strain_stretch_1d(stretch, k=0): return strain -def strain(field, fun=strain_stretch_1d, tensor=True, asvoigt=False, n=0, **kwargs): +def strain( + field, C=None, fun=strain_stretch_1d, tensor=True, asvoigt=False, n=0, **kwargs +): r"""Return Lagrangian strain tensor or its principal values of the n-th field. Parameters ---------- - field : FieldContainer - A field container with a displacement field. + field : FieldContainer or None + A field container with a displacement field from which the deformation gradient + tensor is extracted if ``def_grad`` is None. + C : ndarray of shape (N, N, ...) or None, optional + Optional array of right Cauchy-Green deformation tensors. If None, the + right Cauchy-Green deformation tensor is obtained from the field. Default is + None. fun : callable, optional A callable for the one-dimensional strain-stretch relation. Function signature must be ``lambda stretch, **kwargs: strain`` (default is the log. strain, @@ -132,8 +145,9 @@ def strain(field, fun=strain_stretch_1d, tensor=True, asvoigt=False, n=0, **kwar math.strain_stretch_1d : Compute the Seth-Hill strains. """ - F = deformation_gradient(field) - C = dot(transpose(F), F) + if C is None: + F = deformation_gradient(field) + C = dot(transpose(F), F) if tensor: w, N = eigh(C) diff --git a/src/felupe/region/_boundary.py b/src/felupe/region/_boundary.py index 39622e72..15076b4c 100644 --- a/src/felupe/region/_boundary.py +++ b/src/felupe/region/_boundary.py @@ -465,6 +465,41 @@ class RegionBoundary(Region): >>> plotter.add_legend() >>> mesh.plot(plotter=plotter, style="wireframe").show() + This examples shows how to evaluate the strain on the faces of the boundary region. + A field can't be used to evaluate the strain of a quad-cell in 3D space. However, + it is possible to evaluate the in-plane components of the right Cauchy-Green + deformation tensor on the boundary. With this tensor at hand, it is possible to + evaluate any in-plane strain tensor. + + .. pyvista-plot:: + :force_static: + + >>> import felupe as fem + >>> + >>> mesh = fem.Cube(n=3) + >>> region = fem.RegionHexahedron(mesh) + >>> field = fem.FieldContainer([fem.Field(region, dim=3)]) + >>> + >>> field[0].values[mesh.x == 1, 0] += 0.5 + >>> field[0].values[mesh.x == 1, 2] += 0.5 + >>> field[0].values += mesh.rotate(-30, axis=1).points - mesh.points + >>> + >>> face = fem.RegionHexahedronBoundary(mesh, mask=mesh.x == mesh.x.max()) + >>> u = fem.FieldContainer([fem.Field(face, dim=3)]) + >>> u.link(field) + >>> + >>> mesh_faces = face.mesh_faces() + >>> mesh_faces.points += field[0].values + >>> + >>> C = fem.math.inplane(u.evaluate.right_cauchy_green_deformation(), face.tangents) + >>> e = fem.math.strain(u, C=C, k=0) + >>> + >>> view = mesh_faces.view( + ... cell_data={"ep": fem.math.eigvalsh(e).max(axis=0).mean(axis=-2).T} + ... ) + >>> view.plot( + ... "ep", label="Strain (Max. Principal)", plotter=field.plot(style="wireframe") + ... ).show() """ def __init__( diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 32c066a7..8cf6dc06 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -78,7 +78,6 @@ def test_hyperelastic_jax(): def test_hyperelastic_jax_statevars(): - def W(C, statevars, C10, K): I3 = jnp.linalg.det(C) J = jnp.sqrt(I3) @@ -99,7 +98,6 @@ def W(C, statevars, C10, K): def test_material_jax(): - def dWdF(F, C10, K): J = jnp.linalg.det(F) C = F.T @ F @@ -124,7 +122,6 @@ def dWdF(F, C10, K): def test_material_jax_statevars(): - def dWdF(F, statevars, C10, K): J = jnp.linalg.det(F) C = F.T @ F @@ -149,7 +146,6 @@ def dWdF(F, statevars, C10, K): def test_material_included_jax_statevars(): - for fun, nstatevars in zip( [ mat.models.lagrange.morph, diff --git a/tests/test_field.py b/tests/test_field.py index 3af14b1e..d6a27d86 100644 --- a/tests/test_field.py +++ b/tests/test_field.py @@ -163,6 +163,7 @@ def test_3d_mixed(): f.evaluate.strain() f.evaluate.log_strain() f.evaluate.green_lagrange_strain() + f.evaluate.right_cauchy_green_deformation() f.extract() f.extract(grad=False) From 1b5716f005371d806be2a74925de172adb7e3a30 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 13 Nov 2024 22:57:27 +0100 Subject: [PATCH 108/125] remove PyVista-example downloads to avoid errors on read-the-docs --- examples/ex11_notch-stress.py | 35 ++++++++++++++---------- examples/ex12_foot-bone.py | 17 ++---------- examples/ex12_foot-bones_mesh-voxels.vtu | 24 ++++++++++++++++ 3 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 examples/ex12_foot-bones_mesh-voxels.vtu diff --git a/examples/ex11_notch-stress.py b/examples/ex11_notch-stress.py index a0a9c53b..3dc4d7ea 100644 --- a/examples/ex11_notch-stress.py +++ b/examples/ex11_notch-stress.py @@ -4,7 +4,7 @@ .. topic:: Three-dimensional linear-elastic analysis. - * read a mesh file + * create a hexahedron mesh * define a linear-elastic solid body @@ -23,28 +23,35 @@ A linear-elastic notched plate is subjected to uniaxial tension. The cell-based mean of the stress tensor is projected to the mesh-points and its maximum principal value is -plotted. FElupe has no wedge element formulation implemented and hence, the wedges in -the mesh are converted to hexahedrons. +plotted. """ # sphinx_gallery_thumbnail_number = -1 -import numpy as np import pypardiso -import pyvista as pv import felupe as fem -m = pv.examples.download_notch_displacement() +meshes = [] -hex8 = [0, 2, 1, 1, 3, 5, 4, 4] -mesh = fem.Mesh( - m.points * 250, - np.vstack([m.cells_dict[25][:, :8], m.cells_dict[26][:, hex8]]), - "hexahedron", +radius = fem.mesh.Point(a=-2.5).revolve(n=9, phi=90).translate(5, axis=1) +radius = fem.mesh.flip(radius) +middle = fem.mesh.Line(a=-7.5, b=0, n=9).expand(n=0) +meshes.append(middle.fill_between(radius, n=6)) + +left = fem.mesh.Line(-7.5, 5, n=11).expand(n=0).rotate(90, axis=2, center=[-7.5, 0]) +right = ( + fem.mesh.Line(a=-2.5, b=5, n=11) + .expand(n=0) + .rotate(90, axis=2, center=[-2.5, 0]) + .translate(5, axis=1) ) -point_ids = np.zeros(mesh.npoints, dtype=int) -point_ids[mesh.points_with_cells] = np.arange(len(mesh.points_with_cells)) -mesh.update(points=mesh.points[mesh.points_with_cells], cells=point_ids[mesh.cells]) +meshes.append(right.fill_between(left, n=6)) +meshes.append(fem.Rectangle(a=(-50, 0), b=(-7.5, 12.5), n=(36, 11))) + +mesh = fem.MeshContainer(meshes, merge=True).stack() +mesh = fem.MeshContainer([mesh, mesh.mirror(axis=0)], merge=True, decimals=6).stack() +mesh = fem.MeshContainer([mesh, mesh.mirror(axis=1)], merge=True, decimals=6).stack() +mesh = mesh.expand(n=3, z=2.5) region = fem.RegionHexahedron(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) diff --git a/examples/ex12_foot-bone.py b/examples/ex12_foot-bone.py index d726689f..2550772d 100644 --- a/examples/ex12_foot-bone.py +++ b/examples/ex12_foot-bone.py @@ -1,26 +1,15 @@ r""" -Voxelized Foot Bone -------------------- +Voxelized Foot Bones +-------------------- A :class:`~felupe.Region` on a voxel-based mesh with uniform hexahedrons should be created with ``uniform=True`` to enhance performance. """ import numpy as np -import pyvista as pv -from pyvista import examples import felupe as fem -surface = examples.download_foot_bones() -voxels = pv.voxelize(surface, density=0.6) - -mesh = fem.Mesh( - points=voxels.points, - cells=voxels.cell_connectivity.reshape(-1, 8), - cell_type="hexahedron", -).rotate(90, axis=0) -mesh.points *= 25 -mesh.update(points=np.vstack([mesh.points, [0, 0, mesh.z.min() - 2]])) +mesh = fem.mesh.read("ex12_foot-bones_mesh-voxels.vtu")[0] region = fem.RegionHexahedron(mesh, uniform=True) field = fem.FieldContainer([fem.Field(region, dim=3)]) diff --git a/examples/ex12_foot-bones_mesh-voxels.vtu b/examples/ex12_foot-bones_mesh-voxels.vtu new file mode 100644 index 00000000..e94c1725 --- /dev/null +++ b/examples/ex12_foot-bones_mesh-voxels.vtu @@ -0,0 +1,24 @@ + + + + + + + +AQAAAACAAAB4LQAAhgYAAA==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 + + + + +AQAAAACAAABAPwAAoAkAAA==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 + + +AQAAAACAAADoBwAAWwEAAA==eJwtxRsAqwAAAMDePwzDMAzDMAzDcBiGYRiGYRiGYRiGYTgcPtidXBh8RY6dOHXm3IVLV67d+OXWnXsPHj159uLVm3cfPn359uO3Pw5+fAsdOXbi1JlzFy5duXbjl1t37j149OTZi1dv3n349OXbj9/+OPj5LXTk2IlTZ85duHTl2o1fbt259+DRk2cvXr159+HTl28/fvvj4Ne30JFjJ06dOXfh0pVrN365defeg0dPnr149ebdh09fvv347Y+D399CR46dOHXm3IVLV67d+OXWnXsPHj159uLVm3cfPn359uO3Pw7+fAsdOXbi1JlzFy5duXbjl1t37j149OTZi1dv3n349OXbj9/+OPj7LXTk2IlTZ85duHTl2o1fbt259+DRk2cvXr159+HTl28/fvvj4N+30JFjJ06dOXfh0pVrN365defeg0dPnr149ebdh09fvv34P55hfYs= + + +AQAAAACAAADoBwAAGwAAAA==eJzjYYAAnlF6lB6lR+lRepQepYcdDQAbyQvd + + + + + From 66c904bec490af6730ef3675e6494a946c78ea2a Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 13 Nov 2024 23:19:01 +0100 Subject: [PATCH 109/125] Docs: Fix references --- examples/ex13_morph-rubber-wheel.py | 2 +- .../constitution/tensortrax/_total_lagrange.py | 12 ++++++------ .../constitution/tensortrax/_updated_lagrange.py | 12 ++++++------ .../tensortrax/models/lagrange/_morph.py | 8 ++++++-- .../lagrange/_morph_representative_directions.py | 5 ++++- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/examples/ex13_morph-rubber-wheel.py b/examples/ex13_morph-rubber-wheel.py index 829fd6cb..92424738 100644 --- a/examples/ex13_morph-rubber-wheel.py +++ b/examples/ex13_morph-rubber-wheel.py @@ -181,7 +181,7 @@ def sigmoid(x): # %% # .. note:: # The MORPH material model formulation is also available in FElupe, see -# :class:`~felupe.morph` (tensortrax) and +# :class:`~felupe.constitution.tensortrax.models.lagrange.morph` (tensortrax) and # :class:`~felupe.constitution.jax.models.lagrange.morph` (JAX). # # The force-stress curves are shown for uniaxial incompressible tension cycles. diff --git a/src/felupe/constitution/tensortrax/_total_lagrange.py b/src/felupe/constitution/tensortrax/_total_lagrange.py index 4c708f4c..98fb32fe 100644 --- a/src/felupe/constitution/tensortrax/_total_lagrange.py +++ b/src/felupe/constitution/tensortrax/_total_lagrange.py @@ -46,12 +46,12 @@ def total_lagrange(material): See Also -------- - felupe.Hyperelastic : A hyperelastic material definition with a given function for - the strain energy density function per unit undeformed volume with Automatic - Differentiation. - felupe.MaterialAD : A material definition with a given function for the partial - derivative of the strain energy function w.r.t. the deformation gradient tensor - with Automatic Differentiation. + felupe.constitution.tensortrax.Hyperelastic : A hyperelastic material definition + with a given function for the strain energy density function per unit undeformed + volume with Automatic Differentiation. + felupe.constitution.tensortrax.Material : A material definition with a given + function for the partial derivative of the strain energy function w.r.t. the + deformation gradient tensor with Automatic Differentiation. """ @wraps(material) diff --git a/src/felupe/constitution/tensortrax/_updated_lagrange.py b/src/felupe/constitution/tensortrax/_updated_lagrange.py index 03886979..6588596b 100644 --- a/src/felupe/constitution/tensortrax/_updated_lagrange.py +++ b/src/felupe/constitution/tensortrax/_updated_lagrange.py @@ -48,12 +48,12 @@ def updated_lagrange(material): See Also -------- - felupe.Hyperelastic : A hyperelastic material definition with a given function for - the strain energy density function per unit undeformed volume with Automatic - Differentiation. - felupe.MaterialAD : A material definition with a given function for the partial - derivative of the strain energy function w.r.t. the deformation gradient tensor - with Automatic Differentiation. + felupe.constitution.tensortrax.Hyperelastic : A hyperelastic material definition + with a given function for the strain energy density function per unit undeformed + volume with Automatic Differentiation. + felupe.constitution.tensortrax.Material : A material definition with a given + function for the partial derivative of the strain energy function w.r.t. the + deformation gradient tensor with Automatic Differentiation. """ @wraps(material) diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py index c1c4e7bd..ce90b253 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph.py @@ -181,8 +181,12 @@ def morph(F, statevars, p): See Also -------- - felupe.morph_representative_directions : Strain energy function of the MORPH model - formulation, implemented by the concept of representative directions. + felupe.constitution.tensortrax.models.lagrange.morph_representative_directions : + Strain energy function of the MORPH model formulation, implemented by the + concept of representative directions. + felupe.constitution.jax.models.lagrange.morph_representative_directions : Strain + energy function of the MORPH model formulation, implemented by the concept of + representative directions. """ # right Cauchy-Green deformation tensor diff --git a/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py index a1b8fa16..88425886 100644 --- a/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py +++ b/src/felupe/constitution/tensortrax/models/lagrange/_morph_representative_directions.py @@ -100,7 +100,10 @@ def morph_representative_directions(F, statevars, p, ε=1e-6): See Also -------- - felupe.morph : Strain energy function of the MORPH model formulation. + felupe.constitution.tensortrax.models.lagrange.morph : Strain energy function of the + MORPH model formulation. + felupe.constitution.jax.models.lagrange.morph : Strain energy function of the MORPH + model formulation. """ def f(λ, statevars, **kwargs): From 0c56e51a4fb9ed944d166623cf8d5db109e08b7b Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 13 Nov 2024 23:26:10 +0100 Subject: [PATCH 110/125] Ex. 12: Use a finer mesh --- examples/ex12_foot-bone.py | 10 +++++++++- examples/ex12_foot-bones_mesh-voxels.vtu | 10 +++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/examples/ex12_foot-bone.py b/examples/ex12_foot-bone.py index 2550772d..d58f3572 100644 --- a/examples/ex12_foot-bone.py +++ b/examples/ex12_foot-bone.py @@ -3,9 +3,17 @@ -------------------- A :class:`~felupe.Region` on a voxel-based mesh with uniform hexahedrons should be created with ``uniform=True`` to enhance performance. + +.. admonition:: This example requires external packages. + :class: hint + + .. code-block:: + + pip install pypardiso """ import numpy as np +import pypardiso import felupe as fem @@ -23,7 +31,7 @@ ) step = fem.Step(items=[solid, gravity, bottom], boundaries=boundaries) -job = fem.Job(steps=[step]).evaluate() +job = fem.Job(steps=[step]).evaluate(solver=pypardiso.spsolve, parallel=True) plotter = solid.plot( "Principal Values of Cauchy Stress", show_edges=False, diff --git a/examples/ex12_foot-bones_mesh-voxels.vtu b/examples/ex12_foot-bones_mesh-voxels.vtu index e94c1725..4af3fe0d 100644 --- a/examples/ex12_foot-bones_mesh-voxels.vtu +++ b/examples/ex12_foot-bones_mesh-voxels.vtu @@ -2,21 +2,21 @@ - + -AQAAAACAAAB4LQAAhgYAAA==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 +AgAAAACAAACgYAAAIhAAALcMAAA=eJyF3GuIZ3Udx/FVyyeBZRc0NEnxQmmm4G3VdFR0u5j3zBmdaVQWxUvGWIsUhBcsS7qAhqbrIhHVOpRB1iobOlEzf0ophKwHtnlJjNSuhIYG5YN5nwevw7KPghfx55zz/fz2//v/Ps45+dJND3zgsg8trVmzZuOeX//w1HMvPbzv1usPW9o2df5rr37n1JFft89uJz/4/EkjP/A/t+7+4unHj/yiH722af1jR4x8/22/u2DpjveOfJ/vXvXnK963x8gP+eHZty6e89qJ+slc/7Fnzc5duWa/0fXnXn/u9edef+71515/7vXnXv+lRz7/y11ee+URrz/3+nOvP/f6c68/9/pzrz//3s3PX339QR8d/v+/uHny+/N22XPK+8q9r9z7yr2v3PvKva/c+8q9/k+d/oazf7zzwaPrz73+3OvPvf7c68+9nv9d8da9nt7pyNH15F5P/oN77z5w8Q9nTG3ctuXZJ35z2tQ927b89IAbTlm65Zl//n3DGWeP/KF/feP0Ow89d+R/3eXYzQ/t9rGR7/uOP77xyb+dP/JTP3/u1Zfv/ZHBr93w1K4rN5y45PXkXk/u9eReT+715D3nfPHwM2+f2umYYf3q5UQv//pdj3z5/Pkr95vS7/j2E/cc+ZPDRn7JX9a/ZetRx4z8kENfvnFqy4kj/9zan7/67N2njPzpC9/0wAEXrRu5zz/3+ec+/9znn/v8c59/Xm5zv1/01pHeOtKdr98vuvP1+0V3vrnzzZ3v8PnMN3e+ufPNnW/ufHPnmzvf3Pnmu553x23PXHvW8Nz6/urfK925+72sO3e/l3Xn7vey7tz9Xtade+7cc+c+fD5zz5177txz554799y552vXH/ePnc87Z3gO86vf4853nu933fnOs2/Rne88+xbd+c6zb9Gd7zz7Ft355s43d77D5zPf3Pnmzjd3vvku9z16yS2/nR7uq33L43cetOtl//74yDd98abNp779/JFfteGp0/c/4ryRm4fcPLhf0s2D+z3dPLjf082D+z3dPOTmITcPuXnIzcPw+eQhd47t95xj7hxz55g7x9w5us/UnaP7Xt05uu/VnWPuHHPnmDvH3DnmzjF3jrnzal/tvHLnlTuv3Hnlzit3Xv4u0J1X7rxy55U7r9zns3L/t76y/sbjR88n9/nkPp/c55P7fHKfT+7zyX0+ufd12mffef1ndjp5dF+595V7X7n3lXtfufeVe1/bu877Nl689sGfnTq6ztzrzL3O3OvMvc787m1brnvp059YOmbrNe+57c2nTL3+O3XD5SetW7r8sbft/ejtsyM/aus1j2x+4MKRNxe9fazePlbvd4p+2Svff+EL980vrV31jau/Z7t+vevXu36969ebl95+QG+/p7ff03s+es9H7/no5xx44yX//fUFI7/p6AMfedf9MyPf8sFf7XXi1y4auc95YfV3us859znnPufc55z7nPO+X/S+X/S+X/S+X/S+X0afv7pP0Ns36u0bdXOywHmLbk4WOG/RzckC5y26OcnNSW5OcnPSeYI5yc1Jbk5yc5Kbk7zvQb19i26uPEfSzZXnSLq58hxJN1eeI+nmynMk3Vx5jqSbK8+RdHOVm6vcXOXmqvMNc5Wbq9xc5eYqN1f2F3r7E739m97+TTe3no/p5tbzMd3cej6mm1vPx3Rz6/mYbm49H9PNredjurnNzW1ubnNz2PmMOczNYW4Oc3OYm8O8faDePlBvH6i3D9TNueeBujn3PFA3554H6ubc80DdnHseqJtzzwN1c+55oG7OPQ/UzXluznNznpvbudVzKnObm9vc3M5x3qX3+0U3t7m5neOcUze3c5xz6uZ2jnNO3dzOcc6pm9s5zjl1czvHOadubuc45xx9Prmd45xTN7dznHPuaO7LnHPq5mGZc07dPCxzzqmbh2XOOXXzsMw5p24eljnn1M3DMuecunlY5pxTNw/LnHOOPp885OZhmfPP3PNP3fl6/qk7X88/defr+afufD3/1J2v55+68/X8U3e+nn/qztfzT915ef6pOy/PP3Xn5fmn7rw8/9Sdl+efuvPy/FN3Xrnzyp1X7rw8X80nnK/qPv8J56u6z3/C+aru859wvqr7/HOf/4Rz13wd55m697uOc1fd+13Huavu/a7j3HVH17nIuavudS5y7qp7nYucu+peZ97+bfPhZz5976YThvPP9m96+ze9/ZveHPWej95+VW+/qrdf1duv6v0u01+c/uR189fMjfyrR37phaWD5kd+0AlP3vn4HheP/PX//eYdd128tLjqnnPqPWe956z3nPWes95z1suh3n5Mby56c9Gbi95c9Oai93tZ75xH75xHb75689Wbr+58PZ/Una/n2Lrz9Rxbd7658/V8W+/7SO/7SG//oLd/GH3+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nOvlXC+f9w6+hH+P0MunXj718qmXT7186uVTL596+dTLp14+9fKpl0+9fOrlUy+fevnUy6dePvXyqZdPvXyOPn/Ip15+tgx+P//uoJcfvfzo5UcvP3r50cuPXn708qOXH7386OVHLz96+dHLj15+9PKjlx+9/OjlZ0f1enBw58x69dKrl1699OqlVy+9eunVS2/99dZfb/311l9v/fXWf0fr+bvBnWPrrafeeuqtp9566q2n3nru6Oc+PLjzc72fq/dz9X6u3s/94+DOvfV+rt7P1fu5ej/3scGdY+v9XL2fq/dz9fbVZ6/fffVz1+692Xm1Xq70cqU399Cbe+jNPfTmHrrf3zmz7vd3zqzXF3r10quX3v6gtz/o7Q96+4Pe/qB3rtM71+ndX/TuL3r3F737vt59X+++r5sf58m6+XGerJefZwZ3PqyXH7386OVHLz96+dHrd71+1+t3vXOF3rlCL7d6udXLrV5u9XKr917TO1fonUv1zqWjzx/OpXr3I70+0usjvT7S6yO9PtLrI70+0usjvT7S6yO9PtLrI90+cp6s20fOk3X7yHmybh85T9btI+fJun3kPFm3j5wn6/aR82TdPnKerNtHuX2U20fOpfXmD7r95Vxat7+cS+v2l3Np3f5yLq3bX/57Su6cWTf/zpl18++cWTf/zpl18++cWTf/zpl18++cWTf/zpl18++cWTf/zpl18++cWTf/zpl18++cWS9vTw/uvFcvb3p508ubXt708qaXN7286eVNL296edPLm17e9PKmlze9vOnlTS9vennTy9vo84e86eVNL296edPN1QxzWt1czTCn1c3VDHNa3VzNMKfVzdUMc1rdXM0wp9XN1QxzWt1czTCn1c3VDHNa3VzNMKfVzdUMc9o3qrvzVd26O1/VrbvzVd26O1/VrbvzVd26O1/VrbvzVd26O1/Vrbvz1R2t/1Odz5mX6q2/3vrrrb/e8+o9r97z6u1LOz9ywLrt9x8ymfP0HtQ7B+qd6/TOdXrnOr17k969Se/epHdv0stV7lxIb5311llvnfVypZer0f8/7A967x29945ufZ1H6dbXeZTeOV83D86jdPPgPEo3D86jdPPg753mznP09jG9fUw3b85zdPPmPEc3b85zdPPmPEfv/TX6fPKZm0/nPLr5dM6jm0/nPLr5dM6jm0/nPLr5dM6jm0/nPHrvl9z5jN77Re/9ovd+0e0L5zO6feF8RrcvnM/o9oXzGd2+cD6j2xfOZ3T7wvmMbl84n9HtC+czun3hfEa3L5zP6OVwzuDOSfRyqJdDvRzq5VAvh3o51MuhXg71cqiXQ70c6uVQL4d6OdTLoV4OR58/5FAvh3o51MuhXg51czLFfEM3J1PMN3RzMsV8QzcnU8w3dHMyxXxDNydTzDd0czLFfEM3J1PMJXTrO8VcQre+O1r/xcwBdNd/MXMA3fVfzBxAd/0XMwfQXf8dfU/vrbrf03ur7vfMW+f7b7v5mF3/PHd0z9Lbz/X2c739XG8/1zvn6J1z9M45euccvbrk3qf0+kKvL/T6Qm//1Ns/9fbP0ecP/aXXX3r9pVt371+6dff+pVt371+6dff+pVt37196fZF7D9LNifcg3Zx4D9LNifcg3Zx4Dxp9PjnxHqSbE+9BujnxHqSbE+9BujnxHqSbE+9BujnxHp17X9DNj/cF3fx4X9DNj/cF3fx4X9DNj/cF3fx4X9DNj/cF3fx4X9DNj/cFffL7tIN7Dtcnv0+LT36fFp/8Pi0++X1afPL7tPjk92nxye/T4tVXr76jzx/qq7s+nj9118fzp+76eP7UXZ8p/l3sWy9/6I4rVx49eb/3XHq51cutXm71cquXW73c6uVWL7d6+57evqe37+nte3r1umZwz0V69dKrl16e9fKsl2e9uo8+f6i7Xt316q5Xd72669Vdr+56dderu17d9equV3e9uuv1b+75RzcPnn908+D5RzcPnn908+D5RzcPnn908+D5RzcPnn908+D5RzcPnn908+D5RzcPs5xndPMwy3lGNw+znGd08zDLeUY3D7OcZ3TzMMt5RjcPs5xndPMwy3lGd/23cd7QXf9tnDd0138b5w3d9d/GueKWm5a/ffcLFozev3rrrLfOeuust85666y3znp9p9d3en2n13f65O96De77VJ/8XS988ne98Mnf9cInf9cLn/xdL7w6jj5/qKNeHfXqqFdHvTrq1VGvjnp11KujXh316qhbR9+DunX0PahbR9+DunX0PTj6fOroe1C3jr4Hdevoe1C3jr4Hdevoe1C3jp5nct9funX0/aVbR99funX0/TX6fOro+0u3jr6/dOvo+0u3jp4Tct9Tuuvs++Utm9Y/+IkPf3z0ftFbB7110FsHvefSy6dePvXyqZdPvTzsMbj7s9466K2D3jrorYNeHvTyoLdueuumt25666a3brrr5n6ou27uh7rr5n6ou27uh7rr5n6ou27uh7rr5nskd//RXTf3H911c//RXTf3H91101c/+dLlV//zhM3bt2+/8P/7V2899Z43t7/0nlfvefWeV+95dZ/L/tJ9LveNfBX5132uVeRf97lWkX/d51pF/nWfaxV9nZtP3ecyn7rPZT51nyufM/7v9f3/+M3/BcKlBU0= -AQAAAACAAABAPwAAoAkAAA==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 -AQAAAACAAADoBwAAWwEAAA==eJwtxRsAqwAAAMDePwzDMAzDMAzDcBiGYRiGYRiGYRiGYTgcPtidXBh8RY6dOHXm3IVLV67d+OXWnXsPHj159uLVm3cfPn359uO3Pw5+fAsdOXbi1JlzFy5duXbjl1t37j149OTZi1dv3n349OXbj9/+OPj5LXTk2IlTZ85duHTl2o1fbt259+DRk2cvXr159+HTl28/fvvj4Ne30JFjJ06dOXfh0pVrN365defeg0dPnr149ebdh09fvv347Y+D399CR46dOHXm3IVLV67d+OXWnXsPHj159uLVm3cfPn359uO3Pw7+fAsdOXbi1JlzFy5duXbjl1t37j149OTZi1dv3n349OXbj9/+OPj7LXTk2IlTZ85duHTl2o1fbt259+DRk2cvXr159+HTl28/fvvj4N+30JFjJ06dOXfh0pVrN365defeg0dPnr149ebdh09fvv34P55hfYs= +AQAAAACAAADQLgAATwcAAA==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 -AQAAAACAAADoBwAAGwAAAA==eJzjYYAAnlF6lB6lR+lRepQepYcdDQAbyQvd +AQAAAACAAADQLgAALQAAAA==eJztxSEBAAAMArAHoH/eCzqgNrNcxbZt27Zt27Zt27Zt27Zt27bt4Q8200Y5 From c5dea6213d875e9264389065ddfc31bfb297a863 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Wed, 13 Nov 2024 23:28:17 +0100 Subject: [PATCH 111/125] Update ex18_nonlinear-viscoelasticity-newton.py --- examples/ex18_nonlinear-viscoelasticity-newton.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/ex18_nonlinear-viscoelasticity-newton.py b/examples/ex18_nonlinear-viscoelasticity-newton.py index fa78c5b2..7b271cd9 100644 --- a/examples/ex18_nonlinear-viscoelasticity-newton.py +++ b/examples/ex18_nonlinear-viscoelasticity-newton.py @@ -8,6 +8,7 @@ internal variable are solved using Newton's method [2]_. """ +# sphinx_gallery_thumbnail_number = -1 import tensortrax as tr import tensortrax.math as tm From fc30250bd2e602abc2181914f7ce769cdf70af0e Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 14 Nov 2024 17:37:43 +0100 Subject: [PATCH 112/125] Update _region.py --- src/felupe/region/_region.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/felupe/region/_region.py b/src/felupe/region/_region.py index dd12b1ea..6f4de780 100644 --- a/src/felupe/region/_region.py +++ b/src/felupe/region/_region.py @@ -168,7 +168,7 @@ def astype(self, dtype, copy=True): See Also -------- - felupe.region.copy : Return a copy of the region and reload it if necessary. + felupe.Region.copy : Return a copy of the region and reload it if necessary. """ region = self From 35067a97feba065742024aed1ae2122a9da8d8d3 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 16 Nov 2024 22:58:27 +0100 Subject: [PATCH 113/125] =?UTF-8?q?Add=20the=20Stor=C3=A5kers=20hyperelast?= =?UTF-8?q?ic=20foam=20model=20(#900)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add the hyperelastic foam model (tensortrax) * Update _foam.py * Update _foam.py * Check success of transverse-constraint in `ViewMaterial.plot()` * rename the Foam material to Storakers * Update _storakers.py * Update __init__.py * Update __init__.py * Update _storakers.py * Add the hyperelastic foam model also for JAX * add tests for hyperelastic foam model * Update _storakers.py * Update jax.rst * Update tensortrax.rst * Test the foam model with other parameters which will fail with incompressibility as initial guess in plotting * Update ex08_shear.py * Test value error in `umat.plot()` * Update test_constitution.py * Update _storakers.py --- docs/felupe/constitution/autodiff/jax.rst | 3 + .../constitution/autodiff/tensortrax.rst | 5 +- examples/ex08_shear.py | 1 + src/felupe/__init__.py | 2 + src/felupe/constitution/__init__.py | 2 + src/felupe/constitution/_view.py | 45 +++++-- .../jax/models/hyperelastic/__init__.py | 3 + .../jax/models/hyperelastic/_storakers.py | 36 ++++++ .../models/hyperelastic/__init__.py | 3 + .../models/hyperelastic/_storakers.py | 122 ++++++++++++++++++ tests/test_constitution.py | 44 +++++-- tests/test_constitution_jax.py | 1 + 12 files changed, 245 insertions(+), 22 deletions(-) create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_storakers.py create mode 100644 src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index e57b0f48..41e5b215 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -49,6 +49,7 @@ These material model formulations are defined by a strain energy density functio miehe_goektepe_lulei mooney_rivlin + storakers third_order_deformation yeoh @@ -93,6 +94,8 @@ formulations in :class:`~felupe.constitution.jax.Material`. .. autofunction:: felupe.constitution.jax.models.hyperelastic.mooney_rivlin +.. autofunction:: felupe.constitution.jax.models.hyperelastic.storakers + .. autofunction:: felupe.constitution.jax.models.hyperelastic.third_order_deformation .. autofunction:: felupe.constitution.jax.models.hyperelastic.yeoh diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index f3024875..dacc9731 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -41,6 +41,7 @@ These material model formulations are defined by a strain energy density functio ogden ogden_roxburgh saint_venant_kirchhoff + storakers third_order_deformation van_der_waals yeoh @@ -113,6 +114,8 @@ and :func:`~felupe.constitution.tensortrax.updated_lagrange` material formulatio .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.saint_venant_kirchhoff +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.storakers + .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.third_order_deformation .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.van_der_waals @@ -121,4 +124,4 @@ and :func:`~felupe.constitution.tensortrax.updated_lagrange` material formulatio .. autofunction:: felupe.constitution.tensortrax.models.lagrange.morph -.. autofunction:: felupe.constitution.tensortrax.models.lagrange.morph_representative_directions \ No newline at end of file +.. autofunction:: felupe.constitution.tensortrax.models.lagrange.morph_representative_directions diff --git a/examples/ex08_shear.py b/examples/ex08_shear.py index 87f8000a..f30afa2b 100644 --- a/examples/ex08_shear.py +++ b/examples/ex08_shear.py @@ -72,6 +72,7 @@ # solid body. import felupe.constitution.tensortrax as mat + # import felupe.constitution.jax as mat umat = mat.Hyperelastic( diff --git a/src/felupe/__init__.py b/src/felupe/__init__.py index 2e9e9e0a..190fe801 100644 --- a/src/felupe/__init__.py +++ b/src/felupe/__init__.py @@ -262,6 +262,7 @@ ogden, ogden_roxburgh, saint_venant_kirchhoff, + storakers, third_order_deformation, total_lagrange, updated_lagrange, @@ -289,6 +290,7 @@ "ogden", "ogden_roxburgh", "saint_venant_kirchhoff", + "storakers", "third_order_deformation", "van_der_waals", "yeoh", diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index 91fdb417..c3034992 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -67,6 +67,7 @@ ogden, ogden_roxburgh, saint_venant_kirchhoff, + storakers, third_order_deformation, van_der_waals, yeoh, @@ -89,6 +90,7 @@ "ogden", "ogden_roxburgh", "saint_venant_kirchhoff", + "storakers", "third_order_deformation", "van_der_waals", "yeoh", diff --git a/src/felupe/constitution/_view.py b/src/felupe/constitution/_view.py index 6c93419f..5a34932e 100644 --- a/src/felupe/constitution/_view.py +++ b/src/felupe/constitution/_view.py @@ -28,7 +28,7 @@ def check_stretches(stretches): "Check if any stretch is lower or equal zero." if np.any(stretches <= 0.0): - raise ValueError("All stretches must greater than 0.") + raise ValueError("All stretches must be greater than 0.") return @@ -193,7 +193,7 @@ def __init__( self.statevars_included = np.prod(self.umat.x[-1].shape) > 0 self.statevars = statevars - def uniaxial(self, stretches=None): + def uniaxial(self, stretches=None, **kwargs): """Normal force per undeformed area vs. stretch curve for a uniaxial deformation. @@ -237,7 +237,16 @@ def fun(λ3): from scipy.optimize import root - λ2 = λ3 = root(fun, λ3).x + res = root(fun, λ3, **kwargs) + + if not res.success: + λ2 = λ3 = np.ones_like(λ1) + res = root(fun, λ3, **kwargs) + + if not res.success: + raise ValueError("Uniaxial deformation failed.") + + λ2 = λ3 = res.x F = eye * np.array([λ1, λ2, λ3]).reshape(1, 3, 1, -1) if self.statevars_included: @@ -258,9 +267,9 @@ def fun(λ3): return λ1, P[0, 0].ravel(), "Uniaxial" - def planar(self, stretches=None): + def planar(self, stretches=None, **kwargs): """Normal force per undeformed area vs stretch curve for a planar shear - incompressible deformation. + deformation. Parameters ---------- @@ -301,7 +310,16 @@ def fun(λ3): from scipy.optimize import root - λ3 = root(fun, λ3).x + res = root(fun, λ3, **kwargs) + + if not res.success: + λ3 = np.ones_like(λ1) + res = root(fun, λ3, **kwargs) + + if not res.success: + raise ValueError("Planar deformation failed.") + + λ3 = res.x F = eye * np.array([λ1, λ2, λ3]).reshape(1, 3, 1, -1) if self.statevars_included: @@ -322,9 +340,9 @@ def fun(λ3): return λ1, P[0, 0].ravel(), "Planar Shear" - def biaxial(self, stretches=None): + def biaxial(self, stretches=None, **kwargs): """Normal force per undeformed area vs stretch curve for a equi-biaxial - incompressible deformation. + deformation. Parameters ---------- @@ -364,7 +382,16 @@ def fun(λ3): from scipy.optimize import root - λ3 = root(fun, λ3).x + res = root(fun, λ3, **kwargs) + + if not res.success: + λ3 = np.ones_like(λ1) + res = root(fun, λ3, **kwargs) + + if not res.success: + raise ValueError("Biaxial deformation failed.") + + λ3 = res.x F = eye * np.array([λ1, λ2, λ3]).reshape(1, 3, 1, -1) if self.statevars_included: diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index e9515fad..178de33a 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -1,11 +1,13 @@ from ._miehe_goektepe_lulei import miehe_goektepe_lulei from ._mooney_rivlin import mooney_rivlin +from ._storakers import storakers from ._third_order_deformation import third_order_deformation from ._yeoh import yeoh __all__ = [ "miehe_goektepe_lulei", "mooney_rivlin", + "storakers", "third_order_deformation", "yeoh", ] @@ -13,5 +15,6 @@ # default (stable) material parameters miehe_goektepe_lulei.kwargs = dict(mu=0, N=100, U=0, p=2, q=2) mooney_rivlin.kwargs = dict(C10=0, C01=0) +storakers.kwargs = dict(mu=[0], alpha=[2], beta=[1]) third_order_deformation.kwargs = dict(C10=0, C01=0, C11=0, C20=0, C30=0) yeoh.kwargs = dict(C10=0, C20=0, C30=0) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_storakers.py b/src/felupe/constitution/jax/models/hyperelastic/_storakers.py new file mode 100644 index 00000000..ee8f9a82 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_storakers.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from jax.numpy import array, sqrt +from jax.numpy import sum as asum +from jax.numpy.linalg import eigvalsh + +from ....tensortrax.models.hyperelastic import storakers as storakers_docstring + + +@wraps(storakers_docstring) +def storakers(C, mu, alpha, beta): + λ1, λ2, λ3 = sqrt(eigvalsh(C)) + J = λ1 * λ2 * λ3 + + μ = array(mu) + α = array(alpha) + β = array(beta) + + return asum(2 * μ / α**2 * (λ1**α + λ2**α + λ3**α - 3 + (J ** (-α * β) - 1) / β)) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py index 6b6bbf56..69ff0c2f 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py @@ -22,6 +22,7 @@ from ._ogden import ogden from ._ogden_roxburgh import ogden_roxburgh from ._saint_venant_kirchhoff import saint_venant_kirchhoff +from ._storakers import storakers from ._third_order_deformation import third_order_deformation from ._van_der_waals import van_der_waals from ._yeoh import yeoh @@ -40,6 +41,7 @@ "ogden", "ogden_roxburgh", "saint_venant_kirchhoff", + "storakers", "third_order_deformation", "van_der_waals", "yeoh", @@ -58,6 +60,7 @@ ogden.kwargs = dict(mu=[0, 0], alpha=[2, -2]) ogden_roxburgh.kwargs = dict(r=100, m=1, beta=0, material=neo_hooke, mu=0) saint_venant_kirchhoff.kwargs = dict(mu=0.0, lmbda=0.0) +storakers.kwargs = dict(mu=[0], alpha=[2], beta=[1]) third_order_deformation.kwargs = dict(C10=0, C01=0, C11=0, C20=0, C30=0) van_der_waals.kwargs = dict(mu=0, beta=0, a=0, limit=100) yeoh.kwargs = dict(C10=0, C20=0, C30=0) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py new file mode 100644 index 00000000..70477bca --- /dev/null +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" + +from tensortrax.math import sum as tsum +from tensortrax.math.linalg import det, eigvalsh + + +def storakers(C, mu, alpha, beta): + r"""Strain energy function of the Storåkers isotropic hyperelastic + `foam `_ material formulation [1]_. + + Parameters + ---------- + C : tensortrax.Tensor or jax.Array + Right Cauchy-Green deformation tensor. + mu : list of float + List of moduli. + alpha : list of float + List of stretch exponents. + beta : list of float + List of coefficients for the degree of compressibility. + + Notes + ----- + The strain energy function is given in Eq. :eq:`psi-foam` + + .. math:: + :label: psi-ogden + + \psi = \sum_i \frac{2 \mu_i}{\alpha^2_i} \left[ + \hat{\lambda}_1^{\alpha_i} + + \hat{\lambda}_2^{\alpha_i} + + \hat{\lambda}_3^{\alpha_i} - 3 + + \frac{1}{\beta_i} \left( J^{-\alpha \beta} - 1 \right) + \right] + + The sum of the moduli :math:`\mu_i` is equal to the initial shear modulus + :math:`\mu`, see Eq. :eq:`shear-modulus-foam`, + + .. math:: + :label: shear-modulus-ogden + + \mu = \sum_i \mu_i + + and the initial bulk modulus is given in Eq. :eq:`bulk-modulus-foam`. + + .. math:: + :label: bulk-modulus-ogden + + K = \sum_i 2 \mu_i \left( \frac{1}{3} + \beta_i \right) + + Examples + -------- + First, choose the desired automatic differentiation backend + + .. pyvista-plot:: + :context: + + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. + + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.storakers, + ... mu=[4.5 * (1.85 / 2), -4.5 * (-9.2 / 2)], + ... alpha=[1.85, -9.2], + ... beta=[0.92, 0.92], + ... ) + >>> ax = umat.plot( + ... ux=fem.math.linsteps([1, 2], 15), + ... ps=fem.math.linsteps([1, 1], 15), + ... bx=fem.math.linsteps([1, 1], 9), + ... ) + + .. pyvista-plot:: + :include-source: False + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> fig = ax.get_figure() + >>> chart = pv.ChartMPL(fig) + >>> chart.show() + + References + ---------- + .. [1] B. Storåkers, "On material representation and constitutive branching in + finite compressible elasticity", Journal of the Mechanics and Physics of Solids, + vol. 34, no. 2. Elsevier BV, pp. 125–145, Jan. 1986. doi: + 10.1016/0022-5096(86)90033-5. + """ + + λ2 = eigvalsh(C) + + return tsum( + [ + 2 * μ / α**2 * (tsum(λ2 ** (α / 2)) - 3 + (det(C) ** (-α * β / 2) - 1) / β) + for μ, α, β in zip(mu, alpha, beta) + ] + ) diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 4e436101..de4f56ce 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -341,42 +341,51 @@ def neo_hooke(C, mu=1): for model, kwargs, incompressible in [ (neo_hooke, {"mu": 1}, True), - (fem.constitution.saint_venant_kirchhoff, {"mu": 1, "lmbda": 20.0}, False), - (fem.constitution.neo_hooke, {"mu": 1}, True), - (fem.constitution.mooney_rivlin, {"C10": 0.3, "C01": 0.8}, True), - (fem.constitution.yeoh, {"C10": 0.5, "C20": -0.1, "C30": 0.02}, True), + (fem.saint_venant_kirchhoff, {"mu": 1, "lmbda": 20.0}, False), + (fem.neo_hooke, {"mu": 1}, True), + (fem.mooney_rivlin, {"C10": 0.3, "C01": 0.8}, True), + (fem.yeoh, {"C10": 0.5, "C20": -0.1, "C30": 0.02}, True), ( - fem.constitution.third_order_deformation, + fem.third_order_deformation, {"C10": 0.5, "C01": 0.1, "C11": 0.01, "C20": -0.1, "C30": 0.02}, True, ), - (fem.constitution.ogden, {"mu": [1, 0.2], "alpha": [1.7, -1.5]}, True), - (fem.constitution.arruda_boyce, {"C1": 1.0, "limit": 3.2}, True), + (fem.ogden, {"mu": [1, 0.2], "alpha": [1.7, -1.5]}, True), + (fem.arruda_boyce, {"C1": 1.0, "limit": 3.2}, True), ( - fem.constitution.extended_tube, + fem.extended_tube, {"Gc": 0.1867, "Ge": 0.2169, "beta": 0.2, "delta": 0.09693}, True, ), ( - fem.constitution.van_der_waals, + fem.van_der_waals, {"mu": 1.0, "beta": 0.1, "a": 0.5, "limit": 5.0}, True, ), ( - fem.constitution.alexander, + fem.alexander, dict(C1=0.117, C2=0.137, C3=0.00690, gamma=0.735, k=0.00015), True, ), ( - fem.constitution.anssari_benam_bucchi, + fem.anssari_benam_bucchi, dict(mu=0.29, N=26.8), True, ), ( - fem.constitution.lopez_pamies, + fem.lopez_pamies, dict(mu=[0.2699, 0.00001771], alpha=[1.08, 4.40]), True, ), + ( + fem.storakers, + dict( + mu=[104.869e-3], + alpha=[7.10874], + beta=[0.106469], + ), + False, + ), ]: umat = fem.Hyperelastic(model, **kwargs) @@ -388,6 +397,17 @@ def neo_hooke(C, mu=1): ax = umat.plot(incompressible=incompressible) ax = umat.screenshot(incompressible=incompressible) + umat = fem.Hyperelastic(fem.neo_hooke, mu=np.nan) + + with pytest.raises(ValueError): + umat.plot(bx=None, ps=None) + + with pytest.raises(ValueError): + umat.plot(ux=None, bx=None) + + with pytest.raises(ValueError): + umat.plot(ux=None, ps=None) + def test_umat_hyperelastic2(): r, x = pre(sym=False, add_identity=True, add_random=True) diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 8cf6dc06..a904845c 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -67,6 +67,7 @@ def test_hyperelastic_jax(): md.yeoh, md.third_order_deformation, md.miehe_goektepe_lulei, + md.storakers, ]: umat = mat.Hyperelastic(W, **W.kwargs) solid = fem.SolidBody(umat=umat, field=field) From 6b2d58bb85d92fb87b3798adb5f7d482b8de15d0 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 16 Nov 2024 23:24:20 +0100 Subject: [PATCH 114/125] Aktualisieren von _storakers.py fix docstring typos --- .../tensortrax/models/hyperelastic/_storakers.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py index 70477bca..118606ba 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py @@ -40,27 +40,27 @@ def storakers(C, mu, alpha, beta): The strain energy function is given in Eq. :eq:`psi-foam` .. math:: - :label: psi-ogden + :label: psi-foam \psi = \sum_i \frac{2 \mu_i}{\alpha^2_i} \left[ - \hat{\lambda}_1^{\alpha_i} + - \hat{\lambda}_2^{\alpha_i} + - \hat{\lambda}_3^{\alpha_i} - 3 - + \frac{1}{\beta_i} \left( J^{-\alpha \beta} - 1 \right) + \lambda_1^{\alpha_i} + + \lambda_2^{\alpha_i} + + \lambda_3^{\alpha_i} - 3 + + \frac{1}{\beta_i} \left( J^{-\alpha_i \beta_i} - 1 \right) \right] The sum of the moduli :math:`\mu_i` is equal to the initial shear modulus :math:`\mu`, see Eq. :eq:`shear-modulus-foam`, .. math:: - :label: shear-modulus-ogden + :label: shear-modulus-foam \mu = \sum_i \mu_i and the initial bulk modulus is given in Eq. :eq:`bulk-modulus-foam`. .. math:: - :label: bulk-modulus-ogden + :label: bulk-modulus-foam K = \sum_i 2 \mu_i \left( \frac{1}{3} + \beta_i \right) From a0fa71a2f8bb269fbc2cc5486629703ecbc61299 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 17 Nov 2024 09:24:45 +0100 Subject: [PATCH 115/125] Add the Blatz-Ko hyperelastic foam model (#901) --- docs/felupe/constitution/autodiff/jax.rst | 3 + .../constitution/autodiff/tensortrax.rst | 3 + src/felupe/__init__.py | 2 + src/felupe/constitution/__init__.py | 2 + .../jax/models/hyperelastic/__init__.py | 3 + .../jax/models/hyperelastic/_blatz_ko.py | 33 +++++++ .../models/hyperelastic/__init__.py | 3 + .../models/hyperelastic/_blatz_ko.py | 94 +++++++++++++++++++ tests/test_constitution.py | 1 + tests/test_constitution_jax.py | 1 + 10 files changed, 145 insertions(+) create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py create mode 100644 src/felupe/constitution/tensortrax/models/hyperelastic/_blatz_ko.py diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 41e5b215..5cd3c68f 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -47,6 +47,7 @@ These material model formulations are defined by a strain energy density functio .. autosummary:: + blatz_ko miehe_goektepe_lulei mooney_rivlin storakers @@ -90,6 +91,8 @@ formulations in :class:`~felupe.constitution.jax.Material`. .. autofunction:: felupe.constitution.jax.updated_lagrange +.. autofunction:: felupe.constitution.jax.models.hyperelastic.blatz_ko + .. autofunction:: felupe.constitution.jax.models.hyperelastic.miehe_goektepe_lulei .. autofunction:: felupe.constitution.jax.models.hyperelastic.mooney_rivlin diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index dacc9731..1d264c18 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -32,6 +32,7 @@ These material model formulations are defined by a strain energy density functio alexander anssari_benam_bucchi arruda_boyce + blatz_ko extended_tube finite_strain_viscoelastic lopez_pamies @@ -96,6 +97,8 @@ and :func:`~felupe.constitution.tensortrax.updated_lagrange` material formulatio .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.arruda_boyce +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.blatz_ko + .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.extended_tube .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.finite_strain_viscoelastic diff --git a/src/felupe/__init__.py b/src/felupe/__init__.py index 190fe801..73049104 100644 --- a/src/felupe/__init__.py +++ b/src/felupe/__init__.py @@ -249,6 +249,7 @@ alexander, anssari_benam_bucchi, arruda_boyce, + blatz_ko, constitutive_material, extended_tube, finite_strain_viscoelastic, @@ -278,6 +279,7 @@ "alexander", "anssari_benam_bucchi", "arruda_boyce", + "blatz_ko", "extended_tube", "finite_strain_viscoelastic", "isochoric_volumetric_split", diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index c3034992..bfbc2523 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -58,6 +58,7 @@ alexander, anssari_benam_bucchi, arruda_boyce, + blatz_ko, extended_tube, finite_strain_viscoelastic, lopez_pamies, @@ -78,6 +79,7 @@ "alexander", "anssari_benam_bucchi", "arruda_boyce", + "blatz_ko", "extended_tube", "finite_strain_viscoelastic", "isochoric_volumetric_split", diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index 178de33a..00272c5b 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -1,3 +1,4 @@ +from ._blatz_ko import blatz_ko from ._miehe_goektepe_lulei import miehe_goektepe_lulei from ._mooney_rivlin import mooney_rivlin from ._storakers import storakers @@ -5,6 +6,7 @@ from ._yeoh import yeoh __all__ = [ + "blatz_ko", "miehe_goektepe_lulei", "mooney_rivlin", "storakers", @@ -13,6 +15,7 @@ ] # default (stable) material parameters +blatz_ko.kwargs = dict(mu=1) miehe_goektepe_lulei.kwargs = dict(mu=0, N=100, U=0, p=2, q=2) mooney_rivlin.kwargs = dict(C10=0, C01=0) storakers.kwargs = dict(mu=[0], alpha=[2], beta=[1]) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py b/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py new file mode 100644 index 00000000..2aa79f97 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from jax.numpy import sqrt, trace +from jax.numpy.linalg import det + +from ....tensortrax.models.hyperelastic import blatz_ko as blatz_ko_docstring + + +@wraps(blatz_ko_docstring) +def blatz_ko(C, mu): + + I1 = trace(C) + I2 = (I1**2 - trace(C @ C)) / 2 + I3 = det(C) + + return mu * (I2 / I3 + 2 * sqrt(I3) - 5) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py index 69ff0c2f..2735c551 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py @@ -12,6 +12,7 @@ from ._alexander import alexander from ._anssari_benam_bucchi import anssari_benam_bucchi from ._arruda_boyce import arruda_boyce +from ._blatz_ko import blatz_ko from ._extended_tube import extended_tube from ._finite_strain_viscoelastic import finite_strain_viscoelastic from ._lopez_pamies import lopez_pamies @@ -31,6 +32,7 @@ "alexander", "anssari_benam_bucchi", "arruda_boyce", + "blatz_ko", "extended_tube", "finite_strain_viscoelastic", "lopez_pamies", @@ -51,6 +53,7 @@ alexander.kwargs = dict(C1=0, C2=0, C3=0, gamma=100, k=0) anssari_benam_bucchi.kwargs = dict(mu=0, N=100) arruda_boyce.kwargs = dict(C1=0, limit=100) +blatz_ko.kwargs = dict(mu=0) extended_tube.kwargs = dict(Gc=0, Ge=0, beta=1, delta=0) lopez_pamies.kwargs = dict(mu=[0, 0], alpha=[1, 4]) miehe_goektepe_lulei.kwargs = dict(mu=0, N=100, U=0, p=2, q=2) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_blatz_ko.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_blatz_ko.py new file mode 100644 index 00000000..1444b531 --- /dev/null +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_blatz_ko.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" + +from tensortrax.math import sqrt, trace +from tensortrax.math.linalg import det + + +def blatz_ko(C, mu): + r"""Strain energy function of the Blatz-Ko isotropic hyperelastic + `foam `_ material formulation [1]_. + + Parameters + ---------- + C : tensortrax.Tensor or jax.Array + Right Cauchy-Green deformation tensor. + mu : float + The shear modulus. + + Notes + ----- + The Poisson ratio of the Blatz-Ko model formulation is :math:`\nu = 0.25`. The + strain energy function is given in Eq. :eq:`psi-blatz-ko` + + .. math:: + :label: psi-blatz-ko + + \psi = \frac{\mu}{2} \left(\frac{I_2}{I_3} + 2 \sqrt{I_3} - 5 \right) + + The shear modulus :math:`\mu` is related to young's modulus as denoted in Eq. + :eq:`shear-modulus-blatz-ko`. + + .. math:: + :label: shear-modulus-blatz-ko + + \mu = \frac{2 E}{5} + + Examples + -------- + First, choose the desired automatic differentiation backend + + .. pyvista-plot:: + :context: + + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. + + .. pyvista-plot:: + :context: + + >>> import felupe as fem + >>> + >>> umat = mat.Hyperelastic(mat.models.hyperelastic.blatz_ko, mu=1.0) + >>> ax = umat.plot() + + .. pyvista-plot:: + :include-source: False + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> fig = ax.get_figure() + >>> chart = pv.ChartMPL(fig) + >>> chart.show() + + References + ---------- + .. [1] P. J. Blatz and W. L. Ko, "Application of Finite Elastic Theory to the + Deformation of Rubbery Materials", Transactions of the Society of Rheology, vol. + 6, no. 1. Society of Rheology, pp. 223–252, Mar. 01, 1962. doi: 10.1122/1.548937. + """ + + I1 = trace(C) + I2 = (I1**2 - trace(C @ C)) / 2 + I3 = det(C) + + return mu * (I2 / I3 + 2 * sqrt(I3) - 5) diff --git a/tests/test_constitution.py b/tests/test_constitution.py index de4f56ce..1fdb9b0e 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -386,6 +386,7 @@ def neo_hooke(C, mu=1): ), False, ), + (fem.blatz_ko, dict(mu=1.0), False), ]: umat = fem.Hyperelastic(model, **kwargs) diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index a904845c..e227652a 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -68,6 +68,7 @@ def test_hyperelastic_jax(): md.third_order_deformation, md.miehe_goektepe_lulei, md.storakers, + md.blatz_ko, ]: umat = mat.Hyperelastic(W, **W.kwargs) solid = fem.SolidBody(umat=umat, field=field) From c60d4cd77a79e1a852585bdad77db835ef5f0607 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 17 Nov 2024 10:02:36 +0100 Subject: [PATCH 116/125] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 342e4d94..d6bc2a97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. The format - Add an optional keyword-argument `Region.astype(copy=True)` to modify the data types of the arrays of the region in-place if `copy=False`. - Add `FieldContainer.evaluate.right_cauchy_green_deformation()` and `math.right_cauchy_green_deformation(field)` to evaluate the right Cauchy-Green deformation tensor. - Add `math.strain(field, C=None, ..., **kwargs)` to use a given right Cauchy-Green deformation tensor for the evaluation of the strain tensor. +- Add the hyperelastic foam models `storakers()` and `blatz_ko()` for both AD-backends. ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. From 95398733ae3b944873471937c607781791d9c64c Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sun, 17 Nov 2024 23:49:30 +0100 Subject: [PATCH 117/125] Add the Van-der-Waals model for JAX (#902) * Add the Van-der-Waals model for JAX * Update CHANGELOG.md --- CHANGELOG.md | 4 +- docs/felupe/constitution/autodiff/jax.rst | 3 ++ .../jax/models/hyperelastic/__init__.py | 3 ++ .../jax/models/hyperelastic/_van_der_waals.py | 37 +++++++++++++++++++ .../models/hyperelastic/_van_der_waals.py | 16 ++++++-- tests/test_constitution_jax.py | 1 + 6 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py diff --git a/CHANGELOG.md b/CHANGELOG.md index d6bc2a97..95a4efd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,8 @@ All notable changes to this project will be documented in this file. The format - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. -- Add material models for JAX-based materials: `felupe.constitution.jax.models.hyperelastic.miehe_goektepe_lulei()`, `felupe.constitution.jax.models.hyperelastic.mooney_rivlin()`, `felupe.constitution.jax.models.hyperelastic.yeoh()`, `felupe.constitution.jax.models.hyperelastic.third_order_deformation()`, `felupe.constitution.jax.models.lagrange.morph()`, `felupe.constitution.jax.models.lagrange.morph_representative_directions()`. -- Add `felupe.constitution.jax.total_lagrange()`, `felupe.constitution.jax.updated_lagrange()` and `felupe.constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. +- Add material models for JAX-based materials. Hyperelastic models available at `constitution.jax.models.hyperelastic`: `miehe_goektepe_lulei()`, `mooney_rivlin()`, `yeoh()`, `third_order_deformation()`, `van_der_waals()`. Lagrange (stress-based) models available at `constitution.jax.models.lagrange`: `morph()`, `morph_representative_directions()`. +- Add `constitution.jax.total_lagrange()`, `constitution.jax.updated_lagrange()` and `constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. - Add an optional keyword-argument `Region.astype(copy=True)` to modify the data types of the arrays of the region in-place if `copy=False`. - Add `FieldContainer.evaluate.right_cauchy_green_deformation()` and `math.right_cauchy_green_deformation(field)` to evaluate the right Cauchy-Green deformation tensor. - Add `math.strain(field, C=None, ..., **kwargs)` to use a given right Cauchy-Green deformation tensor for the evaluation of the strain tensor. diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index 5cd3c68f..fd2d438f 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -52,6 +52,7 @@ These material model formulations are defined by a strain energy density functio mooney_rivlin storakers third_order_deformation + van_der_waals yeoh **Material Models for** :class:`felupe.constitution.jax.Material` @@ -101,6 +102,8 @@ formulations in :class:`~felupe.constitution.jax.Material`. .. autofunction:: felupe.constitution.jax.models.hyperelastic.third_order_deformation +.. autofunction:: felupe.constitution.jax.models.hyperelastic.van_der_waals + .. autofunction:: felupe.constitution.jax.models.hyperelastic.yeoh .. autofunction:: felupe.constitution.jax.models.lagrange.morph diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index 00272c5b..fd4dd120 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -3,6 +3,7 @@ from ._mooney_rivlin import mooney_rivlin from ._storakers import storakers from ._third_order_deformation import third_order_deformation +from ._van_der_waals import van_der_waals from ._yeoh import yeoh __all__ = [ @@ -11,6 +12,7 @@ "mooney_rivlin", "storakers", "third_order_deformation", + "van_der_waals", "yeoh", ] @@ -20,4 +22,5 @@ mooney_rivlin.kwargs = dict(C10=0, C01=0) storakers.kwargs = dict(mu=[0], alpha=[2], beta=[1]) third_order_deformation.kwargs = dict(C10=0, C01=0, C11=0, C20=0, C30=0) +van_der_waals.kwargs = dict(mu=0, beta=0, a=0, limit=100) yeoh.kwargs = dict(C10=0, C20=0, C30=0) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py b/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py new file mode 100644 index 00000000..f9304294 --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from jax.lax import select +from jax.numpy import isclose, log, sqrt, trace +from jax.numpy.linalg import det + +from ....tensortrax.models.hyperelastic import van_der_waals as van_der_waals_docstring + + +@wraps(van_der_waals_docstring) +def van_der_waals(C, mu, limit, a, beta): + J3 = det(C) ** (-1 / 3) + I1 = J3 * trace(C) + I2 = (trace(C) ** 2 - J3**2 * trace(C @ C)) / 2 + Im = (1 - beta) * I1 + beta * I2 + Im = select(isclose(Im, 3), Im + 1e-6, Im) + eta = sqrt((Im - 3) / (limit**2 - 3)) + return mu * ( + -(limit**2 - 3) * (log(1 - eta) + eta) - 2 / 3 * a * ((Im - 3) / 2) ** (3 / 2) + ) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py index c4711cdf..03f4c0fc 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py @@ -24,11 +24,11 @@ def van_der_waals(C, mu, limit, a, beta): r"""Strain energy function of the `Van der Waals `_ [1]_ material - formulation., + formulation. Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. mu : float Initial shear modulus. @@ -42,12 +42,22 @@ def van_der_waals(C, mu, limit, a, beta): Examples -------- + First, choose the desired automatic differentiation backend + + .. pyvista-plot:: + :context: + + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. + .. pyvista-plot:: :context: >>> import felupe as fem >>> - >>> umat = fem.Hyperelastic(fem.van_der_waals, mu=1.0, beta=0.1, a=0.5, limit=5.0) + >>> umat = mat.Hyperelastic(fem.van_der_waals, mu=1.0, beta=0.1, a=0.5, limit=5.0) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index e227652a..2f124057 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -68,6 +68,7 @@ def test_hyperelastic_jax(): md.third_order_deformation, md.miehe_goektepe_lulei, md.storakers, + md.van_der_waals, md.blatz_ko, ]: umat = mat.Hyperelastic(W, **W.kwargs) From 7f0890512a818b9e79a64acd5a79da7fbda810d6 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 18 Nov 2024 20:15:42 +0100 Subject: [PATCH 118/125] Add more hyperelastic models (#903) * Add more hyperelastic models SVK-ortho (tensortrax), extended-tube (JAX), neo-hooke (JAX) * Aktualisieren von CHANGELOG.md * Aktualisieren von test_constitution_jax.py --- CHANGELOG.md | 3 +- docs/felupe/constitution/autodiff/jax.rst | 6 + .../constitution/autodiff/tensortrax.rst | 3 + src/felupe/__init__.py | 2 + src/felupe/constitution/__init__.py | 2 + .../jax/models/hyperelastic/__init__.py | 8 +- .../jax/models/hyperelastic/_blatz_ko.py | 1 - .../jax/models/hyperelastic/_extended_tube.py | 36 ++++++ .../jax/models/hyperelastic/_neo_hooke.py | 28 +++++ .../jax/models/hyperelastic/_storakers.py | 8 +- .../jax/models/hyperelastic/_van_der_waals.py | 5 +- .../models/hyperelastic/__init__.py | 9 ++ .../models/hyperelastic/_extended_tube.py | 19 +++- .../models/hyperelastic/_neo_hooke.py | 13 ++- .../_saint_venant_kirchhoff_orthotropic.py | 103 ++++++++++++++++++ .../models/hyperelastic/_storakers.py | 5 +- .../models/hyperelastic/_van_der_waals.py | 10 +- tests/test_constitution.py | 11 ++ tests/test_constitution_jax.py | 1 + tests/umat.png | Bin 0 -> 87999 bytes 20 files changed, 256 insertions(+), 17 deletions(-) create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_extended_tube.py create mode 100644 src/felupe/constitution/jax/models/hyperelastic/_neo_hooke.py create mode 100644 src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py create mode 100644 tests/umat.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a4efd8..08aec9bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,12 +12,13 @@ All notable changes to this project will be documented in this file. The format - Add `math.inplane(A, vectors)` to return the in-plane components of a symmetric tensor `A`, where the plane is defined by its standard unit vectors. - Add `constitution.jax.Hyperelastic` as a feature-equivalent alternative to `Hyperelastic` with `jax` as backend. - Add `constitution.jax.Material(..., jacobian=None)` with JAX as backend. A custom jacobian-callable may be passed to switch between forward- and backward-mode automatic differentiation. -- Add material models for JAX-based materials. Hyperelastic models available at `constitution.jax.models.hyperelastic`: `miehe_goektepe_lulei()`, `mooney_rivlin()`, `yeoh()`, `third_order_deformation()`, `van_der_waals()`. Lagrange (stress-based) models available at `constitution.jax.models.lagrange`: `morph()`, `morph_representative_directions()`. +- Add material models for JAX-based materials. Hyperelastic models available at `constitution.jax.models.hyperelastic`: `extended_tube()`, `miehe_goektepe_lulei()`, `mooney_rivlin()`, `neo_hooke()`, `yeoh()`, `third_order_deformation()`, `van_der_waals()`. Lagrange (stress-based) models available at `constitution.jax.models.lagrange`: `morph()`, `morph_representative_directions()`. - Add `constitution.jax.total_lagrange()`, `constitution.jax.updated_lagrange()` and `constitution.jax.isochoric_volumetric_split()` function decorators for the JAX hyperelastic material class. - Add an optional keyword-argument `Region.astype(copy=True)` to modify the data types of the arrays of the region in-place if `copy=False`. - Add `FieldContainer.evaluate.right_cauchy_green_deformation()` and `math.right_cauchy_green_deformation(field)` to evaluate the right Cauchy-Green deformation tensor. - Add `math.strain(field, C=None, ..., **kwargs)` to use a given right Cauchy-Green deformation tensor for the evaluation of the strain tensor. - Add the hyperelastic foam models `storakers()` and `blatz_ko()` for both AD-backends. +- Add the `saint_venant_kirchhoff_orthotropic()` hyperelastic model (tensortrax). ### Changed - Change default `np.einsum(..., order="K")` to `np.einsum(..., order="C")` in the methods of `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` and `FieldContainer`. diff --git a/docs/felupe/constitution/autodiff/jax.rst b/docs/felupe/constitution/autodiff/jax.rst index fd2d438f..1206b54a 100644 --- a/docs/felupe/constitution/autodiff/jax.rst +++ b/docs/felupe/constitution/autodiff/jax.rst @@ -48,8 +48,10 @@ These material model formulations are defined by a strain energy density functio .. autosummary:: blatz_ko + extended_tube miehe_goektepe_lulei mooney_rivlin + neo_hooke storakers third_order_deformation van_der_waals @@ -94,10 +96,14 @@ formulations in :class:`~felupe.constitution.jax.Material`. .. autofunction:: felupe.constitution.jax.models.hyperelastic.blatz_ko +.. autofunction:: felupe.constitution.jax.models.hyperelastic.extended_tube + .. autofunction:: felupe.constitution.jax.models.hyperelastic.miehe_goektepe_lulei .. autofunction:: felupe.constitution.jax.models.hyperelastic.mooney_rivlin +.. autofunction:: felupe.constitution.jax.models.hyperelastic.neo_hooke + .. autofunction:: felupe.constitution.jax.models.hyperelastic.storakers .. autofunction:: felupe.constitution.jax.models.hyperelastic.third_order_deformation diff --git a/docs/felupe/constitution/autodiff/tensortrax.rst b/docs/felupe/constitution/autodiff/tensortrax.rst index 1d264c18..0483870a 100644 --- a/docs/felupe/constitution/autodiff/tensortrax.rst +++ b/docs/felupe/constitution/autodiff/tensortrax.rst @@ -42,6 +42,7 @@ These material model formulations are defined by a strain energy density functio ogden ogden_roxburgh saint_venant_kirchhoff + saint_venant_kirchhoff_orthotropic storakers third_order_deformation van_der_waals @@ -117,6 +118,8 @@ and :func:`~felupe.constitution.tensortrax.updated_lagrange` material formulatio .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.saint_venant_kirchhoff +.. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.saint_venant_kirchhoff_orthotropic + .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.storakers .. autofunction:: felupe.constitution.tensortrax.models.hyperelastic.third_order_deformation diff --git a/src/felupe/__init__.py b/src/felupe/__init__.py index 73049104..91427396 100644 --- a/src/felupe/__init__.py +++ b/src/felupe/__init__.py @@ -263,6 +263,7 @@ ogden, ogden_roxburgh, saint_venant_kirchhoff, + saint_venant_kirchhoff_orthotropic, storakers, third_order_deformation, total_lagrange, @@ -292,6 +293,7 @@ "ogden", "ogden_roxburgh", "saint_venant_kirchhoff", + "saint_venant_kirchhoff_orthotropic", "storakers", "third_order_deformation", "van_der_waals", diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index bfbc2523..13d0f113 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -68,6 +68,7 @@ ogden, ogden_roxburgh, saint_venant_kirchhoff, + saint_venant_kirchhoff_orthotropic, storakers, third_order_deformation, van_der_waals, @@ -92,6 +93,7 @@ "ogden", "ogden_roxburgh", "saint_venant_kirchhoff", + "saint_venant_kirchhoff_orthotropic", "storakers", "third_order_deformation", "van_der_waals", diff --git a/src/felupe/constitution/jax/models/hyperelastic/__init__.py b/src/felupe/constitution/jax/models/hyperelastic/__init__.py index fd4dd120..1f0c1f01 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/jax/models/hyperelastic/__init__.py @@ -1,6 +1,8 @@ from ._blatz_ko import blatz_ko +from ._extended_tube import extended_tube from ._miehe_goektepe_lulei import miehe_goektepe_lulei from ._mooney_rivlin import mooney_rivlin +from ._neo_hooke import neo_hooke from ._storakers import storakers from ._third_order_deformation import third_order_deformation from ._van_der_waals import van_der_waals @@ -8,8 +10,10 @@ __all__ = [ "blatz_ko", + "extended_tube", "miehe_goektepe_lulei", "mooney_rivlin", + "neo_hooke", "storakers", "third_order_deformation", "van_der_waals", @@ -17,9 +21,11 @@ ] # default (stable) material parameters -blatz_ko.kwargs = dict(mu=1) +blatz_ko.kwargs = dict(mu=0) +extended_tube.kwargs = dict(Gc=0, Ge=0, beta=1, delta=0) miehe_goektepe_lulei.kwargs = dict(mu=0, N=100, U=0, p=2, q=2) mooney_rivlin.kwargs = dict(C10=0, C01=0) +neo_hooke.kwargs = dict(mu=0) storakers.kwargs = dict(mu=[0], alpha=[2], beta=[1]) third_order_deformation.kwargs = dict(C10=0, C01=0, C11=0, C20=0, C30=0) van_der_waals.kwargs = dict(mu=0, beta=0, a=0, limit=100) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py b/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py index 2aa79f97..23ca62dc 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_blatz_ko.py @@ -25,7 +25,6 @@ @wraps(blatz_ko_docstring) def blatz_ko(C, mu): - I1 = trace(C) I2 = (I1**2 - trace(C @ C)) / 2 I3 = det(C) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_extended_tube.py b/src/felupe/constitution/jax/models/hyperelastic/_extended_tube.py new file mode 100644 index 00000000..2fc3c8cc --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_extended_tube.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from jax.numpy import array, diag, log, sqrt, trace +from jax.numpy.linalg import det, eigvalsh + +from ....tensortrax.models.hyperelastic import extended_tube as extended_tube_docstring + + +@wraps(extended_tube_docstring) +def extended_tube(C, Gc, delta, Ge, beta): + J3 = det(C) ** (-1 / 3) + D = J3 * trace(C) + λ1, λ2, λ3 = sqrt(J3 * eigvalsh(C + diag(array([0, 1e-4, -1e-4])))) + β = beta + δ = delta + γ = (1 - δ**2) * (D - 3) / (1 - δ**2 * (D - 3)) + Wc = Gc / 2 * (γ + log(1 - δ**2 * (D - 3))) + We = 2 * Ge / β**2 * (λ1**-β + λ2**-β + λ3**-β - 3) + return Wc + We diff --git a/src/felupe/constitution/jax/models/hyperelastic/_neo_hooke.py b/src/felupe/constitution/jax/models/hyperelastic/_neo_hooke.py new file mode 100644 index 00000000..b9bad55f --- /dev/null +++ b/src/felupe/constitution/jax/models/hyperelastic/_neo_hooke.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from functools import wraps + +from jax.numpy import trace +from jax.numpy.linalg import det + +from ....tensortrax.models.hyperelastic import neo_hooke as neo_hooke_docstring + + +@wraps(neo_hooke_docstring) +def neo_hooke(C, mu): + return mu / 2 * (det(C) ** (-1 / 3) * trace(C) - 3) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_storakers.py b/src/felupe/constitution/jax/models/hyperelastic/_storakers.py index ee8f9a82..1d905aff 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_storakers.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_storakers.py @@ -17,7 +17,7 @@ """ from functools import wraps -from jax.numpy import array, sqrt +from jax.numpy import array, diag, sqrt from jax.numpy import sum as asum from jax.numpy.linalg import eigvalsh @@ -26,11 +26,13 @@ @wraps(storakers_docstring) def storakers(C, mu, alpha, beta): - λ1, λ2, λ3 = sqrt(eigvalsh(C)) + λ1, λ2, λ3 = sqrt(eigvalsh(C + diag(array([0, -1e-4, 1e-4])))) J = λ1 * λ2 * λ3 μ = array(mu) α = array(alpha) β = array(beta) - return asum(2 * μ / α**2 * (λ1**α + λ2**α + λ3**α - 3 + (J ** (-α * β) - 1) / β)) + return asum( + 2 * μ / α**2 * (λ1**α + λ2**α + λ3**α - 3 + (J ** (-α * β) - 1) / β) + ) diff --git a/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py b/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py index f9304294..6e2cc52a 100644 --- a/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py +++ b/src/felupe/constitution/jax/models/hyperelastic/_van_der_waals.py @@ -17,8 +17,7 @@ """ from functools import wraps -from jax.lax import select -from jax.numpy import isclose, log, sqrt, trace +from jax.numpy import log, sqrt, trace from jax.numpy.linalg import det from ....tensortrax.models.hyperelastic import van_der_waals as van_der_waals_docstring @@ -30,7 +29,7 @@ def van_der_waals(C, mu, limit, a, beta): I1 = J3 * trace(C) I2 = (trace(C) ** 2 - J3**2 * trace(C @ C)) / 2 Im = (1 - beta) * I1 + beta * I2 - Im = select(isclose(Im, 3), Im + 1e-6, Im) + Im += 1e-4 eta = sqrt((Im - 3) / (limit**2 - 3)) return mu * ( -(limit**2 - 3) * (log(1 - eta) + eta) - 2 / 3 * a * ((Im - 3) / 2) ** (3 / 2) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py index 2735c551..3a9ad95d 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py @@ -23,6 +23,7 @@ from ._ogden import ogden from ._ogden_roxburgh import ogden_roxburgh from ._saint_venant_kirchhoff import saint_venant_kirchhoff +from ._saint_venant_kirchhoff_orthotropic import saint_venant_kirchhoff_orthotropic from ._storakers import storakers from ._third_order_deformation import third_order_deformation from ._van_der_waals import van_der_waals @@ -43,6 +44,7 @@ "ogden", "ogden_roxburgh", "saint_venant_kirchhoff", + "saint_venant_kirchhoff_orthotropic", "storakers", "third_order_deformation", "van_der_waals", @@ -63,6 +65,13 @@ ogden.kwargs = dict(mu=[0, 0], alpha=[2, -2]) ogden_roxburgh.kwargs = dict(r=100, m=1, beta=0, material=neo_hooke, mu=0) saint_venant_kirchhoff.kwargs = dict(mu=0.0, lmbda=0.0) +saint_venant_kirchhoff_orthotropic.kwargs = dict( + mu=[0.0, 0.0, 0.0], + lmbda=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + r1=[1.0, 0.0, 0.0], + r2=[0.0, 1.0, 0.0], + r3=[0.0, 0.0, 1.0], +) storakers.kwargs = dict(mu=[0], alpha=[2], beta=[1]) third_order_deformation.kwargs = dict(C10=0, C01=0, C11=0, C20=0, C30=0) van_der_waals.kwargs = dict(mu=0, beta=0, a=0, limit=100) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_extended_tube.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_extended_tube.py index d6a28e0a..8ac61fb7 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_extended_tube.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_extended_tube.py @@ -28,7 +28,7 @@ def extended_tube(C, Gc, delta, Ge, beta): Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. Gc : float Cross-link contribution to the initial shear modulus. @@ -82,14 +82,27 @@ def extended_tube(C, Gc, delta, Ge, beta): Examples -------- + First, choose the desired automatic differentiation backend + + .. pyvista-plot:: + :context: + + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. .. pyvista-plot:: :context: >>> import felupe as fem >>> - >>> umat = fem.Hyperelastic( - ... fem.extended_tube, Gc=0.1867, Ge=0.2169, beta=0.2, delta=0.09693 + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.extended_tube, + ... Gc=0.1867, + ... Ge=0.2169, + ... beta=0.2, + ... delta=0.09693, ... ) >>> ax = umat.plot(incompressible=True) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_neo_hooke.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_neo_hooke.py index 5d04be7e..2c9ccf70 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_neo_hooke.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_neo_hooke.py @@ -26,7 +26,7 @@ def neo_hooke(C, mu): Parameters ---------- - C : tensortrax.Tensor + C : tensortrax.Tensor or jax.Array Right Cauchy-Green deformation tensor. mu : float Shear modulus. @@ -42,13 +42,22 @@ def neo_hooke(C, mu): Examples -------- + First, choose the desired automatic differentiation backend + + .. pyvista-plot:: + :context: + + >>> # import felupe.constitution.jax as mat + >>> import felupe.constitution.tensortrax as mat + + and create the hyperelastic material. .. pyvista-plot:: :context: >>> import felupe as fem >>> - >>> umat = fem.Hyperelastic(fem.neo_hooke, mu=1.0) + >>> umat = mat.Hyperelastic(mat.models.hyperelastic.neo_hooke, mu=1.0) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py new file mode 100644 index 00000000..7249a310 --- /dev/null +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +""" +This file is part of FElupe. + +FElupe is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +FElupe is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with FElupe. If not, see . +""" +from numpy import array +from tensortrax.math import base, einsum +from tensortrax.math.special import from_triu_1d + + +def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): + r"""Strain energy function of the orthotropic hyperelastic + `Saint-Venant Kirchhoff `_ + material formulation. + + Parameters + ---------- + C : tensortrax.Tensor + Right Cauchy-Green deformation tensor. + mu : list of float + List of the three shear moduli. + lmbda : list of float + The six orthotropic moduli. + r1 : list of float + First normal vector of planes of symmetry. + r2 : list of float + Second normal vector of planes of symmetry. + r3 : list of float + Third normal vector of planes of symmetry. + + Notes + ----- + The strain energy function is given in Eq. :eq:`psi-svk-ortho` + + .. math:: + :label: psi-svk-ortho + + \psi = \sum_{i=1}^3 + \mu\_i \boldsymbol{E} : \boldsymbol{r}_i \otimes \boldsymbol{r}_i + + \sum_{i=1)^3 \sum_{j=1)^3 \frac{\lambda_{ij}}{2} + \left(\boldsymbol{E} : \boldsymbol{r}_i \otimes \boldsymbol{r}_i \right) + \left(\boldsymbol{E} : \boldsymbol{r}_j \otimes \boldsymbol{r}_j \right) + + Examples + -------- + .. warning:: + The orthotropic Saint-Venant Kirchhoff material formulation is unstable for + large strains. + + .. pyvista-plot:: + :context: + + >>> import felupe.constitution.tensortrax as mat + >>> import felupe as fem + >>> + >>> r = fem.math.rotation_matrix(30, axis=2) + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.saint_venant_kirchhoff_orthotropic, + ... mu=[1, 1, 1], + ... lmbda=[20, 20, 20, 20, 20, 20], + ... r1=r[:, 0], + ... r2=r[:, 1], + ... r3=r[:, 2], + ... ) + >>> ax = umat.plot(incompressible=False) + + .. pyvista-plot:: + :include-source: False + :context: + :force_static: + + >>> import pyvista as pv + >>> + >>> fig = ax.get_figure() + >>> chart = pv.ChartMPL(fig) + >>> chart.show() + + + """ + r = array([r1, r2, r3]) + + E = (C - base.eye(C)) / 2 + Err = einsum("ai...,ij...,aj...->a...", r, E, r) + + I1 = einsum("a...,b...->ab...", Err, Err) + I2 = einsum("ai...,ij...,aj...->a...", r, E @ E, r) + + μ = array(mu) + λ = from_triu_1d(array(lmbda)) + + return einsum("a,a...->...", μ, I2) + einsum("ab,ab...->...", λ, I1**2 / 2) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py index 118606ba..6fac588c 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_storakers.py @@ -116,7 +116,10 @@ def storakers(C, mu, alpha, beta): return tsum( [ - 2 * μ / α**2 * (tsum(λ2 ** (α / 2)) - 3 + (det(C) ** (-α * β / 2) - 1) / β) + 2 + * μ + / α**2 + * (tsum(λ2 ** (α / 2)) - 3 + (det(C) ** (-α * β / 2) - 1) / β) for μ, α, β in zip(mu, alpha, beta) ] ) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py index 03f4c0fc..1ad9875e 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_van_der_waals.py @@ -57,7 +57,13 @@ def van_der_waals(C, mu, limit, a, beta): >>> import felupe as fem >>> - >>> umat = mat.Hyperelastic(fem.van_der_waals, mu=1.0, beta=0.1, a=0.5, limit=5.0) + >>> umat = mat.Hyperelastic( + ... mat.models.hyperelastic.van_der_waals, + ... mu=1.0, + ... beta=0.1, + ... a=0.5, + ... limit=5.0 + ... ) >>> ax = umat.plot(incompressible=True) .. pyvista-plot:: @@ -82,7 +88,7 @@ def van_der_waals(C, mu, limit, a, beta): I1 = J3 * trace(C) I2 = (trace(C) ** 2 - J3**2 * trace(C @ C)) / 2 Im = (1 - beta) * I1 + beta * I2 - Im.x[np.isclose(Im.x, 3)] += 1e-8 + Im += 1e-4 eta = sqrt((Im - 3) / (limit**2 - 3)) return mu * ( -(limit**2 - 3) * (log(1 - eta) + eta) - 2 / 3 * a * ((Im - 3) / 2) ** (3 / 2) diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 1fdb9b0e..7f021187 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -342,6 +342,17 @@ def neo_hooke(C, mu=1): for model, kwargs, incompressible in [ (neo_hooke, {"mu": 1}, True), (fem.saint_venant_kirchhoff, {"mu": 1, "lmbda": 20.0}, False), + ( + fem.saint_venant_kirchhoff_orthotropic, + { + "mu": [1, 1, 1], + "lmbda": [20, 20, 20, 20, 20, 20], + "r1": np.eye(3)[:, 0], + "r2": np.eye(3)[:, 1], + "r3": np.eye(3)[:, 2], + }, + False, + ), (fem.neo_hooke, {"mu": 1}, True), (fem.mooney_rivlin, {"C10": 0.3, "C01": 0.8}, True), (fem.yeoh, {"C10": 0.5, "C20": -0.1, "C30": 0.02}, True), diff --git a/tests/test_constitution_jax.py b/tests/test_constitution_jax.py index 2f124057..483156ad 100644 --- a/tests/test_constitution_jax.py +++ b/tests/test_constitution_jax.py @@ -69,6 +69,7 @@ def test_hyperelastic_jax(): md.miehe_goektepe_lulei, md.storakers, md.van_der_waals, + md.extended_tube, md.blatz_ko, ]: umat = mat.Hyperelastic(W, **W.kwargs) diff --git a/tests/umat.png b/tests/umat.png new file mode 100644 index 0000000000000000000000000000000000000000..a2b9895b7cb87557a692224a453f8b8836599976 GIT binary patch literal 87999 zcmc$`1yt2}+XZ^maU7Fz6q8axMFffyLa7M>#lpRYvz3!g#Y>F^X$E!{rvA=ICpmanjLE>6v}#8nNt@j zls{4^locF*{fX}gehXfX{}Z!6tzoZhZDjAHZ+n%ZsBeGG!rI=#^a_XLRa-k#Yb!xM zQNBY5IZW*Bui1(7^IQJ+5Aa#r8uJUMW+vbvtFOsivZGMg-jRQoSyekoQI=6CvZs!# zTn`y+bJF(jUMwA*)_-_!|AVzod_vRhVmrM*KcAnCUoXge_R{l9-WIW!G=n^Z6>F^n zMRYC&=AJ$G{*u+{<9~16FEG-3B&iZWHrgbWmYS@lPELGJKC*7iI4 ze_;UlQx+AHXtneuMP}`?ElXe83NJsn^i`MH9~w(vmC^pfGLS#M2^%kCp!ma~zUK{D z4hrR1@)@s{jIX@3A5+#czM|yr_<#JsG=zJC4Z&#w_`*()ezrDWh@2fBAQ9X9xA z__GoJ+vtPevdo%TB^vber%B;hIgejtv|@1ole28H4%+1-)RwlRl9H-<_NER$tB-en zd|Vr+9Ai6n(nf|`y0~xsbkV}Bd2UWlqfdffanYA>>2Tip!kM1n0~aIjUAb~)Q12{- zqH%*P!!c)LVbwE=q2jcKQ9~i2g=~D>?OV4@Ci`hSgw3ACtHiyYZg=G$S2Vi0Y2UfV zMJXPY*vk$QmyEuIi1oMSXaDohKb*3PK|)`{Js0Axe0XrRVqoU?ZJ=3V>#FK1s=fUexM zjcUBg*9_BIEBYK(uP)!onr;^2BQ+~?UV1*mj27>od&fqL-E%Hg*L6sk-Z?eYV%}F1 zH8wHvd8%P*a*}4?BN>3^9f9K6`2AaEa$go%fZ-v z;cfyIJ$&lPACjmu$0xz zJn0(B?x=6EF1GY+jX29RKT&&r?ANcduTq*BCa-FuprPkYiHh&T-aTH_m2M0Qg%<3Y^yevA~$Co+gQU-e*JZE zPkXAusqf#vUpL9RapNl==>-i|2}hNtw5#3UzwcsaXJ7fpA3w3mHQuZe!=h))dCIt~ z>sVP?lf>+LVwGdg9l%1gwzlHhY~Hr*ML$b|I<@{Ge^G3Zuz9@6*VndAPU=`|TCSb3 zVz7wf*RNl<&*s$F&Wv5<)y}yvPoGwQx>r#pQR8rKZtka+7A=1sbv3GPVaD~*AM4!t zuyp4or(5mvaCEynJNIney4BgmrM#mn^c#YK8g^pugpIUS;9lqp}{O(0FuLSkpY_mDFZ+^NXTiRpn z)4t5>qgOE9sDa-}TG{!RXEBc9^H;@!!Iegf;tw7^ti>z@ zCsGj-O_3bLVzHKYI8XW=#t7E2O1Mmz&{Hj&Gjh9Ua7>%SN3b$^Jq2zvY2W+$Or@=a})Ft}i z#hEHkD+#{t>G@*myPvYG+RUyyJ4X$SE5ACi(x4$(C+>@&({Ss$`OxU8QRA-X?Nzj) z$f-&H7cWc-CTirPduOMH%sDwZBhA0W#_sRDzb`DuU?fV;U%+FgJHUQ=7CY7A_z69ls{!v`P9a3&NuOlKdT_(*!MQu(nA5f7Qe{p;5)_!CKzeuCXAZ`v0 zj>=JY`V`HNOCFb^F2}|IH)#Lfy=Q`tSZ7h+;9@;&&bFpv2XWr%S$6AL#Z|&RX5;2< zQm=fdOS~lLfAG@92C81ea9e(+b%)gUJFobQ=Pnvoh0z``^K^ARn_Av~@7`Z+o{RJ1 z*o&h_kJhDKmG|e@(^XPZYR+>=Fdak$r4_lmBK*t9XU<)eE06%=1rUS$c{}K1;7xehB8x=gBMm?(Yt@PYg2QEk`h zVMT}A&$6?#-R;I_#(Q}L1TOj^I*+JO2i2k#0`q5I6wgm-O%Atd+1S`jY0~0VRjIm? z%zWA!>dD$)7v|}io{Jt_d-wLwP7XLtihpt(X-^vOt&*2(_ANYh|DV7heqnX0E?JgA zAFWI?|F{`G-GW$bsjOdkc(_@8BDbffC-Xs#3pf(BPxhS6uxt_eP+B_h{{AMj+UUoQ zL(NgH!?~qG=O6D7#<}3<#sKmB08X;6g|5@*#wT|ku?iV}JiL`(H}Ti6YqA1KKg!qK zzkk2Kqqx|pD$J5v`1{AhASrj3Jlz4TkXb`=DDH+4)t^sC6CuhkARxe-MeH?l*nwTU zj_=yFtG_-ecnhC)>{)jA32(cYISJi-$D|*fo!vj)wXCKb+mI@Ld%(15*nXvoqHnevQ<#UO9z0%B=|LZHA@Dw4L0L(#MFod~BV{YHOA`0UWv*N?VY zy?XUj!+qRSv$|M)>ERoz*bZUvwiT@b{CXmPuG@B5Gt&mKT!k)E^&k?deg|&)E1TcH zzPEUIAUhb@54Sc+HP}^22K48=d2@`ujh~+?r2dpe(xvYDNa6G&{7SpSh?CvtWS#tV zOiWDl9GA)d?ONGZiVhYsGWSNmo@H;F8WAg$TAZ_^4@?d=3F?#@8m_Dl6f}N>=Qo!I z@M_iHd+;D{==VhO8<&Bk>_^z7cE>Qg-Y?rpNEo!kg;~flP)<(f(JOL8SUU4LNVr0Z znx3AH%k@B^GT>+cXD4#pA#!e&Eq_+O+8)H;Jspo9IDEDInUJb=lWn}4oXSo||; z+Pp|5?&4JELSfJ*ir3&N0M9Zd?v64Mv%0eDfF3pO^4mq)hSyIaS`QlFCI$3xA31*f z_*5#eq}=5C>*W-AKc$q*Z&gl)8KxUoW%*<_S;To4+IBzq-q~ru^ucPY5vRnpZ(fp= z(aA~SWZgoSiWi>Y3w4O%5@A*o!}%l4rPDvZc6xUz-?@o+dEVi3+pS~Sn|AIruS?cx z@in}D{ra}8eA+oz70PSRob_f2jBBV!rX-wxxMk|_`kf*|yZ7u7q#3(RjC4qsga&=R(nGGzWzWpx-|4OMx%2*R8 zJ=676p(=2UE^_td!B5)`UpaNBN8GmS-uJF9Lun7Bj%-%f@9$PdoVdMaDz)n9xI&(8 zgigNWltE8raKNhtK>u|>ZpXakX3mHRW@o6~i)^L$HRyR34(04Rd8e^-a-e~qc6f0^ zO1pD!sD#HOZgr6YK-}!3(%6x8)MT0MGIPI5n6i&9j!*_1t^1!M;qUP9@VLWS($*%a zI)YXS?f&qJx6kpBi`cx8anhR0TAb$040|EX+OQRu-7lY}$C)vMrCc z*<``hCv&hSPI(`F;LD4{dvMU~nf5z5IdvlTANld)$FQiA+A58QTX@r|rkjkzqr~?n ztVrB*)_Yq~QPGqbF!GE-mFc#RmeR#ef{Vyk`qD*KZFy&a$%8tTJ=ogX+N|@_1frht zeEaxl`_u1i%P2WoAsHJe*F@)MCu@C z(D+be>PcK>zeqsbimIv+Z%L$ROCOSoKmyoW`sV`>R_0@1;EmY~#BkHG4 z-Fp4{wSqd^QTw01^B$KkzXbX=6ECu8N}Hl1BB~dA%y;$m1;&M?)liEU%!)gT-02d- zsn1ovgi06}d*&CG2=E}qVS$j0Dui68ENIAN6+J}&@kr0{xTgn@5uQAGA}1r0BJJ7p zc{_c+MMqVThl~hQQpFHB|q7FS*kv)q{1(=oo3q9$}sS-2XM= z?t?A7@oTs8k*unfW$_hz7T$CC!vp5@4yN_%6`iap6vHjR*>40Q&id59IBZZO>GAo+ z;T;l=gRG?_-B=gRL?`PNCv(X^-@kkJkLO25r5ESY=PQ2}PPZp~e7v*6rXAs;EluCv z4CutDn0?!}{UwJKtU0qSnywT}o7W$7pQNcfg$Rm@HhL^h^wpYrTUNh(%i1g7bn@D@ z6kXs53AR04E6@3X-~4;?=7{*4H5)e62U{1#fgrROy`qP5TFZsi++>o9{deWs{(f2l z$*=M1)a2eU*K5;wF=15-k$vUp`l2`yF zmF5)vn|l?5B457bAUg^)S&L!UOlAf=$10iB#VSRwpB&-Lq&`d}RAyh;^%JX@*q%MJ zf8vD@emprj`O<>sNWr)_c?b|M*%J`DdOSoW-*HHS&3xM(?$74!1v9KZHVzJ|IC(?I z2N1=Fw_T2!bCH{I_>*$XkuY@8klm*r{6rw9EiOz;>1Kqy|~Bg^=Hn+pE^zhG<7|ib@BXO*|E{luQ=cUIbSWDlW_0i5Ni9|3-fXD?GXeCi6?xk zv%jz+fIm3d_EM4CjD4X|IZtNvzIC6=srx7tf!#v`*H%z`&ldiAw|0uoU2;H{06B;Z zOtP}pWx#@c_LYI{{s&jC-6AA;Zst$=Sa(HV&>r5=(NR+=y_d&sNPKy+$vtu}Heb?p zD&wyDhlg7mKopYz(|_VH=DAG9gOXn59IB1Wwd-y6QFJ!bmpd;t6A5e*%_iyc;@wk# zq$J%!O$7go0Bv141$1FI|kk8^wFFWt0 zw65e{SFG3Ichy%XZcmi+P=6wt(^3seH#0Lw-MaM$z2S7ZvYqv`!xLs8;wbP51;4Jr z!9)x*0U5t(%Ehk^e9(Qm&1s6-4OoT9q)Vt?P$|G>Alo9n<5i2S7@ws6<#KAwL=hOz zC8BYB^VQ5WyXqN{i$I1*QMu6Cnrk;??ZWQd^~9bUo#Qy9nfGy?o)Lsh)HJe4U*CaH zH)vg6>ncA~m;6YssT4R?u=S??HZy24cl4(3vU^mIc9wFKLclB|L_JT{`0MDOoo*=h0+->Z>xYKYV&};nVxBuGO=FJ$G zJ5uxf{HCb#&SpbMSan!a2obVi7YP83`?m%}KIJ-b@+1NG!0v-trE?M-iX(mQ+@-jN zg`rqV`usCJV}!pWNV#4m{SDOcd5^IJiJsJc*^$1RHKEgCa+V?a`T2c{uY7!bTHD%& ze3F{~$OW2yKH)3yZJW3~xi9`bzn|_qZ)D;D{*U=9LNTgCHg{NYD_>LA+&22cy7?zgGV*~*{jEyB_$;e6F-|WaHV#16gb;?51Bu;9Z7NpF7@sN+X|0s7@wL_LtdNg4fkv= z-U6-7dR9WtF@`6r?J@9O^GHm=32jID+&O`Lobo=lY z!B)mk-2Uff>Bom+AiT*F%;$M<-?@+r2%`$&R6~*A%8V+lu?JZh?@LR~=~F{f1pX9v z9{v>EB!4kf++kRhjpCJf0!Z_k2A~E>@SL)Q4Iv>KH!}?Yi&Xv!ZbfJ?G*K{Hb}4{Q zXK>p1^9%h?(Pg}v8NS%m$Vh)yV7rPZ4T{^Zwe~&xj8Gobu5Ekl*j zxVWl|X9JtKy^NnqlBO`@5-ZOn{`xFfWdf)(RSFcUgo!b4+2UByhzQv<;z@GlTsBuX zO+)hNQ3dr2ii#Q-#9EN~tleD$!>s1_W(iMQO#<}kc>mey5h|2PaAx4Z z{_0mZCEet}%BAV01?CNW$le24cDi}?vL$z!vZaS<2?1-i@`V_&bMyaOon@&de^Zij zY~dt1Ats1|s{RL5Ic0C$xG{C4h3V)oFS!7|&{w%osr^*rC zV26lB>_`!PI7{6@!gHa3M0U{ffe0U|yo829M5y@%bv^eegv#H~j}2p?h_;CRcPLE= zDO{KxFl)=pBvK`QvtJ`k)}a?;)bwg@O8{ zNo1BNaS=kY8km&Q_$wxZeYIPG-;{5WQMm*HV zB`2y+PSJdkhiT^2LdS{*XA_fHm#M)xh=Y*>{Z7Nf!&4*kIXR-P*WD!u@D{dg7LxUQ z`0!!T;({xEH1{p?gs}d*Kj@v<{dg=-G?fl^7re0E1p?6|Y62Z&lA&{w&sjb~v^595 zavI##-Jn$NA4#Ef{o!G`oO10trYD#rXR^b?yy zKn|i0goeVYW^Dp+mZ#629rzq5NRE!_hcA(`PgMX?w0imx-%(!RmIbEIBiRz?rJ}aBR?6s&*Rpt& z5AI0y;9KUT0@0F9g$k1CI&DQ32TG7K(UOo12o{APUXAqd?8S>%Fh;|l!WYLq7pFag zq&9OxPd*w;&)U2$ZXq<$Z}Skr3&c{dNxTp>7g zpJ#aVy1NHd<0A=nmIgIt)r&yRyfilL&xR|jj$M_sXa-;%E?)G22vqKodQbN0Uei)< z*5)Gjd`xo^e9nCC_o!J@T2w(nf&Ii!r6j%Lb~cv$oE#IZhEuC=+o5&zxL_bJm$}i> z^pO>)90>oPD8I7PHsF1Cf`fzS8!tx5ZHJ!LC+>()65T*#;IC2gTU~iGwQz|Z`TF|W zR~DOm-5p`yS7Z7mV5}a|t`iGj>R}}?>-_lMy+drSgNI9u(xVbqA^(%9$9+*n&48Xm zBwO*lLPB-1dc__=)Qx}teR;5>xZ{O{Q*vQ_%=vJw9&$ly=W|h9@;z)`pC}}~75gY> z=M89T_`6dv3&Lpxs8wITLs!`o(=YyP0JT#KsH>QqI&&skOsc!#!WpY&%a(lvRILe- z_>aO1WyH+BzmB`I0ovpd5v$hg71P~A+IjY$VxgG?+3l5|aSD8*b!LHAPEk`&FMGUR z%R1289Lu{A{K8X8K%nM2)^ViKHSS{6BR!89E*)yFP3IZ94RT#UFcUMyOW`|eJzga| zx&=89`b|AsF`fMO{12!};Cj)ZzfV@5WQqeLwzac+3V9KE{w2`0*?3RoflFzIc|ET9 z1c$-K!+f?9j#TOci2M`9j4o7_1z&pA?YlSLK8*1;i@>f+k%ub$yC z?*jJh8t5TuY;3%Khmee){bau?syv5k?ecPRViEu1b@H=_fR7m|KqiCCs1)5hH8DX% zXmU>pdjjaeLshW^D8sFFN4aFpnl))7+|Stn=IfzrkieX2)ustHaU`jzJfYol(H$Y_ z^TKt+Od_w&XUOyO^8*aY0BzR;Y^p?@Sx=&xm6g>2oxBW?tw_R25adL3OgMN6NCOh` zWJ6))gVDAv+OvOAyjaNK$?7BEqOLOwPx=xdA15)ASN?KS>d9#KAe2uo#Q zP^-%esMX-PFdn|HvXqUK?Y$<4hyPJP^1Dc4bxgR2i~M|QDO<(0>!eoC;lx3}-9a2^ z)g(<-XoQdcT))E*pMXEZ|HS;gRNCiIH`wGvzJ=%f|KbKH!{9|<_SMD^n5{b0oZ0>3 z$L`?D=vOE2YPRj5P~NcSYP6BzrFCdo7e+xn(r80aexswm5=Gr(QWsFhpZxjtBq;)W z(1(sd!mjOqj-Ri2%uH5k<_*}nqEGQm&(4S9FgBEllG8wuA+BNGR2+lC~VcLfoe-IIh4y+t}#J2BIE)>#%>~c<1RiS=nMtUSeYlg zXXzuw!Z=^{XTlLCJ=?DHOFR$=(U%HVcSvvsYl^|xW5r9H|F6IIE*oJWRoL8k=ez; zaSXNcCr_1YPBqx8Y_sb2>I!HiHZiM_ds2{M~*^e;I-ZEbDHTb85}cGicj z(od>6%aW($P?{kh4s?MxIr@}~vA`+ulL*i;GX>ZbPVNH-4!G`Efz4yMJt!A{Pxr@z z*YWC9rJG^RIRI4*&-U-~v1BVYQ z`4MEaUC_v6VQyxN6AU-LM;IG#xXIeungnIPNZj@Wjnpe-n^D(`3()hp1QFZWdvXjk z8dd8nQ!UvY9z3#;mW|>a@NuoT7-QN=EGwERmv8J4GIPUmdkk0AtTc=xRKTY5qgpmj zD}L@S(b8}|FSY%dw(NgIu$5cVR3KyyO=sip0mUvguJ;wj`oMUhqs)8g&;=y8dZ9n? zh&OzkobNsMUMQcAyms&pjk1f}(*=N)&*tXmc?bV2+X0%AT?aZ>>FJH1KE_uf_1XKO z@?VUP|NqJw^_;pq@!?kfc!)qGxp}imnk_|bT-Cd7n=b3*TsuD0lHGtpwOw=VL{GrTCR3AgRgtA-X~1Sq%dN`7=hj%anpOse_KSa^=dv{{Q}+nK%%)NxJhkTfWwtxl3FO!7k1AOI}ob!V4=BN4r=(0uU|T~ z-@LUGtvDob4^2_@H1#$`ZI_7jCs~(9z!AaXLc%`zGbZ)Fv9XoWzMKhFJ!OB3W{JOE z%eea-4RS*NOxAzQp7`Z=H}gm18kpl8QkHM=>c$JM9Hofqb5`}`Uw%gdi(xART7rL(s7tb~*R zZEnqPQ;ib+rAMFf@|VAL`?e_z9>hn+cKzEj;;~uEG+4mOUvBV}sKE8rH8R4F3fc^v zo`7(wnQMEs{s=OM?`hZuT(vrs4J{($q~e?QGu!eQDyd`MX1Ir5oItW=e$LRVCsDd4 z>?e8_1z&qqh=}pVWnrdQ*se!GOzer?azv%>>`ld{m3_j|%{Q6ZRf5wj5B4M8b^Xb? zE%!pMZ8xc$=8HRmTTJ~TxkWSQ+ADHVfgQ)QK=#)coT?unx=!x@Lm zend>sV*#9B+~&tA$83a7-)PyEecVUITUB%T5%P2$vE+ZSAARe%1hhX76UndvJl|NKjg)qgzJ#-`zYfRxrcIy$5)Q(+Ix z?2vY!ozN*hXLjPm2>~H?Ot(1sgHCN@WsmzYNu8s@d3`45Sn*IY(A}VW9vu}GJe8@? zNi#Zp9y})uok(({GgxG6LQG$dPQJ(!Biq zmXWh(&l+o;$1i24kGG!VJ(^LiVy^M}6}do6uhvJ*8XMk0arTfF5fQ0OJ$(4^ z6n*8I&1KaCkX=iBeg6jN5gxGA&!V4G>g z##*vRk?y_IeF-b{0?jfX(&}r4!?GAVu$An9mluUTfAa2zC^3=laY#>PStLha zd?0_XRwB4v>Gcy6YOZ*0f7_Ok@}^Hs@4g`7Se^Ci<{*fP;WdPw6429#6E5#p{){_f z4f6p*Cv!Z)FOq-C#=yJBd+C z?*^^V)v3uMi)8>;txL~S@3)rTAMX0`s{EQdRdp^ONlZGXd%~;x7?jfk#=Vi<)39S) zw71Xbn*jh}Fw3qVKVAcr_t-zgtzmy~{!v40WyEId_bujMM2rht=5#O_&BpCGB|JH6 z^!ZXj^}%lKWar^R8k+V&DFU1<@Zur3{l8x0Ul3GFN#{kRhXRT}bL z{OV16O)v|;Nb)nFy`P>FbjcA#o$`!Yv2m3`rm?wX!j7WB532!sNehQADNar~2VZF2!rCA;YD>bIg| zVy1|lnyFWALj+C6o>jo72*FzoW1pWonS~QK%&d0O_22|9%;$ku``lNmj55b5yPIURNKJFC|QyE1VOKZRdC> zj$q?_sc3ZyDVu(Kv&>b-pGEWb-Mhgbx8K0@u=K&9C;!kOvhUChQgnh&ZtAk&s6Lq9WI-frqU*$~Cd8vML5_g7Hp`D% z4A-~w1oe(tjkj#H=IW|{Tr%G#F!CeIjgy?hh;Pp-jpT)6ffp|T^CPhG!vCNQwxR+f z9pXNlY>i;m(FhoDkH%;rT3!={DqEN|!hL|RT!p>OBBP+SfDvg$m)`|ya&~r(gK_`? zCuNly1pe|-o;4Ul*I6EKYIWW>hiJ|0^0vD2Vt*2cC}+R_z3e$M0}ArdDC6|c&5V{f0nQ9BKKX)?8&!W#ubZUIRY8#Il*b zzqc_D9w!O04BhDI_d?Gr=R|)MC!DLLrqyty~@J#td8W z{Z0GgQG1w$-I+oU)<&-Q-#q>jBqjP5tS2E(xEsme&5s$(0(P*xY^{CpaD@ z8DHETz{-jK1Zq4=#V|@gp$%agqJNYe60)igJ+19?h}K~;apwW^ej^41*@%OL^AQ-p0J zg(na$KcYer9_<2+pGy|i3z%GBuz4s>m|{MTPJcvbJ{7dSde=dN$T5Lev3V-0&d) zI2Y*)Ksbp2o4bT_r;2Uxm>WGyJo%*Jzk%(j31ba&o8O&WJE>l#7p)l}r&E{ec9wA& zy!kq?hA`$vW8VqN7@M3V&p@F^0-B!|WcEd42UiRtwG`zL{n(2GMyo38 z7w*kRH!IV^FQ(U2E@8l}cnHk05YGCF7w4&LER%Vfvmf;wsdFHtE6n^z?c z0BEGjfdW_SU?C^mx=)Ih0`pZ<>tPJ7-9~aD?~Db@t3UR<)wRnK8z@m@kN1*awpIe? zVCFUg4?=SNTKnlC=ZBE3d}^9*a2d zM6?>6CFnBT3VTv$s^eL|%?>8to zxqmEEI{>bpL_BMriwkPmBxOVZb~jcUFo3=kfIb6mg86V1+ufriz;i)3H6&~EV)&kQ z&YhdPLnO969#UiJ^?y=@Y0UxV)MWoW&02ihi-q$I;6Vc*B5|L)R${uyFG9C99s28( z;IiT+ESF=Nbgv~jfNcB+6&;r9VXQn=i6VVRoQgU#Hpi8lupqwvBlkgXBjnpPx{p#q?QAG|w9 zW~i%uBBZ_f_wyhBbPfs!Tewg^xQ^M5r=!Ni>2)VfM+7OEb;zKCwutd>VP^N6Jg90!LM8!+WJh9;Y*N=EZ9A9> zah#FM1+`YAi4SonD}RfV;+`YkDhwnqn)?%Rr@XDHjUai7Rd>p=dLUooKOoQZoEyE1 zCI+sybxE+&G0Ix7>i4(irlVe(WU&>;=&XC%_@>YYN3X`OPZYdBd#J`>b6zcWv6KNc zg^+c~1aY)%N;`f3zHG6Q!iFR?0wtnlApwsv`}+EJNJvN`dDNSKg1=bQye{5KXh}o8 zU}jh<30+ZM$U1fQT8;QN@)!&9Tqa#Dcs%eI@OPeCx-Z5MBE}}#+Q-A%PxB@3< zMzYHhyeoc}>;TF)W;K!bi4qDMK!O%7YniYbn_is%KD8h-Ub*b*P8!?NlqYQNF>BOR z*8ZuUq#1<-+cbb$+kftD0`g`&damLxrAGrN_M9YIZiJnBRUe>Tpjo?BJK%L9uoXjv ziS#)cDN2kZDBhz=lnJy9?+RROsAQp_C5~pGFS>T9eW9v8ctg!L2OUoa$EUFjO*m{I zkDBUNs4x1hkGN}bt$EHs!d??3kRaYn(Sauc0a90Ke#(X&zNz#*yq8sBk|>@DRCbPx zP{~lCfb0-7QaG1MWSOKbY?`r(#zz9pm{hJGV^VQ@L-ILA;G+>|xNGk>7<--MV;z3~ z(nkYEyFk5BIyXS}zkK6G-@aWYRR}-(*$GpKJzA|BeVt)-85XTf^Vg5@>$nzSOwoeI(3CWolPO}t(73k#*VL}Uw0IFCD$1J2X9G zg-NzGT+ZmxySe)Qny)`ABNQ{2^Q{z0ojjE*28DtUi#CQBca3B8{wNXZ9z1$1MC&jc zdwyVZ@?}M3EMg#O6`*`OX0)=hCOJhXx_JdN`-SQ9wx#<$&Jf&K-g{TG25lFrRpIGW zJu@QYeir7i*U4lHe2Db^W|=k)|B)jFai{itC0N4z#K7tUU20{FJH7NX96o~UPDUK@ zsn0d-acc3!zq`1Af@c(-JO{K$G)7*>*Jv zMZ3n51PExRur}E`7CFxzgJKN0d<5B40lo?H8Kh4%H>c|%KX#GjW504j=FgGS(VDc~ zs*`3V>Px#w7j-img)x|z&%~X_4DWbXBrH=aFHAb~Xq)~TsvpW{$ACw^V)l`65Re`! z(#B{<0-NvZSL!E)UB*q6D@&SAvS%*H5JJyLt?n%1Z+3{;Mt<~R_bjEU`JsobMwl=A z;p4}d9aNRL8p~2u03wP#gQqocwtr^ z9+g*-k+nT!MF=pI)mMde6M!$%wp$K(K=F=#EbtpFGfF`H{z=AiXu%tt_JIef#RkyX z|Jg)tEXo*J(^!hMkAsEjnVqd0l#`Ta&bdUE?_uOR-+301H$jID(8&wrN+bwSPhNF( zb^17N8|ob-wRkMd7`x+SH0Rhvz!gM z{^HJMm}8cNMYhpkpnkkRpN3{cuuo6?JKT*|VuRebh?y2B z0ow}O|EwOg7TAdfLIo5MFOa5E)7rhzzGQ$VR1pK1;Z{Z>=z|?d4X2i*d6?Hk0d7~V zikWefk&!WK##(0Ea7{gE*I2ys&!gbt5Zg2{Q@4T9F~`mTC5$6g%)-l`B@%6WwYqk; zdAZ*X;tXf(miI$#eDNpo7o*ZYW&w@~FKR7f>LiN048v1xj8EST@;9lB5_JfvS5U|a zb%^vdRUD8Fcl1pLds5frnk}6E>LtEHrHUHH$Rb@VcO`Eh;^RB#*9FKDuTnWZ^u8pfBzEbNg^@9VG05@uF*%XlA4DK)OO&ohX;;OEeU=%(g77OJ^Fr= zz`B#L4Mh=#hNfj=+#n2X3%~9`)TmamU4QdBS#aM>r(YzbqxQ6ERRQ$Yk@6IyGz+n@ zTje2O)e4ku5{vm4EaN4WhE`|tH?%XBJ@GpL8nDbkSR^nvpEy+KcO1TQi<#FL*u9rD9mvAMZ)*Ls`Q`Byuzx4ikyv` zT56UwB$^^OzBz%VCCU_89}<{;|Gw_pR$EK{TM5lhm~kIw&WqN7=AuAX-OeAjVQDbBXB!?u!9@ zAiPwSeQN0n#2$+KL~aYpb#pf{efZwka30SBfL;g_FdL09!9%E2swArqK@e z4h$rGFS%=u7EuNv9=<%<@i24jy_|AVn4aV$wXI_*>TJE+_Fj^c^Aucj7vY{^&cr2o*FQsfhGNkroTISVcQ4;LZXXz=s-mQiqge29Y+`Ye^{B+_#CIb>(eWHl@}q z@~XPl(^(^h)j)m7dP-F0bE`*3{>^@iye2W~b5n@!I5n_ruMyOcp) zkw+kR^2_4ND@-3o!|iiUg!ZfQr2OQUA!(l}W=aIPZ!GHf`|E{83l0qBbXEQK*yyMrO$NRkCP5Oe zBQ9BDk3`g~Vc7{h*M2qGSWq^7sQ9zka;*fc-Jv{!7L=B@SIG|nS)rU?tk!HZBt znr+S>9lf=#gtTZ+e%xu@cz)xvNVJ=n00PdUGg$=<3*?M43&)iC4sfV~F~Dj*jU8tANe%`k;cZy{&5!JZ-Et^2mRJ1nZl>l9?& z4#kT}rbh{v`KdPz#nT+IkHl$24$hK87Yjj<%#rwJ7w99asR$U)A1L0Vr8tx*AZ``b z{}O&j5{|uXYTk{IYP0~Lz;>QE=%5vBMhyt=Dk5Qmx5X2~El&nc!*Kokp-m1PKfL1V zb59r(_{-q7Wv&E-!JWw&2kDz|B2K)E;25m5YFW6rV^6wEpPPT}c&L!Mrk$BYDi3E; zwOzKsb&WphdO`oj&#q5T8TWMTRYZVye;e;ekQponvynsl4*b-tW^j|Sy|`lNM>r@O ze=+L8hfs`uu1B*~xG--@^>pdk;QkRI*R!e*ex;)tcI*sJwQA~>)3P;KN8VxF(5`*J zHJ_g!7I&O^5!VhEf<66qNe!GrNSi(Ms$GN4l=Xd&Lul>I2)YTiBSAFVn0nkEbd zZE31>Om&BV;l1(zek!p&A@`H_?@-2W%=b>4znfYet+}h=#B5~cK3gZpY(`EmsM23? z5Q&FW8%Xd)YNBq{y-u3-XfOvL@i8g|tL(&j(sXs`@lb>mCT)02;}V@NF;L01b#N>A z>HrQ6O|LJh4iU2xg1y9^)f_KAVP_B5Ny2znJvHGp>-zYFQD1J)Hqv8cctYt|?jk5G z>R$a2kNx)5DQcaLs$WSJr1jHj4c}&OG8o01RD>O2NRJ6x_>Gx2Q`JL3d9LwsYIPB@ zd$Yp!tM5}^8VSro_yH&GIn5khz3DteBG<~j!Fw~pUjDOEUW1f9y$oy`6egzZi)}`dgCibMbUM3v@|7)t{RB+&XtWtz+ECHDTf1Lf({Qbv` z(LoQNKHQrb7`dD6^b%A^6?5}KQ_%n5P7Fr9xFz`SgogUU=(0u`<@wAz)VOn_;*5~| z?f3s4EkZWv(%Y1MzK#?FG-Jj>CsZb57{ve%&ufi}JK(YACk{rxNZh9b@LnNb`aRpM z#>L6GAKl2rw}RK4+8<27S8woK+|Kv?sp+?Z9<)Qm+3mBLsOa#TRXTD2=abbm3H+W=!F+*2xOgGHB1*a}u;t%7fm zpx0j#Je7LCNAFr;+k~Ym??u|u)!d3_z#hRV3nrV<5E5eLkpn)P%>pVicNX^!ElAl% zNmLKdc`r&bUvF}#Ak9^EBx-ote(9RbmFllZ?D8tFs;bf*AIr;qFMagr+;an1(zs;N z*!8Jr7}r|&kWI^}p*1a6s<&wea~;VL}D?>sAML@(^YTP~xJwL(8eemFCk9Yw}=|&uQV-MFe$G;zsb{X+%A9P&_r{4!s1_9Ll zzlYR=_#LsQh?^4&dLteG=n8YwPEm!fe_$L64p|bmLW%#}tnfdOXkmeFJ=9UG2d5(m z;;1MDl#sL4dIj)ovhzE;Vy1xZRiU^^&RkKk2_M+HDY?2u3#N%kEHFz1F+6P#hmK|| zcV<66LPJ@;I%eAa06P=Ac@R*CS7=Gt2_nR?LFAb1Z&qiveviD6bzPnIVC*3uexTKh z2wYuS4V_f;vY=gg*XI9?ThLDGwfDSDX9Oq8BI6}*V_c+eJ0Qw>PxNwp_Ws%vH~ZJ8 zk#J6lyu)~cydL|Uro0cIFs+>VK+Ni-y=8E(Fy_7VwlLq3Ih6nR4!tmpch0-sUrU!# zMFE)+QM_6h0@+M?V632vWt+L&p??%6nKa#Bx;|(%U}#cHZ>cLg^13rZxT|Vc-e$W` zD(n}Gy-=00W~h8Qdx-1LmmgsHYw($Yk%yka{itQo9y;hUh$JO)6%i84w)PB#$1s#- z=C$f|cX_3sJ$=l6AG5F(^w31w+F)H9s2G%H{vfWWyFaRGn698}rCTqAtnFoQ2W0RW zbVDWUvsSWpu0clblT@CsG8qjPX{Hbc<1gg=>+l#6pQCNejU?R<2g7Tj z*+Q(Y=*5%72FzMjN!)mniW2fmmz#CX#hDC2fg=LH0ANhx#ph}7|0+{g_IQs&SItJ{ zLW3D^mxcD;r7dyVQ?*J1(M@rD1~neiyGr^r&^tn2aYS5ket7?jm}N(i4%D4|yh4L? zx~*psJ+!YGK%;5!;YU<*6+m2B?br0$TE0k#x(Sgzo}9bwmxF*?$}{GWc45T6(IHR3FJ+r$Ah0O6fV zDp?knz%%9G`XjFeNQ4sVbl5P%^}Z6mJO!* zc8fmleWW1m(i`f;$>pw1>eLuMX`(xQ>J;%Xk^aN3uCA1azkn|kPF(r7z4cf0Ic+ih zcNT>AXk}6kj@d{PsZm+`*KT6nplkM@42D3(PPDm@4r>L6WW{6E5+|HkKeKPCbHi}ktzwQ$5d6WDzkYGULX`^758YGY?bC7pWdNcWG9ydC=fsDg z2REnLkN5YTSftUzL|!Tf%~8^2qU^?o^itwdhtFQ#ul;)G`rI7R!QB`Sr!4UuuJUxh z9G{Cy+0(4>*bH^krG-_qZM5&KJkn8zjI(*ij(FHXOz>hfq6NVH$|)@^4T6tK#krPj z>jv^Ocrl19+P@;n2bc#}-9k4GUiyLeevyv5d64i2_wM;psZ=BdGgVj2D$XFlyDu}7 z%KcX65Uo^%J>d@5P6nf*qy+&Z;=YoGcJh7%q!=DpsUTD54_z-g1bZ!&_#*HVVhtu+ zTJWYX&Nzrf=!+KYxixIz0XOH0q2NFr^FIh(UmUU&*mC5oTb^E>j zkK)>4JSo&3x%!{aPlX3sqwUnWdw9hi)KNxF43=^~(xFBS_-55FZ=AF+@)-Sbn%;K< zjW47wie}3w;;ALR3|!R=_-2SACpG{qJLZo7vd- zuzSk9|4r&RJW)Hbwse!P@Zmi|GoPui37Gc$6g`B%BKTjlu>G!h8p=%FtGJ6zxjsQB z1Ax4Uu%OV1LKU*J;80Wg*^4!%ckx~U*#`5!FYl5@8@p{lpsSIY<~JebB*V9UvpsLE zRa&2p$RkPbT%L%;KK-WL2jf=ofmSo4^$t<#!b>k=AfoRbfe0t(-F zO>mZMA0N1{XT6$w6kgY)HX%YADXY%FBuSi@F0BYBE#8Q|h3IJk9ihTH6hjx5Nn1uy zTfK&3K;9yN8F9 zfsuHCll>H8HZ250WQG?ay1M!T{W?-tLb{T%@b9X(4`lBhrs5(6P*0u@=9GjVUMg=UoUE0{NM`5xwUMhO=kGayN{QeY#fT*S9ZJ1E;(IY_T6-JMS z8eAwq`_bJM0ccg_H$m6=`~u#iVI?sP1xXy8>zr|T3tCeFbjZCyH+_3KFZ?gmZpX_fU@|1J0!Ui|~SyPy*`FOE*2-o)ulz4ze|P z2TFQs`rwhP<(u)&*Zt@yB897a8~0>D#U(0!ZOnOfq>{}nEC*$G9I;{{{VuklmH!K2 zZvsta`?ig5qEN{!nPuFj%#x6ldEVPRC6df@hN6K`WS-~QCS;yTlp!gRc}OT*B9hGC zdF%In-@D##{r{i!tktTX_P*}xzJ~KW&f_>vJIUqOPOK?+%CyRMez$64Kkxpb=Ytp| z=%)MVRFgJhZ+ZvH8;#F@{n6TSa>igVwZG%^5xy-#8A4ow;CdFnzjrr+ReoCh4WMm6 z+(#@HuK_?8)d(QOozcb{Y8T$opJ#wVIzF+;<=>;kz@tF)8j}aUrJk%FAp24Ut35;b z^jIX7LlAnPvLShx7ii+ah6wC$^#Ij+fs`Xb2yQ&Z4ODUDTvRWy)Wf80C#vrMTq!Jz zZ~Au>Lw0)vt9gMFFrvnX1*SRjf55d%rhOt%)`D94Ge`w*dckI#)P z9}2(8uTc|2td6hp&g^;J_4?nAF$H*G7z`vX|0`zz_h9(Qxa^wF5se3g$B3DO9*D*_ zLC4c`t7-{!ei-sT$~V^7+d-5z1s(~75o*PJyTQW0634pYy$6>>*(qN2US?FBM|**15rSM{34^5 z!J|VaN3wFxrOl9XYJ>yb-g%>3F-Z?>&4vJVW0rPRKny2<#te=i^MG2z8YzaD)4uEj zBs9kSXh}8U7xz_R!CV+-E#Ij>D1UQ!Lm&(@j)FoEk{Csmck#SghTwd; zJO6xvUzJ|}?_04_+xb-R9-Y5@Kz2^hq#f{x$M4?CEk^jHVb|{{2ROkH>Mz8;w&e^VZWF&Ca0WN<73=Hqp^zr`;pX%KP)q00g-J{t6uX=&0PR8T*2 zpP!>da*ZQoeb(>MaE<#v=t{u?@M^@64e=QTtq>yb_FGK0oB#6V20~Sy=SNb;IaXn` zsN^6fuo?gL|KuOO5wPjOjuQw!pPeN@r(NVt(99#FSuRY zdgWlg2m5af1eH8YibcgxjAb z2|)!c1{~QJvM&cQ8=Gsx&&b6vow=d^nRX8VkHAa=z~MN=Y7KC1qbb<@+Z_*&ofLOD zl-2M5)TRIFl15@6d*D$nt&oAh>_CD;DEx?nD+27c{+&AswisiGFwE7cE&Z=1tJ7gO z#^YtfZTE>DvbEDk+#nQC$y>;>IT1bu)UXhr<==Bpg^_q0R2@lBZ~i0;T&N|$MJ^6; z!K2Io;CSxkjmM`L3U-nfZ~pIWBPbVE%Q8~ShWxA$mKt#MUta)t+WYO-`cf$rYRTt+ zzwgD9g{R7-jHXtXoR3awAel2-AuKV3i+p4;4)?MlM2d);GY`*`%gB0RqV``hZh>7zpnXyTIXeqhps_|_pMEvU+T2G_jXh;U9i4sgQLW|wu2aI95+ z|IF*+EU&_E!F#b`cw!!2ee*3joQ)C8mlD>;M>#(sqvWEk1ww*CIzx&DM<{ny&dqhwTC9JUN%{Qz`8AVc@#4dAoSo+KCe zV0fZcbQp=~T3&l@)2|;va42aR_}}4zMoI{`L2EPq^5&Cah)Scr?R(Ej-K*X|uixLb znA79L!{06iWoKmBvcl00oJn@X(hb5>J*ZbA+&bVoE&+4V0Q6Z38C6h3y6$)uO3TG^ zwOvLM!k;Gp{bS2|qbUV%H=x37o(H_;-*qf!{uYRqV3uoV=m7hYPg#iNW0b^In#8kq zxHHHbM*AEc{!vaj9r+degAMTCvB8FWdi_uG6UvRI7}iDLF;2Z!*?{1+zUo6sw%@Pk z^t23&_BeSceP0e--8ee%DwQU^`1Yb`yl1Z)d42Vk`0@Fr+=6?nJR33mbEvjEd7Xr> zw+H6i?RM5}Yj0aJoofq=d3!RCuyUt~$;nExoq)Vw^Cl7wCP}Uzq z02gH`}G+M#=M!K}#I^hj54ZgxmvDW3P&Kbs^ zc%rVr@<2sNoB`0egcSc;emOavnR3P%u9aokuM`vm%lnA!?@jtkmA^>u zIQAR4N}{%H|DF&_jOFQKCC#4lTZ5TeWh$FB2arCkQh@Sdp=r0 zyZ>zk!StVfDSTR3;FBbDsCasCO zJyLBcF_vCEEjpjyov}F&F94B$L2UaS5&@(zq>!<;lIDGYJ0(xFI=^v6@c7W!o^gGrQ^M|8+vt1~`+F_w~*BeQJ&u`lvqhwg3kmub)9QJ`xU#+6~2i?pD}5 z!c^ROOSl61#7Gy&_VVE zy+hk=wv)5Ce1JiCG(o(LB zAn=q9f*nmmzTYza-OB)d4DLS%dcD#jwP~aMESkW}8y*vBTr>W8F;ahu)GW-gqnYqQ zo=_Qf024ifIsk9VXsBp&=nY!3PL2pC;a7TVKOLzTJt~WUB<-%C*i7Tr$%G018Ot#M zlb6vdMTny*MA4NCHTc=UWXfFwCZvKK6(w^v@*!{z6!^u)Xo|n=R|0VP$MfS5S$-c6 z&Wl2e`)1-=^hVj2EDHx_Xn72a@74sS6B?aFAXt*eqfDv(gPeg&IEbYQk z&R)187vEIXBmvN8l<`;#uD3)foE9r}AYg!Xck4^pCYYo|Fxc((&A-cjzMFkAcfVv6 zTQs=Z_J6-{mDv2G33B)|#5Lp47xQH5w8`Y-B>b@#o4C?{8p2w;kL9|fc3*<4d@ebY zQK4YI1hov7lL*QpWTrB{k&AfRU`rCz;&^YkL11e0udpJefl%A=w#~h_Z@o=Ex(8qv z55^?1U1QReSrHcR>c#QfRo*&K%y%v;K>NB3X0~pryf1?#9VD=@MvwqYL&6~eH1!2g zsmPPzhTId8Kti-ykEa6i8|S$&WM!MMHcw-=Ajl|5S`BceHpN3Rq0@^%S zBm5U&@*z4!gayrSdIH6!u5mK$U;Pa!F8u!U3H#!<1QPzvGm7ZyjS}#AuJ&i4e+1Dm z#&0(mV~OW4!SQ#b>j8El*9K2o|ZOtG}l7L$c5s@HH7GNJ$gy_M6eMskd z8kn+w?;IMY(2DnAJlxzr&ez6bN6O0(z7bRG4VA=4`b4mtnqAHG@OH0kLJfNu8F3?x z4Gl6SxS)WyH`=};ZZ4{N&^n|Vj7h}b`uX}Um6W#*0wPllj{`EpL!`DjZ!FJzpbA)k z=r9m5&duCu2F>#gWLrO>V2$?t6QgxZz(`=j z<5>3wghB|Y0?&sS412PQfk6w9#B?1 z+T3tJJ^KpZAKW;9`k}Jgvw^)y*r&&E^X)hziJmS&_;6Phm_WqLAqE3T`9H`PZl(1Y zLA$!!e|Nq>5Ujar$k>d_!1^O8GTVr{MifURcQCfc9~=BLK1WeZzOLUGZLna;STYhr z79UqnC>wMNilrsc7zHrU4?r{qkxPpwGc^?zhbquM-@pG1Lw5J?*t!ihpm6nPV#Apw zn`s%vo6nFl)IB{(Wohz&u@E&qT7sV>;FFWt@MxmfGEt3p$6|lsV;mm58#v821LrAF z^-KV1N?&}RUh;&+kJtPySYD3YFU|EuFeebG?|y}f=#eXu1h^uJLg@dwUH&+F$I?ZP zrDP{5WQf%oc@ydkA)X6AU}1^#E)6_=TXpMzgBHSyE$)5e$^=ZkKnV_I!w9z`%e~*a zFU*?^MB@w^r&5e!r)+lrszt zvHM=YCoR4Yr7nreo^J8O)nh2>(8u+8EyX`>3`dxH(m6)V&9QG2Pm&ZnPwo+No_TLV z5LE^59$|?h;(sWwm?B>VKxYvI5jgN404yyQ(jvqX29VgJ^#_0RPwo$=hQLp`Wq{i8 zh(9H`3GD6dLG*qLLg*j?DsMrJ{rjthYu{buxO=;O|uwf5!B%7|k5cqXS8f4ZEoC=`%0t%*wn1BF`gj84&v&TASm$M-dz~%uL zskf`kO-?ZL-k;=Jmzgq1PZ4{F9nb}VPZlbQ7}TXlvx1<*7Qk|qv)>IfOE(vU{3?p; z)YV3&H0yF4W1xj>^mc>Od%a(Gq{<16Dh&pUgDkqlAr*bR)Ec(du@*+Vj_ohB8tfaf9f{GIj9RljmnPU`jT_?epyG1azhZJ ze;U`;C!m+?BMy?~+NNobV%zA&Ehmb~*ERWsXW`$xxa-w3d>;0V0=fHl@c2ipnh-=9 z>J6=k(IH55mO6s-JYE5ui(K^*wARn>ng-9q|IpwVhj@Y01t1Ec`$1WIp}m-B~( z`FLf!F~Y0n7Gg5*qUsp^W8n5p2%v3`%3{2N)%grFUtfB$2<=-wub&YyOd$POmemS+ zZ(w2&9~EeGu~z#Pd_RGUEC$P6pwOfWDRLuZJz7B%#6PpLkr|~x7Yel3S@{zV-x|^j z8Z!$sZ+WHVTN8&H!$ru3jm}o(FIN0BX=d#8#c1)HmwR;h$b}QgEtqi)ne2HzU%7Ta zs5C6h&m(r@&{t%18S%D&LkZ0HFC$vz4swrafT_f7R0eH7@n|GvS$Ew9!mY2lqhe`D z83XPGyQ$_TsM9vDy%olcmsBI^R9sRNjYjbCeCgA!<(?8Jg|g;#rR~Kw;|dAr%DEfr z;T}VEUxhj)7nf7}feUcMkmX)+=S8%<=0jtXol-8A=KWArWkHGVu!I5Jq z6#yZS`tA|jVgXcR_9k>4j)5LVQvKU8RGy%mh=og8 zpuU4v>XwMWyorj~rT3VcoZ+Kyd+=RdN_$^@x(dDL(xcKn*(~`jFJeglI83h_85=5( z9SW?778uz_0K5Wya1`$?fT%POrV`K?;tefy0az|Y_6;d%7^$ECr-_~Y`PG6(i0^NC zre&wJN+A1&Nyp}UMAV&u{tEnD*t>z{MX!zDZSxhlyQj+tNg&$!cB~Y_Xj*M;Q!mazwvEVdF`zn#V7V+~YVj4=_4abCR8%pm zkCaf|WRNAlab_r?eQS_}CpIIy4Y@B)zc~_Ks{%`660fl?2!Ufz5E zoE3Ai%C(*zK4b&QCBkT+v}+2!vAKwN8<<(C8Bm%5rBr>1?}kYbxB{~OWAVV9THt%_ z&AYX&t$_qz0+bYF)MpNM6y%w=doVse-XlZa`q(z5dyt0($#Sy`EycCXN1<(=dpc** zcyPs1PvqsqJC_#W?uk{SF&yepm!3o;bKaK#AW0MA{*5HiK|C2QUPGhzDX2Z*!pA0o0>Fqh>-)cRv|cL_i~b>S4EKYDs#VS{S|OAUl` z5UZz&ECBb0`tN!DLsto1La;YZF*JzB#a53sJ~jRP`!uTF z0R+^LcaapVCYLqrE~eZ8GYw5gF%#}-zsG(KXdv3ny6q;vior)nemmBEA@3=VbH+g;lY#l^f%#6!Vx!@_EF31h zfB5p#Th~Uwk_ph8O&7R`h9MP2D!uRm?PuE`Akf&b6Bso%xRBq^RlUSLr59K@b_su9 z+vg;R+5{4i1uc|5b?=Mzoj{v{M4X4bj^m&7I(s7afLn zKf3xsN31Z=3!%;GD}|+mi`ybwfzuE(7-~4iavK<6NEU-wqoZa`28;gYg7k%WgSa z_^i@g8IF*@SEBNseE&08PM;v(ZBu||J+Sujp@{>+P=cF94+!jlKV@V7t2Firc615c z{W3N|61U!+jbIRagO>!X*3>s3|GE)B*b0+gV_yP%Fnw9s~dXnDS`lAY?qM;HLqTxRW=xU z`h47N&J_HEKd1-wiPkkHG5QIDqG8@qGi`(>5fcHW&{<+~j zv)7ELd725MHmT2ea>7OF8&N=;0E0n-s}{>|I|L*^rzjdEJ@%RiU0qcxSmWv071&hVH9d8y*o zt^1EQIcQ@$aD$u9&XpEfDsT zA(S)zZ~+P#ui?CaQ1}iwBbqdN79*GrJj%4UBb@MlusxtbOm9z*>i&)!EiX!8@yGMg za(cs-q7pYl%}uR^OZH|@-To5}`-VU^sHJA-oljCqm_OS6u0J*4oE6|YxX5{9@ssC{ zqu3DLz<*WPkeU}F(MF^^(7Wx=H|S@O4ODp$e`_MyJ&b}I78w|2>LPT_3J>5_*2!D9 z?d(r$N4qUbC2z&IXn!?*p7=EO^}*IjHnFlaO|oLW;|3q;MWqV08&bi;|AfI~EFebR z|4fI*fWC?}1Q~*MaWRW5=X)|ADzo@1K?oXCCDumUX8K>OhX2d@!LBt$4{Be)-E`Jf z?(YASK2wN*HQj+PqHbdg;tM9Ft~tMV2C$XQu)*)(7MS%IT?@YD{Jz81#j(O->y{Dr zgVf0s;-JZht?cbbR}aZX|5KJjY(T-#1rIfb;>eAytq~;LfIk#@a)}5f9nf0( zXlh^~AvlbQT}{=vOFVD*F;UO4qSaKU%Cs>6?cqU(=87-Nq`}0OCDNF=Nhm<`Opos< ze&hdF?aqvt47e{qti-qB+H&S{G&XPLrz{~AQP9QbyhqI!)i0~2;xfmQt6%LTr>mxx z*EEpcoE%M0)Dv(9^)l#vA?{gZ-OJ_cD8t z^6Gn(O-Uya-`;BKmEq)cz{2&c_ofDxe%|wFgVUh5Fs)M<=!1Z&Upd?5#%FlfAwC?Yd_}JeM%x6?Y5=X$cN#&Fn%;>;`F3D}@A~6T=N+($XqR zp}@#=E#pjuR(kLJ0YRPae<*>o(%$J4`GEJ;b2Z;FF35*B7Q9B*-B)%!=`~L5Qoh5t z)%$XGQpHLy7z+ufNlL=8@o5`-&%Xkw7%F=xe+%J!1Zcr>{QFl!VE;Hux;g!u_ZYaSkjuOcOr{Ag*+9c&clLEdoFrvI!W>BJz67;Av?_NBa7~4A(+bgcp z7>_&OK;PS#0d=?OGZm1}r!Hx{tzF63I z+t#=VO3Gf4*8t0Fz$p_t0)9g(M_{XQ)S?TlUi6rKz>W~nW*`o_hzCBP8Fq$E2wIES zq^#o;y)J)gES@fNyrg+YOttJiRCA9j#L)O_l96gq8m+{Y5zXue2ocAWkr)+R8EnPc zo>RGocD<&6LJ34c{5!D?^+^fn(SXQP`3*{=s;V}e-X`$rBTd@$fj1})e}@bRa{jyI z;9JwZQXAqpoHhK&nY3IcZaFK=iMw|=44zdtENpN)P%n+F{;G_Rf+*EbXSviW3lDZjb8T105tya^}%ylFja)OvIT6)>_ZHDpgjNIXo^TLj!~zJP1hbBFy$pZK6^w3 z1@#c&7uqQ5oQ?x8^sF=AV(-*|VZEcC%EF8e`qKsb8MM?u=`uaQpnPyygC7{DD#(j8 zw?ukw0=Abbcp0vX4B(77tfjmHq94MM`1|=QX?f5O3ReE~3I6nHA!3)rhjprnT2uQ0 z&cV)(mD6jttguB&pEqG`Ri;DvAUaw#)gvT0IDa>3{$?H4WXI`ZNq5y8j z^2_~uqxh=`v>ceL@V?PqlCManMbO?0s{(NMe&mz<-bK#s;kZ4<$y24sF8JBZ0ph@U z3-aAqACT^BLO_qW=mHPNqcJl1NKOL=z++?QP;6(6Seq@bj-0}pS*H~rCa7Z2lv6as@#j5|05fC?*e)i~{QlQT74c1BAr?BIhDnXehvd z;tG_o)d1H3r1$dL4z4S`#DdE=ef5iHcw;!&>-l7b4LCb!i7tbxM{ zj3}3;7FQvPA^jy)cB)>GuT*B!ko!+rrD|7+x-H`rNy)jH(c4pe>WGtDEX0;&iJ zQ*P(`d8BD9VyT1JS0LSh)X2(ywrp7-UI5@ePv=91s_4bXN_FtRX0o^(F!1`^C&yD? zXx9tBKULi|NFPt3F-jlf>oRX@YLE?xd5Ei&(mEmVNnxEgEq?_Pp0|r@1O}pjxFJ0< zfRj|yNDFF#O8h+fw58Nu!Wupr{rt9P)kpWrmmEafK{r$=mG#re>ov*b@A`O*rE#{U zs9wR2F%}-%nLa<}XgmQGoNmK)O{mbcw;{#lmX`;oxz3Un_zj>hBi=zB{L*Ff{hzg6 zT71=JYeJh+`*K~O{$`uXNo-(?SN|DYS#1vGXDG5Nv{r+mEtmzZ!ze!Dp5xOCRw*oA zy;KTTFRYz3yWu6NqxKA*D%>EUS3;Alq*pRJ9D8#WN;*+1FaTQURRi{mNP}4L0q|j( z0k;yS?_?;e;7szvypO5MeNn(sw%BxwaFmHzBlAtYp+XB^zAnkY$GH2Otz0!U@%>5@tYobnG5jQaI(F_&agdaAK3+x0>^r=4BT$o- zf;bNh-Vxia*gVfChVXhMTxMkNHE(=1#cPk;H8~2j6{jiu1((8udP+*PToSF%i^*xP z-&(e1oRQ`FP$--F0y-a=^}vT6!I2Q4au$Ov6hes^0yQ^++iCsy1m&x6D8#sY2$Z<& zx+6G%6wl9@xm@@{>t60a?;L_HtexIJz?Ko`S4QNy_d7e*PV20%y8gHHrtrurIc1^fu* zz7%Y_tR8^j-Kw*%p*+*UmxOQdVv2c6rz5>*&5#!=&eUXAn zFkx)|jPZdQRo>^=q1FI@hjWj%> z>{uIE!yb_-z}{sOnglLIE3@c=SXcsVc#kUD&`AKu$feF_P*Gj~k-CgiRdyZWX;2Is z?#;BcVLRDr4mb0RG_z~0r(Y8dYx*x=vcx6^1MF>f+F}(enDD6MaOp!7aiop}4~|j@ zRiytri6ltCTjD3q!el?jJ7dBgM-PTh#VZ9k)naZsuMk;bb}gAIb(vNRnN}^C7EQI# zp1-o!_~EEE;dW~NsV}q)!YGuh70eQF{1$Hl#k8Kv|JpHw(>fov+4Nho9IhY*-6NVB z!+IVB+A#_X4GmShz+Dj<`aPW{mgP~< zd4l>(SIff5u5seNCIMxM#5>&K&!+D@M0LvPXrBnUdp*5E?J3{vbtQZi;ZC&y&x>YL zRISi;(nR>6(4lvd4?qC2xa^DfAYvkI&&^YoS;%)%`?^{dn49Bq?Gw>;m%_(9<=2f` z&e_H@8Lv6jj}Qh-5VkrE=@UAs(cVi_f*%_SY9l43-&(#Ydo;PvpS`Jyvy)lK@Xq+# zv^=xsJwG?fWwGwzm7^xsi~i#Fs_u))we-?;r<0i5$3`3e^AT|_8dj8)A1{5?ojdYT>tHC_r5c~V*FVvA3>th5%(h>AOfa{6ra<~#rn z`<1}_E(3((GBh)h+BQo~*`oQgYvyWuG^+DfCq8ahX50E&A}#Mt!#7INx-a$l9(407 z{3V@z#m6=$ufQcdD#;`}e7;2d6QMfxf?^i(To?>Y&%*Mu>GxKSXcDsE9FkmijvOgB z{y%hYn3x|uen*tPj?2ec`z9{9*0@P%T44g_SXx?6}Up7!AwX=N&BGWqoK&p@6w!ov0l9n4WBzIh5BY~7Ho35yNd?D z4u|1R@C=8Q{8c7ic3H@iyP9?DH2+pgkdb4Y4zdoq|HAmd@eeOMkylVK2chI>>%B`L zYYzb|;|8!ax+s__DHoL2Hmo$HzYa1n8yF-S-qcA^EaZV_ecYkh@13;)7cC$9~N5~o0jMZ8wZ@hsENnXIbkp}7w z9e_hWJIesy@;159Zmp|WII8&F5T6VFBTb<99(8R(Ev&}y$84yNb(TD(EX0KCLl2!^ zzZi$F3^oX&rA|TSd9l}#+KBjuy?q!IYQBJ-bkb#iNf49-LEGeH83B$Qs^zuZ*MAq^ zN$HR@E>qT`N60oN2Ah(5sAovt{A7CSbC=QBWb8-wiTpc~WNB7$_a(xTk`Xtk2pXj8> zp;OD|;M`Dd$xqf}KUq)cS<;oZ*|m(2maO*^s7KbGhv(qnuJA;PwPtM&0GL08cd^Ku z*ke=gv&sT5{|SIaR^UkiA{^p8y+~`eoVrJBBu3s&40M*pX}Qi;H4l=;9nqZ}k#OU=7vl}JPm~T3tT~+-Z8*oHg?yV|Av|CgqzeS7jEoF;Kv$6I z5}=?a(glu6AE2Es7+72_#>_#k0)4)Okd+5MAy|6O1O0@DdFdbCubXs7;7b! zr;5gNFBE^_3{~QwR=R%N{<`thB{ErQ^1SQc+RB3^bh0IM8cymoP|un$%zjlz)`hPX z;mLN;ZCrp1x756e4mKfRSmItP!Qg7+1(w;u-$%+>IjO?5%%SWj;`v>t`pz&JsL;B= zn^yz`CDl$7pOrpRQ4*-dQ^}j}kxr~S4d_b27@n1hjT7nWlA~!UytX$@3| z-~Kq7LRU2*ySqK^lfLWDl6|^+n94&~MvtfC{Ze@=sWd2plKk7#kF`%-Rp<;PX0%-} z+4kz_Eu>X8KKlG<(Fvl@;LNn)c%JU*m)ThqkZ`IUM#urjkh*WhosgVd+>(ATg`HB@ zO(ni?u8KPI%ixB(%tC^-`a9=KjOhU~$?z>I#V8ITLLYLRup9B;8?QT#uQ~1d-N|}d z{%h`N*HI0?zDAmddXc!~e=4+m?hX3?5YqGPIWfEN4%{`a*$d0OywZ(y#giJ zS0k=#!=-XPX6M-hpECqLXO1zDZm%wzEF2Bp%HFB^0&?tyR>J7%7V`9pFF-AOWd>UE z5>LMYEXd;p*!iQ^B*ThqLRFu?O3Jk)!^Fn=Tp|-kZ|2d(HVPM8j8`xJCBrw!#pY~UujCh&xJE=Wacpw@n35SG z+kAOuL|@5ctWTDna(nNqq8n5&7aw(tiFh%DacBayD?xgE3fX$aE+s^~afFzMjS+Y( zqh_*R{6fsW%kc93@rm*KL3;UmE|y&F{nKRk7}wq^i!yUpyfd<~;RJu5XTV8^0|(^k zWC#JH_%&Q6v(`h`0=(zM^6VHXF?}_32lzeuv=`}`)T2%4KLixDrs>t;&1r}Cow1hX zcGy-vwuH07*I|;+Q;CP28(w}KF^6@(R_2%fLAM#FpIG8Kj;^fH#}ReM6UG_u6!%rt z_BUF_|C||{DEVD&h)=N7=H$bmi!dLi>F+tw;sOqgY;C++(vsRaVyy}LG(bR>1=v5y znKLI)d!R}>E9saNmdlY7Gdmv}o8<0CW`j=F^34^Es3`i%F{-|zNi%jyi6ZFxM7grb zf)Ay4^w~A%VisF$&52oqv3fTu%8#a+vA?7FiM!*_ym4q4)w~+*yqeeGwK9x7wXA4Y z$^82gN#o@O_)|0iS^tdjcu#zJuUBnhlb~jfYP4-&cqwU~zy!u-;`yRnls(_yvr%Cp z4{SrgGUp?>EkVN<0u*>821E0MBxy7Un)J_;)we$1S|91@;N$9qM$T=F4?KzpjtJxM zKS4scwl}_9hQV zvle&pU891f$i9y*=8Hqypod5^Mn=?ZT6Zq#XTLKjY)#;ci{g{0!**kEY=$IJeDUL= zn)hxcaO!=Q!?zKqJGF3$HHNy|veR7=pnIh#@KEXZPVL{}87jA0^;*gDT>?65k=~}Y zCn}LCY;q$xBk2GhJHI9Syl<4?zLKLVz9z%DVl%qK{m@$g*W#4d* z+r|EQT}}6i?aR1&d2t*Z=H=H-R)}LV7Rxi!FX`k;=~SJW{d6uWX{F7T!|!AE~nDkp~7mM)xDx(!DT66!F5Z3 zYi`7r>Se9$vXgokiFLHIsTU(9=bXSj&$6y^yhnn1=ZB>&zeD`KQD~RULX6`|=U8ve z1Z@~wbn~6_epsQNgebrGP!3V4Tf0j>pk1d3QyK;7f0(Kj*k+S}I|u>F^T#M9=ma|= z7(+%hqt)_@fcxYYtgLiPg@Q<+v67^(ToCT&yf+j9WAo~v*Q}|P{v_z4gWi4{0^i=< zpg8*NovtCva!S2^n&jmnnt3zn1UuqIiTe+9I*VIk8xW!@NK# zgu`^Z(<801bIwDCJgD2e)ovxL7t)qqwHw4J^Zr5buIXh`uCJgHt!iNi@R>u;MYhF)~m zDqJb^AD3m+o#wuKwQyhLtf6p-RW)`giB%hOHfnEZEv z3lb$XSitLqhQ5nb%x{1GK;GKr?=+K_{yFVeYbLKXDTYlID1t)O+c#gd_opkEXdLV` z82H9l`?0PSos66BWYra+BHH9F7}D^{;lswd_G0jynZIY=4;qx+9scIEJ>fp??_tMB z`KniuusHav0iAWa!&1rPs3G{RQr+aBB2lr@I?lqpQ1zUuphcp(C0AHwEw)Z~%g{wR zHk8UinH0Gu#3qOmGBa7B(De|a#2lm;(~EPe9T`?MGRlWimB-oKv>Pl6A|ZJk}t;M9ltL+?kZe`f3G)#mV7@Blu2zT&+e} zwFa?XwXND_jfQ!leW8%PVvo`%#%Pn!8&2#Y@%cnBZX>&<&nEKzDP0?GBv^ULT;F>7?v1-GSC}(4hgD0?tsZlZk2uHjaYBiL zD6cPGrALR2?`ry8HTd=7)yR3nI(^aMz>@Oe#2+hzNv^%|N&*jSg3n6og-IIQIPpEG z$tRLbD34YCT#k3N7`7ibwzV&Gj?EV`O7x$WZo&_n85`Vjl?#z{s@;HZ&Xgh z`*$&qdogi;J7X~%20RgYc+TjEAwtQWgW9-u6ZC@@`NWQSa{^veqbkFyoTmLV2~%=Hiiv3sjg(}oaGni$nnwgG!aMg_g&I0 zuih2Gm6t`IIKcm?DtlWWoJ(d{%_n6lXfe>v3>v>%k2uW0z z+&S|csC4jopO%T@oH^8D^V9-{<@9yk-z(VhV|hY{Mq<(eO^w?>i}tNBtyE3b>hYu` znIY+v7))$$D+|rY6PV?+!X9l(S5B0+eg-}+u@W8J*0>j(0_1XX9`o;l4xfk?odl3*1m6eM09gSoFPW^-NuuP zFG(t@DuY_$iGP#|SnvF%zrJGC{zkM-vuoSxQ$aivH) zr4(OfgVlIhNM9N%52&R-b5|PAs*2j^FN|f5O zw}rX+WzI5LT#c|pN_%(=8%o%@Rp!yGH=78@svMo9LJbQ(54)fh6deESYhGQ38W)?0 zd6||<{^DwkkYS3<55f zfg4UeL^Lpp7JoGj!ey`@t9SiEm?0k+SzRsuj8&e+*?ILZ2_Z)gN3DE-eCwqx=D3GH z>9^=I1TVC`4j45VPvNbUqBta}Ul(@WW@THl&*;}}Y=rqKl-I#Me3_fe!A3$j_i6ra zM$!ZN9)`QoNe>cJ=Hn!FxvqM;bL&laNaP80a>P}}c61q#(O=?I8*5RMwvW-19AxU@ zQ|8Wr7gY3EWS7X`_HACd!#xiOr0{WDt23574{AU^0*vot(7=b}@yCB52&mlJWO>Yqr9@&PuZ0?7fkzjQrO z{J%K(jtR$z{*qNqPxH&jYi$nj+UMY-77gwl%DywE%H{fUASEiML!z(dX*#Xh4}sy4 zT0QA;BUg5JBs-H$@*;EqC&jZDtWY+h3`Acx=|%6cQaw4%7~;~peH=V;M(bQyA$1EE z!*FoKQo_OIQrh|O1Mx-tj=|5T_JRek6!#+cnnIg%v`oxr$ZR+lrwy!$hwh%aeSv1p z>8%(Eomjk@f+Ow+)*XG`)E%v#nx>`_n<|4bG7bN7%O!Y_+`zSJ#4L~3mOr>;zl3wR zWFp@&pNRp1v22J|yQN|tJ`E4=fZn@N$;n|5ncV=#9YCujn3#SGH!si51_80s3g}7F zch}fpKVUdW9tO!P9=78dOFV{77mE;CN^VnGe>BY)Reh?@Qz}$`BExc^sYRJN>(zx# znk%OCU*8%k+IGi>s=aHk`s*pHuHx^Np52-r75OcUA&OtK4&N}O_-ycxfvZP_qP>5y zbt-1u${#sw*yWi}e)@FK}I&VTa*H1qo%-9U) zQu5#?A%q+0Zc0>0_v2HtPYrqUhv>Zq(cD~BqhG1QP==TI6d*yfQH5RbU7ru&Do14jB#R1y9^&UjL^(J<#quvC`8lJ>FU!Q` z{!A^Hnaw@Nn#_g^2n{T?h}!R!SFl!^Ug57b)TS&wU;&il_u9K)Hj+@S_ex3uDU$5@ z4A*FrqaN6iE_Jn@ZG3?tJfrLY!!h6~N-O>HrKq+3lF94WJ?DOs8&t$KFPuM)oh21Wwk+t*3_h>S#=@y(h-L&wuJsie92TBq7-`y{viRJo{EHRk2?j z_G> z5*k8h>Q`V!_0ntE;1r9j^uQm{Qex$;w2xe*#tZbCJB7PY=OgAGVU%ghEk^t%r zxzV^UA3k34SI1&ba{FMx-8ueSWcg&;bAuK<#TG^7tj!u% zaPOoY^e!41w@(by(VDGTm``*}bdl3eI_kc8bv z&^04K>y!;nxZ^v(+-7HICjfnwQER|Oc(?4ZH31DC!eRR!M^jVMrZ@fa5n1d$dsG)n ztl@u3Yi`&+@sUWs0E?bI(4B3wZGZH&p{~XqBiuc0BR*@;07E^_;Lg>NtM9gIE6QTS zpu5S-eOlD^V8r>Iu#`VvvpGCMfSJ>muXj$c(wo+gsy0Z=AgiopQ|Y1AyI~Oxelam> zuz`5};MfWGeb=&!M63a81mNmbx-8{9 z98^G{&~k==|H)kFd)^qa`TDK(O%-%MO?&9yY7X;MHBLfV<`=`Ne46ffY)(+;uSB}b71VQofv@pR>prP+9sGQ%z>;7H4vA*5`ZFB)zAGMB*3hkB_x@O){ z$Rl?xg+sHjxxhhlZ+Kfcu2Kja@T!?aUz@tQmLaN;!I_8Z82Fp@zbP8v{7W7|Hdv}l zOPBn(qKI<^&JVMnF6^VKTtz>epR4`+gZ$E)zoPrHnz>nRtYbVzzLf$Q*tY00QNncv z1r!*7Q_#_cfG1vaz&4dyK2=#++3gQm1khx+dx=`fMp8>T?G1flYmi2MQ@zjCtq`M0 zdyyacf8Lx?EJpog(%~s%N$+oYp~;u^(KQbJRb3Pb=)HwQ4V0`fBwj;c81`FpiYI46*@CWk0J7y1D)iY%BAT#ZnGb*jDU$mwJz z?@;-}j5d!HAjjMSdhlk3gXZr(0go34%LDWV|vLsS`6h&;M2>EW519Tgewh{+X_5X(=?tmbqpm zern~0?W@gVWST>#9~<*jV9>Nk7fAuLdJ1$r*_d`cF9{(yGd==Q>l_gAJD^>+2$Y6G zyR50NX((YXJY=)#8Rq)CjJLdqm&5&{Y`wEi+nK|0UmJ?O6;tgE@^{}=K5Z(B9ZnYQub*b_Ho^VjNrjcT%=`u08{&XLHZvu| z0~pouGc3;l$Gbyq2#gd(xL$P&p6v|%61Heo(9xlAo~$Rx*9!v?F|-<{0`an>?WmH{ zb`BLLiCLVH(b=h6cT06j`$G1?;~dQbUYqtB&Gv?Eg|vezkT7%VWqm$@w|{665$=4r zO%tC~riHm2`F0_c$Sg2{Bspiz!N555T9MwHD?T>yh3C^8Bc!Wv>zk_@zfPiB)NTi&n#eC z`;1h8!_T27-aWwM4b|D ziY`%9T$mo)AiC22>96PG))cb4+p4l1IWcU8WWGM1Uu&VS+;g!L=d~oO>ARS1V5~)e zRG~QhOd_N=COzr>`RBIIG{fn8YS|C!#BlYO6gX~GLLCOKE^{lW{{!rcDuOoPt-H6! zdly{pbEAP6kien-s*{?Ua-9R_0-a#(yxVZwvUNXoh3zN1>wR`epcInTbGi#@KkS^$ za_7k+QRXLo7_=*_PjOfN_&3(hIqSOuF`_iV;|Y-2p1WH@jXmA0o_*ifPI}C>AKEWK zu;CLA;0TCgT$eu!LLqsvNn1}ZrdF8p;{+%Bd4ikIBf9!WQ)Lz;=_LPFea*bRI99sG z7)V(lmpdD=5|kxAS*9kn8Op!97(8PrN$F-UeW;LLAp_6;v4@!T1{WOxwof|ife)W} zKzs%6`>hiq%7#b#Ciyfh3aBlf0a-LPD19TLkU3v60ILzA=2_@fGygp_bbZx!T>aTa z(c@>Ryax8Zv3a!*zE{^R_iX8KlI9?hzC>T||G||p`fSm{iRuH^S=~a{-5w4&QQ*mE zJ02Mk$%S4~GV^;-_r;oLm>YNQ?xozaM6n+)-u;;YdIJ2sdPZ$z8Ssl3`~_KI{hfkx zRd8EdVA)C?YznApzZw~#2UA(T0^YDt_bu^lKEg<%S^Hl7baz7sLxJVWQ^RIBTE|BZ zQL@t6EN+|MOTTzi@#(lwe7Hk3Yf?-RUBXq+=eBfXvc&#@Nc}EHqD0N9BFs3sAi5#v z<@1v;p4V{Ao_s-#j3xd8g0Z=~cYyog1=m@HQ-G3#8@Mp^hk5{YfOe=aL$UimN6P0i z^QRDjWdXe%+1}7SPlH*GlCp!kgVI$TCH%<(ALl>nYX#(%qFD_4A)|hA(8TW0`Ldj{ zv(9$*C&XDutCLW00=vFj66I24d3%0sxVn8=n>q_Ut4i1>W1MSiD^-pA5l%-tHT%WJ zd{!D+r=i`=aHObn_};q?Y?TUVNcUr^X~fF^3Izod(=%{;Jm+|xDlAKf#`($(j+}=i zPfx!d&AmyP$xyEU^XvCVwB`owpQgnE8L5ca9Hm^>?bsH}zIcCruTb?;p-LNNni%kw zkA%=!R=uO=lCaysl~Zt#C=_58n&h)Gs77;Q_)W0xSNqh;*4!3I_>rZ{@xK^*?{KdB z_YL@?kXa!!B2-2Zkr9eSLrG*rb|_>;_9|r*DHU0vLdj?t*~&;|L=GOHNU*j6*bzbN7{?syW#&u!WZa;80Hcsyo+02_9xUOjYTrnZx z7~MYQ{M6-5_oXWBm9-C6MyFir{OCj3wq?at4T}EiKOI?GDOJ^zhP=!^K~@E(0%B4^ z0YB_KPM-?0DU$$fbV?4h)+%V)mn)ni2LFSIiRDf;HdwuXeW32>$mWodTiFqt5^q(! z7US1VNXvf6X0YZ6*IC_qPP>I7??iFNM@n*WF&k?$cQwoN%&bU1TdwYEv#6PNaN8@p z@45`z#EVj~+O6A$s2RiLyBC(fEfh5^LGMGnKE6z5iGLVeZ`n_;1_%lUL z0usFPKXy1<#rN(!b>>l{h~ZO7f!7OWd-N<7BST6nqH{S5xi&BsNe86qRSVw5p+9k4 zUz^ckSeK#g*7cHIsHozHo0uIKfY(W@d?xqytT{^mVpQ|_?=w*fV?z}OufGw=jJaL$ ztvl%2hrs%ZI+5E4_oVZ;hKa8nJp>!GOY*u){~#k-yU|A0DZT(21LJcUh^<|k)7Ahi1cwBKGZ|yRkY^hFmjrlz}7L;tf#B?Yx$oi-TtFr}*vp{%*PX4Xk-dndif`1U%WDZFXMccogtbKXT8b1AC@i0$Y!y zi^=K+J^h_ZULv7zik1Gf>q2Lph8PQuzQMUnBicm!7*(YAzQ2}PHiF)|%WqNlaQ&l6 z%{qRCdd*gzAW0s-XgBp62Wd>Y84?ocg_WAib;8)2WGHq!xO3f`IW)J}e*L)ZS8Ija zZz}=ajOpKvHO(C>_#PEwpzNAwkMwzF^#2y9E<4HUsBZPp(C|0`y4leVGeg%?2O?j% z{Hn1qDRp`AT3nSf&PNm3NHP7~RIUSiC&y*C#N1=DfpTr5!PosC86DPmh2v#X>brTq ziwrrWCGvcH)lPFu$x2{(r{lN?U|Ef_+F!3f+F6BVf|_6MUAnRTMT6a!s!)NRkLP-R zD7;+%xQ%UiTByf#Ww3xizYcHyWtHkOd!79a+jBE~b|UO)ey-0=mInV@l*GRL$)(51 zNfq0SILl+wA#06sa@zQ#&1M#M?^1FYQzss3ntbW9^}NuvEwG`5YGTlnC;1Xz?SzHq zu&z@0;Ws-t!VE7CvY%|aufcsT+lbcmz5}BR0DJNizH0fI_iW0Td=pS^K9%@RVWiAy zMwwQhKVwlylvVzhxU<(v0WQPzhv%5@PRZPxJ6995zAdg*X<4kJ4hec_J z-boK1eaCkspSI!b{^g~fzGVUUv<}7aO^Xv>mn>>a`4k5PL${|5FwGwSvGRRikXry{ zY1_(m+;ejMdK(_jbbk##Y3oqV8**WNq|nLix9;77EKN_Yi_ghUs}-EsklQEt{oe<# z{wl`}Qoyl{b+a2MSAAz}Ph=3`2>anSn*1ZlNwTNDydruc=$YZd`aBm^hnL!U`pxv6 ztE&a1rQ{nI=3abCF?;DcX+Ip|+OTt>Dkv2FsGpGCKtNXsoRjaL1u+UDPWQJ^y$-F7*Yfw2rY0};zZ+)T@p=C@3DS$AkpX^qh1vye2+2y9~`$HOJ>nl2r9cw)wvi#(A z{clx**m-!u(Idkf6!b!fckcH@&W#F)s7ryeOoc{u@CGX1UyoSNrqgRJB0c#hvyo+1 z>$hL+LCcUoH+QRzelep8)1IDD7Cm!`n|skSW;||G<)M%KU9-KCCEa(oe&)-H*y^$D z2~rE95r&iG6uLxvHs4TPOYK-xc3PI85@>0@@bRM|I`G%{`}j_OB*qeLk14G4VGy&|mT3gqz&SKht9Vl?3Nn^= z=lL}?H7R=z9t_v96qCRZtQt%(i%v>f?c?L)J3m%1+?2BNeM?Ioh)7w6c`J~*?t`Qd zVil%UtNe8~i)F=5b6rtTr2YMM;#*9y$W23*U#!Oma&8!isa_0-N!)JS8zubF{!Qsg zhaWDF7`U1WmA+@aopFp?KHeEkZ)f7KtEH&OmL9xce?IxuD|Jd>X{q0aZQW;4)m8KM zR@}OEt8;%H3#JjO8Mo(IX@VC(W9IjZeY~qQ0?a^5oRkNQw}$yBWdYL;S%$nfTYrgxxgC+hKU@O5jfR=I6Io30r2LCJ-tRxzJA%U&niU zsVLwIHJ(ofX^4taQd)YIRo4ac&{+v2PT_){&5@r6t$y~u24Rhs0^KQ^Yi|Y=I@aop zo8Bv_2;D2>Dx9OVjv*_|JF(;-hr{-hDohh^{Hu9X1X2bBV%3=*LG_`==3tmBQfG>M=QqT*o6opsg#cTi$%40F9l96>0Q!cYUs9yPTU zN0O9`cvD#7Zfa}$hKKgkB|dR=rD;=1tJ_41Umg^z4!yq_xKwXm=RA}snydt zY+IKfYSUhHrf2TGYbn4=t-9TPZOwHQYam73i>t6Uj44Md?SEiJ^i@lygBv3(9w11l2$ME`R`85#JxiZ^fGv|3za zi5;WcO2LCyp;bQDvYO#9+EG0xdxE+=OifK=72U<4;bHuih2wF5zxCMI--H9r4GpXD z4f_uqc>P-iqaDmLKK}by6jR@1u^IB9X&Sq>2S5|}(m#F<91^*Cu<*r;RM=QM(3i7? zo^_$=i@T%qSf)(l%$;w3-@bj*i1-&OBY{4AGZauDw5N5T3$J_GLIwt}qf*KQUl#V~tT!v9&#zv+x})1b6P-*;w7y*Vp%)eyi1Ed$c8ozrTNI{i#m%ef#dS<_?_^w&5?kfI?2- zs|~EiUv|#uv#OsO9U2_08ImJU+HAaMM{(%ecpQ0q1o7FY0*z)9fP6aa6l+@z#o^M1kLIzL)7qN*F}FOe+5rQxui|s z9v8%fZhz)Q!}PH4;zPG^1^MMS5qwXGz?jl-0drf@Fg#%vCAKMtiQe8I%pX{VN~&g& z>%exjidu#~8HNTQ5A+K5ojD_h2@XvVlPVpQG5|ISE)7xZG4P4re-YYfYY|pLj!z@9!E`^HuKAtIc1O|u-#43ujhlj@H)qLSXGJ-dJP%X|WIJq~9#+GSw&K-T{%53__xpvNb zXA8^Xg{1zSl($#0jGzXspx9w@ZrMDs%;^)w84y{pYk9y-F(0VEiDI@|>}qfVSxvtRG?F=_T#pZ?VyjS6A!Dp`)wD|G6KIbLRe$zwIO<(*D>iCbRnzW`JH zQry_ODjf3_dy?$UP7M$P?fK(t2ys(rsNDkvx@$>Ekq{BGgzo(RxG7>fmO(PO*iWyT zS-GQ3GOHdO(%!!GQTf$_`ssX^rv+6@FZ3!aY6dJeN_8e6=O>3`*Ez2xs4igL4gRK1@5HW#S5iqC*u4KrC3}rFnEh3;je2)vyRjq( z)yjC!zJSC>6HVP6nMgBiSHY5BX`&~^ng}OxaX)bHGwPzN7(SH znN7!E_`#bW0X{Etm8Ubi=6*`-oPB8QKK-zdKF?6^Z8OgaN5zk0~I!Lu@DUH;5EVcZHM$hWs=x*caaJxfX#@_V*OZ1}SwvVzHQUK0PezHyOZPDIc4Z$8~%u;}k45S=B ze{RA6Cyc*XBgm4@$x=EdajEv}8%KbBx0BKuD(hG5p3V-Vx>_>py?NQpNE7B0WElA< zcfl>NYs=yWMomsDW-i3aOACr+oQq>E=P$eZAt-9PtswjRrS7@*eG0bmUzxA`vl`(c z|HT2Y6;Q}Y#mM6at1pK#h)y3+df-qLJ{jA}>kc+c*_hGFy?4CaTK{_yZo(0~af9vp z_3NaFp?g_PJ>**EQOm_VA488hDm}G^xd-ef+kN(&oGt8N4{-jsl6qN$;5j-P0c==M zMWw4XWvvd?7tdRvuZ^?6HbnIEx*ubdDjU&f7Bc>$CODY!51~rEUg6NFHas-6>K|Z6 zzU+^%!9!f=lhY@8GvvIE=alSN?b}A126pw&WjHuAgPQOM5Lxsf-iI{a*V!L^RkucEo%VhUh2G@lSJ6?~D4nhMq7~-m#Z~yoc$YpS!U^EgVj)sPY-2D8V?();O zNDm21sWOTQ*LBxypP%F_{Uvllzrx_lqe}hy0^!u_T5GA{w>L^jHDmj6TcwVPtgCzb zR^8WE2@q`0w{P^(`>jWEhqt|Sicq)K1FNy@iwoZ_wd8>e@gau`pB6?5)Q46lb*Fg5 zV7#xz85#ZcHlm_;-bg$3R%|R?rXGWwoWG{P$xS1=y%C&}&V4n^uc|ZKyD*wj6%E8X z545=1G&QV~z8*WpRjfjNd&7Xq#6u*+S`)f#tJ`jE4!siEwG;LD=H}*(@-JV$^nU-I z<)&|eJ14D;(kS}nJ^%dNL=jL_zaOktizHV%#l?sSgScBbxew z5jBDW0)a2rg@xBG+!p0}zLO3lk8}0=1bd2;WVb(jE@|eZe(&b>>#3z`+Vr~ICoCQLKxpvi5sC_J-@Z0*uH7UcAOM_tCJ;I(fkTbSeF(e=SZ--)>Ad*Ys|4UWx^A9{ z?%m>@zA)d-_BVH)HbzV}{qxIa9&t?>jmJ-ppiwcj%Lc1S?4J3lQ>VV#!S>Xx%gV~a z9|+I|&pf4yz63M0xbWMI6tiTtZul-YiVDgIY}Clv|_hYVW>havc6oGJ`MPs zI%*xZ(qeE&%QqB;ls78B)iG#)Loa?wR)bqJiS>5qv~H#zrB#(3~Saf^=tcu zkBY48Xrxu=vDp|PVKf; zqlZo1a|VLmS)JJK_3u`yhuDBFf$2;npHGmN>h@DvnAW9Kph9?+og?~FnAU#HrE-a$ zkB@IFjMNn5T-?Mjd+}$o+p#SI-(|_c&Z0r2^%;sV|x>`YpFZU2#|=w7Y5x1Jt57wx2Z2OO5CAh;#}8 zlz4a@`ddriU;^su=>60BlKtg2?|2-qV8pm|y$Z=1;Vm!(Yu)P^|Gz&p@%Dswz3+)~ zYU=fNx06#R;#K^-Q+~TZ_;t(!0z$`!$NC?jsRV&(EaQ6^dOia6g_y_fuq27R?!fsihi3IB-JkAIwFY~1 z?H$RhGzY5mpo6#nhM1mGl9E?2Lid${U6Sp1+V?7)cv>9<2633BF-t|+Zri|%#H{sI z^V&E`)XpH#Ks@JKYARAeBh_8VC~m~jhkDLSL}4skT%q`r6ikEe$nwWDKJaqPJ9@&p z)Lb&9nT-DM=U*QDoBr40#!tg}7hU;JC+-MSszcUR*4}rc*C}c$cf!NxNB|%)%c5s4sGSeY;g(df|bbTe+(rDSYjJ- z40!_jH;GwJ{0(@58lZV&k}_=KyXT2|V(69Lws!5>KrkVAF#Jyz%$TOseT={opXfZK z{#&w}se8OINyzJXdIFn=wnH_E?M{E&^`;%FmQ9(uTVf1Juy0S?xQ`?PtnR@arU#TBx#Ra2xwesCN=3BRJkqizDC@D-5Q}X)xs;4ZX9wu@v zH#a>6ZM~xh>MGpXT}=E%Gz@rJ9dm|=FMW^YisGZ@p5Yr zKwd&jh%r7*P)7!eYL;&1>MBj-!es24C~%eJS#L|6bjF0R3-k4h-bXX_NLMuk@aZ`@ zIl&$vH*NM;yIFK}w1xAoPmN8SNC(JHfD-~#<3iWd5z(6mNz*b0)NDWt_#l{E?%gP!I9o-aMo!qBSFFb!P3#=px;}$KdF46<+is}+A0}4VScMKJXf7~h0G^0T{Hx@^4l0cH@7JEn1ON;wua%rfddL1 z7$~a`&mDcZnrd{UCc z?4Lga9XSr4o>bwDe~s@N?eq9Gay$h$g|=XaQz3_UB0xN+l#Gc3Cje^gej_@lx? z`4sd<71d0PkK?X7t2zZ-ZEe+4Mf^g!h(uwq;}(YqoK}wPZ-SJ7hq4m$UW8 z7VS&v>FM;Tg5JM{AH0^b9tbF0+$yE{<)g>V$>RlQ)+xg6B0-QivU+`e6Y!EscqA57sUYvQZdSg(7A}~I z0`0t@n>UX~JGkM=)#&t)0Uu^-Nmf=$yW{4>? z!w#DidoUx>+Tpny0|PE#)I8~{z#@nof4Gjcw&6=zu+zkuVTesI#?A^TDe*!Kh#6CE zR|5+~(}N{+W%g@ny~4sZA&KN|e416ZwCF=kLz4pWViIl>;}RN5M?ek;V&8o4>DjH)MdcMq?r~(Uq%N2m>_70m zt8|y9FCro zjO|1|-csk0{x-4)>DtNuY4cj@-m!`oW**?|(Bv6z{R{3Z>c!Ff*G5z;XxK!%NKGw_ zAAA?X=pWHIz~z42YsBBetqFmX?J?e;uzpV~nJ+>&Yt5#rC zikX=iP$ghw$I|5FrPqv8BSDQlOZz6D+d*L#!<%@cz&{`)SuP;+qqY{&_^|HpmblsMSmCJ)rY zwA(HVOdkk7QuOrkrnaavv`aNK^P4~u;L;PL$`g&-G?-eSPup9ZiW`d($C*f1ctpvv z*%g7_F~`o@ALTv#!|z%m*X zCk8(}nzDjaOWSNi4ncqbC^+18ESw8H6~T=fxoPr??o{f zn>;9zV_YBsm#VzE9 zc1bf5;CPRshxsB9<&_kUZ6~M^ij|HL)DBfl?=Xr|DItTBg?>8VzSyt*h^C0)lENA4Le6Drip8q4`FOj z>+W%4okd;>d)td1Us3kam)&;an}ql1xOvE7t2=3y-xB!O5#E@};Y%7jqT&>acLOy0+{_Z`A zzRj@ddeM#r0ZWUtY}ydHzEE1KjNsH&DW6PtmzdnJcI{m`dW%rCl%^xqBQT=bEiVz* zJAeNug%VGKqB{eIJ-zQ7N5&vicopG6FQ%J%(~$B!THjJDbjmGmF;6Xm3)g|WOr1qE^x zyL3SasrDk~w1Z>G?re5;cMs7M3qcwLFVT$1a)oyByC_BX5iTtWstUrQg}FV$KmU0{ zaTY2$DAC%Lxp-9!@-S+o=W1+X)FK8DnVp z;3I^I)f<#zM~7)|9t^>Cy0F`Nr(?%DxLK^z-@Atmk@;ttmhwPmGbH?QA0o2Y9k#2X z!x>Q<#Xr=sbMxj0bO(||7O(dGca6}QPeUX@==|G<1D4$>fmsj&Dkf5PmLH89rC=4-n^<$-5M(rgEqED#nIZymuSB2|F+#u@I zZL2?VP^->w7N=87kx(Bz0#=y!2n4fwk>;LjTZ99$oPO1M;)XG^XZ@G+QJJ zM13htkvpmG?)bGoQ*Y3|+z4}gSb;OWBDjpK>=tEZ<@PzJ@&)}ZQro?!?askGSGb&V zpX^b^h#58{ru93#ZYFavzU=7e5b10j%cC*fUG|B;Gd8w8t%OmLXOq3OM2-==(T&|k z^QUfi583&54E$1R5FgBH`NdS7V8A+zfV!w{ed+=(P*RlB_1_3PJj6)0p&_Z$Qs*p9}9V(QvEVC)?Uh z&bEYwW%P9YVKEF;3?n0O5~cGDnPA|tq-n5@zyXKHp7*z|+`2n$*Y}fRELPRIHFiBG z&y}}9T&1(NrbfeOS2_Lacl%e6LhP%U+dzV>K(Gg52dtp>wwZqz!r4@{5C&&w=O%w0 zljmpHVccj0Ci*|af4V;iL(N}vDW~F+>*-EusiB{mKGDm{9FUQdlS@$YlJ4$&SEjEI>GLKG z1}BsSn4TI$xGa2pS22zOvuUW-?{ug@=8<>igIJ<^a$1_u%=b?haOEt}YbNhLLc+}z zXkI{b4fU#3R%ikJ_}rcoYV|sSK8ttqHq2+y*EKaY`EE%-ixN}YDZh8@ALwKRkL`#6 zl+ONkE+R?_IC`QqDg(P$$?bVm@3hk~IJD02;HQHuu(i6EbsP?U8Z^mxkzs9?wkd~y zUV6ulXb>sVoLn#ign1nUjW8=c%!i}1qOm{QPSBs5BwELZheM&W@%e>2qnZDoO>jhd z8C;-jKTtlh>->1DgqZ0^E=FGVWX#t`W$8+%rKbK&2#-D9Hq;46>FOBou9uXV zl>TXe-K}k|s^&Y;>pjYedDs)L%_XjV5b}_+sxe1ALkR>Y-vW8r>{R1!7H;k^%;_Ms zgjku=$0Ex>L;7%J;1D8MBu%+M8nNdqCC$pzvF4M=EYvoIUUlb{tzCVz{H*ICtpNja z*zEIJbSg`ybm^FlO1)))h8!1mQd1wa{(aMS*5!PI`$qo>1I{mJzM09#pmc$bx}Gym z$1No+^L}W=w>~yD@Yy9SEZjH)RPsZlUR_6l{Ff3hwm|RbvCpgmM(xjDzaz$Xc-Rh2 zFyw9kU|D%rrSA(aMwf^Nu!;+>9|gZMG}PDE?|8bktJJ5RtPv8XGfwtx>)+%cbv~2+ z6LWO}it{Vc4`qPL3To?4WVYz)QZ3c|0$nx4@#JNxO$ zrbd5IDhOCZIQ6gGd9W5~51XA#Oy9nVA?Pdni3Hg&aW z`H7!JE7YFx2tmz#`z#RPd!4mMawqTHL!tDbr9%T2I2V^XM%-XEWjhAlCc4Kn@K|YR z&?4yW+6fAzVY$CwP{GNgcdFk{&3!fFg-J{23;T&B5Zbh9Q@7u?ty`M_tWzowkUzKG z(K>|iylv(*+P8aGN~qz0$jTpA>&UdzwAUU!Dj=`62dse&7KRGmh6WriWRja&D|%t5b>6 zSw!f$lT1<7vjJ);dfyhU7E9dNuQ&|Y-{l0SIt@XVIVLnyT1U&?-jRJ{-U*ba2bj|e z3UFmA3=I>##r3r1iU`ue4Gqb=lhafXY{D-$xE;>HRq0s{Il+&j!}ui1-3_wOafIO+ z!3;Io74mSq)Pwu?zwzBq)f1C~Nmtj<;PC9ExqrYM0#(brzizX$uPpOsVlf749m(^x zHn()@-#<1Wufn!j3#z)-(pPw78C;8$G|Q1W_hJq=C2)<(?A@lG+(;%c>gE$V*|dQlAZq9N8Ar+sd)tu9m&tIc zqH*o1LhA|RqbPDV$5$+3*PhdVL!`?woOj;CqXsQuR1}1zwM3)x!fTWTkL%nJ`LIPv z$t3>XC<3aoK7rJ~paf@77tY8~rM1%v>88xD@v?rz5Zjs=9+rx))V;IoeD=&+Qv{j& zV2pG97raRtNJmd!2|mPg+kqQz29ORK;_25v&Y9YLX*D0ip2VKv505x8dyz9i!HpK! zVHKh$9UL_hw85`S7cwIa#UMC39KqbYyh_}`a~zJiEKfZgA?0-bjHY}4?eg;7C^sQ@ zaq*jaCnt}|O#l<~JjPCt+7{Z}-^$jcz9+G}-!A{Zh0VWj-$pD>hys+>+I&e6dkPgbqnf1u*eE2s%*qz`!voi;+X}<#y8%RQ_+GkzCdS*_SEz)kk z%{E)jK0LJlwcc>dZ>Rnce(w*yTN;N^?{sQFw2xM{AYf9^Ck=r#&hV9(y82I_xM8C9 z5RQ^Uefu4m)4>>UWlnIJ{rfAucR@f?7y+Jxva*eH0Cc2)P48k@D0+(XM=l7+;6XTqgBk4!^m&Mo z012Ye7)V+;a4mEEa-sLHhaP&jREoCgOu_K3pg`{ZftxgqpcoGUSZY8K*xo;JC{(+J z?@ae&eeSn&cO!K;={7^-)eIMsRDnpOgWTgXfJneQq)-4l8!m?hq8-xhkF@F3i1UxW zsNI$TD2a$6sdAtgFDWVM3z2?#c#Z5dNkB>Ihc`pUoefZIduKy^Jp%?tuEG6;kU}tK z_tJPxFJUDc8Q(`h3aFT)hZI6!GsdURit1006GxT z9Z4Pv-G)|U=%?A=^IJKOWv*MbnzsUVXmYoKiVz?YsAeT{LxOe!QR8@BhI$GxVQvy6 zVBlD^2bC|LmDGT?8Rx&k$#eljnKz9QhcFbew-o}K46||-QiZXwpaRJn-SdpNZZGkd zKM*gBPNUtF8LJwCG=PIo@!TF@m_$jGe5$A}?a5+~YE-2{pukkpJgrJ0r6VwqE&^6a z(TbBMlrg{|1UW^e;Y|BMaqzTPk#h`!VKoo}3^SCKmzS@os#<~bM`HQSTCstcc}#=| zybFGO|FpyLeN)psBTFfF^wD+VA6QC%PJh!K6HEk7sl<4XzErCraLJ4lS`}zbKYq#} zi?@rq?bd_16+b1yBO}|6JZ&amV1SX37y;rhsHFskgoJqTZG=oyu)tls7*W%-X-LRC z-^#;Y3SV$qQygX6pO1}>CS9=yx(;F(|4|^ipG&-MJmu}$W1+$}>0|f0g2hnXMnvjx zq=mR7IsraNPFxw-yM6~L#p|tryCu6vX|?Aa@SxQc6f22|SvSTlkbXG6rk_1J8qH1C zHjoUuV&X<$ki2Cy#z4F;P*y0uq9OcHH(u=KI@IP!h_jZBE$yUMd}w$ZEH4WX2Lh*e zcXzk;u8rH~e`Axh5cnu6M*P7|Tj&)Bx+L;ZXBSOyy#Iin5UR9netfMaTG8Lf#t!o_ zL>sv}J6AkA-Galx;O%>t5*^=1$jmO6cDY$vLRV~Tef_9i#K>lwF$LODL6E(T=A z3&>1j6`2H|R`2T!3$NXk3fe*XJMvjY{|99Bm*i5A>Am}_ILtGBJseEC~L z4<^AVUD)EiMNrHe|2ATY_Z+6i)8V>RBPJ)8U&&{N3HUrxeY?+vQYwEZ_fAiA^K)=a z{N1aavsJ~5U%Wx3RrJP*&^${+t5(SghdX!iI^-w3X;*T!VX61?%)OrWe=&o07Es); z&A$kgheJuy0`Lzv0M@EGeci@#j_1?SC+zm?jjnh8m^Q2$2`u@(k}Il9|_o|*J35W%00 zZBTSYF&sr~N(J6Ge20>lpla0D?Tg7rMUKDt^k~UFJDlZl_~JcUuyV-HgBogm`abZT zVXaqCHYj;4h*SfX7@r|iuKE(_3+U?AJH zG#okVz4Y`UubCorD1PGPz}O%u6)6xCUg-TpoNtqq*W*|MLbbT2!tTUz+dKiHVOhB67k4b*fPO0L2`aJuNl+?I)3k$jdZ zL@Tp+{6hlOuby#p$JC7F^NSN4^=b7N5;IULYHL>k<N}i;v{_meDkY#4SKW#L(i2l9jDZ(Y+i2$8pn-^g-u(w zq>(7}TL6YuslnAVvisoZWZy=x$bP2yUU!*&^v8AUQgrn}SO9PQi~7IigiQYKr-^DA zMiFF0Ux#$wtb5rJiQA)B>Q)3I&9y|62Jy9!|C+K4YxyWGExpVO6BeeXYzNoC_tyu5 zkglZLw+(bcG`vDX54|kdl|32*%`QXv461t^Ht|0HNUDPMl@8@JZw6c`fyMKqr}bxM zW;!~-tW%h?yS@We8@V$M$OgRoB9fEMlIC?p*5Q)XV%`811u$C;cJZorcZQuvjF?u( zIquio42eIJ=h`mi#3wGB1#icHvZ(NS!I^tS^ROmqe2GiL%|g1Dr`k}Y;{zoYUd0Nc zo99SAhw3c2Fm*cT2|H=@FUZ^>U9~uY&pV|q0f{UuE-rUTP%k1RD({R}u0Hm5@6%p7mZ?V~51^mu7Ls=s02{<+df`~J zq4VDjYRSUGF@I!5F0bKnrRD{-stA4$YrNWf6hje@LW73zBcQiUc>C?HOnUMV+Cd(~ zj-2BMUgh4sdlelWJRsqbvM7(-*((GH1Cp;`v*zfcg-Ut=2CDK zrkIl&1{=M)b?oEE+sbCYGLm+#S)?c=i%Hw`CZk^(?|3KkLV;6v+pPolk2(H99o%i& zsN7$f(!bxKG(zQ1Kbu3xGkQuBGI274*_L5bX{m%#Xm#q17iknf6UQF`6YbJX7jSHc zVPpERYadH}F@m6hXRn?mH6_t0&U$8<971<$gwpn?0DJuL_Xx>QoIAadzxGP}EkIraG zp?Q70yo(@FcA*4<*bmBFBr=yCm=#j5CX`0sxo_!{Gc!9~?oE_|%hd}{OY&6kkq`5& z)>#dj8tQN~iaPC`b;z)ge^XK3CMdMLYQClbF0DTB5h@DqVoRKc{OR|?9rh#A|vnXGV5k-9FL~hn3q+p^*3!38n>MTxN(6rkz1&cJIDp503n~{pDeb zsh91ttFmc?C<5@fHd8`SL!W^l0B)q7v=oyU=jidpJ6!G!B0ybFM4u>k(H4c8%}WF| z#Qc)#^R^SuDj;x|i=Geo2rg8vRe>UF@%}2dM+uuk6z(dJI}*xW0f=rZDOk;h=eZem zabvj&Am8;ONCw1vRK!&Bq9ek1@FOhIX@S(J^_wozI^gw-iOMZqNVmd}3Q;I%EV>Nl zCLiIsJl95YQkYa_Y`IWfEAKHHa>OWJ>@3IP`j@0nn51>N$MzN`LKtvLD2W+5BHlw#xo=0%X0E6RTA66kBsKu9(Qi1Me zb(>d2$7y88RdRk1Ln{tovYNcl%vKV3V1o$_fq(#5)1x`2%53}Q2T8tOx`5Cc_5Ks{ zw3fp^@&9ZZT08}**SEVZZA+9k*d;nR*M7n9ZS|V4&^j5YhCVD^z!6#T>+s>j)wq`g zJ0hzM`d#j`XX?1?gr$m1WECoXMQ8WA)nuV#WaUw9TV5HvwZM@<@(KaX#{z}HLfn_^ zPE?F*L3e4!T_%SJ6g3>fAS83Nt9e7QJOdrO=RYk1I+hAp^p$by;zg{dC^cA%{diU& zoAx<87{(9hx*6RY5UXWCu{i_vF+$b@%0BSPEK|=CAg3pYS;RgX8W~lBy-YmtKXO*m zXc^|Q2B89b7ubZen;WzvH(`1a0dtVK>>KhQZNUm7lpo{lLgZM=1jLm<7Bjx%`nxFq)6fmbH!aei4 z;^^oYg32k^71gPP)9u-bxrpj28yd#1?k>h1Hl+yQ={L7~7)1>L-FAB%&|Vnk#{QP>~1vF=YNCr%w5s}=7d6jD)fGbjCez{4M4gmU) z{{DX6c{EQD8sbl12c#)6X%ldy)S8;LO7k%Na_#f6C)<9Hf-l90O^_=bgT5LAs8n7m z8!n-XY2W&YltXCFy9i)+{pU*pbXAB+o{fQ>c-`LEk6|hR`eJrhvtVZ5<^O`#{bMLycXZMyA9@NB8kV{Vz?sb1&s+pt5uhU^G>`GmVYt2o z?Iw5*sfHm8zR;=YJG&i>=!-~q&EMZUKn^r%HFq02veht`LR1wHP~kmRW$Ha_G04iXWFs|V-&2fUi^X~l7W2B3(6Pg>|svLb_qVnB}9N9U-vQbtMDQO>nJ3ARpRUk*bD>v0~cs;cs;NH zoJ(ZbD^T+xeYUt9M^n^jaHM*G$rFTlyt^FU+*<$+6lPkn6JBj{dio*&P1O2=P!g&_ z5C^wJA_Ec$0iyt!hYRE`uzfC7&ZD`Ujfq>D8UzOdf{;N#`-NG7)}n-|(p{^L`9I}L ziz_KIhy%J8e*WBCJBKSmQdC@UDhdwnE5MVaU5S(*d}r5gIg-%iLtB9FA-)Q59RQL= zQ1)xln7eg@if<^H3x(KM{`@#Ep{*gR*aO;H=^Cv4O5ic>=IvBMpkQ#enMP~pD@rfh@I>=h0n868AW z11t{7Wc=sHvgGWAF~_>QCz5nY`~8dt)T;BOR(N)*~v5MI2(o8UM$m_+HC{{Q9u@%VmcE&@4| zAo$QTkXKZ+MC1y-hbW;65)BRHrKk(HBz^3||I*%0eXZ#I8=H_odw5@ME4PfaAm%6hrBfDsU3{@~GpDUw#F^TGVW8Y$A7Jms|6jNlMK^XGKI4@9-xSGFi97=bp_A{sA! zDm;GzZXB&WG%tq7va4kMN%nm{9Y4(GVF#o6ksS zd&z!!UARQ?X@?=Q;nAOLxRnEDA_*_eqKZdl0ejo+84I=Qwb#~w(b=i@C|kBRjoM*O zF|FpR=cijVC<3S%z3mCzuDaIsiZjYZp4mcKGT4M`v9WfODuc3wq-gV&tF&_i408TE z;D~NyS03T0uAro#>aBL}+_SEonB&=6=7ci$=bnXi)T)!eetl5kps8jtgdRmy1?u9 zYNd^VwEMd1p*O1n6OHpGcFM}KBLD|d{K7+zh&-cW#P}=`^9K4)bc54?v$u+rHsJW5 zMO2SkVa5^M>JZmS8cMR?4EG|cJ!^0uaDGBScRW&>n8=4XjOnbgFslXXY^eJxLs!KG zT&l6TZF87MBGqm<^%80Yq|ycc{N&eaMo>(6<((u^=1V=iq=`tm-KEsmt0Bxn5H?6cWMojE+7!KaUY86&LB*CPA_y zJuC!PbRU`GQ5{780?ZaG5{4oV79T%*&eN#tGNLS1basa%Dh6nMJ1_YndMre_?fm%X zO1w8JgW7%oG-!WE``t6LvDv)1IPXLmxpDlPvD;z1CaHv<8(wQ^WtE4cg~o}79u@z& zZ(H;p#!M;yLb_E0Z2lVhBf%KRLO}?~K|?bnD_uxC3#AA599pVDm42n@tKgEcI~wT< zRGu`dmGTQe)8mNgW#|JmmzqwvPd$H&|@bRU5tt!C!CplmY?*6+JuA{P+VA&RD2wYN~l#L?O15 z2X|_jQM`L`mJ~B<@M)ygtMoS7we6kQxNoRsRt?2xV|K=QmRCzY#lR>zau#aKDd`eT~bWUMUZ^HBJJwv z%Q_%pH^PL$IuM!Plik@Eg)JT%L&jbDV@3vciZO>{%~JQ$qQPCiOBXK+Kp;8Ld!xtR zmY3Lo=dTCRsD*AQPZq|Qijq`< zf~NJ@N)METG*OdaYMX$|2%J+lont*~bUNt`IvScpe@{taTO$L|Q6seToxkN6Z> z@d8*eVZB2?6OcL#0E|NgDzBD#Mnhx6e7Tda{D|Cus86}S(X@T+Z^fb8A3aH&ZD53r)5?8cj&QuT@_gy*FgAe(U4lufjN zWy>dA1EpHJOmGgDsa42tlWZSf2@6w2-@&i8dcBTZQ*`KF@N zho)l)T}#gj;$`h`*>{4aW`WGQ!{6wJIAJv^Xt12R&pn_Atqv2-dWBuPgcKA$_1J3* z<;d0{od_o&6T(mU3U5v0!CxIMO1I(Z671g^ozl)G@g!imO01Ahk?Sc^0VR^PR zpFl7n_EUjJ*^&i1ui0+`Rz9762f?DDvGL1y@3z$nexX74&a@Jzdi#ED?Z)R_O`$89 z-$mV+yA?)wyY1O0!8ko8oVV_jpzx#r#G1L3y=5ppScch=M>)9|(@d!#K_fZP2@h{$ z!{+)NXRM}y9H>>t-@5f+>Nm1y48U399k|r*kq|M$WxMb_xxMeiTI|i8{)~u-LqTjj zMmJo%HpM*Myp3s7c_g_CdqTN&I@MF5dUg)=!PPif zd+N@PXExkA7SKo)7ZO?-=$)dFS^#~lS?_sS^-VUzG1}uNn3+qiPT5O9Rh=c`@RJM$ z_Rm;WY^0V+iDz?uHSe9|R zZSmldBOoivGTc;x+l=?{djK#b6-(*e$$p+ybaZOm(bHF!(WUypcU8b~ z%LQeCD10GoCdf2y&@HQ8?=baXFs)L-@t_1|WQg!8o}&X7P-FjoI^ai>ueT%>$umVJXFK+Untqz>X5*!ASx9er z@npTq=|=$ztB6MN2Xq`DOH@2p=Pq^X-3##=*NHCWG22Q==kqw62l`3S5!qW+V#fJd zGx<^)W_D$Pwl+2#b3dAtx&SCa(IxN)|HStv5*mJhZY;kPs37N}zPspu-S5X_iS=PI zLg)I&ckJ?ia4+u2Z391aZZMRZ#tatm^71B(DxRk~g>l5FjaY)cG>c!S$_R+<%6BwQ z@&or-3Jeis-m3Gn6P*P)O}Zzhe0YO`$tmI7u)$O~BKwh^*jUx#9h$kY@L=3Z8KVg# zGqF3@3Q|zj?@jl!P&_5!aqR6>&Z@lGFY9Tcco(z&U0kNCamjDkA1{9v$%pbk!w29{ zq|fkv8jw9K^(gBA|K5nC@-W05_H0&Q^h>txl&Mv~;X@O#Q#?vS0HDi`c1mV}?{Ox| z$kgm_#9m0?G5BSzmpyYYG5k4bWEW}`6co6T$Wq-+djG(Q>bx!#W*%3*xO-P%Oz>CH zrae>dfr?PTe>}x>`=lZVg<>FZKwVYuj%e6^@wu@HO58# z_*C=en&`RRc5nHPt{IP1%A=ronhcjtIhu3ep;L!3!a$Jg&P>ZcNm6yh_jY2v$SEk^KFU?CK9xDmv~`IY%_>WVEJz{`Ke z__rH9rV|}55UT?2+wrO%Or8kozyD8lZyuIo+xCr~70HljHl|EXk}{-3QX)ikHE19W z6hhJsPpHRtyxESrqi=5cu`exa2^_q07|4#I z=hx4EbJs>a3UiqE0Jy;i#S()h*KLNZV3O%6uWO;WPV9~i#zUZitc5I=f0|tlNsT(b z3mb#q-!N)u6}!8q@@jJGee?x_;(}2v*o%@*bk&j+7Hl0Ug~%!cBsXrlx907T(V}BR z7r$g)023dzY2eASR)i(>XG60l%nSs7LuvaC5->s%>|o|3z#diYCe*3Gg!a`bz;+AY z$4;gYkP2DaNc)W9hvos10}9dx_>R-7_li%2igqGC;UySJa5!8dVF8L%k`iKPE&3CKbpa!^BZ2kiT}%SC{B?ErL{sKB$UrZt3tnbg)ylq3PN%50FGHURp54Sv+NrFqwUpXg1q_Z(_wXCR^Z9b9w{k@sh zsre&>v_1hGI1?}q#O{Ziv$>&Rb;l=$5Fzp95H!_w>$T7(Xh0xF3b_lHE)mcC=~end zEcr={HKsD-kkQR^k`cm+Duw!c#l9yKporupMifeKB0u3W)B1!%U z$iR#eee^2Zb`Gw~415yu_oM0}vI4)HhaI8kumxxl5&_^Vrtd4_9EbameTkcZVMCU^ zr$S*M8iyAO02W7M$)j0OCf9?jGWq3k3kjWvummjiX5ZTI@~GSN$#A_1q)D^bXwQ4s-cEJ^?7LCuMyc>S)>XT>_tXcfn;^u$4JK*rHMiZc zY|nLf(H>6rTpzW@D%<-3hYC19JE+Y_wu%P11f3Gj`=F0qX6j-y=dTmrcwntq^x6{( zp{N^DyOWGKqWmw~&&LV>S$lEKX@e!l4*DDt7o6x`%sctda0gFuS(%XYvfJm3Aaa1K z&3Ea}@HPnLs14D2gxiNz9J}L$z$6&yfJh=&5LQ6711t?ks3HL%*ZLL9aRQFT*$T0g z2pY>0;LykCJ!=2-DgMX(;9#L3aBR?hgNNWK_&qp>pue!yfCbf5R0`+pm?`Ch?H3j? z4p7ErDB`?Hs$w`4VG6?K*x={gc~D{EyK-uQK!Q5^eNrmmIzN#O5IAD;RBtmhSEu|e z#Tc4Xjy_i+TYmqCvVVCDWX*+>?Wy+L)V&4kG{!nLAl{*db$E1?;9L?PQg;3M-g_H@ z*#=ZU0c|e<-z#?!5#w}|?B7N#Tw(2$Vx z<8`QI=3zNYvCbu<$D@&Mco;l@?^{>JSzpe#m=v#J4$uA^M%J?YDtp<+fI0WH%xodf z!x~aWQo@9dsBN3}1?HR-+PP!f(FjBu4j*h@6(%=l+vGoUTY&K#t(r6i;v5U2xfLBh zlccZ%k2N|FAlxdjHIXNHC7HDD>|EnAmpVvn5Old=3!ZaDWWyyWq$FAK?kG6Sfw^B? z-?Mw4&F15zYNlodzz_BNumi&^OdTMKolS5dQS>M)Y5y;g|I#}mBNtz+7)q;e;Lnin z0f8hX9nvF=OLd-Xik~)My|I$?xv_6;HZxnm%gamUDTJc?-k1B6&I9T)pEDaW?xm%T z?>d0m^93eL!}s|b6f}Z=IH7_S06>1()AKAq4T4b7l}FP&qOL2u^}u7|nxoH?BE>B5 z77pYUKqUZpiJOSJeUMwu@P3=(xjH{TpGa9KgHbDM5mAlkjCh08`Pgov%SD@YhR5>jp;=8E5Cl(G?AaSEn5=@$XzMAU zw0LI7C7?KM0%PxL7ruF^KGs?w^J~tW^%rFyg+)b2zx$G+)cFI8t3>h5h4L0~OFWQ3 zgR0vcxkAr(FpCf8LX7DUTN zOdeLww3LM)1qIy&d?)0H;Gv8#pC_o5`RV=dxlfZ?2P(`}7Up9p7FyS($ey7rW5gRahwMzqZ!rLFh^wUUXkO=5mKDL~>zZP!K1B?k&r6 zVdOPTiT!oFO^~&F^VV&}V$yT#7(WPMr;-pfeu6!uDs&PejRXQb3IKA1uA6{*qSnVo z-;N>mCPV@?96+FPq)AOs+fKn@&Fqg~dd`U7td5kM?IQHGJq>q6EhY)l1>mLk6N(nd zZ38_-F-rJ*`2*RyTpNblI1mg3ekD|qUs9A`Q{c>Nw{3TxA%Ux-Nl#9j-hf^oXfPY@ z%x0A2vY_~3MGIA&E6J8UVMEEIUWPtn@FW2eUH>f5(G|49hNH6f zQs)iXDnerbvIM5)0|K0K@rhxi|16_3BW&h6at;;wU-dZ5S5ztf%m3_;Luyr^YrLdK z%C&U0#c>utUmpw0@T-4QLz2+{di&+bP->qwBmTiN<>NxLjt34Ng-!10Db|{Of4?@q z_{GW6QEQIL%gt=w6ww{v`YL8!Vt}3Oe_xog!{kj^jo`B%e~il&mFl%5AAbx>x+x?6 z@2ALHW-m+|FHk5X20O(5cI)!FVYz(1KX}X?DoV3bFJKbne`)y2*M;3Lye{^?y0&TV+_M-zbD|>d#9hug z3B~^<*c;ER!g^t6KvV3PJ2@ou{j{}z6kH7MBAl!~-q$bY__*bj;^1LpJ?>P9;JfK@=66yh0Qd?Hz4PKs_r zLavgLzN7qqU$H7ICB*qCxb%xtOclT%3)uX~>IefjBHa>-qMhnK7dask(q=5^viflL z0S7+XTiJgY5*d3<@S%=cY3>Thv}F|;oHflqPf_kZaYYQ zsWFl`_{O-vsIl>pS5i}hw(-RVqr2G+)19RJ8eS*vwOd}D>uogA?zXzR%0_Pt>Ui~Z3f!|z+{Z|ysHa0(wEUm%aJuCA-cPEPT4OJ+Sx zE#`N&-IA0T-(`O14z2(GG^ZMlzW!8L#s$5;) zyWieice#&G)$HA$IpuEFuZ(V(yOcGJOobXW{zBipLMppIsTtX|bffG>{f)Ff5dpvF%0Z=Q8m_{e-&L=p{VLiEo^L-zx zhLPzW<>IfKn%dz5FGjE7h3+OA@Ws_i-)y%@{@P~nfpNWFn={;9=*ym(qhx4)xVhVf zB(7UdVNFh1wDrOa1ZGG8Rr3I(HXX45lm$zP2PlCvsz=bR$Pc&nz^cP3VsQos*93+* zA!wFd{4T}cMtlV2a*RyhB!%2&pNUfi+pyPCk~xh>_dO1()04CfsgI&=U@`k_dP znYMzl->KozqH;&blZk8<_q-|vF}cH-WRmb*OnGYMl~x&yZkHVV^zwmMIBgiUVfZj0 zospO*w0ut+>J=Bi^5NgeaAVxD`9&TveQ{zts{x;ZlTkR?w+Izs(nssdTf&Y97P?So z59(R~QRV=B=!`@FLGstMa`(Gaa=eQJ&K0b7YkIW){qc~$KkIIH{n#U`^$Qn9S0CT8 zUljfAy7i-<$6H%lZ>+Un0_soi2oHl_Rv<%=`Y$X8`YL44!NgS<1k8XxIRE*T zQ|o}!+7|`3W?3G%Qq+!Y2;(B$6U#xmPg$@NN68J@eeBper^D8R5BCnl;LE194yX~S z)gdJe9(-7s$O=+eRmB61uFUb@=ytX!?*Mw87*yLza*%n%V- zKCjVBAn&8n0T3-dmxISo}!m-<|L3D8kdqBU)WUiBy zO{+feDTxQ0X*zUgvCUOapU#9BlHDEaP6){x609ZA7=U)tU}oUBXb12=F$n(Rt<6)W zO=FGDuTzEyGy3?3PPYiCk|Zk=_;`86>g|vYmt_Swa3b@rt1H3rCvHdyz?chJSy>gX z1#sVGHKS2Yz}44%cobHzz?4xWt4z)@Nja`Ob?Ve~q=UxxeG1VhKt8##3tw4f6 z)@TEg39#A?x(4B1S`2HC_d3V(=gv(@4h{=5ZEMjVux`!EX&Q?EY&bM95a{QLww4QW zp;!lK-lvXWSJEx3DaU#{H~*r~XE(P;tNbfv@637F z$2U{^ryXJ>$&ki;qm>Q4MM=s+C8aq6k}MVC<6kI!y$#7fYt_n~MQz&Vfc za1h&m0_aHL$nl)HAh^g2in%O4B>6#CjL4#E6{MMgs8o(3L$OLhib&I)WldA|pn%bz|ab8Z^!AppD0aE8RQ60WTj^p^uuS&CkkQbR!R zPY0+ou?#7(Y+W63^ga@eFoH13JRXQXE;?< z)~t}BX*5iAlEHEcS*774pb|g}UM7Da&-`^*(;Q?#q#XXl4Zv3*!6^ld4RVQ$Q8dRJ zJ0pdnuvq+LG)1>2?e|IaBUBwlt_gFKl1JCl|7vmB`w<{pQN8 z03Wrn9t`P!^!H?X2jDO@Wcw2Ad(I!jociaD9C~gj_qH+W`jq~>zFUuWp3YX<{&t^# zc-kaE?bk2gH#XdAnd^Te$nePgwK;38vI~9;DfIpL!H0`qOSx+8*r(b7KnUX8)VXpU z9jd_Y;Eef(q+Nm(O44GhrY0}gB3?!f{f}PID0IBBz4Sp`T%qEv?ZMuwn|nlCISnue zr9`rhC@oyL3Cg>z-QNSSRmA(Ob}_>txr3Q;H1GRnf2&o!XD^O@RliP&JKO)b<|6P= zwGxUT>4ES>(}&qjUma5iUA(Vc33hSKdH7JsC?$SxjnW;|U}Ey}_X_)d^>V6gk68a` z*F1c@+EWh4kMrV+K~<8s3yit~=}no-z}2K&d4Arn2Z9T8qPMCQ@c2c6vlNb*MRukR zDo`#~;E`=yqL_v##c;{X%iAGsCe{j(`I5+_TEJYs|Mtwo!VJKmNuT!x?giKyIcU&- z5V%ZMc}0az&JhUdu=%A-3TnRxI4x>d2ng+jk2f;1g;ZU6l3|A6&$;rlwpI-&Sv!!Coxv!3UT|FY@mre>(Q?K;0 z$`1o}vJXpMGx%xeaXMiM3&3t<8a0x{(%$gh6L2B{Eo5KE$JlIcE(TrWlt4o9G3DV3 zz!K<61t58xgwypBwh(p(^FwgzdGVGQLSc|q`TY5Fa-HG$m;h5#8Pq0sv*zpkRE7*w zrS;j>rcA^gAeK(Z#TA(;T3bkv7$!KQ;) z+KCJ}!|gUZV{uNjU*Ea@@qq}}OF$J!Nr=OSwYwl=MfG36XUl2$TecvvF!X4?Cl690 zcCE#Z(vK0L5RzPT$xXNiwhD40K^IrpC|~6|NFm|rGPZ;c?8~sS=^1Ized_q3r^3p)ao88>8M%2xwdf05>CQEXn*tVF~!l~o|oRv>a{>Q^sE2n zPO?aonieDiJwGBL0ev2Y)1kRjXLkA3OmELe-N(46rY^^cn7s02tQou`;0&HX zl%mQ-Zs6Q0*QZsd&-tz}R`rrSb;rRm&Rd6<_4A{+@jruV*BnnVVAQ}`ww7&TXnqL% z!!9)wiBwp@H$p94XF|>?BNQbvVF+l4D7O^lHl8w#vl)q`oCPfh!7pjZf&8;Eq^85! zpvfPqieODJB^Pjwib_j4aa@zYj^ESt7O9$V6@`j zToBmM>3b?-7qqnPm3o`=M3KhPp?er$VnO8O(OF zW3dDxb`zxUNZN5RK%#4Z+;4T+cC&ux>xFJR(|$b-B*6}DGviL9ez4CNW?IigPkH{? zvvc>X3pD)=bCD?ky}BobApuI)S*~ImzvoeIQ>!n=Cg?OLHD5`E{>p1*<)^Eno9ezO z;YBuTsS9mH^j8Nu=bhS zPAu!0UEv6Q09=_4M$YEydqBD!NvZjgj;7EIs-iw2@nTE9t8r(H;uJ`{4+f8-|HVE~ z`xXno3_R4H&kyHG?+j%7S(TlAd2W;TxK{nVe&Xk; z5o^uwu143JMFsA+C5%o_`Qj?xy2-90;ZR4E`HKx9XLE1VFBZe-rurkB0)K6_#Q8E| z;>4}@KVfg#dqc@d2EvP}m_T=;w@Co>x%S8&R21h?wmqq<Pz2TjOt)C%eWSF z46UP1U0u-muD=I|%NoZ<0zCpEqAxDgny#4eRrW+_%@ggnqD*<{R$JUW0w)?$_g(=S zq0`}j4^4@v7+EnB0%}ro5W#_xAsQ0l+QWy5L8AJJNj%`IPh}&891Vja{m&W+92eTDJH_#Sc=MzA@B13RdJE0; zUvaJSz2dC8TT`x8cE;-^2_hib9Ysmt`D7{k_TtG2Lgc8M>f;m;5jQ!srNzWYcm+GS z8}xMNQE37ymj&YlS~gNmc_~>tu$DQP4==)!%j=6?Q2iU|LyJFzaY_Dr$4a-Ze z1*o2@}k&V zGNJ(dB-a_}Tc=0|(xc!RplxdR?%l(v42fiikDU{(B=sF2N=-knsCJJUviKuc^7_ip zp)ho)`hT1%-CjtPzFsI+WRZD)#&ls>MwN@$H-yWm|Ix`tZY&%aBG^$S4{Q+a82GkZ z^32+KdTm)+15zE&XWw+)xD=s*`(M9)tr;QI2`H)7-r@YAk0Lx1U^1eLYBcLg6NhM+4E zGSqlWZdKpl;FTYKO^yWJ5)eOK57K#BnKXU_;w=sa-D7IGvF`I{&&Y*>n$qOvjBQ+J zQPn(Bv->-~MZ2>Pb4Dl(LFN0P1z6yiR@0^?C*TJ`;cKj`Riqqv{Rd~+vLC{X5&|?( ztidBgEID@8tuL!ubL=M(d_!3%l|7ytZuR`j&In(TO z6GZw0fQhcdkwT~(s)h7A?uuWDzdWbvaV*5BH)_As8wS9xZ`+!PEtz1w@n~m<9*8|b zYybK6W2di$l$H+zc&OXF(bUB2aV_$VJ#p&tYv&$DVb~=@$~nPP*P5^fKVNel_8A(~vSt=x^`fwZwIt#&C# zK9m?d8vXLH_Qy3XqXicVQNpog-Xb>1v#AyID(>hK_q>pg0{5JPE{REWVP@TYLp9E4 zc;K+rkP3uABGCzCWkTK69_G}#5#LlB&eXggFO+~x#jRX*99_vVRP8rz&h8Bhj47`F zwCM9srR>5(MMefib6#XiHX!Iiaszx$G2wGeb5Ce1rBo%M0b8t$4|2X%j)HZ80wiaL z1J|22XZ17$M9?S{RNS!&v<;%=5Cx(`x!dS0SNZLHDGWWao>|M?jB9S$1?b^|ehzx| zVO4LE3EsqY7C28*Smc*_E2=R#S){`Q=B8^MhB{D_j{`i1dhWy*GeF>Nv{ALEkVJ}^ zqmZM;v)ksEZ<~Qe8COsE7@Ybl2#c-gqgE3?jGI*elw;!%wbX6^})-!xzZM75#A&u%h43(R=&0Q)Ge?$l|{7!l+JW5X;sMN6P8 zrl}8EkJj(0M}4{S@T(bc-cSTOWvk#MfTow5Y)k~`)1zB1ob|Y}aw?V!eJh&6;4@!2 zcl&*VfF(O_wgHJPgH@N3;b5kvQKuw&K_7G#dU%L3=0M4M&eL-;tWvQKVPRp^?x6jh zg`c1X9+q%X*dsZyanZ~*QhY#Zt-9p;K0Fwl@}tHyR|Bz0DBH{szywSD=6}N>XisIx zo`t6&j@3-+BD?-i+O%ilWGe>GOwa*oJAkiH0s`F$f(DCEg=yv=?D;g=ad>$6 zHlTOwy7-yEeMq57DWW)Sb&fkjTQ%`a4Ag20Bm^ZPFwz4a&pDdMhPGoJdDpMZFM+m} zdA~Rx<*0ttkO4+vA}6v9YN%p#Td}PNNrr@W<=XY@Z12Nfe)#aAB=I4Lq2adkJl~)- z?f{5Dssf4!$h2)11l~>g__(RxP+pm%<8;RS6^zhJ$V`Du6ov;523x#A)R3l{qF9Be zkIyta=v^q9j&j+?|A)V)e+P0V^6NLB&2SGfXv<+kaP`oQDSBu3#C|ZJ{feF_AP~V> zH-?9uyB_GT13@@2PtadG2Toh?E;A_P!AZPR7161YRjV9$P-j4m`%dgHl=};Z;FH=~ z9jiCESA1ARwQtdSPHfl!=PwQ_c6TTdZdVM!)~S$yz0r~1P*6Z1Hsg%w1&Sr7?2QUx z7!F|AN$$U2P~aA+$j-qL+ex5qhjazPy2TkTV`F1~47tjgZYr?}KYDM)_^L7}X^1Haapon&k5u zspv?k3$UJ(TJh`|KhWOV6)9g}e;i=%N%USZ77cNg7y>1`PU#KdYtMjGS$gnP|2RgA z$A@Nm#10Tfi@O`&vZnjR8qo{o&z}oWuA6_^5(eoXh``S?1+tU$F-k!Atz@o zDgA-(-NsshU_P@+;!{1yz^SAX!+pM`V8@QO5y72mAl*o810gk`d%JRhuZW?&m?%0S zk(D4ea7KGSyl6xl0eT#NEbz#Y%T2tLo?*z7#z9M*2F0bNPe7!go-0NMp9dvr)YfLG zeJyzK2c5S$f>J1`i_)60UH4c%?50Wwa6&N(3o>&N3<-fI#fgDGx`H}$AEH(y8+&1& zC+`z|W(+1ne@3LZqSF^2G(bY1v=4~mp!wEdeDodUew2xa&4|;<$%&M3IB7grp3$?x z0kaQ1B$&z~X!vMk3vNyu9`v-VEOk7rHPA_rkOtB{>9j9+A0J$TcTl8Js1a)WnIa-Q z3sMi5Bj=g?^|A699v&Vv76Ze`R#IUIh5AAX35xJ1*&lIPq@;xNnDsRkPdOJiH%Ywg zP>G^md|XpQw8b!vDb0Zbv|mMlmsgw~J_f0r(anLCkoH1{51d<)OdmL#NPh$%T*v5& zdEp4aAi;-Ag=cmJZNDrQ_iR?x-HvLiyychk`etvWv53#qA{q+}%U78IEXLwKW;g4*W42_9%%G4iZ` zwyf8LAjn?zMM_sseMct+F1V`lmWq3UqE6qWS0xo5vVYi!IQN(1jI!EEXj}0|r!nG# zg+J9|LePznQyRGh=V4LGFA^2w7FLhDkPHUeun;L*VE3F|Jz|_{cIwV_ z{;=n4qhe#KPs6HP{d_R&!MMO4xlnAdXI&9XCRt&iSfHj$Gv$oUP{Wg&!)xEQsEydJ;Z1L@Gv zJglyBXbLTGxWQ0;D}R$5mu+kOg{xPZ_w^>Yr480?5U$IRJgCsztt3r6F#1jD#om?-9XIgZ%V&H>=7%a5mngCz z=?_rT0uZ*|$@wCoTiIvt-Ex+VolzKM5 zlCFV)y0BVRHxc4vqf~iR#LU&ez>6rWgm(YI30??EF57~yj%rKNAmfO@zzq~6Y@!qP z|@mG6xnvj-}ZCdE;R({lYV6iQ$4vWMp>MgZrAo-TfyKl^?NMOdFnf zcX#&;9w_d%a8RBN#^@Ls&4!i=-3CX<_R{7_bjQx3gk>LlX^cP`Fu7M|`ishWP0&Af zEG>T%`l2Wu6gYH(&0pv24$hZ3xk1b7z=58%6oOZ~7=m~RSa;-BdTpU+6*AJ1>1Xk- znpV>9K*Uj<9zw`-3c?=yog%V;XU6Q&*0$T>Ym%kl;2+lU-%iPW1gjuCx zVjNHWwf|1kM(X43^hx?_Yr%0J-|$Kqzn@-@&b;EFHywXXo6ToP7noj_)i(%SML@8tjNIAU_vaU;{+eYQC|X7{g?kR70~=A-3f`!UddxI*^-vjq_f){)?!m#q z`9-(o3XQq``zt-YFhlk2#;f1a6KlZkz>u0aF0S+5^}X0D>Nt8qMj-^~rM()<=&)`_ zvE!=s_@!v|Dy_o?xq)`sQEE_JT|{bRvacx zG+Nb8!ZGUquWxdxH6_osdicAb>VK}7oHdj?|6cwZEf5X<@AZFhiT{2@I+Vs=2~W_w z|9ky^y-EMW4;gj52i!VUF2vh|z#R_`LWDfEUv+hLyp5;OTVk^_SB5++prIb2QNBIm zsb~+lbJHYOSn7L$J* z8$T7qBp|?_{!WQV_!L&WLp^E+y*D8iAae?Of6@+6b}ax@?2OSUx`z?B>>m)ovQ&mj zC|0qtlEXC126L54BSO(xsW%J}F@O(+7WEv2OAuSo)JOU^IBSi(M;&6l9l0k@mKb!% zg0@Ywr#;6g69ZU@^`fLt?6MTAi&mp9#dHonK`9QLto$8&3@U?CngSYGZ))`(_T_4F zs?P}Agi>4pIt6z3S`BnPh!L^$?Dq5W(%GGwr~&O&U;`#qC)v&G49sS6f^$X$jCe*kdN`VM6*vHD&l?c!-O@j~HR=!ND;!gSa*F@tk(}IIFE|$B?^eEi zsT=*H4*xHeUf_4aAq73mp}t~J2dDJTO0Xta9R}gHs1%u!UOXS8iW+X0fPjci2#(s?&3xE<+@CIZ6J_c|Z9aABY2Uvf08I=JX zs>TmPEz8bOEHRpmB1Aqzl1)TO_y#vWi1n$|Ko;@Vki6i=t-G@hq31!~L{v+eCdHO-R*~0q51&eahK1a3CjfSKR?SbP{?p-hO_Y zLF6IXgn{seDhLVyW6Th&hg9fU5Ui58g2L_)(`4lP+kvIu+k}iW-;^XO8PGSe@w=LK z<|LXxEW^-OMU!*^wKiRoTes#CW{S_W40~uA(xFI|_SQnv>wmd7t|^k=ay4Dpa52&kMk1V$jk>i!KAwo6J0^snK5NI>NG1M)`ETdv}KA z*2qratTWL@bmqTts7V3u$%iG$51QIw_XkvESF@WT01WKpFAzNRurXpqO?}SIvEcSv zVc6_gRp|GpEW^b*6;eEwTch_-uoDEX&R43Q6Q#@S^&UZ$b{R`bD7RDsSjlCSz}sw3 z13ltB>fNaKrdltw?`EQL?mB~$ri(W{nIIS_h5Ul6>xCg_jnCY!rR4{_B)tEk1k_wT zcJRJ#@v=ZnzGUT!vwEkk2C8%+cZ(@L0Mw&a4p^Sv=we0uP6Y)8H021r7F)Vh!$uij zC!jmW`Fm7DYf;bky<_}SMb!W|#Tf5KR}~QSF1WW{{`~}f96V@O+1=s8_pUe&B-G!} z7nyCmN2_jp>M?;-B`fm{bV(*wYr~Ubk&>{ew+E7zpa=8!7;t-JH?jEg;=28^n*tm4 z4yy=6AF!ng{p8(D9}}6f%QF`;3`h*rybUgMiEs}WatP(*xA?^P;HRWDJTeo>0onJ3kCQa_0X}J79|`;QMAY93}|fL`o}$q`)W3a9`wSFS7Y^1 z@M5E0t>BWhcoXesrKBnZvYRCRv8P8$d4v52AAJidVFI@N0NSbaH7~k;Wa}t#1n_UL zi#s3At00&I&|Ib#%DS_iKM$POHrR>Fi=YT@mC-U0fxWQ5)S;%~?e87x(?0bnmK{p`B3zsQ!67gc;(SR1M5VAX@w@LW z*}g-sY9EfWH>y3>l>jsRFi?}B**Z|EdYOF0=O*twqBRh|i$FsjWY=iSzTsb?kI||9 z>&DU}eauhdL0WnHuwBoJRjbqi&a+vM4M(@@PMcy2z&OiW5;}8LuoYCJp?w5bG7n~< zCjcoHT&Pxm5U>+lKNbB9+H(=nKr=Z^0W#4% zQEXW!X0HBSfUQ&v!6l%%Xs7~qyzelb-v;C|{C4cmo#Xi4iBG3(@v_%zZk$r+zKF4Tb$_8s8|;LTJqEZp&@@I#id~#oX0Drb#u;pC^?{Tivsw9 zEm}igUy!ms=^&!CQym@NKR+VIC~F4QkW}WGtuOR!_egEA$B!-rUBN+fm_^XR)&+gc zF;XO`0JoWI!O_!_4n-^Ci+U2@RqKc18AWyCI9{D>DzGT$>v{ntU(BqP2uR#x`4iuB z3e)bprnTB=8VZB}b4q*h?~K5@JdVJkI6ARefTezC3V!TKmfl}DTYkR}>m#s>`k>!P zZHvi(Mo}g$88?;Pog|z7&CfQ}rzO4)so*oMIvf-hwhYQeN!ypetZYv@eC)=NqmD}u zn~TvBk#EfQ>RQ#ubvNPkxmOP{8Yb~&s#@{OFGffqe~vN@8&cdk2ts zwSy3BvMf(xaR@=xyPafAc&@}CXE$lj#WOOk>9DSY^N#vuw)dq{lPtG5PZbTEgVMg% zzN9d+TRb-y4V%rfOXFh_5kiKN=C)X6QqT0G`}bcW1_as>wySHBra#mP_HCc5^z-O8 zXL=-bZ*}b4t;`xEunf9IHiqVs0?kNRmiomc3sY@zp6vn#z!c)3TBXPtZ|RlmYYo;{ zSjkbEp_zG@d#4d8w|K3=$?)zy5T7Exa56*p9lN);iO0u-Psz1{M+isuYV^SrSct76 z;KBMm1_L{rZ4;-{svm#uXYpdwZ7Fv%KD)$JM^{IOv2Li>%@QzHM`R&Q5 zOS;an@y|{6&%C2h=GXp!ZHkDJmy4JEFNq|NiiV{Tr_X_}VJ{D@IZOhY@JD4x4Z`Z+ zyxN!zNlL8Wb=14mHUgTItyv5Qn_v@+i@qsbkFUBp`E3xeL>yQq>OBhSDjN7FN(nH`dI}a5w zeI~2ss%KqnH(AzwdeR?dgDi);3!Z<^H5x?kS(9#|0nC~RBV5~0Ap8@0Ivw=fDiU`D zzFVc|bmDbN150mFV(7BLSZT6xu zvbh^YU2W9+End0WRRF6Yy3$dP&R_vLgKZGo;-0s+8ysLvhRL6lRPcO`3HKku4-c4< zouRo$y1KnP7-U6?Dg!xhG%jZwFgkkYbrBY zcE7Z1NFa`oU4|jkDxhLAk{Z3?tkNseW*OsfJ~(Q$@n&;|m3RN9fb22tj+~oAJNMIR z;Yv(|4d+_hHV3_-irgJPI{seuZd`T6=&#!EJx_E2ovoFgg>s8!v;>tGgnc{5rTwHx zt!wUWOpVBV12b1Z?)r<#$yVV$i|jsrqi}zJ zQJ7~ZFxrTM@ed76$_xhlpgCyI>bs#B|IR0DNQV{J-QBCgL{qm_ZVz7 zxKS8&Tw}$mB+w%Wem)%834gh^((|K$Ce!n8EnTu?3aSS-6^bOD`w`!zPRlqnBt!zV zpF~M5nhoEc)%zF!{3rnfMR`IPT-h>#U2t~-xRXg+hta)+IBA|naQ5FSUU$^$7ud(z zx-!5|vrG2Q572vvPRLMkgQ&3N|^HOF{H_euywVdSG=@2;0ckqjan9GjSAZzJ*5z~tIvH);RtTD|nf>FaJE&#i1 zNA#8Tk^_TKWh~h-O9`#CZ)5WVyM>fEift+yB^K#JP!WFzdPt2JV*3MgdvXyAhHSs( z4#}y}BxS?f*S>{{(LWrig_EE@65n+O3jW1STEL@e*dz6~D4Enz;SpH;;NioC@D<>+ zEXH2RyyrGDf{HbE;MuLUeAGaqXIX&}Q8@W0;lE!3iVJ4@JDen1n=- zGuOHihaqu3P|;rq37M5Y`b7zCo+yT&bt+;#Ufe%}B&?u}FQNR3hN9lN!*>noQBlfK z2@Kgoke@HCJP6gh{VIJnhiPUPq9SBLrxKEhs^L6B7KmvN3-hH=F=(#Gk#7cYE|O%H zA$KI8Aq)H{Wdi|A*f8gVQL9``J5Re2)dMZOfFS5hSmn%dO$WOxCl zv2FJs0}-4(`achCvO8r)$;QkKe5jJ{DWL^Ufw>;{@85rL=67!C!0b6YhOW0q`otCd zxf2)X1xsjBvaw9?p}JEGAsSVSJ-_8eXry@;I4?= z)K4}%3$;Ky7CU)1pjoeh8jZr^5G7pqSV_!w7@i*LCJA>yqx1xlB?vSopqIgdkA}a1 z76%UcXS=Ug7@`~ejx|9amfju3mk)MPE>Wt0D5M$BUI}pZl{dMQ@FywR9}21~XlvW> zWHRpP90*;xfgw{^ofX5T+GoJ5Y7h`&R(*S8txDU?ww!~`&Ze;j-`A~@M)45oKUwrb z{&@iFe_uN4DPNiYK&+SRFd^_i|L}i+xBhP-?f)TK`kxQ=e}bC-KYzrQDBL_r zG9E!X1=-ieCD&;LdEL|11cYmPkK^u==^$UhCC^4RPNU4t(7R&25F`pIoUr`Hbii6`_Ytu zV*}lKbCq5A0qwc?1@-AJqR6QUXwm~aDQS-(GCy;>{{;IJCoX_6Xs}p>cXtsOCpK7z zBhHK@1mwXNSWG-mU{_rNAE|VJDAD*jMZc>oa7kzflQXshg@#9VI)lM?24}6%wc=_p z425(YJ~#fJ6OW4G*C=zqDvz-vvoUxqciqgZr~(Cn58ANNlEn{Ao#{hPmEU*W@b;Tf z=EFcy1CbVcB|g>FkdWP$^9agsDjw%o1h(Nh$DzhBI7FofM*voX(IF*AzY$Qz*cEs9 zuYi}b`I#g?fPp*~n0!Hz&j2a_Tp-8fl4>)=OaEJIX%?^X8PY-`<7OA6eb{)5Q0w7n zA*hnJ1i012hIZmp60T1)H!|9{qyA8x#My zuz7RjGO|B-# zBjUj!He!3f*oJQHOcFl3h;m;7d0vtgqpjWG(c*}fbN z1#WJ*q?9j3V;D*01CVkbZa>8pQQ{x8e6X&km*)m(_lIY|7Y)cZASegkYl=#MGX&sx zpu>%uH)$a9Vy{g?_>}GdH$*{6W3N5Hiw*OW!&2Hcy}ID)naRX>;OU_R5LksmDLras z;zC*3T}B&F7TfN|=!%476B!|ZMf$t(aAv`cD=*IneGSX#1K1GyG3@SCvTYM+#%8}f zkg9f6&jv;^sOZ<79^Tb^3LOR?9^;D@Xh^(BsLe!yCqLMseFw-1yE~~d|4+h0S6M~H z*&vqG8}@Ml7`ccekT!6Xtg!i<=T`!&_vp+x*&1bz;k1-~f9!qvOd=$p$`OZ}#jd0BEpiZLC5;tm))PuUyG;`2&fT zz)fY@v4w6KT_6_l>2RlO?L|Z)ci-4It|Z0y`r}4{N2y@g;AMKr zTOVnQs#d?*PhA)sW=qwZmKIHx#u@0YB!fFe7HwF%^v){>DVLp3 zE#(3q-J$bDrK_#Cut%OFQW22*KT_WP-V9{<_&4k}G&BQ=fQ=!zG!nN{2=2zD?}slY zq9}_u3EGg3K?4(z!t2|8!p=@YZ+j|-df(H^$|Mz@wHHB@k+jXduX)m0x9etKzI;&( ztv`w&Db2EpFY8b~%i1=r#CTrc3xP zkE?7oz@LIHP`W0UQdc3Bjd`zk?3gUfi+A5Jbg7pDIKx5>lmJrDm9u?`?udzT-<9SQ zu-5Z7M%x?)1b#g{0(nTq%~FT{9hSEhf5tp;g`Z*kjL7_jOH^y9lUl@lp-5O_%YuS1 zI1`t0CbB%R^;F={O$<;-zkh#u^(INTYm4A)m1;hOnGaYH41-mv?&9L&*DSBuF zT(ic&DhE$DEN6N*SEOR+ndq{*Q>5R-?vRlUFk;dxGT*@0m_e6#kZ;$2G~%Bec39wP zy#dVQV8uG#0cgNNVHx-Iz(ep;EA&Ua!2PlAP`DY!`vZ0R2M|} z09%Bat0O7kETqUN(b0&}Rlo+NVG9ralU z8bO@%K^1)!`xi)S9Y&}CO4!F>HNK;_??B1~nhTfo4w-FUt-6V&DLOuGu~;0q?H4>e zwpDpRhW&oE28L5Kj@Mzcg#J|sxHdES_|D@D>Y$)PTm^#UN%o0r4=oVkwNM|>6z5+b zH;kPHV^*6hxO|Tfpl_Pcg{D;zB5wcd*LAyvVRK1?}VM ziD_je@)|;gjc~Su>DeJ}Dl~;Xs`lFCk`r>+$kkY1NCuDdVLf!d=Wu#=|5dcbDqN;> zNPBIZ@R+9F&XxF6Vw?U6Z7Nn^U#D0V0H!aU#OZA$|8G*4yo*<T{{rLzVyFNB literal 0 HcmV?d00001 From e741f0db835a4aa352e90caa52b0ea4c86ad0cff Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Mon, 18 Nov 2024 21:27:42 +0100 Subject: [PATCH 119/125] Aktualisieren von _saint_venant_kirchhoff_orthotropic.py --- .../_saint_venant_kirchhoff_orthotropic.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py index 7249a310..63a0774a 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py @@ -32,7 +32,7 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): mu : list of float List of the three shear moduli. lmbda : list of float - The six orthotropic moduli. + The six (upper triangle) orthotropic moduli. r1 : list of float First normal vector of planes of symmetry. r2 : list of float @@ -47,11 +47,11 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): .. math:: :label: psi-svk-ortho - \psi = \sum_{i=1}^3 - \mu\_i \boldsymbol{E} : \boldsymbol{r}_i \otimes \boldsymbol{r}_i + - \sum_{i=1)^3 \sum_{j=1)^3 \frac{\lambda_{ij}}{2} - \left(\boldsymbol{E} : \boldsymbol{r}_i \otimes \boldsymbol{r}_i \right) - \left(\boldsymbol{E} : \boldsymbol{r}_j \otimes \boldsymbol{r}_j \right) + \psi = \sum_{a=1}^3 + \mu_a \boldsymbol{E} : \boldsymbol{r}_a \otimes \boldsymbol{r}_a + + \sum_{a=1}^3 \sum_{b=1}^3 \frac{\lambda_{ab}}{2} + \left(\boldsymbol{E} : \boldsymbol{r}_a \otimes \boldsymbol{r}_a \right) + \left(\boldsymbol{E} : \boldsymbol{r}_b \otimes \boldsymbol{r}_b \right) Examples -------- From 98f42f3cb418042956495c2a380c3e24ce4d68e8 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 19 Nov 2024 21:34:17 +0100 Subject: [PATCH 120/125] Add `constitution.lame_converter_orthotropic()` (#904) --- docs/felupe/constitution/tools.rst | 3 + src/felupe/constitution/__init__.py | 2 + .../linear_elasticity/__init__.py | 3 +- .../linear_elasticity/_lame_converter.py | 71 +++++++++++++++++ .../_linear_elastic_orthotropic.py | 76 +++++-------------- .../_saint_venant_kirchhoff_orthotropic.py | 18 +++-- tests/test_constitution.py | 22 +++--- 7 files changed, 120 insertions(+), 75 deletions(-) diff --git a/docs/felupe/constitution/tools.rst b/docs/felupe/constitution/tools.rst index ed6f658f..7614342e 100644 --- a/docs/felupe/constitution/tools.rst +++ b/docs/felupe/constitution/tools.rst @@ -29,6 +29,7 @@ This page contains tools and helpers for constitutive material formulations. .. autosummary:: constitution.lame_converter + constitution.lame_converter_orthotropic **Detailed API Reference** @@ -68,3 +69,5 @@ This page contains tools and helpers for constitutive material formulations. :inherited-members: .. autofunction:: felupe.constitution.lame_converter + +.. autofunction:: felupe.constitution.lame_converter_orthotropic \ No newline at end of file diff --git a/src/felupe/constitution/__init__.py b/src/felupe/constitution/__init__.py index 13d0f113..1907f408 100644 --- a/src/felupe/constitution/__init__.py +++ b/src/felupe/constitution/__init__.py @@ -12,6 +12,7 @@ LinearElasticPlaneStress, LinearElasticTensorNotation, lame_converter, + lame_converter_orthotropic, ) from .poisson import Laplace from .small_strain import MaterialStrain @@ -32,6 +33,7 @@ "LinearElasticPlaneStress", "LinearElasticTensorNotation", "lame_converter", + "lame_converter_orthotropic", "OgdenRoxburgh", "LinearElasticPlasticIsotropicHardening", "Material", diff --git a/src/felupe/constitution/linear_elasticity/__init__.py b/src/felupe/constitution/linear_elasticity/__init__.py index ca1ce89f..3e0f8ef9 100644 --- a/src/felupe/constitution/linear_elasticity/__init__.py +++ b/src/felupe/constitution/linear_elasticity/__init__.py @@ -1,4 +1,4 @@ -from ._lame_converter import lame_converter +from ._lame_converter import lame_converter, lame_converter_orthotropic from ._linear_elastic import ( LinearElastic, LinearElasticPlaneStrain, @@ -10,6 +10,7 @@ __all__ = [ "lame_converter", + "lame_converter_orthotropic", "LinearElastic", "LinearElasticLargeStrain", "LinearElasticOrthotropic", diff --git a/src/felupe/constitution/linear_elasticity/_lame_converter.py b/src/felupe/constitution/linear_elasticity/_lame_converter.py index 611a84a5..3e688876 100644 --- a/src/felupe/constitution/linear_elasticity/_lame_converter.py +++ b/src/felupe/constitution/linear_elasticity/_lame_converter.py @@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License along with FElupe. If not, see . """ +from numpy.linalg import inv def lame_converter(E, nu): @@ -50,3 +51,73 @@ def lame_converter(E, nu): mu = E / (2 * (1 + nu)) return lmbda, mu + + +def lame_converter_orthotropic(E, nu, G): + r"""Convert elastic orthotropic material parameters to Lamé parameter. + + Parameters + ---------- + E : list of float + List of the three elastic moduli :math:`E_1, E_2, E_3`. + nu : list of float + List of three poisson ratios :math:`\nu_{12}, \nu_{23}, \nu_{31}`. + G : list of float + List of three shear moduli :math:`G_{12}, G_{23}, G_{31}`. + + Returns + ------- + lmbda : list of float + List of six (upper triangle) first Lamé parameters + :math:`\lambda_11, \lambda_12, \lambda_13, \lambda_22, \lambda_23, \lambda_33`. + mu : list of float + List of the three second Lamé parameters :math:`\mu_1,\mu_2, \mu3`. + + """ + + # unpack orthotropic elastic material parameters + E1, E2, E3 = E + ν12, ν23, ν31 = nu + G12, G23, G31 = G + + # orthotropic symmetry + ν21 = ν12 * E2 / E1 + ν32 = ν23 * E3 / E2 + ν13 = ν31 * E1 / E3 + + C = inv( + [ + [1 / E1, -ν21 / E2, -ν31 / E3, 0, 0, 0], + [-ν12 / E1, 1 / E2, -ν32 / E3, 0, 0, 0], + [-ν13 / E1, -ν23 / E2, 1 / E3, 0, 0, 0], + [0, 0, 0, 1 / G12, 0, 0], + [0, 0, 0, 0, 1 / G23, 0], + [0, 0, 0, 0, 0, 1 / G31], + ] + ) + + # take the components from this matrix + # + # [λ11 + 2 * μ1, λ12, λ13, 0, 0, 0] + # [λ12, λ22 + 2 * μ2, λ23, 0, 0, 0] + # [λ13, λ23, λ33 + 2 * μ3, 0, 0, 0] + # [0, 0, 0, (μ1 + μ2) / 2, 0, 0] + # [0, 0, 0, 0, (μ2 + μ3) / 2, 0] + # [0, 0, 0, 0, 0, (μ1 + μ3) / 2] + + λ12 = C[0, 1] + λ23 = C[1, 2] + λ13 = C[0, 2] + + μ1 = C[3, 3] - C[4, 4] + C[5, 5] + μ2 = C[3, 3] + C[4, 4] - C[5, 5] + μ3 = -C[3, 3] + C[4, 4] + C[5, 5] + + λ11 = C[0, 0] - 2 * μ1 + λ22 = C[1, 1] - 2 * μ2 + λ33 = C[2, 2] - 2 * μ3 + + lmbda = [λ11, λ12, λ13, λ22, λ23, λ33] + mu = [μ1, μ2, μ3] + + return lmbda, mu diff --git a/src/felupe/constitution/linear_elasticity/_linear_elastic_orthotropic.py b/src/felupe/constitution/linear_elasticity/_linear_elastic_orthotropic.py index b6ff19ec..62967864 100644 --- a/src/felupe/constitution/linear_elasticity/_linear_elastic_orthotropic.py +++ b/src/felupe/constitution/linear_elasticity/_linear_elastic_orthotropic.py @@ -27,24 +27,12 @@ class LinearElasticOrthotropic(ConstitutiveMaterial): Parameters ---------- - E1 : float - Young's modulus. - E2 : float - Young's modulus. - E3 : float - Young's modulus. - nu12 : float - Poisson ratio. - nu23 : float - Poisson ratio. - nu13 : float - Poisson ratio. - G12 : float - Shear modulus. - G23 : float - Shear modulus. - G13 : float - Shear modulus. + E : float + Young's modulus (E1, E2, E3). + nu : float + Poisson ratio (nu12, nu23, n31). + G : float + Shear modulus (G12, G23, G31). Examples -------- @@ -54,8 +42,8 @@ class LinearElasticOrthotropic(ConstitutiveMaterial): >>> import felupe as fem >>> >>> umat = fem.LinearElasticOrthotropic( - >>> E1=1, E2=1, E3=1, nu12=0.3, nu23=0.3, nu13=0.3, G12=0.4, G23=0.4, G13=0.4 - >>> ) + ... E=[1, 1, 1], nu=[0.3, 0.3, 0.3], G=[0.4, 0.4, 0.4] + ... ) >>> ax = umat.plot() .. pyvista-plot:: @@ -71,30 +59,12 @@ class LinearElasticOrthotropic(ConstitutiveMaterial): """ - def __init__(self, E1, E2, E3, nu12, nu23, nu13, G12, G23, G13): - self.E1 = E1 - self.E2 = E1 - self.E3 = E3 - - self.nu12 = nu12 - self.nu23 = nu23 - self.nu13 = nu13 - - self.G12 = G12 - self.G23 = G23 - self.G13 = G13 - - self.kwargs = { - "E1": self.E1, - "E2": self.E2, - "E3": self.E3, - "nu12": self.nu12, - "nu23": self.nu23, - "nu13": self.nu13, - "G12": self.G12, - "G23": self.G23, - "G13": self.G13, - } + def __init__(self, E, nu, G): + self.E = E + self.nu = nu + self.G = G + + self.kwargs = {"E": self.E, "nu": self.nu, "G": self.G} # aliases for gradient and hessian self.stress = self.gradient @@ -149,17 +119,9 @@ def hessian(self, x=None, shape=(1, 1), dtype=None): """ - E1 = self.E1 - E2 = self.E2 - E3 = self.E3 - - nu12 = self.nu12 - nu23 = self.nu23 - nu13 = self.nu13 - - G12 = self.G12 - G23 = self.G23 - G13 = self.G13 + E1, E2, E3 = self.E + nu12, nu23, nu31 = self.nu + G12, G23, G31 = self.G if x is not None: dtype = x[0].dtype @@ -168,7 +130,7 @@ def hessian(self, x=None, shape=(1, 1), dtype=None): nu21 = nu12 * E2 / E1 nu32 = nu23 * E3 / E2 - nu31 = nu13 * E3 / E1 + nu13 = nu31 * E1 / E3 J = 1 / (1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 - 2 * nu21 * nu32 * nu13) @@ -192,7 +154,7 @@ def hessian(self, x=None, shape=(1, 1), dtype=None): [2, 0, 2, 0], [0, 0, 2, 2], [2, 2, 0, 0], - ] = G13 + ] = G31 elast[ [1, 2, 1, 2], diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py index 63a0774a..f79546ea 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py @@ -30,9 +30,10 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): C : tensortrax.Tensor Right Cauchy-Green deformation tensor. mu : list of float - List of the three shear moduli. + List of the three second Lamé parameters :math:`\mu_1,\mu_2, \mu3`. lmbda : list of float - The six (upper triangle) orthotropic moduli. + List of six (upper triangle) first Lamé parameters + :math:`\lambda_11, \lambda_12, \lambda_13, \lambda_22, \lambda_23, \lambda_33`. r1 : list of float First normal vector of planes of symmetry. r2 : list of float @@ -65,16 +66,21 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): >>> import felupe.constitution.tensortrax as mat >>> import felupe as fem >>> - >>> r = fem.math.rotation_matrix(30, axis=2) + >>> r = fem.math.rotation_matrix(0, axis=2) + >>> lmbda, mu = fem.constitution.lame_converter_orthotropic( + ... E=[10, 10, 10], + ... nu=[0.3, 0.3, 0.3], + ... G=[1, 1, 1], + ... ) >>> umat = mat.Hyperelastic( ... mat.models.hyperelastic.saint_venant_kirchhoff_orthotropic, - ... mu=[1, 1, 1], - ... lmbda=[20, 20, 20, 20, 20, 20], + ... mu=mu, + ... lmbda=lmbda, ... r1=r[:, 0], ... r2=r[:, 1], ... r3=r[:, 2], ... ) - >>> ax = umat.plot(incompressible=False) + >>> ax = umat.plot(ux=fem.math.linsteps([1, 1.1], num=10), ps=None, bx=None) .. pyvista-plot:: :include-source: False diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 7f021187..7c127d44 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -136,22 +136,22 @@ def test_linear(): def test_linear_orthotropic(): r, F = pre(sym=False, add_identity=True) + lmbda, mu = fem.constitution.lame_converter_orthotropic( + E=[6919, 271, 450], + nu=[0.388, 0.278, 0.375], + G=[262, 34, 354], + ) + for Material in [ (fem.constitution.LinearElasticOrthotropic, {}), ]: - LinearElastic, kwargs = Material + LinearElasticOrtho, kwargs = Material # doi.org/10.2478/ace-2018-0027 (pine wood) - le = LinearElastic( - E1=6919, - E2=271, - E3=450, - nu12=0.388, - nu23=0.278, - nu13=0.375, - G12=262, - G23=34, - G13=354, + le = LinearElasticOrtho( + E=[6919, 271, 450], + nu=[0.388, 0.278, 0.375], + G=[262, 34, 354], **kwargs, ) From 029c05fdeee3c76766acb3d70ec982e112082219 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Tue, 19 Nov 2024 22:02:45 +0100 Subject: [PATCH 121/125] Update _saint_venant_kirchhoff_orthotropic.py --- .../_saint_venant_kirchhoff_orthotropic.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py index f79546ea..3b2114ac 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py @@ -95,15 +95,16 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): """ + eye = base.eye + μ = array(mu) + λ = from_triu_1d(array(lmbda)) + r = array([r1, r2, r3]) - E = (C - base.eye(C)) / 2 + E = (C - eye(C)) / 2 Err = einsum("ai...,ij...,aj...->a...", r, E, r) - I1 = einsum("a...,b...->ab...", Err, Err) - I2 = einsum("ai...,ij...,aj...->a...", r, E @ E, r) - - μ = array(mu) - λ = from_triu_1d(array(lmbda)) + λI1 = einsum("ab,a...,b...->...", λ / 2, Err, Err) + μI2 = einsum("a,ai...,ij...,aj...->...", μ, r, E @ E, r) - return einsum("a,a...->...", μ, I2) + einsum("ab,ab...->...", λ, I1**2 / 2) + return μI2 + λI1 From 02e014bab61531060443b27b5343cb283d2342ff Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 21 Nov 2024 07:45:41 +0100 Subject: [PATCH 122/125] Add an optional strain exponent for the SVK-material (#905) * Add an optional strain exponent for the SVK-material * Make the third orthotropic-direction optional in `saint_venant_kirchhoff_orthotropic()` --- .../models/hyperelastic/__init__.py | 2 +- .../hyperelastic/_saint_venant_kirchhoff.py | 28 ++++++++++++-- .../_saint_venant_kirchhoff_orthotropic.py | 38 ++++++++++++++----- tests/test_constitution.py | 26 +++++++++++++ 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py index 3a9ad95d..d4f2fd3f 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/__init__.py @@ -64,7 +64,7 @@ neo_hooke.kwargs = dict(mu=0) ogden.kwargs = dict(mu=[0, 0], alpha=[2, -2]) ogden_roxburgh.kwargs = dict(r=100, m=1, beta=0, material=neo_hooke, mu=0) -saint_venant_kirchhoff.kwargs = dict(mu=0.0, lmbda=0.0) +saint_venant_kirchhoff.kwargs = dict(mu=0.0, lmbda=0.0, k=2) saint_venant_kirchhoff_orthotropic.kwargs = dict( mu=[0.0, 0.0, 0.0], lmbda=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py index 186db8e4..81a0adaa 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff.py @@ -16,10 +16,13 @@ along with FElupe. If not, see . """ +from tensortrax.math import base, log +from tensortrax.math import sum as tsum from tensortrax.math import trace +from tensortrax.math.linalg import eigvalsh -def saint_venant_kirchhoff(C, mu, lmbda): +def saint_venant_kirchhoff(C, mu, lmbda, k=2): r"""Strain energy function of the isotropic hyperelastic `Saint-Venant Kirchhoff `_ material formulation. @@ -32,6 +35,9 @@ def saint_venant_kirchhoff(C, mu, lmbda): Second Lamé constant (shear modulus). lmbda : float First Lamé constant (shear modulus). + k : float, optional + Strain exponent (default is 2). If 2, the Green-Lagrange strain measure is used. + For any other value, the family of Seth-Hill strains is used. Notes ----- @@ -79,6 +85,22 @@ def saint_venant_kirchhoff(C, mu, lmbda): """ - I1 = trace(C) / 2 - 3 / 2 - I2 = trace(C @ C) / 4 - trace(C) / 2 + 3 / 4 + eye = base.eye + + if k == 2: + E = (C - eye(C)) / 2 + + I1 = trace(E) + I2 = trace(E @ E) + + else: + λ2 = eigvalsh(C) + if k == 0: + Ek = log(λ2) / 2 + else: + Ek = (λ2 ** (k / 2) - 1) / k + + I1 = tsum(Ek) + I2 = tsum(Ek**2) + return mu * I2 + lmbda * I1**2 / 2 diff --git a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py index 3b2114ac..3cd1808d 100644 --- a/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py +++ b/src/felupe/constitution/tensortrax/models/hyperelastic/_saint_venant_kirchhoff_orthotropic.py @@ -16,11 +16,15 @@ along with FElupe. If not, see . """ from numpy import array -from tensortrax.math import base, einsum +from tensortrax.math import base, einsum, log +from tensortrax.math import sum as tsum +from tensortrax.math.linalg import eigh from tensortrax.math.special import from_triu_1d +from .....math import cross -def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): + +def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3=None, k=2): r"""Strain energy function of the orthotropic hyperelastic `Saint-Venant Kirchhoff `_ material formulation. @@ -30,16 +34,20 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): C : tensortrax.Tensor Right Cauchy-Green deformation tensor. mu : list of float - List of the three second Lamé parameters :math:`\mu_1,\mu_2, \mu3`. + List of the three second Lamé parameters :math:`\mu_1,\mu_2, \mu_3`. lmbda : list of float - List of six (upper triangle) first Lamé parameters - :math:`\lambda_11, \lambda_12, \lambda_13, \lambda_22, \lambda_23, \lambda_33`. + List of six (upper triangle) first Lamé parameters :math:`\lambda_{11}, + \lambda_{12}, \lambda_{13}, \lambda_{22}, \lambda_{23}, \lambda_{33}`. r1 : list of float First normal vector of planes of symmetry. r2 : list of float Second normal vector of planes of symmetry. - r3 : list of float - Third normal vector of planes of symmetry. + r3 : list of float or None, optional + Third normal vector of planes of symmetry. If None, the third normal vector + is evaluated as :math:`r_1 \times r_2`. Default is None. + k : float, optional + Strain exponent (default is 2). If 2, the Green-Lagrange strain measure is used. + For any other value, the family of Seth-Hill strains is used. Notes ----- @@ -96,12 +104,24 @@ def saint_venant_kirchhoff_orthotropic(C, mu, lmbda, r1, r2, r3): """ eye = base.eye + + if k == 2: + E = (C - eye(C)) / 2 + + else: + λ2, M = eigh(C) + if k == 0: + E = tsum(log(λ2) / 2 * M, axis=0) + else: + E = tsum((λ2 ** (k / 2) - 1) / k * M, axis=0) + μ = array(mu) λ = from_triu_1d(array(lmbda)) - r = array([r1, r2, r3]) + if r3 is None: + r3 = cross(r1, r2) - E = (C - eye(C)) / 2 + r = array([r1, r2, r3]) Err = einsum("ai...,ij...,aj...->a...", r, E, r) λI1 = einsum("ab,a...,b...->...", λ / 2, Err, Err) diff --git a/tests/test_constitution.py b/tests/test_constitution.py index 7c127d44..05891b88 100644 --- a/tests/test_constitution.py +++ b/tests/test_constitution.py @@ -342,6 +342,8 @@ def neo_hooke(C, mu=1): for model, kwargs, incompressible in [ (neo_hooke, {"mu": 1}, True), (fem.saint_venant_kirchhoff, {"mu": 1, "lmbda": 20.0}, False), + (fem.saint_venant_kirchhoff, {"mu": 1, "lmbda": 20.0, "k": 0}, False), + (fem.saint_venant_kirchhoff, {"mu": 1, "lmbda": 20.0, "k": 1}, False), ( fem.saint_venant_kirchhoff_orthotropic, { @@ -353,6 +355,30 @@ def neo_hooke(C, mu=1): }, False, ), + ( + fem.saint_venant_kirchhoff_orthotropic, + { + "mu": [1, 1, 1], + "lmbda": [20, 20, 20, 20, 20, 20], + "r1": np.eye(3)[:, 0], + "r2": np.eye(3)[:, 1], + "r3": None, + "k": 0, + }, + False, + ), + ( + fem.saint_venant_kirchhoff_orthotropic, + { + "mu": [1, 1, 1], + "lmbda": [20, 20, 20, 20, 20, 20], + "r1": np.eye(3)[:, 0], + "r2": np.eye(3)[:, 1], + "r3": np.eye(3)[:, 2], + "k": 1, + }, + False, + ), (fem.neo_hooke, {"mu": 1}, True), (fem.mooney_rivlin, {"C10": 0.3, "C01": 0.8}, True), (fem.yeoh, {"C10": 0.5, "C20": -0.1, "C30": 0.02}, True), From fc59ddc9c33ed79cb781956c024a8a6119a70d93 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Thu, 21 Nov 2024 23:17:34 +0100 Subject: [PATCH 123/125] Update _lame_converter.py --- .../linear_elasticity/_lame_converter.py | 57 +++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/felupe/constitution/linear_elasticity/_lame_converter.py b/src/felupe/constitution/linear_elasticity/_lame_converter.py index 3e688876..162e3a1b 100644 --- a/src/felupe/constitution/linear_elasticity/_lame_converter.py +++ b/src/felupe/constitution/linear_elasticity/_lame_converter.py @@ -54,7 +54,7 @@ def lame_converter(E, nu): def lame_converter_orthotropic(E, nu, G): - r"""Convert elastic orthotropic material parameters to Lamé parameter. + r"""Convert elastic orthotropic material parameters to Lamé constants. Parameters ---------- @@ -68,11 +68,60 @@ def lame_converter_orthotropic(E, nu, G): Returns ------- lmbda : list of float - List of six (upper triangle) first Lamé parameters - :math:`\lambda_11, \lambda_12, \lambda_13, \lambda_22, \lambda_23, \lambda_33`. + List of six (upper triangle) first Lamé parameters :math:`\lambda_{11}, + \lambda_{12}, \lambda_{13}, \lambda_{22}, \lambda_{23}, \lambda_{33}`. mu : list of float - List of the three second Lamé parameters :math:`\mu_1,\mu_2, \mu3`. + List of the three second Lamé parameters :math:`\mu_1,\mu_2, \mu_3`. + Notes + ----- + The orthotropic material parameters are converted to orthotropic Lamé + constants. + + The compliance matrix as the inverse of the stiffness matrix with the + parameters :math:`E_i`, :math:`\nu_{ij}` and :math:`G_{ij}` is given in + Eq. :eq:`ortho-matrix-inv`. + + .. math:: + :label: ortho-matrix-inv + + \boldsymbol{C}^{-1} = \begin{bmatrix} + \frac{1}{E_1} & -\frac{\nu_{21}}{E_2} & -\frac{\nu_{31}}{E_3} + & 0 & 0 & 0 \\ + -\frac{\nu_{12}}{E_1} & \frac{1}{E_2} & -\frac{\nu_{32}}{E_3} + & 0 & 0 & 0 \\ + -\frac{\nu_{13}}{E_1} & -\frac{\nu_{23}}{E_2} & \frac{1}{E_3} + & 0 & 0 & 0 \\ + 0 & 0 & 0 & \frac{1}{G_{12}} & 0 & 0 \\ + 0 & 0 & 0 & 0 & \frac{1}{G_{23}} & 0 \\ + 0 & 0 & 0 & 0 & 0 & \frac{1}{G_{31}} + \end{bmatrix} + + The stiffness matrix with the Lamé constants is denoted in + Eq. :eq:`ortho-matrix`. + + .. math:: + :label: ortho-matrix-inv + + \boldsymbol{C} = \begin{bmatrix} + \lambda_{11} + 2 \mu_1 & \lambda_{12} & \lambda_{13} & 0 & 0 & 0 \\ + \lambda_{11} & \lambda_{12} + 2 \mu_2 & \lambda_{13} & 0 & 0 & 0 \\ + \lambda_{11} & \lambda_{12} & \lambda_{13} + 2 \mu_3 & 0 & 0 & 0 \\ + 0 & 0 & 0 & \frac{\mu_1 + \mu_2}{2} & 0 & 0 \\ + 0 & 0 & 0 & 0 & \frac{\mu_2 + \mu_3}{2} & 0 \\ + 0 & 0 & 0 & 0 & 0 & \frac{\mu_3 + \mu_1}{2} + \end{bmatrix} + + Eq. :eq:`ortho-matrix-inv` is evaluated and inverted numerically to extract + the Lamé constants. + + See Also + -------- + felupe.LinearElasticOrthotropic : Orthotropic linear-elastic + material formulation. + felupe.constitution.tensortrax.models.hyperelastic.saint_venant_kirchhoff_orthotropic : + Strain energy function of the orthotropic hyperelastic Saint-Venant + Kirchhoff material formulation. """ # unpack orthotropic elastic material parameters From 452411a9220ba630a3e925ec57459349aa4b6931 Mon Sep 17 00:00:00 2001 From: Andreas Dutzler Date: Sat, 23 Nov 2024 08:41:10 +0100 Subject: [PATCH 124/125] Add a `paper.md` for JOSS (draft) --- paper/examples.png | Bin 0 -> 807482 bytes paper/field.pdf | Bin 0 -> 14503 bytes paper/job.pdf | Bin 0 -> 17361 bytes paper/paper.bib | 275 +++++++++++++++++++++++++++++++++++++++++++++ paper/paper.md | 100 +++++++++++++++++ paper/strain.png | Bin 0 -> 162624 bytes 6 files changed, 375 insertions(+) create mode 100644 paper/examples.png create mode 100644 paper/field.pdf create mode 100644 paper/job.pdf create mode 100644 paper/paper.bib create mode 100644 paper/paper.md create mode 100644 paper/strain.png diff --git a/paper/examples.png b/paper/examples.png new file mode 100644 index 0000000000000000000000000000000000000000..3e95ee5e5f098d07f8545887c413eddfeb5393f0 GIT binary patch literal 807482 zcmZ6y1z6Nkw>>;6N+_slOrZF2F)sS`8sB&1COj_rk*36au*$&hAfr9rH;oWmR34 z-iqpt+MOY?Vv%_C;YDRy+>M*^EtNlh;Ejh{I-Y40Yd^kr48geAt2;$O&*E;N+THBG zN4V}Yx^6&xK6Gn*U^|zWX!=|oaVO4z%Dhgb#8@GylJY#Eq1?F zLcUr3{;eOB!IVmZoU`P!3ChUD232|^Q^Xx{w$z8e{M#eYaeCf!Xos<0J{CCvK2`cV z)QWnXuDl#{>{|~p8c+DU_ZQJxLUtIfLg$etHXoy!^kPoOlm!}fopz`UN#qmxi<&yY z{RL6R%+g1Qt7mz0H@o1`h3DnMFAk+kIUN7+*{s+7AVlRF-HJ%x@2HaK^!vfxXF0aF zUv5*a;`@=$KHK@YlJ))(!aXxnHp17>=ErPZW|zmud5ZhLvyiWUDx6C^HNNg9k!ja` zLAqMfyl1VrF=CLI38|ND=le?9@SV)J6~>MAmG!l0zO_?t$YPwsFzfYQBnZnTW2C$c zf~|GytUB#D&%_Z0+U&vc&k|GpNw_WyhPyLjk-zi)_d z_3$Y+`N|*NRZw5A`%1d4`-P*3=g%5e)^JOEHeX_aI$9Glp@My?>wng7g|03tEY%wr z9_2>h4i7I44NeqJO^Gvzp2ml#31z2FiSO?1mFs|C<7x-z8vEa0^!+80FRP*v1eW#O zNr_EWWx22Y$$Xtd_w)DN&mVA7Kp>K2Pg?%x7-8$3yQ5BXhgKp!>lewdT(Ph>*O{CY zqotF`nrb>Hc6wkjUstDd7XtBpo9_QV!H89BX)l>$V;r4f!8@7H26uL{z3o|e+x7gX z5JkuZ2qf};A(fJretof-ejQD(5<^n8;GGTKGjG;UYYY?BA@~om zM!gi1+TE|U>vgpm5ghnk*Quk_4=YyU#9g`?|x zjdL%$@=%UF5_~h2I~hCtwWlskC(}}ZMXkppVdw#rT$Z&&`H%yAn&!2KD0J&VM=hzB= zOoI>GJ;WF@PLB%Hve|!XziT4+T)qBf!blmypRP!mJXRys@J@KHOhonmfdy$?fE&a8 zds9Sqt=~o9H~JJqO;8V>8$aM4{d-r_O^b@fh6GbRTIGD6v|;!{L4b+NJf(Uf20zlE4ejMkNO<7}rIa*_l~mttZZ zaanEh;Z~lWQkf<}LxY2bTUeIm_4OyLZDxkxcAflG7v}h!0lkL;+w>9a^V%a1J-Fhw zdb7{ot2FFnM5tVo$D%WcjOE*vyr6tzW}6^ba@H$B0YMSn3KVv~MwX5#qX1q^%}u)B zdi(4Su1H_%;G)gz|Ey*bUGM&Ev_wC4P6!l%?)kc(&mXvZ{@xYYJy>x%_=KSbi#Ck= zd7kx_2i-4Q->_pLe|XsXVzp&gQ#Co18islt_OBV7 zlLpVX#c}g~_PZkzpB@$_A}$wUC$EMEAkQ~MzJ6IAeo{w5MP@(YV1)c2}Gu|MaLn*E%#>bX zYInkSY_$d%*><97h#R!cciCA3{vl3^rIq7T-J~Sn|ASg1jDHPt z{*rVN3u(^R)qOv2Fk>Zytl4F0%ecw0B z!el4c{k+^BTZixLW}bri-;h?_*4g!mn5Smdi9mWJ=1!7rVnS)Xyc zS_ZMKrqgo(+SsGJ-kXC(Wsi}^3+=VRjdW{e$Ybdr%Jms`J>Ex%prK~F&=pieSVVCo zcF22JX3kszxlH#pqacpn9v$7z>h^{s4tDFjdB?|dNrzl}EZIE;@vGiv zExRP3E<-+^R#gc&Z>-x))_drJ`&i=LSXycjA?A(3ho=o~ZpOc_O|Gl=c>8%?=OI8* zT5J;^Z&hIuQC?PmC}G=|Z*XHhPWJWabR)FgrLQ$j{M2Cll~dXM&Gk5OQ|?0>YYt+K ze}I~EtAry7uVPaJs|YBG$tsMiaPpx4xbXBp#R>9Q%(JE-PXD-0-+gOkd1*-#faM|a zrQvCbJQFsRrOla4!ez_=m+|Q{ig=opJ2-|+v)TN-{+bk(V0$dft!HF$S=s#IZ_ysf z0<#yHlH+wxS1H`uZwXmw#b-^`p*;O8X1glPYhXRa7+=T+RU#&=(vgaCqmks!znakc z%)nsq@GxG|74Pp>WCGaqjfgZ}3ojgN+kMXT+Wzpf=koM#)*ZvHKdP(O8k>b|-)y0jT((k*n$ z)KS>#0nuxH1v9w5JpK1)m`pKh>#2#C29I|Wg$&k75(sGriOd@K{F%M6 zp~#v$w`t0oAyMdE$vUGly?DXaRvRtjEz>9v>$@%&SXCa);L51@tu;9ELrnyAn6Gm` z0j+?=D|U_mB?|qdgG;^b_oo+n?|i&$d2sZ)1PxvHl(spjS3c0DvAM2fxZV6xwQH}` zc(zgd&hx+2T=IRlu5O*rS;_izGY3MX`j{M{E|4_XZ^E{#H+?dlSL!3_<#pmfFCQ)) z2vWno3{A^Ml`R`mtcEb<6x^ZdDMC5?IEG%1lZmwd#XRKk0=ec&lCX*nal0DnZ-_1B zHTmvqvu}^cieo5qWr;*jPSajeH#>&;RH_0T!FN zyu7aE>UuTgA_U^1z-b7Tr@3QZ`S!&nWY&dNIPrRAg(abeG?jj)AWw+TI_>Zt_lIMu zJIfnOqS*am^xPJ5R>>s$%BsU;0>}TDx5&52`fBI>bsNO^ldhki`lGwkQU^?OSz|ss zmxGe>(IteQ(m?ZapjER8i^i-O{n46zR>f;1Z3qu~proNpww_p7L_lNKM8ByGj(80f zVM61oRyg}m+2v3fkNLB|VT6c;^U5vs^GKJXo6@33%&flt3` zUcY`F)3ZRR9wG__KEIPljEE#!aB>+?iMcGej>8W$R}hkd;=1g2J?pZmrouQP5|LYj z-vxw47YFnoQ${-lzJ6HUf`x(&W`_jm&T6Edb_F3(mHZUrA($(p|JnwH%Ks!Z4u}i5YAaH>@o(#AX&YgM z#md^c;~GozrZM{Zu`qxVOPl@CB2MN~ESYo5Yim!>KBl|7yFUZF9}n2|#Uk#?7@oJS z%azb!&SpkKXTGykcUp85Fz^CEI(i|NVnjK(>SJ?z@KQ7Hy(F`w>h}CcyV29uwl8Yh z<+8~He*KGVq=1#xRcE95WbUHmrvh%N3&1;&M7ZUr&F@s9{u>^+U1K7$;(#Q z1vl28Id#)u!zKr$rmJ+^q_;RNoG8izkb9*5GGuW&vqH9tJbee!ti#f4I zoOi|$0I)1U$9Cc570BopfIgX@%fB2SA56C(APtY1kRgdxDA(W;wqFmYJ4MeHh!2(w zBVEJ|v4Ki1^a4_lmdm+W+%oERHYU2w3q8X8Gf=^042lCiu)0!STo~8B1C3vbwB+jK z)hfCAHw?ZH>s|M&)+ZZ_LHc!L=mCApug{gw1jm1yW@u^DC+M|&C!t+bXWs+o&m?3h zs-a%1=LqQJS2m?#sKKJ6Bngas7k zeyDto4cxvK=5vrfqS}Y5+)D9T?$f^KUdcTs8|_6K7oY|I`q25q z@_tscqsKM}2Tlz{0;_{iPSVYHH+mlx+sw*|PODJFWtF;<`Xy*Iaf)A;Idw4`V3=k541?U(oocDJChm7ku5BbRa8QgLH`vaTi zcUnn17hgB07-Dbef_pwyTvH+qeVjqf2NZ|96gU;{* z_PaQeVX0)D{Z&yW^gvdRo5{dS@6HAHhuLq4XK;Denmid|DvQ4=1cd*dIRx=cudx(d za$HtiZ*$%(Us^PbLDX9jubMpYYpjN#uzYsz!q5v-G-sZJ7*=asR0<7zL(OVf!^G8s zd%ZZ#t%=MUdX2ochZt?>S+2N*WOv+td0T?63mb&ACgMOnLZ4?64i_o;2vkAvp%4LX z@UQOq%K&>XT#%-faMA(o2ZM+ckh0oh3fL~ZA{22&CPQPW`70FdyN}ApG+E85vSz8s5+dq@N374{_lPOmX?Et+1=Z< z0`ix9MCuR#Mfan_p@|8+)H%qwehC$;1#S64nam+7t>pd2(*(Y)iT3UwT%g5?@_kYI)^RhdJRV zY^?H4*TI1ic|_jwU>Vj9EHR`^J-pz;iEr>fJUaT$K=ynsy)=Fd5Thza0xG)1)9Y4Ix;0yifF zGUS`J3O-zd&>}HNU=&T}C_!?h&+A-`j}PEbY`@7KWle-+w}LtjL%XDq^gfHon)c3U z7~IA|eQY3G(;psFTjfyGt`+ZZ-}SZDNzE!*V2)=HmD5h-;o%YgqenTZQ~K28kVsUmR+9Y>Ni5!>OlG;P04^S( zDa_Ui7w1m>Db0FsN>cfuj?1+#Pn{>Uw+}|BScqhJp z?_1LqbUGR#H+}!ilan| z3Mp&O&W0lfhKAmC! zg}s}`g$u8imomCZA?d>ERQIv;ccY}%v%gscvdG#6J-x+(Er6eX6%9AU4mAK&8Md`2 z7Q<89tn^s|btai5bnxwn&|WEdD}2i`p@2f;FQ`E)-@ku1KW|DEBAX)S;nKUmxUle$ zkBEdK|6E|3?O^~KzL9TXc-xYmw;3PZY&UcbvPlC%+Nnr6S&ZT zLUcilhFu&EECk@{Ff_k*1~&wxnlpc^iJM7US7NMt8>zqo^h7NzuqMvjv7H#DL<5aH zecUhpi)j*HpV@)ak!WCtn|)2TaGUsG)~of3&C$`3{RWwa;5kUTa&c*?g_oD|{`yq^ zJo4tw?B!l0E}YSaaKHO9{_1G`Kl;kve@g~1aPtDB>@xxWy8;kdBu6inF2`zgBAyIG z)9~Aj+mdl4F-Q@L7Ti!H$tBNcZ0PrAo+4%Z6g+rdiD`Oj00HT*E|SK4>FF6RexZH@ zLL-bA`10inLA)6MZWYI~T>1ItywELYSJy%xLp7kI$VZ6fn6NPp&a~lmU=UxbaNfNt zABoejn>&04hnA1{!YZ^EeB?QuTcB8bY;j16SG`Q7Ls`~?vw&83)2o|ZY(0YmQ2aQW zQ=emrBCg%75%wgq=oLr2lhj9;4VBWu^r_a#$E4|xS8X7Wz8hhv>7frbHFgH7k|;2v{bOayV4sj0B5iPs0+g|{I72@*TjxqPc^h1TdJO}D(yDoH%m2>h%a;=q z69>M3PtM87dE2|F$sXghxBAU;^LcYOE40`N0{LYv2jq+qz!~5Ou|}`ujoTUq25F!u zE&bYx2Cvi%&LGH(5Fxd?^Q<4n>pR5o$6zYqx_AqFg{7t9=g*&U zS>L`r>*?*a0)dE*j!sNVE3K+cNJ<(U7{KM^=JHEO@K}gGe_vChQ|vGs)@bmtBMHb; zl!TS`CD=~Zl@RpE6@#NU1bQ_sk-na)9~K_A@~NMafW}}71B$HE{d!T3ubJ1c9-5>S z-lswy2OvXD)Ty|6!&gk`(^jH*L2p5iC%?&!L0ip0@!w8g9neIp)wDk!=RxD%FT=yT z#=e=mGH}d5t+uyH(r&zALl2A_k&e$*2#$k7=<8BlQIQ48l5lutU|=AFQTX^~@cvnS z^TMRJyE_U5e)!Db*|Yr9GuuF^jKecNK0Xo0g-~$zrlC*Db%uWbcGx`&>3FA@JrLe~ zHzXt^F)3+c>r5SPj_X~F>0Jb8P@0{cz5EF13yV5{;H-=q3}$O<@AQ;P6sr2nvK;;( z_I{dn+AhCSY1UkXENyyM8B{p_{rg*9?#q`T49ug6gW;tp?9UIzSeaqmcv4QfF{vN! zCybgCyGzd;J}ox`73KMSuMlPYht@%fxcTGeH&9q1d4*NG$~JJ^$!WcAzQ#ant3O$w ze<&~N*|YxR;|8)oDSkDuz`|mTmX;PsD$?Hs?-eE?r$&jWY#Q5 zFDfcp6&e8%{hBPC3911VSs=r(7WK`Wg+8Ulma`c#pt7f|b`_q| za&mI3)jlHvZ9MKX0{Si(JoV+Eex^m&)t??LR->>t%8U`O3#d$ysWE!s_ z8k;?;i#=J3JJft$z1LMOhgW9`g{yFeZkoAPJ;xOO=42 zGnf{#Hy-0sy%x3)znf9-%Bwc1-ah_lx7_>2U?6NoyRxz}+o2Zib(IKWZgX#{pY-P4 zEg~@RvC*%Dy#~zgCbT5W*N%iFw&Gzcd=1m`j661r3vFDRt&R^uj@P(jO-L$XRU<^f zV5^rWCJ#I31ZC7Wtn`ICXfl_UEV#J1?xhhfT{$gx{wOWJP*UB>*49@3W1CgXTtaH9 zR)$)h79aSeL`x+hEp2pXXD2)z0h0C0m(Uk4UTAPqgT#buj&FgIqS?l#KOY?!c=2!f z5EBp>*=-d(Q$pVMQujH|*tgoszq=U1>Ofi&gk-Ai|cQQjfT^Ql%_Bici z2k*4q$zN-m5P05~I_ihr$>b%U)@>2c{auO#e=PGHsn?b2fHt1>9R;C(730-`Ms+ZdB zgUPdk?A+8L?WUb)jXSfW&Ra2Ym3#J@wh2E-Az5L=)5mnTI<7N)+jl!B4aZFyB1|8N z8byql2T`iA5g{8Ki%wWRtZWpA6u_yun^*&pML~)UjtE^O{pV3N`WP5c7^JL{i58_1 z+@Qd|$QwP(0T+rS#%;|gly?|{of8smWgQ$GMCt37&~a{sKjoy}*SNdYWE=YJIxQig zj}E_o|DL)XpO`rQM6=^Vy=J)J!tCs9cqGDxKiX5=fINGZBGHY@<%OAJDIj=#o0!%_1 zxqfEbc_TLtfAf{A2$`p6xl1$~k)`=T=%|pM5p%A&JUK2xEv4+D#r6aH))*V~N3QKz z$r@OfJ@z@v{c9_oFKKmWb(&t2#1S1uQU2isjo*ZGT=?yT;;n7l(>1%{s||n1J(&Ta zl6K1o2b|85z*qJ(D5Kcd>;aE>C@h>0$_f_`kGAf_YEwj(n2nt!e&S?z{H0q)48uky zy_u>kWj^#iD9U5|;=A6B+H}<4#I(fIruhUnXw>29>Y~IOo(l^LE}nMHM{WiZ9($|d zM?+InAC7b+MRnXZO3O(ghR;}|`!_$ut0cRj^(H528AP)(W}X0IT`mNP{JDY|XVaND zWwoxvRb2%m4F(laP0oDXg!bPx7T!~pZZ$Aj-#F2E?L!iYQ62V}A<^4(am{Nl z!Nhu|T;*2}=;f>A2t8;d^-*P0e)0VW5)#ds!^$?AxIcgXFlZ_PCQ!&_w^yjcY(p&S z;?ub2vFp!#RM{D&QB0!V3nCrvB9!W0?2x56j8o6g0>p0hAXU5PIVe@~{FHV@lT^w8 zq+Gt|Rw-g#!|OTX-4CWvgCqgwNs5yV%sj^wZ6*{Ut)# z8ZB+i87AI;b{7)-jNKK|dP%Wh|0U?FJ1r6EOH;PStACkc(M0KPk9P)c{A1V8pU-!j z>YKGi_a3)EH=62S!KX0$M^oO#nB%)Q$d0^A^$Y0Cj%#o3Y(;n}_#FH^+8Mg-CE4rwN7easf@gWzDsJ~j zitH%U(Xs z1uS8xsT*X0UTrLZ4IOzKj5qU#yPkQ9m!5bBx~d%|kN??lT?L`;bDS=9R$23Mt?t@t zVq5ySF{nsf97-(=iKGC{EMedvkTg7YU?k?U>@4DPoCW55I`j~ddr`jFVn~;FA}wbW z&Ms(fBWkyqJ_X8&&^5)qwQ&Jy#-u@$dC~?SSyZlpb>bf-AUOuxHy@9mXAM9O_z|2T z#rXo8ckXHAwbv_WZj6QlUy5<_hR00gNfQqP{pMz;&|OJp&GYQUCvQsoc`YZ#SF0B~ zj4{)Z@|o#fzkk1f)A0^AeA1M~;D=)}y1^6%OjD9|U_?|x0L&Lwu?(AN@l3!Y? z`pr7L3%a0YrXX!Jqh9&nJ-VoDi67&+ z`@Y_x3qU-KzbN$mk$~g}UP{C4MKZtl&ozQ&O@Cq%*h(JvH#^Xn*I&sTjfTa<~inhrh|?z8U~Vnm{hh2UeU~ z^v#e<>6w)>7o*iOaLcy_D9rH6uP(_BFmhs0POcB(XNlrKtQDHZkoK1zBQcTn1qld4*HsYvD`V4wq?sw;FBqMqt>?4-I_*snF($(%ix zuvWM?d$dB>#Pm?=tF&_KFUx$5?e@t|HPaJbU5A4 z&iTzgYK>lAA{YmC`EW)cao-QQkUp2?BL7h+=aB6N-sa36YjPfFW(?e0Biu4>ZJ4Sv z9c|Il$ZcfUjW3NXZSYPkBR7Vj6^{54XOB2)=w|}yRXO(kw%IMv&dZcnRA>|jKjEZ? zBeK;Ioixg-s@kuvad2=9Pt0%skxwHJ130=;)soN9O9zH?9)7VWwu_ThI-CU>?EF{E zZiL9*GNHI4;ARvo=NAb8tEZ=jAC1q?&tHB?{~VCenKe-1D?v*RkU3@1R-YpP97g0r}A1ACf*3?sH@(#H3`kvlEBcL;nyrV(pO#UPricc_k)R!ZiS#Z zkCy87cWCR6#5HePoNNV6l}em$`it*wNsK5iCEHHdWds3jrn0ib|D3s1et{u0UmdX< zY991q?!{yOD;9-XvrcLouLA@hiwdBjnm;AwIu{4)U$wz`lSOB6_7dSmDdgv($4c=z zDM*4=Yj_?a`FqdGYcS6;Sc6o4sL*z1Qf0hE>izWE^5lpre}o)ZFt}@lT>2EAJe8^; z3GOR^U;gk=l4xGo)?EYqQ}&N%(@gCV5KHP)!wNzU7zR~MqbKKH=GpoS5qyRsgMFL9 zmoB}2_~=o=sox#3JvaRmuM6GJKX6j`R`u`rVq?^>H-tiea9o?^Ta9uXhDv;nk}PX? z&&!HF4|nFt`YEt%d^!Fax9~4g#vg&gozAQ2z?32kCc`*OWI2F^W z=s$mi!7T77>g^ES6;y7;p9oGy12FZz-&|~GX(u5eVQ>QX0PV|^%YLViO?~oYwU{}# zH)_VMdVhTLfZXq((I%2fQ7uraW#8tcqC1M+#!N9A_oidE$;SQ>;M&IJI@MGvjT4MR zB6!i$^;p5jw)OR4;jW^8+Z&jk+x)~~>!Nsu#A%;Db(*_++S#D$ug?ZiCf9Jp>X5%pZ|R^q%hBVcQZh~!oWZ^LDzWgg zN?{n+{rTn$PSQ+f7bjElIVTxO7x*`~e8nE?PAhnDydi3AOk=1gCux{uPHZ<2ohI* z_~vz6A_KZ14p#0F%5;vnx%w(?dZhowhYg_4hbqMMV40eiw9bYZzkK-U)fkVZ>VLjlL=p#c@nZF6 zv>BrgB5;6~;n#wI3VU8;ZGEk1xj~tAqLkc%ySsmnI>fJ)`SFE&Q(pc7Obw2tzgJq) z7u9vCU<&s;?E13yX!LiJrq8r5!P@I&E!D=t0*1bTMwKgSe}owe z`4zxtMjxn`Wp!mh@mLqqq=$B=9a^_wlaAJt_K3}w#8Wq1qwDoacYEB%XtZ&2N4#?XGUW|Y6jp|8YCXqAxs{#+yPHS; zB7iiP$l~c!56;mghS#0=+6Se`9n=4mk2RBvGc;7U(+cUVkJh^@X?RvS+ zZE#jfBr;h@V1q$Wx(4>;*>&!GkFcs9;voU@IKW9#Vq;?~Dk@-j4Cse%dx`Ts=rjjT zi0Pi+F)=aAC%^xA?s^06&{UATDxNwm`R1k&iG##OQ-|@BZ1sB@9TX-?t5mWL&M8Sr zmyd;1l$A9{`GPw-I+ooJ`NhPFJ33?mR9b#|7uD5;08&|j+TFWpz1pMr-g3~<9svnd z@KKIyQ9{BkFi;Q+K!Y}R0JB*rguSwCTXK#sYZ{CjO6G)`%{&A zvb?xkF7fAr*XBM@0fFGKv%A<-5OPzI;LjTwVSH~0Va8VbBfiXBpmaKRu??a$#9>1&Pagp*ffmevTEea(zcH_qnJ;0Iec#=rlsjx$W!e=#Y3S-9yhukMELG zzV2Gw_8S$j=8qo7^O;vhmf^2F{q}r+>yd`w(iII5@+@W6Xie7WC){yQRqfJ#=Qc}6 zhzaC_nK3o7WLa;r)&*7`PifGoBFj}pz?9|;!xezEu4=QGF+^}^ky7ntja1Z;*n^+&p7W%z`9N<|V1JnP|k||t`l?-qo+AKoQIZPPdAz#qZZw^CnpD3 zyS+}TrvFN^3Q2_7EO2_dpVpe~1onEVr=9*xGhfPQ+ug}c{cFRUto3?YvI2D30(FCy z_5gCBtYS-qY30?^s(FCm((o$o5(*L{n0kNvEUTq%WheIio-$~5^e+tz(+0%~VVKba z4@PaeONRmA5o_>75#Y&O^~qnvdmT{gv$oZyk)0>zjicgi;75a;(({5TS|yJk1)ap` zjm3)Bk4jhzu`15T-i=YSynS?k`0+a}{-}yf29>c9F{AZ}oxh2j5*ns#4xVBF4|JG6 zf3BoADMm}n2wWmhS)+~od?}*GeG%VVpl5i69C&z-i%<_)tdpf?#F#Xz1%WkTH~l9% zXP~HAomx46gWj&DDKOZW;!pbZvLpO$;ky;Q70WRhZ6atqyM+*>bnCbn7mJn(wu(f zQL711!%`6`z55bmk9f3QAru!-id_>{uY@f}++8t~tI4`IYCXF+<1*4L#6&n})2j1# zs_?-BDme))&?FO?d`4#3t9c4Bz6xVx?3Gs6=SN>Z8GR>^cO9Mw6)*=%Q7Nrz-;a^? zvcD~&Y)KK+=?W}@u>Zm5AD)GU-5yy{QMCZ+?&WoXmWD>7q%fr8+_(}jfwEfm0a(Fa z0&q-k@AYij(COVpc9$F4y;JW6vMLFCBrx4(4BP=Y;(5Tb=hi&0oBb1M-j` zJ|Q{TT1aJV7x*@U+s4NW2#@L*9DirqCFogc2V=LF`O@4K4GzAu?X(Iu=N#>?TRJ*M z2cB2|>Tof-bS1a>u;buG5~+Zu6__f}i?#r~kQY3#eUA3Sy&w|XYvg|Woi%aTlJ&aa z?x1=Lu#ur1$zOhFMPCqIR2+utO5_x!=_#HEcvFYR6`P9AtxlAVPVghPE*1FOaeS|w8*5sx zy!WcLCSQJI>N~BoGJZC?7-g4UytH%lb3%vbyBW^tp%fHBKR9*}K*1mati`s#&rBcW z10&9QZ1srpf)-~Kr#6@HuQ7pw*n_)cz; z7-+HUD5pg3J+~k~0zO}k&xL|JHHt;kl z3|MJ%FR%29W%ha>W}*&%MIRoUNtEz-uRjG3x2(AD&c0!MRD)+er~GzZFEA2R=Nag2 zyhLyW@GArRD~1^PPQft}_ED4a=y=YWKftN+A#3d&MvpuhfPuy&aqU&C742B>*8#{x zcXBp&#sKhepu*eY5y7J{?YlRmf*xB=EGfivvpty@9V3f%o15Q$38s?3;)obde-l=2 zt+^j84U{w>?ZuQ^gD$a3nzh52*TK-#-MvmkYp5?^EgfMa30u|y+|OYwfFLEOYl^wq zs{)UsMYfYlhnaXTVP}V#Y(CnmKELl3Hyq<^(ai-tJ>)hvHr+IF7cW2~o2Z2o><4-M z3OH)|7Y#El5t-6p$Vc?Dk1IfNTn}yI#9aLaTQ+04mcZyhQT((K2CToqwX9WJDrN2C zmDi8!6i%IaqTiJPQbY9hl|2@Q`U!!|n%3`zRa6g$hHU{^@@uM?Rq?#i+Oc)0nHA>- zFPH?BQEQZcqs?`Bq}yEZVfeiH{+tzu5}$;G-AQ?wbMcsE%2SU?SsRbJFt~;M5uI+a zmvv~64MEps5(bqW_#uXW{i+FP6wRNB;svT^L1}4P$2sH3R9^(^@x$XFBrYE{;5JNG z-L|#=>tdl6bV=%oSRb*` z03NIN2Za*C;nBTseG=GN^MhDMXdH{XQaSIT7}^eK)ppG)NM z5lca*BN1gZzNWP~jAE2)7fOZ;;NA<-u?28aBBThv+WTpdF|tIV@N&ur7R&Ey%89NO z0cngu6Iq0&oGF=RJ-N$@9@w!G{uXE73Wq?(s_Mytvp&%s?n=R{@D{DGLZzS9q@bYuzq+R{Vq5kY}PE8&lS~El!y= zRsQd`-szxF1-4oqNk#uvFoUMd3AT*z6-~xqk%jd?kWM9GJe?UHn;{4ES#fCD)wVEeGm-rhnHWwvl zNn+hhZidLlD8dWZUNm6Bc(tVIFaW|zLV#0aW%T#ZkOqIl^XO4_JZq_lqIg<0wa%vh z^+2h|e>|s9cRMd9D!hk2%ugvSR#RAuuWBPqWkDaPnXgeG%Iycp&9&;?U2?BE-Ni}} z=#t5r9)Ad_Lukj{(SeZOmD~^mVBV!HP?tW`ogK3dqRc^I0}FGUOEzf)i8HIdV24=Q zes&gBn$<_l=7B82JE{<>J-E}g4qpdwkIM6S=y+*!Qr1y1CA ziFBDIoH0ZbX>5%(;Xp&Pj1fOA;mVc>6WP%1aM}?>-5Uf>vt^tg4b4vhweiQ?00sW* zvm6j~=26!-rAzI-uLw2(a<7G@+}(uSw2_IaJpr+^@8DV4t73n$QeQ6I^4bucx-N|V zP55r<@o%0L8#|AQ)bh;Nk}kayBQ=#PQ27oVL6z_A)xAAB7sxnEV%a`Si>LE=@q#sW z#naZ7JN69}L(od89ssR$w|uVP#cXll+8fqN$Es(;SuW_L7%)HjJ5niIn`zrs?7-PQ zEhjRs(pY;Ga5+|?=@tB*Id*XKlpIgO$Vr;5c>$i{qN4orUCvL_OyE|7Ezqtk)OYE4 z9n;UXzrU_3N*`jD@ZJ!7hv?t-ob?*)jZ}Y07XbwLk{;MD&5KIlJ>5q9zy&->kd|KfSo zTA%dy$CM^Y{1rx4>r-QuYqo@|9H4AYFh0D~(VgzAT&Z?$azga_Y)`nC)#W&RGd1#M zMaqUG+k@fPeu>_9F3h`2NYAjDGb1u8_NAe|z`(HfyTuMt)m^0J2&?&o)YuUr8(MCx zCuhhga_(g(B`5ZF3vQv|8-FJ?1`~F6?AW^`=)F??H*tr{ zS9+%D&c+VnW47k3gIH{;=Yu(Fpk|;G-cnY|mY=h{r6JmM!{FeBx3~BnUZBK^@2izW ziGbkL7|x}l9-AqvTI^z#Egb@8?5&P^nYz^*%dLglpaqr=QZ$dc(4KkkT=b?Nj)8~g z)OLhS6G_p~d}ay1!|0WIZsMkCMSalsiuD6u(ix}+{=I$JL6QkabsOS0gZ;MtSCY7_ z#X8$=um#cp&}>zdj(=>I_=8RBOPc;oog(fvu6Pvhjt^$haM)_Sm?GgLUbVH7(zd>3 zL!^WQJnh!C$XRkBx5cuuvTM2!nF5W$`@DN!o#}J4Z(k@qR7T$ks(Hl<#2A8QZZ{pV zw!5^268?52=^wOrLSrqc33P#|x~VB6shYh7N(aQ}txp}oH7QJ8w)gT;%nURXSX$2f z(CbfY2-c}itdHPum}B&SZggZ)=#pB#CMhmp|1$1^yZ+ZPIA$BwR3 zO(f(L!Bsez(10;`Y_`%=YKmtmuFxed2P)2rzh2vl7Li+f?VcPXJbR_o4Iepc6E>%5 zfSu^>RfL08zy6(y<-H4m^GnQTNHA$bouM#5o&tu`D5R=AM{&( z8az7s6Q4tCILf`og-Lu;*{+@k!!jY#3zBl6ggE?RFGEqq>XQLvASw^5%FFZV z1UGaFb>7oaDfzlpe6$TH{C`xvbyQSg+dYhc(jeU+F(54K4&4mDS=d4Z+V@Uw&@#11`wWV-f&L{PXn!3~8HR4=~#N(HpoD?V<;1Mgeyc3V5RP{;(uom2St+0jKpw>;`4%cOjR5Me-fQVXacW z+fD|r6Iz2J`#83Y-cQf#%D7`JV6iAAf7WLM1=^67#J&Z&RoGEiShu$UAhc&qOQQ-& zS+jp53G)2Jz(;=P-F+$Ivz_SMNY?d}`9)~vV_{|$8MFW^-s@I^I_#Jq>Jlj1ve~0n zNgrwuTBEC#t;!5i?(8C&Iwus%l?@7RY;2s%1Os4?nJB!Hy5BM$|Mx%RAUivA=6FBR zyHkIx|6l;ox(T_ZkFg7mp)APCo)HcIUjX1q@y}0{n|MeDm`(Q2;}1Qq8%=dvUBHKj zpQ-jB7T!eYYZ00qvA#Gf*VhVYyLgq~nq+nhvWp-fdV_?w z;h0G90qEl_ch&(&CIpN~$u5f=@t^lm49xc)Y1NLXBTq zE5-&J-&w@ON&-i_aqlwKC)qNfc}+e~btmOzATs8xPuQ=cTLUIF8p|E;6Ewl5~YJe=>JK(VMG8My*37^jrQm?Hvr5#LnTd3{#!J@nQ838CSV#s z_9g!)w)Y9no6K|ULa#WDaT4h7Y#JKHN(!~1ZHLW; zyAlmOWXymG#t}HUKkkla&dz4~DzrZdwX@OfFSnnbNM+_6k&nn)mR*kf?&!{xKW%uf z;4j`eo91m)|M%ci^x0s%+^KH?t=vRJT~3Kzuov(0@bXu{ZvKbX76UTOTzNcwG^kMf zBQ2WVVv2ay>xWAC(R?-pA65z2}^hPEc`+H&26bZ3W4B~f33p7vo885x^&O|LyvWG#e=O% zn{>g2(oOv3_^!0Ft+@JdCqdIe_e;)2E7Cz8uCkcAhzJ(a*@0yT(5$)f)LY|R8>v4D zEM`;YjyWY6RmH^RwtG1o<(79YT4L|#^Tb>min(n1Vz{Exq^Qr+BW@Tsy+0(zE5IV@N&y*uiy)~&-&kd_yzIF9<0^=U%&Ru#?^^?vk#_F3yvYAy&lW)G%mEKet zZ8I9KOILm0w089tCy2+(4}2fs5<{kxq_CWfc>!C~v=jj`!Ez~-6?>bpGG{j@8-~rj z?c&4xyBqz#ich26_Zf`$EQjqnf9J0}<6C!?MC9^!cxR$@7*+~&&OH**}x-vOzJ`^di=!F>PF!2-Phwq72AkJjYCZU0IC1phOl;*wdu(eYh>z zQroMg6w6LkJ?hK7+Fs6Rh9eK0pM`1B^YCVu$JX=Oki)Vu-NgyB@zR6Lrx|;ui#>+u z497nEqH0d+_}r_So$kj)GFbYUcbNrlLTh{G~Q`$Cbtp zmg-bN|BZy6t<>>gwEOd34>{koW)vDhoZZ$d>}2{*d$K^el-AHAhH6f^hMo<#N?R|+ zCG_9P<=)6(Wmj*$Coj|l1O)9sV)~d|+t$+-_~ks#-rk@MrO13KK4a7S_h~che1d|! zJlPS2M-rlMn;qn~jeYZv24Yn1^cv4=ubed$5~mY~rBk8v?;U1!uS~fd>X-|o+T^sp zg5x6x*)$edEw^{_MLm4v^_%PR+6CrIpRbx9rehbef2fKQ3q*_47x~CH`!f!S-Xo|1 zzCXEqvL!c7-h;!zy*w83`!x;N-g!FPlcKMMGERD*l0lK-jtf)Jc*;Z5J%jqrs zd?FP+bBDTl>xrR%+)2q~m2s>AH~7{=me9sWM1ECm5iyJ!oO*8=t8E(;Rh`D zq0Qf9!~rlD2!OdM^@$!HtA!v!%PZ(w^w%}dT)<=o zOtqqjw8{H;(`iDR4uuGJC4uSKpUOgA^uzkIzx5w~_9-Rn4VR;V}yTQo`HF7Cx|w-6t!O@e0+kfimlwX=2?Z%=*OVRR@f|e^D0a7lLUk3Uo|M5 zh^Aw$8m|YiJzSsRgsuC|-X5#tqFHn~@Ghzs&&x71FyF^upIybW{Y>~C=hM@^1koyo z&GYjzim7Q;lwMm+zP=X>M47(#xBU4LUyygwdYj@vcPP2)GD~r3!uENc=V{B=SI+n5 zfjT`E@VgwB_t>m1D!XcY=7^*E2IteCacyl=Y`^mr$%^SLfn5olUL+NIHtw~ix3#BLM&-#^F3E?zi{y39bO)}i0N z_dLKwY4DEm`2~EfRUD~X%dXfo+TlP1p-}YAEk?q$I@ej7J~`{)kuVJSf`OvE((b1F zy!zW_@Avby($iihb$qpYf}?LW9(DG6d!NvO+JgPSVxYuMSp1Wg9d|hx7J{)qT;y>Z zK+$f+x9Gl4M%c+HtAV>-Noa$<{4s|sA<<@uGjOVN+Ed_{$SVlR{^C&pXiA6C!o+XN zv5(Q#vHIi6WN&^^Dxi;r1A5gP&^MhWugxXCtC)+->5jq|Sm|UFr)N~A?fo-bH(tM+ z(%1yJnm`&S3;9)C2gmUa`6VMe`BgfmSl1+`@}>dRzx$P3wT2p^njlQOCUL`pLvfU* z^|?z4aq~rivRpdQYSS$%k4~sm78FZ^xw*-~5v<52Hetq5a`-?6n|#!#oOJW8%cmS! zIRHf##k%?73B-SqvDNq-WjQ?yvY47-)OY)Z<8@WG;!!2_d>z8zWc9ZGrZsQ8h~9JB zX3Q+FGb2Luext|-29!9~j(l zy;t69Z?G$HjP5**nwtKg%mq+-w@wB7g@&(v9?h~WY$Ujvy)I9 zDW7vyD$9}<$!6hPe7;}`_q`qyk}E4(d(Lzmj$58j7|oB#_)f6?k{}m@D8&gEw>i7T zgx7UUBd zaP@ZJ%|+P_())pg1Xa1z)B7+|tuO{miY&6v_+xkU&UpjDb*}HDUV%Rgl`Y=E^E#nS zo>8_pf)@Ytsg^=atMMkA`MX+Y(}G8h&T~RDxC@0u&Abtf%{`DR>ax?laFSeIVx9cT zR!l-A8BG&3j1W6XgB;XNgH1yns)WLdxSs0{b#$=*Hrn$fVUn`JOS{nZmw>&GZVN$` z7J^nLZVF0o#dfupJzcZ3z)mIJnU$L6;{F;no=)#3)}?PHFYqUNM+x~$C<>mQ)mX*( zpq>YmN?))d*n9W$tNt%>TnH>{=Whs2M7ELW8LVs^8&38`@uD`;x)0{OzZR5~fn-tt zMA3eG@%F@>eXNMlQ@}i>_c`M|{$fTNT%FbEwIbNZQ3vBjY_@-%I=S-oz38d%~u5<{53@DthIL}ohmzRwcbhO(_baI;_Kf_HeSC1#8#$9en(rc zVf2r`J>;iPP6)K}Get+9SlT{qj+bwlOfsBr44-q{4XdImcjGc2mZe_OzA)!YEHmE< z?EZZgKh;P4Q8~h*+!{^L6XJ6>TW`KUa2^8V_*&mPNjnx!+h@`Vcf_VuBV-8vPJRMg zi}tnM8QC;D-8Uxd%}RYkwzoz$wk)^b*2a2!pUr~(@zx4kPn(lglWTe~m!v`x?U}3s%Wu7t(6!cn zCWW`n!3rr;^cPV~{Lj<-PCPCuy}su~u&0|A4qwhG1rB4e9cAd@{ZAzZ7JI~cXbFl% zKMFY4p9t-+DokuOM;8pZ9D$1gyzi8-(uQoyQ@7DbwNNbyK1?qze33-5*?`rms|y~& zOps&#!nI?p2A#vnA ztJ1*VR;{A_;@Gwyp7MUYh^J?Sk#06DBWgs$3&Q?IhXizu_Z;DCb(r*vjHnVu=%>Zg+#qYnxepOTshaw$gBB9Y5%1kaxXvh5mua zZIFh>wdu&5RNsiq_S?d&jGyxem+Y=-^EGrn*_Jo>w9^t%{!qNzOfQAB*9F*S@W)0| z3R+*DiHGWPF+Jti%TeE&e{;QEj+Ae?S5FBa*BfYq6|q{6yc;Tv8-8%e#g;{zH2myW_sL>%)wrTliA)9KICTuhB^Zb2q3t82Di)yx7ZmP&NH@ zsrN?Maka=5Cbx%3oczx53^d3bZ3!FMK(CZ=v_vUX4R)i= zBL}Ljr4W!d$Uo1kw6yEO-(bQV0NM^#{k)(@O3d4j5gzy0czkTcMU|lHf_S}7|~uG82mtB#(i_9D=bWHGRXFq84ai9wb@Ly_ffM-(kg|@ctnzxn;p+9 zX=r&I{t@wyp!0h~2H`ePci5FTt98ZQ%;eQbVI9McHrLkEjC=T!bi;PCsLkp`KbohS z{dt?(#}~t{*nM3{4~MdD5Ep$EoK}+EMIe1?WMu|_rR`_fNlgzIa(qlDq3`_+{chDj5A{9~3Pv>6GwOl^E++@6{ zD9&+s3Cj~bPtmT9W50J!{hs>Q5xBdiKV!EI%vPrY)qGpsC4+ix?kBB zbL{oNUX|KtiBChUqi8KYHFK3s9)IH2tnD&)E2JVjru(|=Ywx%VgGng#H!3<-DMZ6i z%YUKh#avK2`8$623J6$6Z%L(k@ahcx8oJ0;TrA&w{>RGzcmmsqtXr;kX7xX zBnsKg^SXgTD57Fx8pb~STd*HvAruNjXT_vlu0HOALEN@F-Q_%**+6(hULFsVZ2q5? z`vrB1{$6L1VXp3GjG@dJ*Lc5F@MI_yrd{k9W)V2mXmF^-aIFw zjOH%H=pbV!oy$zxQjrS);eQiD7FUob5f1>V?5mfp;{p98w$k%&%L}zuOAVpEE$R|Z zeRy#%xd?izDRK#WQ<`6oJJ?$jTaYy*1XMwC_kYRZ$Psrtablu$pH^U@EDjivQPISJ zD87S$@tPkc)Zqc)kwC}gr$c3YNDxfh2pp70kdIPFFqc6cX)Np2(DQQmWlVq^WwBF%rUzlvNCLd>fnNi>de4iUEj0Dm9IQ@;#eU z^s@@R$?HMCkIJ~?(mwS?$^E?7XWio?+o#@)*kevNjdOLJs40V392wpMo$ea8rdBJ! z*MRUp&j>hMLe+pfF=0&|p_tAwk5Ifygt%&uYb-4cY5gACs-gR>Xi{XE zWCb?ZeL=}#BV#`~6FEJr2|0_+8%d^0IjvE5UFzm~ITN$aI8Ob%GBWynw3RlsYj^aq z7Nm$1!CO-m{GIvPttup3{At&69@d9 zyFc}=H<04YQvT>Z%dzw7hyG63$FCo$ zB{t^SGq!=Zp@B{ic9#QgaL+pm)~QY|3f6Taa%@97@W22b`i9*jH41t3yEf0zQeim| z8qdP;opw7!jeu`my)bS8-#8Nco8lIFt9d5=(8&>Pmxg0gd?|HAypV}*} zDh=kYQ21=nn{B3S8YJOQ)5>eitEH0I-$6q!b94Ea8cijr5B0$ILsaoz^u+O;$jqcz z^fVm#wEJ%ZzZZaB2fs1e@&h3-l(;kXMvnKoKX1Gxre0k`dW-MO_JY~b=9T-Cv0_)z zmB`YAxc}6O$|$F2&#Rjp#)(gbnB?8}+tz5&tK}BEp&GGXuv=0u^YWsuW3}8^Y1bt> z3NA16{C0gFgdE}L&tc&<7M*p-zCxb3%_EU=drb#m57bviM!^a%g z#RreO(f7oVMd<-N$Xz#RB$JTc-Q$g~+sw=%9vZ16T@c5wVHJ{1{?l-hiDnIkCRb7Q-ESdK*I#bJ{4 z!<=b(29OtT|IwDbfJIY~&%*X+cf z`D5(hcR6G{9#V`$P(za3yjz+~bEKSMg9+qe!a&Bp-|iv9m5gjxm^CgSY>;5 zJMlT$*DCq*@d-@o#dVEV%iWr(oY-kj&$YYQA813uZU87Dpe7e5LGuN~$PIO>_Z@_l zI~)WYFFyy2$dO|B4Ih7`RoJ1%UUlNp*PZ)Q2LZ6SPFa&m^G^tvRl}eWQ3XwIHoA+G za<#R`l|9CXHLCb_w@=i@y(qB>J(e4%$awW-Ow6*30m55ccLh)sEgmOs27MTU#{E+- zZU-Ly(v6WnIbYAbtxeKJbV}bPda?OWdVMA-+)8Be552E7=~rvFwp|h}Gf(JZ;=LXw zw6Bv0$qL5Jm-i9NK>Hmc^hE3xZq%2tv$ishSMAMOe_n6QGL9IySjS9ByhQjZIn*8G zZvzroK6BzoEVI~@fR%0Z*|NPM;*|B5L2pc&R!@2vLM+Z)=2a2UzOp!$81-$fn!1Ez zxK@oPY-$K*YqL`q(!~E@TrF_2wxBc~%9*NpA2Rd0JGz}xV)XSea@oPf2enDT8&tA^ z1%|ScL1>JI*o%TUeZxiwtV$D0`xQrZU-dj#Mtd{Uy8SNb3IZ3YgSa#JDe@kdrFuF{ zYi0sGp?w9m9VBI=!B%j-bGUu@a1n%V4di78O0Kx3_ zE^I&%2QFsyf7Mqbaka1HNs;kAhA@8ai^^v~WX@{8x`%RFLfh>7f!LUQpllLb+{N$@ zIlTt3um|e8VX~Ih`fDyq)+L`^=#K#-loJr{x=;d;Cx416gF_x#=upXT;64=1cZ!^V zl7G35H;kW@A=bi8NzKKX)*;^$FMRKnmP!Tdd<_I}%$&F7O~PM1{%S}ScE!W|(&_mp z<2(lp6yaAC`{mkA@N9E2%?)PiCe#k-E;;wosT{S8)OjsZ(VXR1eiD@J##a$@#FUTP zLs(17uU;j6R6@DuXSchkw*PCT;Bek-OwsPSU2#Kvq!7KKjaT_nHq0l9UjHm&tM97y z@$ibktffBX26hBf97G&r{B&K)(%tvtm$XWKHw<=Y(4ETU<8{u8y;@rJL-fh+G&g5F zuj&u2RU}n>wYz07hOKqy6@l;l0^+siYs%TH>G@q{T%J%&2Psm~K+o%V07sjftVF!l zcrr(GB$v&cBN##v;VR3n8=~N^dASDVc|O>I9+KS+&`j|^A7XrFTQrx=1MQbk;06!K z>#{Ysg?dsS?g(XObfer9`=O-};RI=&|Hh$OCE4{at~*~@HikS6rx&6UYh-1q=mjk) z1q0!Mx&0u%_mw`5{upg_-*2{?ZwLf<-qo~9)V(nY_upC?y@S28DdEF|#xas~-@LW8p5db1oM z^JaSVjoqO2sFz9RH=n24JIyHZE5U(?S?Ulv6?QHbsmSjAF=k;jI^9xBXc+a93rG9x z|CVE|8DhnAAf*^O_&#Gg3ZyNRASk%7w|}w~KRS+&9yD*ULi=?zMMBNF)F#dPS0PeT z962k~`yq1FCi7*f5it&ws&&1!1wX<*dVG!eea^Ub8a9-F5E?f)#Dae=IDiHso)3fI@m6VefoKtL@M4amdjPkbav60{ z0A>dsHFKqK5ZlYT-ToCo%ecgpBbGx8M*2EdOOF7~@M7x3igsG}2#Y?^AEtp7A>)=< z65BB<85zX9KbGyP^ZOZw+J-MXR*0O8lHdlvcrpkr-c#^cs^T2Wu{Gg0jYf}JX*7D{ zpKb8$czeMll|^F5ydP~t+F835%E!&BzuFJo=WQ2m%1Czze*!fm@GHj*F&EJpUjo4Z zF|*2$2T2ak@kl#(D7P2NPrUdM<|^f=J1rVQzH-<$5LE5Bv@)}F8TnGuD#uPJYQu;Y zluIGw{Te^#GZ_Yn-SL6~+|89d^WlStzM#YXyZ+eh9k$%A_sCO4eHrY{2PeF67Y*`f z?+v-J+b?TSt}%;P^J$Wn2GQIjQpHLuQ+&(Wn{%-iICrw*+%yveTZc(rSXKti?@GCs|D6iEj}sY?kIW_I=p7u(mpSb zv>(&2jK4Y39z4%Hk}LT@57cuc87U)F)ZG^*LHX-~p1KL8RvW#1%8>KYpd<1njlNB7 zL{VX)!bdH)C?6b^y`|t6c30;=X*8xU0kA*)v4F)G>AFA47rFDZs**

  • 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

    f)a)xw`(u7B%mi;9`DL| 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%0Ah7cuN812_MA!GcGxzO5ky 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 A>uTSPfOFki$*kpYV?$kta-+);)|D8l(Rp-cp9h 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∓`@cZit@Mms7v}Thj^3!Xjr+O0Zrb6Pf^!$%7B2LqS{;dcz4sCriObdhI z*9K&812T1^#hhlc=}M!-6tg!A0r8)%imUB@y0(g>X+gI)`8UqIMZNBEnmv~2SDSMZ zT{!rSF)L({c)wSsPqcqRNvHp0R*ut}97|?h6VUenqubYC8ymy^{8`opHiLIoK_bxQ z(zaMsA(q?TqLhRex+yYBUlryXPuZMzYjhJEWy|ya`=1XEzwD07(unph?dJL>I7+sj z@ZuK-xS4=@a~8S>M)EETkIA-uC=!wu?1u^x$?fi@OK|g*d6{kAVz@in=Ev{_TgG)A zGkoz#zx;xtAah^E_&yU{*HYS-S6L7wSV_p0R85?UGajQt5dv=Wc;`GILq@|p!4(LW z2odZO49D_%gXD*N%ky4XklBSbAJOo3o9=c_+=s^{fKcImxWgsDXL5R|yX_EFHa}jEcMNZg7}IGh^p_aDXcd3f>;3!Smnbm6iZ;DWpJAV7aXn(MKncxCV(QUXPP{ZjoUj_gy%YMmc1$3Ft03v zFIY}cZqoIZW#`IULtH;|h$>qaGe6&tBGt)n*ahi+8c4}ZBomQnF`5@8A&WG9QmfiE zQL)C)@lbz73r(dx+nT(lt{{+tkjT=dNUmQ@9=5<${`Eaa?2{KDBr7bn{m`nQsctGl ziIcX&j3GCEMRBX$A1$d%nBnb>GvPmrztK~*mT5}NIg|axf)vZ)8%>S`zL!_Il!Cm) zPr2r53pJ{zSY7M%>Mpi~Z8p?=wtrQ%uG&fP4fuXtAyyO`I+{6p$UQeQw2`8!#+wN% ztN%mN3fKmsxofGeo6)fTel2q_^hv)S{)*4$PhY@7hxhT^Kmd{Nd&<|di(6&I zpRO$q?}X5A#cD0Z4RA!sWYyivWpn$#H|q3QQie!Lq(l|6M0870)IZqEQkx8#)DR>;hoRbYf~Fu;f1!n z^ZzM>)cw_fjp$@qy-bSAV=92}WqV6wJRmQk?^Ukp^Ih72S|2KlAG$_o6GlU*0`A|k zBUJ2w-_D~`L)>?$a@6rz+uwqmx|QR>UV0^bUERVWlKi=zjjMk#LNxb{sL_GQZu;|9 zWJ{JTfEy-0(!93+wpalt(~Tid3hk9M21Ex+0Y_zSRa|4rcWYgLD$ag0t^A$?7GGfE z?^-%V2KRPq;BvXH~@K%wPlY@@TE7k9h~KRQS7buBzK zpjY@xaD4o*eD)o##91L5Zco#>a5QG?`jq&7T~t_qzg_Tf9$QMEY87Cw)D1|3uhJ9F z)3d&;NMd$#jkIongkz$M?HoUziq8d`?fS9LhCt)dSDzScBQI8lmSb|7xZZB|Flr+y-N#0=_Z!4{SLZ zi$hbGl(^I>Oqy673+l7nVd?Tv_ef`w3Ek3&(7iwrwa_Yf7S)2Jc-tzzkQy%&cXytM zvOWHM7Y>6=#hR({-D;?`Z>bWmtnt`4MjhHU(;(L4QDYAk-;!^OPVOSxYAx(_)S1EK zS#c<`72Yl=9f%)Eos!%ZpRs%qPv-gAcWeSqkg%^g5AYQ(R7S?~AZoI=)`4Zd~rB!5y8{YjM4iE}^);(j|ise*ugzO%OOa zG?a5RM#Z*aEwPPX%yrH~I95@?Fv&wu4q>`p{pPninJMS~DdFcLDFl4InwnHU+sgXw zPe=iwCSbjmDs()`R5-F&E4ATir6O+-py_^tmj*(FDm=y82DP7_CieBee1xH@o@S4B zCgRJ4jfVDM@tPswQLMzgA35_iBOZOvxx246v|H>7Y11yB>Hl25Amv?kQW^VMT+wvt z==CMt?8#5>@y6XX)2(H`n%FkE;G^_hKKjv2r^X{Tp0znwhIN|PqC&Mu-fhHQB#8$}!x#rX zEf$>qFqW=8QScs)T^ogRgPSR3;s85a>H%9C&I-mM)&|Eq{L;d!a`3@}{uLQ_FFtLA z+qdLBhobMh0$h#^WV5su7shdlc+EPk1zw^Vr^%h`glDGM5>v9w(pAK$WUo;cGJRDZ zb|~WcJ0roqJe|bHgy0krO;w>=IeL{^s+sPM1m8;t%7@FRG}r8|CpnenFAi{PXvO0& z`8+izndmP8AF~MT&W?pM506W3(2QJRAK0<1)ZIP(gEuRPCIkR7vD&5NX?bPJ%$cq5 zH(zxDl(Af46L%i@-Fb7J>#q+RI~Bw? z5gS%K^(doJR@`>1-yCpnp45I>woyd}*#JAr?oj|h=95<@;9XeNR6x`uqkpL_>97k? zD}#YEANaVW_DCM985{@GH7A@Iyf17VHkW zHfuhU;toCCSr%SBGB|6x*x|XrPkNoXyKG0hQbO}6(k=``ZqhM|&0c=GWJ9yuoMM%) zbFYUQ)-Ytm*OuoamDH(Akyx?ojA=-I0k&OuQlSqs$Ld0FxcoRzoH6^b@ihhn3_Zu{8kPa#LC_7}7IDRL&TELQn#-6?S%DBIB5bcT$pts#N!qX&MLt}NlsKz4mML>xs{ z7A|**_7^GXZ!bm=iPx-eZ0md~x#sJ0A2*tK3Andj>PXOrq2H?(>2Uzytnf17I6Htq z7K^R^*nbvUvT*6${GQo1MTCEn!h35Fq4&M@j{LAI;NIQ_SU4j&w!~;_fI1-6&)=A# zB2)kDy!SrtjGJ48@I|F8axANiFD=tp-v(FyS;!Qyq}2l*#hj)I0jY>`i^L$pd!ZbS z(Od;99E>K|tA{ZRi+C{7dC^{M zaQ8H)j-@*2m`-a{gfZy#Bbi4V*WGVq`yE8 zsuJ}9GPVJEC>kjLS-tnhv!ro1t!Ju=8Q2~Bn*4g{RT&kh@Ny*kSA0!QJ`H*XUW5*W zgkDAtqSM@IO2K8Vk^Yj?KaP|~?*Z#R#<+oegV~@VUI~waGN-MUiF{z0T)FxM_c**? zk(CdTX>5EnWMsa_B^hE9`H7tqcgd^R(91MP`35UU`V+e!5=D(aoM_Hzx^WLJoQ$cUn&M1iAy~35^EY2*Y8|t1b2BQ*AOFT%v2!w9A;cnG?s0*=+Qa*P*M8Pf>=9kM}Lk1EmY<2>fF#beX*%xm-pV2t6j`eEY z^{O|So-5>&%|5sZ9#8`T$f0G3TGOS2&*s&Jy3LeR?QjeOOw^Ha?Uz5jJW(F4M@>&< z0DDt3n-E{+r}!+gC+hbjsQACSNCr4h}H z9{o;AGVRqO@|ZW)8UA?$(Nk?YmPvhf+T=F2yJzI{%{WuPa(iq)HGBV%h)2TqM6i8t zfRS_BeDuhCG%CVnhtcz7V9G{+Kp^Q>Unp?evl{y;&X!!0AoN^omA-Z}u|bszm3wp7 z>;vxy#P2$iiyG~#?YTOx8TcX?Lb_Z>Ia|c4|I9_QCOr&avrgPu&ZeOaw%Z5|F+FkI z-pQz!&ukU64%ko59{(0+G16`p$T}RKZ6il3e74m!Too&fNgbF>r0|tSH-}@jPH|Fc^&o`FIIcoq;ZY1F3 z?lxJ~U#S>s14EKVvKK^9naXjWJLR}W>S-0~?(8=Y7D9eJ zQ)0H_*PZ^dEMaL@eR0||Uw+e>4W0-0V2BJ|ELuXcRPnL%l8}hvo>lhQc-pZE;Xl;R-FOyA9R91**?#pq62*C-V5r1Q--9dP^SP); z1w=+Ut^x~E(qeWJ|5BFxd<@ntf0x|)NB>6hfVl!PC=BtNFgF2|#Yg2))`1lIHnoaX(p)7xKZCu15CRS=;nP4nYH1)-RSh8Pe2Z^7iT>M3I!z>KZ}5c)KFsv{GU%!YQW z05(K#nznjcaI)FtnbGM1zR&K4>uwwkB|K_#MVC5`oB{W`VW6_SpvIgQ2;&TZ<5-|; zRYKMc4AxC^@?yBtFX#C1tk$cj#mc(0%xE6!8`juJa`t)kr=ic@0Em`CJVh2Uehneh zMMtX*Te5|w2W@MjX7H=Hw*l4uObX~eZ5KEP=-FRl9y)}&Vps>Vm3s{9n&=oHBqU*< z#+>)5Ocjv{E)o$>Nj?`TPJXs;ET(-pw_@7L+*9R^ z)-}zm-vG@1xVjt+qZ2_4p_?@S^Jo~#Wd_$DM8zD5_*BT3lL3z)AUW1Hg2GsiICBz- z+f%Z5+?ppudxy@rODhNS*zn!JD4T&RZ68U!Hyit2i@E4=K#!2b-e2$S)11KvSp%C- zQf%Yg#2lOyD*M)J^!{0bVmC{W^0{vbek+|P8dUj^F!7~?43`!0>^-Mx_9wM+PfNH` zZ2@B|K4}6;X%Bfm`B`G!9D;>K;GqbW(&FvrrB_prp=oVDh`I`l{ru}MZ%D;S)<;pI zzFoSbKk1yTqNWkkb60t$6YQ?1%t0Qpw_B5Vr{B99vqQpd{Rb{4E`=oRjth&OG~*pC zC_EWBzm~oU3iRGB7=a=L|1uHgopKgZV*Mp zioh31flb9$UR_;DJG~HM1@EM3ui#FW@44%}eqiF=c}%tI+#tZg}fm(5m%|b{GJ%nJ@wEO;1l@MRLI_$LQ-<*gHdHGMnAId~Pg}widu}?gtDS zNvz8A>@eirzit*(h`tL=eL1<~4^9h#nRJTxVXhytvge z=Ix&QZwFLzV00QT_6lZm<-HGr-^xSbS(XKN8n_l85I<6VYIka2ro|Ub^$*9!=L>y) zI*K(6_sQ@juyDwbZa86qXf!Jy!f*6_m?Cd?bfk8{I2jcDS_tqqlXt|sk{CRp%FBRD zgOm6V4qIC63rn1$MzZdyAN0nsTis#w?C2Sw0%+C z-n%G8jjUy_yW~uYV=)RyX(TB;jd1AejH9Ht+F|raD8+&hrQ`hmlH}OULMKtT1kq%+ z-yFq8B*9UKKs@or#&W*|Vu(XG3>FmaKrvq!V?`nc@43gB|D z^s&T-O?nvu0eJ~G1A71?_j<(u(AgaFfIPM*c1X(QJCBjewEuIwTh^T1^&k+2UAMQ_ zONpLe8m}|peVzulQ?&>SwfpRZ2>zPR1~DqZMl1IbR?4s&+S|7jXa^LU2zUTAK{SH1ypji;aC39$ zgi>W+Q1*?HrTMFqE0?BNaMa)&RHiAz1;w)W0p}-Sm^3XJgRrXb8k`mx6IEb-#1Rk| z*vVq8_hsFy*Q-Blo=@VmPi=R*{M1F952$mMI(HG8`6m2t_f|JGkd8h;+&T7}f`3?O zFW7#u^_Cx;I-{vhGo~AlX~d-(U?e~OGSHFnmF z#P51if0gnuAB(yx^m)ncXzqCR&>8q%9_o?G1NR#ey~E~MKpqdQn$X^cys6cn)DK{P zbx-zhCc1#VNAtSdg zuycOW6fjPX`b%YeSVZh=XaN%i0+0?IRanT7{CD`|fZ+?pBKQZw-Ei+xzr_IE9Sc*B z`prC?be?WHC-bKit>?r``mU$6;uC?bI?S<0yzb2t;JQ$Qc=B|E#(xJ%E@x_W@NcEC zn@Tx>ki^cHLtD5$(>^;z2f)4~QL?kOd!hhlVf~T8@%l9*v9u2Phd|=H;|h*hj^3=m$E$Xkn0 z^kZ#(3(gdsxAT5IFK}3gHW1l(iu_p)8_#TC!EUOmy4MBXO8aMkrwPf^I16v&^V#28 z!MG1-jjyjRA-k>EKP!(_0evhd*gYwR+fd^&ZCn*b5S_X8{xp6T-Js2M)9qe?=WTsK zg+;);-L$Oh#&v@}zv*;(&=sjz9l9yN&!VI%DywB{qyFk_3#*IerU@IV?@&%^Qa3e( z_FASr6;kvRzroR)H#qulX$WPPV}DHb_t<^iCUNS5v>HbGqZPZ0)1Ak(ww#t5B1Fa7PXtDn+4U7}|$Qyl) zFuT#$|4~-o=@V7Mv^M751m=j~Dyul^0<2T6z|5<3-8$wlp zbrM<{^OT9lYL|u9-Xkc@3y)l(2`%f-EhsDbpnY@ zK<)$y8TGwwy`M+QOJ?OQ%K?VPB=`H#H b?YAq*X_0%`6dFUmSU^#fRfU#G8^8NMidCUi literal 0 HcmV?d00001 diff --git a/paper/field.pdf b/paper/field.pdf new file mode 100644 index 0000000000000000000000000000000000000000..889ac885aa4a64b5de510b7aa6771e165e5fa730 GIT binary patch literal 14503 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 literal 0 HcmV?d00001 diff --git a/paper/job.pdf b/paper/job.pdf new file mode 100644 index 0000000000000000000000000000000000000000..23cd714ffb9d8407ace28686b592a1e067850d56 GIT binary patch literal 17361 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 literal 0 HcmV?d00001 diff --git a/paper/paper.bib b/paper/paper.bib new file mode 100644 index 00000000..6222ef00 --- /dev/null +++ b/paper/paper.bib @@ -0,0 +1,275 @@ +@Article{dutzler2021, + author = {Dutzler, Andreas and Buzzi, Christian and Leitner, Martin}, + journal = {Journal of Applied Engineering Design and Simulation}, + title = {Nondimensional translational characteristics of elastomer components}, + year = {2021}, + issn = {2805-5756}, + month = sep, + number = {1}, + volume = {1}, + doi = {10.24191/jaeds.v1i1.20}, + publisher = {UiTM Press, Universiti Teknologi MARA}, +} + +@Article{torggler2023, + author = {Torggler, J. and Dutzler, A. and Oberdorfer, B. and Faethe, T. and Müller, H. and Buzzi, C. and Leitner, M.}, + journal = {Applied Composite Materials}, + title = {Investigating Damage Mechanisms in Cord-Rubber Composite Air Spring Bellows of Rail Vehicles and Representative Specimen Design}, + year = {2023}, + issn = {1573-4897}, + month = aug, + number = {6}, + pages = {1979--1999}, + volume = {30}, + doi = {10.1007/s10443-023-10157-1}, + publisher = {Springer Science and Business Media LLC}, +} + +@Book{bonetwood, + author = {Bonet, Javier and Wood, Richard D.}, + publisher = {Cambridge University Press}, + title = {Nonlinear Continuum Mechanics for Finite Element Analysis}, + year = {2008}, + isbn = {9780511755446}, + month = mar, + doi = {10.1017/cbo9780511755446}, +} + +@Article{scikitfem, + author = {Gustafsson, Tom and McBain, G.}, + journal = {Journal of Open Source Software}, + title = {scikit-fem: A Python package for finite element assembly}, + year = {2020}, + issn = {2475-9066}, + month = aug, + number = {52}, + pages = {2369}, + volume = {5}, + doi = {10.21105/joss.02369}, + publisher = {The Open Journal}, +} + +@Book{bathe, + author = {Bathe, Klaus-Jürgen}, + publisher = {Bathe}, + title = {Finite element procedures}, + year = {2006}, + address = {[Boston, Mass.]}, + isbn = {9780979004902}, + note = {Frühere Ausg. u.d.T.: Bathe, Klaus-Jürgen: Finite element procedures in engineering analysis}, + pagetotal = {1037}, + ppn_gvk = {641562853}, +} + +@Book{zienkiewicz, + author = {Zienkiewicz, O. C.}, + editor = {Robert L. Taylor and Jianzhong Zhu and Olek C Zienkiewicz}, + publisher = {Elsevier Science & Technology}, + title = {Finite Element Method}, + year = {2013}, + address = {Oxford}, + edition = {7th ed.}, + isbn = {9780080951355}, + note = {Description based on publisher supplied metadata and other sources.}, + series = {The Finite Element Method Ser}, + pagetotal = {1753}, + ppn_gvk = {1658035038}, + subtitle = {Its Basis and Fundamentals}, +} + +@Article{pyvista, + author = {Sullivan, C. and Kaszynski, Alexander}, + journal = {Journal of Open Source Software}, + title = {PyVista: 3D plotting and mesh analysis through a streamlined interface for the Visualization Toolkit (VTK)}, + year = {2019}, + issn = {2475-9066}, + month = may, + number = {37}, + pages = {1450}, + volume = {4}, + doi = {10.21105/joss.01450}, + publisher = {The Open Journal}, +} + +@Misc{feplot, + author = {Mohamed ZAARAOUI,}, + title = {ZAARAOUI999/feplot: v0.1.13}, + year = {2023}, + copyright = {Creative Commons Attribution 4.0 International}, + doi = {10.5281/zenodo.10429691}, + publisher = {Zenodo}, +} + +@Misc{matadi, + author = {Dutzler, Andreas}, + title = {matADi: Material Definition with Automatic Differentiation}, + year = {2024}, + copyright = {GNU General Public License v3.0 only}, + doi = {10.5281/zenodo.5519971}, + publisher = {Zenodo}, +} + +@Misc{tensortrax, + author = {Dutzler, Andreas}, + title = {tensortrax: Math on (Hyper-Dual) Tensors with Trailing Axes.}, + year = {2024}, + copyright = {GNU General Public License v3.0 only}, + doi = {10.5281/zenodo.7384105}, + publisher = {Zenodo}, +} + +@Misc{meshio, + author = {Schlömer, Nico}, + title = {meshio: Tools for mesh files}, + year = {2024}, + copyright = {MIT License}, + doi = {10.5281/zenodo.1173115}, + publisher = {Zenodo}, +} + +@Misc{hyperelastic, + author = {Dutzler, Andreas}, + title = {Hyperelastic: Constitutive hyperelastic material formulations for FElupe}, + year = {2024}, + copyright = {GNU General Public License v3.0 only}, + doi = {10.5281/zenodo.8106469}, + publisher = {Zenodo}, +} + +@Misc{fenicsx, + author = {Baratta, Igor A. and Dean, Joseph P. and Dokken, Jørgen S. and Habera, Michal and Hale, Jack S. and Richardson, Chris N. and Rognes, Marie E. and Scroggs, Matthew W. and Sime, Nathan and Wells, Garth N.}, + title = {DOLFINx: The next generation FEniCS problem solving environment}, + year = {2023}, + copyright = {Creative Commons Attribution 4.0 International}, + doi = {10.5281/zenodo.10447666]}, + language = {en}, + publisher = {Zenodo}, +} + +@Unpublished{getfem, + author = {Renard, Yves and Poulios, Konstantinos}, + note = {working paper or preprint}, + title = {{GetFEM: Automated FE modeling of multiphysics problems based on a generic weak form language}}, + month = Apr, + year = {2020}, + hal_id = {hal-02532422}, + hal_version = {v1}, + keywords = {Automated FEM ; coupled PDEs ; symbolic differentiation ; weak form language}, + pdf = {https://hal.science/hal-02532422v1/file/gwfl_paper_prepub.pdf}, + url = {https://hal.science/hal-02532422}, +} + +@Article{sfepy, + author = {Cimrman, Robert and Lukeš, Vladimír and Rohan, Eduard}, + journal = {Advances in Computational Mathematics}, + title = {Multiscale finite element calculations in Python using SfePy}, + year = {2019}, + issn = {1572-9044}, + month = may, + number = {4}, + pages = {1897--1921}, + volume = {45}, + doi = {10.1007/s10444-019-09666-0}, + publisher = {Springer Science and Business Media LLC}, +} + +@Article{numpy, + author = {Harris, Charles R. and Millman, K. Jarrod and van der Walt, Stéfan J. and Gommers, Ralf and Virtanen, Pauli and Cournapeau, David and Wieser, Eric and Taylor, Julian and Berg, Sebastian and Smith, Nathaniel J. and Kern, Robert and Picus, Matti and Hoyer, Stephan and van Kerkwijk, Marten H. and Brett, Matthew and Haldane, Allan and del Río, Jaime Fernández and Wiebe, Mark and Peterson, Pearu and Gérard-Marchant, Pierre and Sheppard, Kevin and Reddy, Tyler and Weckesser, Warren and Abbasi, Hameer and Gohlke, Christoph and Oliphant, Travis E.}, + journal = {Nature}, + title = {Array programming with NumPy}, + year = {2020}, + issn = {1476-4687}, + month = sep, + number = {7825}, + pages = {357--362}, + volume = {585}, + doi = {10.1038/s41586-020-2649-2}, + publisher = {Springer Science and Business Media LLC}, +} + +@software{jax, + author = {James Bradbury and Roy Frostig and Peter Hawkins and Matthew James Johnson and Chris Leary and Dougal Maclaurin and George Necula and Adam Paszke and Jake Vander{P}las and Skye Wanderman-{M}ilne and Qiao Zhang}, + title = {{JAX}: composable transformations of {P}ython+{N}um{P}y programs}, + url = {http://github.com/jax-ml/jax}, + version = {0.3.13}, + year = {2018}, +} + +@InProceedings{pytorch, + author = {Ansel, Jason and Yang, Edward and He, Horace and Gimelshein, Natalia and Jain, Animesh and Voznesensky, Michael and Bao, Bin and Bell, Peter and Berard, David and Burovski, Evgeni and Chauhan, Geeta and Chourdia, Anjali and Constable, Will and Desmaison, Alban and DeVito, Zachary and Ellison, Elias and Feng, Will and Gong, Jiong and Gschwind, Michael and Hirsh, Brian and Huang, Sherlock and Kalambarkar, Kshiteej and Kirsch, Laurent and Lazos, Michael and Lezcano, Mario and Liang, Yanbo and Liang, Jason and Lu, Yinghai and Luk, C. K. and Maher, Bert and Pan, Yunjie and Puhrsch, Christian and Reso, Matthias and Saroufim, Mark and Siraichi, Marcos Yukio and Suk, Helen and Zhang, Shunting and Suo, Michael and Tillet, Phil and Zhao, Xu and Wang, Eikan and Zhou, Keren and Zou, Richard and Wang, Xiaodong and Mathews, Ajit and Wen, William and Chanan, Gregory and Wu, Peng and Chintala, Soumith}, + booktitle = {Proceedings of the 29th ACM International Conference on Architectural Support for Programming Languages and Operating Systems, Volume 2}, + title = {PyTorch 2: Faster Machine Learning Through Dynamic Python Bytecode Transformation and Graph Compilation}, + year = {2024}, + month = apr, + pages = {929--947}, + publisher = {ACM}, + series = {ASPLOS ’24}, + volume = {5}, + collection = {ASPLOS ’24}, + doi = {10.1145/3620665.3640366}, +} + +@Article{jaxfem, + author = {Xue, Tianju and Liao, Shuheng and Gan, Zhengtao and Park, Chanwook and Xie, Xiaoyu and Liu, Wing Kam and Cao, Jian}, + journal = {Computer Physics Communications}, + title = {JAX-FEM: A differentiable GPU-accelerated 3D finite element solver for automatic inverse design and mechanistic data science}, + year = {2023}, + issn = {0010-4655}, + month = oct, + pages = {108802}, + volume = {291}, + doi = {10.1016/j.cpc.2023.108802}, + publisher = {Elsevier BV}, +} + +@InProceedings{buzzi2022, + author = {Buzzi, Christian and Dutzler, Andreas and Faethe, Tobias and Lassacher, Johannes and Leitner, Martin and Weber, Franz-Josef}, + booktitle = {Proceedings of the 12th International Conference on Railway Bogies and Running Gears}, + title = {Development of a tool for estimating the characteristic curves of rubber-metal parts}, + year = {2022}, + address = {Budapest, Hungary}, + editor = {Szabó, András}, + pages = {191--200}, + publisher = {Scientific Society for Mechanical Engineering}, + isbn = {978-963-9058-46-0}, +} + +@Article{mooney, + author = {M. Mooney}, + journal = {Journal of Applied Physics}, + title = {A Theory of Large Elastic Deformation}, + year = {1940}, + month = {sep}, + number = {9}, + pages = {582--592}, + volume = {11}, + doi = {10.1063/1.1712836}, + publisher = {{AIP} Publishing}, +} + +@Article{rivlin, + author = {R. S. Rivlin and D. W. Saunders}, + journal = {Philosophical Transactions of the Royal Society of London. Series A, Mathematical and Physical Sciences}, + title = {Large elastic deformations of isotropic materials {VII}. Experiments on the deformation of rubber}, + year = {1951}, + month = {apr}, + number = {865}, + pages = {251--288}, + volume = {243}, + doi = {10.1098/rsta.1951.0004}, + publisher = {The Royal Society}, +} + +@Article{treloar, + author = {L. R. G. Treloar}, + journal = {Transactions of the Faraday Society}, + title = {The elasticity of a network of long-chain molecules{\textemdash}{II}}, + year = {1943}, + number = {0}, + pages = {241--246}, + volume = {39}, + doi = {10.1039/tf9433900241}, + publisher = {Royal Society of Chemistry ({RSC})}, +} + +@Comment{jabref-meta: databaseType:bibtex;} diff --git a/paper/paper.md b/paper/paper.md new file mode 100644 index 00000000..4dca46e7 --- /dev/null +++ b/paper/paper.md @@ -0,0 +1,100 @@ +--- +title: 'FElupe: Finite element analysis for continuum mechanics of solid bodies' +tags: + - python + - finite-elements + - hyperelasticity + - computations-mechanics + - scientific-computing +authors: + - name: Andreas Dutzler + orcid: 0000-0002-9383-9686 + affiliation: [ 1, 2 ] + - name: Martin Leitner + orcid: 0000-0002-3530-1183 + affiliation: 1 +affiliations: + - index: 1 + name: Institute of Structural Durability and Railway Technology, Graz University of Technology, Austria + - index: 2 + name: Siemens Mobility Austria GmbH, Austria +date: 18 October 2024 +bibliography: paper.bib +--- + +# Summary +FElupe is a Python package for finite element analysis focusing on the formulation and +numerical solution of nonlinear problems in continuum mechanics of solid bodies. This package is intended for scientific research, but is also suitable for running nonlinear simulations in general. In addition to the transformation of general weak forms into sparse vectors and matrices, FElupe provides an efficient high-level abstraction layer for the simulation of the deformation of solid bodies. The finite element method, as used in FElupe, is generally based on the preliminary works by [@bonetwood], [@bathe] and [@zienkiewicz]. + +## Highlights +- pure Python package built with NumPy and SciPy +- easy-to-learn and productive high-level API +- nonlinear deformation of solid bodies with interactive views +- hyperelastic material models with automatic differentiation + +# Statement of need +There are well-established Python packages available for finite element analysis. These packages are either distributed as binary packages or need to be compiled on installation, like FEniCSx [@fenicsx], GetFEM [@getfem] or SfePy [@sfepy]. JAX-FEM [@jaxfem], which is built on JAX [@jax], is a pure Python package but requires many dependencies in its recommended environment. `scikit-fem` [@scikitfem] is a pure Python package with minimal dependencies but with a more general scope [@scikitfem]. FElupe is both easy-to-install as well as easy-to-use in its target domain of hyperelastic solid bodies. + +The performance of FElupe is good for a non-compiled package but mediocre in comparison to compiled codes. However, it is still well-suited for up to mid-sized problems, i.e. up to $10^5$ degrees of freedom, when basic hyperelastic model formulations are used. A performance benchmark for times spent on stiffness matrix assembly is included in the documentation. Internally, efficient NumPy [@numpy] based math is realized by element-wise operating trailing axes [@scikitfem]. An all-at-once approach per operation is used instead of a cell-by-cell evaluation loop. The constitutive material formulation class is backend agnostic: FElupe provides NumPy-arrays as input arguments and requires NumPy-arrays as return values. This enables backends like JAX [@jax] or PyTorch [@pytorch] to be used. Interactive views of meshes, fields and solid bodies are enabled by PyVista [@pyvista]. The capabilities of FElupe may be enhanced with additional Python packages, e.g. `meshio` [@meshio], `matadi` [@matadi], `tensortrax` [@tensortrax], `hyperelastic` [@hyperelastic] or `feplot` [@feplot]. + + + +# Features +The essential high-level parts of solving problems with FElupe include a field, a solid body, boundary conditions and a job. With the combination of a mesh, a finite element formulation and a quadrature rule, a numeric region is created. A field for a field container is further created on top of this numeric region, see \autoref{fig:field}. + +![Schematic representation of classes needed to create a field container.\label{fig:field}](field.pdf) + +In a solid body, a constitutive material formulation is applied on this field container. Along with constant and ramped boundary conditions a step is created. During job evaluation, the field values are updated in-place after each completed substep as shown in \autoref{fig:job}. + +![Schematic representation of classes needed to evaluate a job.\label{fig:job}](job.pdf) + +For example, consider a quarter model of a solid cube with nearly-incompressible hyperelastic material behavior subjected to a uniaxial elongation applied at a clamped end-face. First, a meshed cube out of hexahedron cells is created. A numeric region, pre-defined for hexahedrons, is created on the mesh. The appropriate finite element and its quadrature scheme are chosen automatically. A vector-valued displacement field is initiated on the region and is further added to a field container. + +A uniaxial load case is applied on the displacement field to create the boundary conditions. This involves setting up symmetry planes as well as the absolute value of the prescribed displacement at the mesh-points on the right-end face of the cube. The right-end face is clamped, i.e. its displacements are fixed, except for the components in longitudinal direction. An isotropic hyperelastic Neo-Hookean material formulation [@treloar], [@bonetwood] is applied on the displacement field of a solid body. A step generates the consecutive substep-movements of a selected boundary condition. The step is further added to a list of steps of a job. After the job evaluation is completed, the maximum principal values of logarithmic strain of the last completed substep are plotted, see \autoref{fig:strain}. + +\newpage + +```python +import felupe as fem + +region = fem.RegionHexahedron(mesh=fem.Cube(n=6)) +field = fem.FieldContainer([fem.Field(region, dim=3)]) +umat = fem.NeoHooke(mu=1) +solid = fem.SolidBodyNearlyIncompressible(umat=umat, field=field, bulk=5000) +boundaries, loadcase = fem.dof.uniaxial(field, clamped=True) + +move = fem.math.linsteps([0, 1], num=5) +step = fem.Step([solid], ramp={boundaries["move"]: move}, boundaries=boundaries) +job = fem.Job(steps=[step]).evaluate() + +solid.plot("Principal Values of Logarithmic Strain").show() +``` + +![Final logarithmic strain distribution of the deformed hyperelastic solid body at a stretch $l/L=2$, where $l$ is the deformed length and $L$ the undeformed length of the solid body in longitudinal direction. The undeformed configuration is shown in transparent grey.\label{fig:strain}](strain.png){height=40mm} + +Any other hyperelastic material model formulation may be used instead of the Neo-Hookean material model given above, most easily by its strain energy density function. The strain energy density function of the Mooney-Rivlin material model formulation [@mooney], [@rivlin], as given in \autoref{eq:mooney-rivlin}, is implemented by a hyperelastic material class in FElupe with the help of `tensortrax` (bundled with FElupe). + +\begin{equation} + \label{eq:mooney-rivlin} + \hat{\psi}(\boldsymbol{C}) = C_{10} \left( \hat{I}_1 - 3 \right) + C_{01} \left( \hat{I}_2 - 3 \right) +\end{equation} + +```python +import tensortrax.math as tm + +def mooney_rivlin(C, C10, C01): + I1 = tm.trace(C) + I2 = (I1**2 - tm.trace(C @ C)) / 2 + I3 = tm.linalg.det(C) + return C10 * (I3**(-1/3) * I1 - 3) + C01 * (I3**(-2/3) * I2 - 3) + +umat = fem.Hyperelastic(mooney_rivlin, C10=0.5, C01=0.1) +solid = fem.SolidBodyNearlyIncompressible(umat=umat, field=field, bulk=5000) +``` + +# Examples +The documentation of FElupe contains interactive tutorials and examples for simulating the deformation of solid bodies. Resulting deformed solid bodies of selected examples are shown in \autoref{fig:examples}. Computational results of FElupe are used in several scientific publications, e.g. [@dutzler2021], [@buzzi2022] and [@torggler2023]. + +![Equivalent stress distribution of a plate with a hole (top left). Shear-loaded hyperelastic block (top middle). Endurable cycles obtained by local stresses (top right). Multiaxially loaded rubber bushing (bottom left). Rotating rubber wheel on a frictionless contact (bottom middle). A hyperelastic solid with frictionless rigid contacts (bottom right).\label{fig:examples}](examples.png) + +# References diff --git a/paper/strain.png b/paper/strain.png new file mode 100644 index 0000000000000000000000000000000000000000..f37991886c823ba2a4e14e9e363dab547a40e4c6 GIT binary patch literal 162624 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

    E^j1O21i)VPxvPKEc8esS+pysn0km0ddv}n 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 Date: Sat, 23 Nov 2024 08:42:26 +0100 Subject: [PATCH 125/125] Set version to 9.1.0 --- CHANGELOG.md | 2 ++ src/felupe/__about__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08aec9bd..68715dc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. The format ## [Unreleased] +## [9.1.0] - 2024-11-23 + ### Added - Add the hessian of the element shape functions for a quadratic quad element `QuadraticQuad.hessian()`. - Add the `order`-argument to `FieldContainer.extract(order="C")` as well as for `Field`, `FieldAxisymmetric`, `FieldPlaneStrain` to return C-contiguous arrays by default. diff --git a/src/felupe/__about__.py b/src/felupe/__about__.py index e54ff8ae..ba280739 100644 --- a/src/felupe/__about__.py +++ b/src/felupe/__about__.py @@ -1 +1 @@ -__version__ = "9.1.0-dev" +__version__ = "9.1.0"

    %8UhgB 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%0D?Y&6@Ozt#W%sV}EZvypG$UYILnHcl2vK)0@9 zd>@$D>I>($dGgZ7*pdoEJe`NMbl(FI1e^H=F4Y?x4;gcOZi@If+{N3`f>aQg!BBL1 z_yYR&a9eiO}%8Kt8%CD2%# zhJ$Uc(kLm23ifKQYZ?Ys--Z*X3LxUce=b=4%z;VJ(9F#o;!ZePhx;f@@+?=H?ZiNv z4eaGGAOA8k?K&x(BR}10&r+f98w+eq&|O4O&@59_v+NQ`M}iY%L$fpi8Dh}8Oxq4@ zf8TT~J|V5iHt>K1{C? z30p^Q2wHX?@F#e9k(&P_g0QOFhBDSkr}lzz%ys^HCUS8mH8_OiD@oZz@5yHnHOb%( zuc}au$Y6Vs^wai}DZUof3xmOUF2--p;>hnJ|7Me`=^)YypwC(}d;h$kbBBX_3~R3T zcjr@hs8lmO{fISscOX4{+Uen~c7w=dxesv_AJ@n-5F+(;=Nn>;IOA5p+{fEft(*J0Yqqyu(h3(YWjO^ z+D{1=#f5HWi>sMD+BXkU))iJhUBA`ht+X0%vmB6V_LFsUg05m06DS>{^uH4xPxNu~ z1gv-3dNF>uov>7ibVp9>ix?XTs=!izsi$Ti_b~8240ZSSUR9jpuZrvTw~f1);6ia6 z?P7^9L3H|lJu{~0?|Na+B2pBWt0!EFL7}Og3x=kqRfu(*)4=w8jHUj#(GzU0KHXEJ zrRKBsZs5?%=bAnpVgJ}X-%7+_`rnxLqEpFy_HzsT@lH!dn%IO6!XHfJm1F_TorcLm zZNc;(yECyfu}yrEKqQteL`)<33BWQ_p^h{Etq{ra^*faLPfJ@Nwe4l3rE62Cl%wrT zv@uteBIvMaHvN!WHWWOyHto5=G=9pya5?#H$W>{Z&^+9*p?FTzuRa6|LQl`dQm#&M zHz?(Qw=1}dc43{EC}V~RoR*su^z}({ANPtgxUA<&Y$5#Ae=Xany7#9Rt7!@lxF6T% zC!uD~fQROK_oq>#4J|t&>ApM(G#(kB5N?crg`&L4T|IGcXC@rlTYtJevz=d*Q42X! zJhP#94OF+=MPwe5-ibEgF>oNh+&BC}m%k1%==k}jO#fTYkht}9n_THxMc%|WJ~nF2 zdy|A_*p+LjH)H3aCR+AJ>TM#q5i* zL`!3}wmjHY5xLq&l+VJvgAZoBz2PJXwL@Z}kB~+!43n6kTNAn~aA@mI>T3|v z!$NV6q8v_AA2J;shj?r>26G+^JiWuyu$A^!Gz6PN++wA%8(|2PFuAG49vy)hP^AqC zh+9c7i!?e7G=sI+%R_PdD;3=!g>b^Dl*$!#9)xPW8#gNqkIq*OZFKhrXD6n!M9uqa^NoC@TZ zSKe|OS2i&vM5L38Xf86DZ1m6m?&^rWB>k;pvTSam}1vsZ={~5 zjrdWc*-uQqU;3nCVsXRAy5PW_dFI<4%G0wkI`5BZjZBDK-+CKmK@oQ1vJ z;UFH1xu}me7d$z`v#s2!%mLV&lVBcnRF=_J!ln6`(!1Wm6TA!K(eX3iT|aDXM|C@T zy`=a{)fEp*Bon8p+}&W~=E~C@>G748%Go{6;U(u=?Q)29f@rzw>lx~UqyPUeR&OPe z0bVE+Cos|W#502ryB04!XwC9ng!NGwzc(m=+Ce zg>Yn#S3vUa5OLg8nO075V) zY#G};w*tOLEaDUU*asC%mkicOba#%()oAfQW@Ef#u#?eBxI2=1yrcW0t>t!evS74lzu3>yx8i?+txgW&mZ$S zcj%XrpZWa^EG(!6Kwk5q)AgY_!gAO9x&I7bERz**$pQR;-cy?LTpz^!V!YwmlvPC_ zkuV@OI7}!Iw%or>PjarC*ye z`VuJkEKWirEm69!f%ob3NVR0454e@I8ER{{Kj4uK&-Myv7p`{YhD_3-t3RvqO9~xy zSJ$Gf&0-^A%HD(*uRNaZ`n3M=C-HcFLm{+{i5e~<nIuXY-}!IqE?{|7XL#ufd@%*E(F)L#KOQTt&KqH;-<&GebidvW738;f&ldfV zYet@MhbhcAG7g#0RoN;v$8JxiB225v}0rt zFUXsRi`~8q6%l8%YS5+^4od=Ex#m<3D~2DZnyvmd1nOVyYIEMP%_Vw1ZWGWTQq(YIl~+BJ z&lf9Mp0+p@RK@0iYwu$d1Vp%Nnf=E$C+4z?awHcEPf%}0R| zDTRX}U^3&FaYL2-+h8g|EQ&Tm?zHTO2%#@LlwXUW?!55I>dA?PC#fusqUHS$h{P?c z_z%nQSF>L@y534i8jnqSZ<4xHVAvT^ozP zErYsRXt6iBxtaZ zUysCeK!h$PxEFqsyFVIhWtM!rUlB^`XJPJsoUP5rfY_d}3# zNXPdHG8FUk>k8nnCKn;tFCOT{s$w+4Ha?wZ_%bPeramHL@v@go3$1pigz^31ACycZ z9lZP|m|943CXS0`Q*pfoG;|ytvj`X5l$qP_k&dt09sus=rOAGcM2ZvND5XXRsoS*O zzY^Hq^RK;2W!`7+6i5&9JLL=izK|UIo34t%j__V~A}7)*Jj`64EN{#91mZkS=Nw`n z9^cv3ZM#^nR+FU)nl3Q^X)bd}6(l5z5wK(n^nd$7M5`F*e8Y{M!9PTJ%bjNkN}*)d z&)N$M|6USL^!gx8!x5nGdg#@K8s#~hxe@?1ud75 zXwI!BZ{zUB=TnVKb$_hKxygPQj^W4ZXf|he)hW2U8zI|FYMWj`-_EN!>Ghtt^64V9 z-Scvpr|Wea$i!C}7`V~I&}HC_R3QXbM+t*b3UC^>KiBJuXEkI`99Ohuvia!QPFiFE zMF85X2?Fg6HpW=V*80Iy4m$;wJZXHwsXYL%8tQ+F?2tM)5Q*@3%g(JQAUH&(<#xsU zaJG9aZt8oD_i)LZXZv5pL+Faq%DX0Kx#7x)T72hDdvZFv87Whu#g?MU<0s&jY)}Jc z-(lPUCPzg7mA>M&VnNWgjbQ@}0C(&%4~scSx^$-R z!}wcZ$^$Zfh%&yX%yxU)^U~%xidvTNqh@&J zhCY!8`m6oeUl|G*C?UouTf)%RFGhh0+c3bewl^E2WE+SP7<2~8z@Ql) z7skIoT0&C@P4&7DNp-wz<1D-wmT|$*ECkF|0C+4W0_Mv;K} zpF!Q-*8h630KVi@q^Uyw-x*n1&-Px?xt&il5Ch0HJXn)2rbxYPP^EKp`{QEy4ZhEg zPHwLE?zO7KiFU^=4-fhbZmAzz+w1*0SPmEXSI<1$&SGoyuG9GLj9KBTdZ}Gr!aJI3-N9u^&m-NRWVy2nihuZ?q zfOlNG79!}!nPaPicvz|rF$;w96_hc%@z#R0&L{nCXr7uWuuu@LShNJ@H{i_aA`E5v z+_mM0eM-JUX_(EHV7o42WzNf%_{k~JQF@YiuDMaJn$|J}*thhSggR%IYbUsfc(N@A;AbVHXzGlWRI1 zy;|L`6sl(*Yy`(`M`6F>~Cv_VL_HMeA}L z^@PYXOud$JMfO@Urz(ciC7xED_Q#^z)6RE65JYijp6Kbs1B_KKp(9i9@}l>|w=iJt z(43S%9fox|M+EeLEk2vbAl!fW;0Z?z+*N}33i!W3)E*!;E^2wC3h8+F?mCe{^pCpW z(%m2LkJI%T0*fp@`ekq|PQ0AYV?sA(5J(n~Q*nqf+@`|0!`j z&wgg)4U^$P%Wl_Q!%<=6wTucvIO?aJJ9KAE47*S_LHJNX_^AGrfsjJ+>MalFma$;9 zjGAP1%W!m2EzX@o@j7R z(Tq+LBv8;fC5wtzJGy97^MH3Zu6uRyI&?* zOCp5_fW-?th{8-pk-Oh$_Eo-H8qxjh66x>kb}(L};K_XtNVXz&$h*8SJSKGnUfn?U z+wz&hX`HNN{kDt(UMAZjY0PWG>=#wLC7iaAiz7zMb1Lhn0;kn0@xNuhPSK&Cq%W@$$?!RDfTK%amVj@hW@|RttRD& z)R-VCIvZIlM|GMYd{Lc2d4$iONonlw0CWQ7oQqL+NqmI{*&EnsdD4gEOLwB#-zs7d ziB3Q7)bWc&0Y*?o@l_ChT8YjtH6VWrb;kT!JH;fGgM~I5=hz*X2ZPm_y#&V2EJd`6 zn722{X!PCGF$yB%@Zq&+@i5J-r&)cyJQX0Mgg#+>i0PX3OP|>LyKi-_13IYXp=jrZSqGfO3s;Fxkqq`Lt^rCAewX;A zFkyr#V$TN?#5-)iQqRjo*u&3SAks=@L6#Kh5H}c_#2S4yO@et7Kqt_1272kuRdRyEF#hAddVQ+h~WPJT!7MS ze|5Wf?>{X(CvTk-d{M5Nv-k~-N#B88g-cle-6a{K%p3iUWZ5IBU|x#bp6UzT=d(!Z zLbAKRRDHDFQy=;r;i5t{;kK;5AQm6osj*F?hUH^^7d`?Y?J)E++>_cRfv4^Dc76wg zpzk04aB$>$>z!3djz9{UV)PaXMg^C#f^9kECxidbCw}|g%yYUmc?Y?gc6Ad-1ss4E z50SuE`ARtnct`kIFCPHe(1|jr?CGkm(a%Dq1ZtA%;?w=P3<)ep)sxq=+p)rv&f2RPK|;q4 zrNAkg*()4k<1PxyE=_FuYO^2w@{LwqHqaO-u^_p^U&ze%1CQ#6BX6JI=DR_$`I>y2 zP1d218I3(cmiof!vP-&v8{rLj+H!266tcgoI+@v69J{x3sPmc^m@75&?1KonC{Q_# z@}*HK*utN3S<~E&E$&(Wu*)grSIxp%_VK|PuoOo+^VoGjg z8_xma>+##pto-R)Nf=B7MW*lfstAey!*Z2hw8qm|_7_7xrc$-I@*qH_L=83QuZ)@z zp%DQF5dXLFpr4&kYvC`Kjm;i<i9R4%YcuL|b!i;uTXE zEe^+?$ipcp2*1L4wGQIl<4l2}#pr1$Gi;PuXZ^P0&mMwmEnY*;wz8C9v^2bLJv*9kl z1)Mi&9E}+Wz4>|-ETF^2J7l*cZzSgT(VVIpC$;~Z=Ro>`YoPFhAZZ<5pK-l7dbFV0 z<7zYh%v82u&_To-VOT!$UZvTp0jJP8Djk3cb!;NFe_ex)mvq-&xAxdW%5yPwT}_t# zAL1mO?*ySuOquM$&fH#_^n>%Re*4o*tHSH0%RCaeGZP`(Q-TsDLW(*uo#~RmFAzY~ zY|-*QEjZIt-7TEeI-lRUvH)5U(92Jw{*nr?V}J)$tY&W0B75ZHzMkh=I6XET{@hM# zLW4A|5n7)@L*`z6oj4zaHm8s>#?t!W z6NTRYw8QtoT@R^5DzcC3j#NQhuXNc#s}V6jQ~ZhJ*xEj0T2qExC{lV0fMl?Z)4S@8 zNLetwS_Tf?=`cS_P)cGdQwHZt;E=kJGGV%kQ-5RDy8dvjNubmIrTkm1;fodXRRemu z=NLKd52mxEdAKh$I>yGkI|z8vp7>&>GO;zUK|n-w0Cf(GxeQbP02l1sH3hb{T!c$^{zD5W;7=;MfBK1Y*h%so&@_g7EDIu@!BD&`w+glML_~o-aPR zWi7}B@PakM>i-dE($}*>zjmQwHQ>|fIse`cZx&R>>ZAIvXoz9qa1OFk@VXwoxCvy; z3PVZ57+8~_qSR(`)cki`^El0H1)KZ$EJ35tjO@hcC8Phv?Xyo1jqtks^~oRKN=RWMZDA$U zg#GX)wG(EGn2z{_-jv6tQ|`{HPSN%UgTR{E+Lgh0wi!w7xMz(WGGTRh{oAsJa0Oh(BmI#~k}PNvMDH zDzOmu1J$12H7tFkFdG4wYAG!vDC$}Fe6Q|ajI0j8n?YbwoeNi%VlU&&~l`~{nFXP|3>UK!ER~a9phJ+Q*eo@!MMB)w28-{RWE-tnMIpVpU3|ajQ7tZH zh!3$@W&s#cA33gyi4)euTg6Hq*Gssz86tk(kGVeo#mouW?F`yu?HtYy5+$d}3q!wB zqEJQD*Fr5NB8cIWqli9BWs1m9#(v_e#h8Ov^!30h*wULL2{v`_r+&gGrhp#CBFlQP zUfS`GEu!V8OxXlu37{t)=1V8&=BJ7Qw?)z4LpZ+DH&~K~h?Q=sr0=DKQV7-c4b6}i zDW|XW_uLn_7xrNDr+iYP<3fU^D^(6dA%z`FNH2nLbo$cpizKwM2)Gke;2G^PfL;=u zq*oP17AI;k%Pm21!0^P1N?KtjID0#01EKf07viZL;c(M<;j~hgK{_iBVM%P z_$O#Lc7BXw#U+RbvZP#mO}5Xys>>LdTrIoTKrnup;Zh9#BcxA7$D)= z+@3UdKfxv*if21}LpdZE0U7qe&cjf=7=bJ(Mo6&J!W*Og9!<^%K>}0$hT?hM#pb1) zk(;6ysF}C8S;^sQLrS#-0eAR{-5rUv?``3~h&UR~U6gOWEVk4LR) zC6gbSqIA@CaWp0fKg1t(j-I~FJ3B_Q5GpetGin9NH7qju3yAr zTb^)*Q%EdHNy*N=pgVZQ8C-G`d|wIKpL_UaeoSv<39xY4Muw!53ACR#M@dIuN2a0On>=U4|#++!2l&*6}V+l?OZmILGu)%6xA_3^v^5 zwd&_(WK(BUM-U5t^207y^{wy8a->E_4ql(7ioae?QEd425x?InrSVG>o30AP;oFtk ztm^E=Wk0`vJYTVQwV5DCKl?!lq5H&sJqv7;GCI4A-`Fn%SUN_Ha!9gQ;;UAN9;%o7 zd<+G1(Yu_Cv9;&W80g`{vS}}U16g6aSc_oOeyo#T=i)i+Top6=KBS>{kai7|RgRxe{`-*iX-Q*uBer z@{7oAl$Y<;Z7aL-92Dqq=*3R8g&H?8IR+0oN`r_Y`am4MC&sq}o5f95-J6jQ+hl%w1;oCW6noCC!aKe} zHmP?+Is40vyLmDFlQU|>C2;*C%*t{}D=m518v)J^4W>p23?vN7=#3VE{P z!~D^`+Ar~975;m#AOrVkpHW4d+%P#^|IbbR!sok2qZ^RzHaW0JKEnc>0TPzuFkkuA zX16cP@_e*;)#NcHPDd8}i6J`lnyfVg#=U)cE@{h(wBpMeaE#wMg7b zb!+b|IRcfqNZiiR=y;K5Ht_E^uBoqsj(;x4d@qeQ%&v3DJY#G}E8*Ix|~uWiD}Ru*3NqK3zOPo9}Ob`M!tUV`7&PX6Uz zW#%!42}E_Jb0t{`v~AC_cln=?hfhpjb-H|Uxt;S}b*ZpIpptV?p@da%j7%lTk+JE_ zbDHE0XpB7x5bPT^X#VMuy|$@xSJzxfQwrtbj`s0jmhtiUL{o_4d!q*LH1Tcl-YC*q z&mX|X>CE^UK4Hxh%=Y254L9X`MC^ad8ouLW67IHl6-5!nH#`98&`akmw?LvCrrN74?nPP&g|Mm5sF!-Lm$$5=_8w74Ag$a)C zIgZ{tDHtHi!X63C7j6X!hCLm2e*|fnC-VI#EK{uUj+;G%$ArsCO@0&-wkPgkMy^KO zn)XQWm^dEam})_clm;-OQYNPWTs!s>>lp*)l2O!fv`*}$0Z&aSE+O)M#?5??5dD%x zJk-X6Z(YdvffTs_Y=|pA)IN)2ZtO#d{tL&50w;&_^!w{~@Ynp^Ltt#e{Oi*USM%B(qU*_rU<%Si*R=eFO&~YQp#t5V!Gf zde|`CNsKVe#uc6*4UlRr=|1du>3OrL@upBdzsqcBeu2Y-GYKR}i68RuoQ_Lb0}Q6A zN;FI0G~k-;j2#_`8p*dZinT1!Bjq#hF(z4zC{Go83EO4sofPX)lRWDix)EB{mgW(y zIIu?wf4PT7kD7svEX%3d%r{B&9mZ?VPz(#etDR=gWFKH6mJGk8q;>*m(Eq@ijPeyRAK}wTY zh>6R?JT6OX01iFOg`g7}t94{3;tt)H(KsrdBBEH+hW#>b+$vrDZF9LB-=_(Y1H5@m zx^vIe5mogDx6|~h??C6c2M4sLWmDWX-^T$bKwQpd#2-vC<-b$(QZuJBb^UF6$1P_@ z$%47aEswJt;|HFve@8os1)5tCi*3lk&s|5dakfQANb_((Ew=hSN@T>QUft6H-PR(* zOt-65pfEYY3xd^C$GKxZ4#<-_X6Ekl8^%C)KzV#5cqS8H&2Ncq!@+P7?8j!m-CQ-0v-yTC0zjM0n2U zwgl7Cm^OAbExVzWDCK540bpMM?+B(btX|IM(JQ}(z?TIvZj&U15J(BAr} zgzh?>Q@WJ|lV%GIIvnAVewXPD&a#c^xSiL#Kbtl)JpEt5f~?;-vsz!JyG@KvN`eK{ zNi*D;B7aGT+{$DF6Byiiu6Fr|&?%DkYkeXUrXoYA@1+K-Xq<53T*+nq(r5aPCMKI; zuF#M~*!3tw+!7G67`bH`D{5r6!!%niteBZN`rgPtKZt+AkeF)bV97$xj*slqj#PrlD)Vv0{u2p-I8yHXrp$^EDfNN|;8z<_Bk)MgEo8%>L@rbo-VyQJ18sY)HT}G*^H^A$ z=?gzN`@wmp7ha7HCkN#6ug;5#imJcD$D7;Kl*+2IRFiQTno_MuSb3vr&5Q7qP4hhQ zGSb%eALn*r2C1#U43PHss62V{QA@h3cMj*eA)!s}gne;a#%GzCFaEWhu`@>)EEyJZ ztFG&E_ed>fyaU^(qeeiu6f;ONG}M4gG#hKMJigap^fEc?zMh-+K0a^~gpw-@l-#G5 z)xPd>*~Dlgp!`$l=QwUes5I7^Ot;9awz4`F>%&R2g<#B9Y^9D694Ni@iI6 z)?8;VCA&P&vAm;_R1GM9 zAmb#_(9s0S=`!Fp|7PZ4^iwB`0ov|r=7Z(z zeTv5Z#HaDsOz*NPo$p`zvz8{9I2p-NboJ!_2#CaH@q<@J>~Sf`EYGR9KKweciq7i% z{Q0ah57`FX9SzZi*oIS9`R4a=_G4O-Y3!u@d1^X)hIRPT1+Dh*T$&fbNLF3r?laOJ zP@ScQHZm_Ppa+lF5UOiNzrXIPW$%8BpV#CIj-z1duuOl*W(#NS^7`!6U3=j?sXPIM zVJoJiwQV_U$SbpUo-F$5uu&7sodqTG5GR@KBtIRZAjJqrpU23Wm;|RsS?u)jUGXJn zc!>YQl1N8r6a13PpWgokFY}~=`EKdmpt{ssn52Yy_Cthg3|4flMRFp=WFKJH1z<|B+oM|8xD$SD{QICnuSTz3I-J?v>(WfI1b zJMzW;;&3#K^pHbCbH|oh$pa|0X4A{0w5VJGloja$j`>t_I2w@N=W(wx1T%y%=#@C= zT~hrEvlQO7MCT2ASNtfL9r!v!`g?yIbd!XwxM$8P=+;bJty_vANwI&8->BR349;BMIFroOfK1P=-$z`xv1W_jY?UGkuI__mvTym_k+Mz^wjlLm^n5{n+72|Z zJE3a%B%eQ0tiC$c48~(w2IuxtL!7ua*8LppEy`kRXJ9LT?YHu|52`5jCf zF#dfiXSh!Mnj{dgB9Ks!4yyWA2g{Ji6FKBmPwMx3g4JK32Xh$bX#osUW&$!**7D?k z&KSU*(3~m!l?C)#*xCp9EB^ecpaie?QtLVvQS79B#00(C@ZZd>ihVU z$+hdqr{`L|_G*RQhLaS&i!a(Cc)FYRFns zFHs)jXPw4jDfKvnG;>0YfUQjFAx}rs*kX8{~kYiywG;Isc9< zRtt9i`Zp@IQ#(_$Gt1B{M07bMuKya36WauqHKX@7x%OG|0<>AzVd+%)c1%<+YI?mH zONuy|@G>+#R7s`HXnP}J0rXI&U_e-QKroKN@ZjEx^w3lFY8apQ2eGJ-2YWc=K+?nK zs^snkG_wq-^Fyx81D|HJ>&`5A&*|}(rzIBWMYFGVxNFHlH#U>o3?Si867D9_#UxOpx^iF6!v_3 zKYV@p$H7l-HHBU0W{$v)+{C&eLOBN@MT%92XEJgn^)x;p0_Pq z_A}d;YwUXhsTuI3H%g=`Vr8UvJy~X@9is zz`qg69qmw+GExw>PJHHVX%w+!A}y;}RKC3a`>p0{BcEA#p{)8EQPlSE0wm z0rYQ@P^_{>*ytMd5t-jKxy#C~$_T&D?m@>Qay4171xkg({rW_k2S7qq;gaRz5xafF zwn8=TVvKvZib#+!2sFCFRDS`ho}AM#rMjQ^)Kpi;H+S#;B6gkWO>v*C<+UT-X?4r0 zX&Pd!ZVANeutGFY{M}ge1x7+8T^I#2mdbIDqtUo)Qef0#uP!6v+4xHvZcP~{XNb|v zJF#2iCD#}CFlH`a)Etknn`^a$URnA9?f)A0o}lFJT@%bKt63o-n?WP;P-iJyB<~Y! z|GhPdNXtLbBZrd=`H;RR=_;!CX2&pE=h8QlgR3>A#h4+ix9=~=0h}W!&3{7T;&laF zzoRs?tx$l{ z;rql91n?7)13zZ_N_hAg5;gs8c}Y~s(bn2OG?ygR*V^CUHXjSL=&)g5%rE@S$V#`5 ztMAp@K^mWvpD)OIL@(Rsl9Uq!`M6d?URoRpp*J3xbOcUPVJ-=A4V~GJcf236hmy)4*ymE3;WbS(CF5 za7?*jT_3@O$7#K+MmN_%nQvJ9?&D)|pb3TDn>3tLdQB#}_7e>3x*HVdv$F20%u-q7 z4q^SJ@7t!hL=PDys7!tL^HGUAI|f2?1yf+(HVPdh(PE=}k2GVk(~p-E=FGcEcY<)U zygo8+9xpR)Xxh@KSCybZ)SuKHfZPVdAzxFHvU2gk14^$Ushd+h{|i;Fc5m-V?}}Qz z=eHC3cvyCbkvd!0HKYb6piw4{DbRk6aJ`Y-(ZqrVxD{ikw&VJ(5r?@36gz~D&4=9eUbFky*Q5;Lmq?ayP(LqDp;_fqT34p3r4mG(im!Mn-HuD7f*G0#DIityZMS;&(H;#|Mr)%&Hno z?sCtonh2DHGwIZYfI3h2J8t)qJzA=GFju6se-moxdo3eL^&@Hba(=^&F*(`7Ukw)v zavI+{NGQMf2Sv5Z#t}rYA;r~@@_QLpexM80xgiK++H!AN z{%6cyV+In}5j6+ctNnvyXs?jU%AJ9FdvCP*vX0Zc2u3c+L|sdzO=|E5j6Z z;c_kc^O6BqL@u81WA(k|$Dqg|NqZ{YJb^l;tI)3=PI?*1B^2Hb(TP9hO)iV0Z@%~I z(L^NGrD#hwf7vwu#%OYx;`VFna1u_h8Z1_9;IolhjRl$uv8js%HzwRr>+{p?bbc>(16=_cWhEGU>YOW^MrEBTc_LS zo&cZGmT5*!wf;aeiK+V*1nmp9%;E<#BlA5}BGYh@#H6AQX&<`>+779P$GWF}@C1sVV}Fju6c?iQ1DR z(!6M@wy1YyxyZ5S={}H>zrIs$NJ4V}1v3x;Y?^{S)L{xSvY)VHXOT|mD^l^PFl9|* z!_!0(V=mQYtbC!4ut$jbbqY+x7&ypj#lSX{kc5vT8JmqTO0QrL_K1J2nS8^Q)410# z$a~I;7g!DJPkl*s+3-~o>(4hSBm&G29Wygb?r0?LG7EApWzK&iMpVd&y#wMz1Ql@D zHb2bR6P@-`2T+FMOwQPi84B39b;q1O#e{EfRH5z4&Vtb9YBpsW$aZuF0Ch`xq7#8}@% z-lMh^sBB!IgR0Y5t~6iTMiX((WTuOcRiZOe#_oV_s&K4ed1}xe-ngG+(_*- zqid~TL$RLWiI+UQ`z0HRG`KNN1j_$`&GfH-jQ)gV^?TX>z-FSaxzjF-%Qrgy+Mn0qm`WFzRIKRTfF0i1;{%6T zFl&x(<5J+g>MEk0gRC&G-7N5R9b{ZL7hxni`=#(3SmwF$g)7pB6M1lA^U;cT8LbQ^c2Q0Y@cvM}zqp~LkJgFu z`ZoKZjUh-fLkOD3ilvG%XJU)dG$sFIgI{hX1>J8oSYu9YqCa_gctGf7s2t7o;6O+- z7fA)bmqLB<%>eNM0y&f3rV1g+DqrSp0g<|Xm%zYI^ZViW0wEm9uHRcgGopWcTDFXO z@7kd*am-hLwI1fPT(64-V?ES8OuQijcpCd;RO9CdJH)3$WLaY2rT*l*sPic;Y}!Bt z9uPOyVS$QevE4#uGo+P_q`QmWays(h2m2%MUzDrtxATH}_Ia zA)z7ObNrnafS14X)H~DpU4qjoT9?)P-_r$DY&CW1Ro3?7F3c|fHy%Zi{OIV9)34sh zb?>{Y=lB)1^A+Ci&YSknX9$L!Kd@OvDh8C^pOx=VZnBOm)@y^MiV%2vVT)zYbUAbbGbO5*h0M=fC5r4%apZBU;VQJ1sLu0HxuvK zQpw%2eDI}tF_}(*yhHMktF=s82AOsHJ7Th3%ClCS!VGCec#UQeJcPHD_i=T~-b@XLdAsvj5m2 zxJ032zKrde|J{(KnP`PV6&m%)PXBFM`vFf!eQzkT0=m92lr2o|_-CY@_HhQzK=Q(k z*){FAPz20YqVkY(OBwjIgybzm`KqA1CL`a-yB<%dUE$GZFq6uZ>J4)s`rmATa#|T{ zi40KED+W2&DbaEu4ZjHx=8E3m7G5i(g67w!i%3M*A&b{4i}xg(^XiFK&2+`^rHmWF z21C+_(nCdzQavXx5cB!q&H_CG60Xi(^_~405_{SbKWQ7;Mv|#+%0t?{0 zHDLm~!cc1$46>J$?ah5#Hu=Ij#m$FgoJDD``z?83lA503Bok0VDBEcRWd&99)Jmvj z$n~@FvR8?9=cl<>q0@`9`vE2&qBf;za}W#z0ol@?P~e4J4pE8IAjzsucjeFvWWS0> zwiufpry&`B;tu}fvVB;oMO+$^Hd}WvzJyK=>w9SK*I@*tuqSsf3rn+^R7FKi9Z^Qj z)8$mB5(k9XSd~cG8}@5V-aAV$2a(sQHv(qTGTm!wM@t##>FD4~_EN|rn1-~|?!4E! zs)k5TZ0J7!$^JTI_eT{$eQl~TqS%~+8KWN20brv=;INGN~Y_d~V6X)nzSYsL~c+sC=FJm7>JEyMVh zKppvxkh_9RLm`#zb!l9FFCeQ}Pv%*o?PdH$bOICr21w-QBvE`$E3=?4lWiasBPtZOpv(hu0wt3<4AQoDvmSU^kVL6^N{>Vaz zZR!uTT|Rr|NEQh+OK<@u1O>q=@J|F<*o*QI!# z>*M*Cr*|jo_4gdJAjI?Ibe8_S6gg&QSDjFA8v%jenUhI4luPX{*XZz$Q?+ z%WYkgrOhp&o6nZQ^4Gs5lw`=57HJEtP#rCRQD6glTm9MEX%F}8FJ|3=&anN@zLmo~ zQ*zyBxWB^x(3&*hlE7?7lhVAuQi99G9&)q|7n)|y<%E(@k$TRSNxbcC1V&K>)r$JF z3>F?vsmVh!j$RU98nsb%1eGUYXw5zBbfF`oV@BpcP2?XhtDWnLIJu(5A;UALH(+FX zY7GLFe&<+bn@=PgRGwbvI9>4U+#7vxDq&tj^kgEEt#3mNn^Zxl6hp4EjTko82!dgl zXMO~&xHIJdFJ!u@rSMWIAQ$t^$LDgY0R~27$6lrkHN%U`v^}cqaO&hBMY1Ep3<;AWnJFB5;L+GjhGOg;GWTQLsWbAUV?&Cm zvw~f52}rCvpAME0DpGuo`yM(t;dm{ncw30j?X@kTa!+{7DJO(Tr=p_~|+t`Izl()VW8Qbfz4_H^{^fMZ6f~QoJ&NY*`2o-suXiEsM zYb7PMK$Il}{_ZCbA2o*%-rTwA;^~b5lZ++>p((WSenIVKEZr!i9HN+(o#q0ehP*LB zh|ADKf4eHIrB1j!QdjUd8U8MLT2k7xEtPpl_E3)ejYYWl1G#nQisOQ>O=1HZANv8D zC_0X);N)%S%GdN8QL`aQu53xH9C2+^7dq>{Y5~q;p}%r6EVS zGknhPUOs~}WSiq3>)Kg$B39qSVi8xlSaZ0Y3}mSS%@x0KR71`Pl$OaAN4=KQTt^PC)&qd<&s3f2^eBRoOAzkp z;eFL+T|?bzj}=Tsr08^a2K+{E;#^`@cj163_(L0WiAY`V3iHZqV33+VJ2BEKC9BYl zv!Sl4${c4-CWZ$eK&-qoXiuYR91}OpEoNJB%QhtjL&dd-Tsvpv8lq0f>=(kepdNt( z2cQ%p_&|)MrF5O}0o)xINnt|MJMEHM1y;W2kU9dKcyAGNFK?ipo+;wmdAvnQd zfZ*;D+}(q_yE_4by9W;*-2Qpbch34Rrq`Oj=)UM(d)FgXg&kyp$zP$im{&_rBABK7 z!vb?06eqR4&YWxqL&y0^ha-tfL#@tAwX;bvdHypCAzly-M-83|-+_&BT|a;kOd}3P zNftv#0nQiE00J{qgC*4P#$kcYy&#WrTG=KYM;ms>YCsfne(hY zoEC%(;;0QL<10KL_TWA*hAUu>6VS(+GVU$2_sa0FQ!b;}P_?(CuM9wSJRh+J(s=kt zVL>X{5f;Sbn|ZHVuJJ+Mfn!+m>U;&|<2gZ(*lltzuP{=o zpOg37C=o(8-6g^wCp1O)PXD_ZKC4oi&my%vyO9-0E43WkDsPs4Sp2Qq0#hM&r;4*^ z8OzI|ZQ5La(B-jhJI;(I4&qK($<5q54&ceRVkNOyTMZK?d#lXKQL>6U^+tKdy(&I^ z+~3Va20issy%BY-Lm~Rv!iR-iw+@mSbO7eADepNgOKe0c$|TnVIAt_NM42 z@SPJ(l%YC@+>jDDGUVV`y$^GZ_D&Ht)0P22U4hQ7kSDmV z-ior>6~=61yAAh56R1dL(Ncf1Ra1@E_`%8=XJP+6WF{O?2- zB?ewYUnR5Ne<)=+KM9FEojhX36}=(Z_5zJ9QK<(yeQS=pi;WYCmz2@$y}n27O+Qoe z`7pr$FJ&-gwYDgJ-n!!}=JcK&8=xuIgCId+&KgsHWm-%9VZ7a0exphXxMdpgC1T4T z92`Yp||H$ znOWceiZ`6>oa7QiD)YHATAYMBZnnLZ)SR6&R5@t~jbM7tzLZ*8+cSGg!CPsN#q)jerU29n6a$q{<tl?)@_PUNCb2E$W zKv$Sw)uAT;m}LhQ?+s9laTL$~aS)hYds}hF(Fn8oC}j`t{r&gspyI@~l0G~=cDGba z4RHtsbJm*OO}RK|ES3rHFnKN-dNFYs0X6O(Cz6ic!KZMEC}UG#*O#I7eey*Cqb2#ZS*&Ro#zV zYiY0tN8fk5iqMg+Y&;D4y}l_8RGCG(ROIJxcfb?*EFF1GnC|I2O|#2hw3; zf8a%xo5Ap-!JM+=*5hJL8PK!$tnb%~P4#%Jhcon8&_75{SdwpaGl++_6yMX)(twr{2L z>z@0)?CjRWq)WHUCD!#mlj_x0*6~$6E#7Rd>SO%=Lv7`9*B;`2sfWEuSw(4Xr^45Y zA$wS7yI(DS{Zv(b@JMyrnzxNZa&ZMP*THpr&3vow^o@(nX$hZGK35W!opsrbxPj6I zwjWU*pMH{j?y4T|@v-HnBV7oo&Eug*^!ZvI1nuCOYquYH@M36tkV7~8IPR6|G>-cf zkIM1nIr9GS@Mp)8dSi(Ey0C38?N+NR)8Xsn^#8e1xlN;EwP7B{EqaJXe$y9?Q{QY% zB_rSp#upjkB1rH+A2EQhJG-o1yz7u4m+9VR=97Q2)+WC|>NW?LrU;|F`Wo-VxuW){ zL!w%*M$bpf+VKO)QAJUle&BVj$3lY?AY%j( zix9`z#w#fOocr-p{4GkQ?4;*>rHZAG^&%a+2USI>jE6*`tPOdgk7AOf)F-O({C-l# ze^(OZqN6)YLNC1|=m-WBaRK58AFU}7cuE)Y2tkJlwP?^t*REAVtbng9GsljDCfT@? z-9Zs)KDvbjglS6Q=58S4?{Kxh@FnEWrRkRHsF&i${>PIelsiSshC3>*zAtAs@)EFFY;!t4C>0f ziY%@u&G1J*TK`$J2_5uFYHEtx)9UFzqOIfp-a+K_iz8au9XyauvrmHO7X zYMwjoWR~p}2Uu@r-M(JXirJbzBv;8Cc-tsH&S~m8)KDrpP(lzz;IS*y#87d-e(dWi z6ynFZo=LsC4lQiYSjy#0kWpU9oAqrDW>uj=!1sB0Qi9j_*h0AwZptO_^UZrE9i6If z;(;sq_!+qvA=JsN3?WoO=qsw7&w3wIC|wTvvPkt+lG#x9+J`oIF3xi!0tN)s>`6;KxwqL8+$oK-jfNnq*(l)fo@f= z#g!U+t0%O>-UFv7>>nD+@y~UcPGbBBW9tJN_z*-j%PzmGS+HLF$r!IA zB@Rx;Oo%1f8Jbs~I`Ts$h1CFBmK!=mU8)l@STYMSfBByhp%rX?o_eK!VhJv}} zkh5@91j7=ELAXeiEE1p+ya;iHLkLxf4BFmyA~CmG|8@idGY37lx~>rJP;Iyp3s{nl zkj;SaD~dvMy6RFNuQZ1>K9abmtS-XpC^4&=wB%hk~hUiy4sUq5Paz%N-gr9z!vCgb8jMmVmC?fwu*ovK4Z^BC^0SKDUPm zOk8$EW4iU)*gDwtVKZ&=bc-PSp#${Mq9zo4hf`~2u@epT{&V`%%w3Gz`){4>Em8PX0zkqHJsmj05oOK&4f$~FugauD_1UJAWkQ<;f*9nWy(@jw>ktv zE9x$riSDo4w@%M7bki$KMTQ<@mYBN%fAGH_B3M4075o426^!J)eB1MKze@0KcUrBp z88f?-hf6P__J<0C))SM{NcwM5A%%w?-fu|;DYt)xw&S5yq*`++s*>{jguD4wJggp- z{q+X1?`|g8VYgl#e;WAp8j`#N0IJsr_jc7+bFxg(my!E9@{O=wW}a)TJ@c=8&-Ad; zEh-Qv0rRng2(N;+qMRo8%tbB}47#6+9|d3fm^3=^O%!m3SeTYDeg;aAOh~(7UcG9q zd2FD2w*K3j_{_Pqb?o(J6cvphal;zUI}krg2Xj@o+jEH4{<%j@bsS<(P-v|@vC&&!V$M463Ple(e>MGQ z221Ch6jLjDT$=WcwdRp3h3jW(2N4}FZOF^P;2u+I!ljpfJB%N+lX}3EquJL~cVmu^ z6i|d?NCngwwAwh)1RxnnpfLxy8`|wcPA1H6YL#P)?}R_^OfAbe`@$vC+$cH;FpSbD z&pCELTksiu{rAHfl%Wf+4jPrR4AAP=!rd(;WuRGv+FAELFz1lSAW>I2v*F5j#<+fC zaIwIldd~CoY2EMBqdB11bbUN>WYe zR4JXK2y;XI+>PM7-$lcgdq*Veu|!cW>=Dt2A1c_j1uh5MT^iNqqhgzLzHHGW$LmIL z04n=G?)w7@abzf|$v=3w8)FeLbdHWxc(~_Fg`j;1j6|S9AkafGT}sfyNSiNTwnik; zt~JK2kYr!&dRsKA8rB;qd4Kd-fd@iix>UpJEG6Otm30Q+7d7Bq2tEb?=(-MBWC-V6 z;dgQR#HGdbeHIlm3-!$tm~nn3N?h@}Q1n$UBd3}=A}uEP+yH-{K-R}!HIfnUC4VX+ z_=s@^*IG2^HQ)K(h0MB=*_+TsMmr`@z;$+huY&Z`EO+a_PZ*=U(VT$1=o{iJ(#h^i z%iWR0eZZrykhg=7!0ZN{dJh85rhsccY@a{NdMss~mL1ls*c zz$o57M*?51-;`~^iqVhx*{z zo5Tl_L!%kc-D@VC?^AdK%lmJ1Flh@#%ie_`PuE3*tru95Pctb)#V<^t^K-Y%1u_ob)Vogsm|E?n&gzg1YjuPNcOL&HuhIlZOs{Z@NaU+q2OxJ#1eyq<5j#Zm5!EWplQ7 z>V7vixegtzM?o`wVJ)>nqYRvNu8n{Um}LxB(S)i<37z-iYq}%kDX6h7&7+YMNKP05U`MdL@j4BI_utk%WkIVAUMe zu%M@kOttQ zYSP5Ti-i#4ewMN%)d$GnghtC{>A|RNZzt3SVpgQpo(#Ld2=tyXf1-m1zI;b--(Yj2 z(vke?V6owqP8ya!L8|m3!wY3CSpYp3qB*T#Y`Q-H8u|>DoNIAo-|x9z@5b()Gwh#- zz8f%gai!?9WWTxc!eph(?EQ_RJr=S>H~I@`rGW>#E;zci)W;ktKKFZFxqVO`6B&T2 zFbXycc1&$2Pku%VEYw-|JFlRlxR=I4hjq{SLm=WaG|7L+ooIplt{2LE{{#Cgd#{Zu zw@T;uqz=^ntrRJx`V$WEjBIs!P=@`wSf9yHOv|#y(7_j)L2#u&kTjpvicM-Ww@Y6lH`pCu zJGO&iZv}m{u{hUD5Cf*U%kA+B36eT4WH83sqI<0ENKfe>z{DQ+Qzu#p)jv35D7`MP za_TPVHx-YQkyv*={-(+m$+t-LVa01jFk;nl=)Bv8Bj>Nq)VF?|3IxLJY*{ggM}Z>N(t9y3ns$IhpS7gPrWXiwiizg%7fS_~i`iw!t@i zw-eWAtfb2Ioq*ug8Q=Nvf!QF=R6KX&MI`spnKYQwFGkicHjFprz0(YD>D5zk>un;4 zA3~d_8FmHI*%BV?`Pv=PpmKI-TJvSQnM;+`rhoMJ(itVXBa+*Y$Hx*k7 z4T=-o&4d`Gh1U2}Kkr-n@wR=ZB-N+tv*t6D4>6^;#nTMTL*=y+qvOz|+P(eRhoV8Q zl7bgRR|JF4#6nv(&%5FQt$kHwjPVa=`blN5_0{khE}^s|HN2Vib&=LbYRqYeBCB{OMMbzFSNZ!vuS zkp%icxgab`jJhU9DavB)J{c@_$2~1u&A$0z_VyDoyv$d6c4%-*H=w1VtjcyNE)?gL ztTFV!Untq_BaE7xeAO9_HEbAgIXM&@ah?GZa@)=w<>q6%N0#GkmRT|_ zdyyW`A1Am7iV_-MK0FiWb=Slo+J$=Kp-Ayh-mSknHtYQN{Awn$b8}X!XabZHP)LpQ z0K}2f{0yoIti@Z8+r+8st%oREDo~XzKq0sZi;;sRIbvSq(-tvg z-y!s~DDibp;xmZf6*FD+G3^(b85&~zknSOVLMZ8M`%}DQwYz&(BG%~5bWQe10Zl^j zJ|Ep&pd!SP*^%6jj8)!-n;jaZ{gcxOod?h;^)}urIt1*kGBd!L{q%SvBpS zG-+v9mO;jMN#C9H*qqU=wMAoH@`|Now@&dC!5+flsE7rX)5m+e>SYlMPxT z-g=@J0>)FU9!T2Op(cM9)y4%g@1JwZFJBGq_SynI<_g(R)_Bg4X82Y>3%TbjoXeis zKj@pRy=*g-DWt#;H1Rnc%BI@x+^eJy-1m6W-#ov{{J{(i@%e=QECjN=rq7yjoa|K{ z>=her&JVYfq+Dwb6Y4DfwGA1BvO<^c!6gW`Oa}U>-Sd30p2iFa1uofosBC21V zS-8D#>y_5uE{WgWr%aRu%RA2XOn&BRI`up>HzF(026@ijzX~!nUv8?r2J3wL-&&e7 z$>fm=A;`Vy%k{Nj7D)snRZ&<%&X2x$UyS4jEMhB1Mk_Izt437{yizG%NuYY$qdISv z{7DSe7>HpBFoW+vtyio873pKBZ>{(rzjxH9+rlT(K>zvtxI_Fsm|cX*i_5~pxKrR< zRKZn5rWEYL3Y0)W&Z41ZLaM|$f8GM64WI=?w=_r$7nAXRirr8)5maXCGpZfeLQ+Bl zi4*g&;EfJ)i!<22)3W-tMi&0Onh1X4j2B~#_L#iI5)5I{M=Pj#FO}qF9JrNGfr~~V zdi)q`y5U{+^G7$wSgVv(#Bac7sFp5pOB4`=An^q`+42Vpk0quWMp|(Ek8V`S-;}&g z{t?mE%X%M35TUrdq9P5lKH2iIP*Pc7@BS!#E?L+XYSEYFKJ|~tD&7i~Qkk1HyH@@Z zl!lKWFT3-7mywg~Fn%nC|LY}<&o5=M7-g|UWh&=yUmA|B6GSdH$YL9~M$$1`&EPN^ zRQiC~gKvMgeRwhbP1_;zNGUW+2`&;A{nr#RxG%nc&kIt~rNRy=nQ_}=dsH1E+GC4@7iE?|RCTCi{u0lfA5x{Z_^B zBzub}$J7_7?#{MV3z-E)%Ktd98{g!yi)j4$rwt`*?EA9@0jq~m6#SFW+is&sjQ&xJ zw*Hy~?Ya7DM~Wt#hMO$IQzAS^k9YkzTTUtDr63|t`sPZYhiqXq;eNfNgN}}NextH^ zy@_KxL6(X6SnXv9RhV>BR8WbDxBKF88MElWqFQitu84a6M3|_r8WGzv8{e&qD@saH zq1$?$-JDAeNz6l^PvQEtW-@knYnZda@&-n{;=aLbqrtP*IFFx62N#lgAj5NK@3F-!#uKIJ;W3cp~iVG+9E@L42k| z&hgUsF=AR1J-OU?@`*7Q^vQd zX2Wiw|MT;ao!S_-##t}qIc+e6B`jA-?eAJ<>i^X&pm1f4XC&%~b&ozGVb~zjflH)k zW34D7o>Eo9<&zKyL)*=l8`|YIu`PxWtChDw*whV+ZZF0co$_oAEpsrm?O80(QIyM4 z?f2?CZ37f5?Q9FnBx#T5+_t0PrNY00DdS3l1S|k#Bf~P)owPjRNAC@8n~n*1ZmWLf3hE>2EApAt z=wK`)#VOhkiHeOJQ%G579nJ!4ZoX&twz)o7_fNgZ%LtiS&?5F;+Fx);DN$|#O0}r2 zu3=+b*+u1^@1+TP>J?s|-#m?pPVXOo$yKSASD&Z&YCWBJAoPa7DInY{wZSR2!Y>2; z1>@EO8h^yO!p<^Cq{vYIr7Fq}`Xl|*Xjg9!1(_Ul7WW{9Crf&fzl=o4@4fD&=FnN0 zQ{p2<29&?Hj=Ng^qew%Hi`Pt6 zPOvuqNp>FIi~BnDA8RjAi!zFFVoM2}W%pB$Q?1vOQ+3QNW^FXwL3adq2o(aWBLdE-EY-JV5yK>L&J=nAhU(Gs$7(^dksJ6@tJ? z8#08#EW^m`w65FT7QSZqvCk-AFAyrtjjk8vXKqiJ7I9eu2sT~qv zkErL%up0+@>1BDPjaAJ(@Q)Huw^wDo92X2d9mioOTh9#L`saBk1hLzC>dH6PaP-w- zr6^ER|6D@{7_3^FCGFLpw%7eT7WY0`w|cllUYmbKQ4>{FH~7@mm22qhsD#zi{m9bT zlGb{HENI&IPs*rchjgU;)}wM=wfCk%*3nCct@%zcO>m(<2c7#nr>r;~5;f1Xi;n06 zZ?$h8vZ0{q$0?8{8YyM`RK_M|Ua2b?`ubH(&qbYY*1s#8t1{gt8t5_$r;ZUYU5Ip9 zet04jy4(Ii@e7UzK*5|(0LDO!X4eP+{+d?+7F$F}mKt^id))Dz@LVyZ;dFhLAPpS7P6-0wFK$nAt8hDA4 z*zU;*lkXlE$##{{jlit818P*cUDUqkDe_&L_2Q!Vts1Vm9e&bLF|3A0`&%^vJq`ym z<0woDLG9HT3x`!aSo5(EM?opn88Hn-*rhect;$gWjoHx_F&RPvi5w>!VTBeQhAOQ0 zz#*_1Z9zK-C$sM*Dw8^Ph6T#4faWUbw!DdsXlzu}cY?U!yKoWUR{J8v(Rr=HCeJIB}n~yx!k@HeTTrXnFoR_M1N?OZWel z+3w&CB~#vZIZBJxW{YUNLQQ?dMoS$ul80A$yHYy+@2g#~ zf@sOW9qpGT9e&|+qVt4S9(()70Np0uSf=;oXuO!5z{FU4%u?t~H28UcEw`HJwNHPg zxALOVMdu?zoX7cwfFy#i|4I}B=7ChvhF7cf_MLlne;X+R8bp@^7QYoX>!BjcIFq6# z_H&P=E%Lp2xV8Vipl;poYpH{{0!ql|LisgV40DLGJQ;!XEy*^1h4!T27UvyTv2`pj zc9q4NTmzoS%pBt0C~bHP(%*p_-)I=~QqX#7)^TS}+f>nzKIc*e{5#yI>^0Nqi3T#s zT}shQVKuGz_xU8Mp}g^J^X{6T<&TRqR~2)J$8T>2rp-c2wt#Y1qW5rrxVT<`~=MCi*?r58ZEkW@YF zbqTi~Ra!laj*-QWpk1KDyh>te+tVBEhYA@OWDcA<5X|uXH7fal`nQQ9dgFkm?({DW z;iPu%TIQD@5Bu30N8|?&`_j(8H_a5~vWxV*2qWQo+KjonuY$ffN?@c8){zZOE*V1e z0#ZlYk*iE{gV>#X0I6&sF{*0DZ)@t0oRs*3a`fRrpGCY#%VCr1g=659(~z@Tmye86_?+uNn;M2WqCl*!gCUvUI;hluMw|agc&w z&To-fpN>HtJU$)g)OaTYdY?(CE~rB}q!TmYT)JMk9Tz)9 z_o!!L14C_30vLk9F9+hZA6eC24KedA<MR3n|6;E^YJVMpzWO*r=^%r|D)qK9?uDo~QI^v=Zcd~*spH_))QBu= zXVH#1?>g0pzs9*&AWv)i%n3al^K6E!zdJ8yGH|B+xs)T}LoAhAwU`9ux$0iCx@ zcE*f(f)ow6&5xSJZaxj(ZnS&mqUr62DvMW^d|B!|NQS!7k*YpcHDoggGKPhaqDaV? ze&l#s@g=Kh2v-*RYUt&5#1!0dd4K2^%B5njle46j!pC@w2=iBjEyVBXucE%MDPN>V zKtrqp+aYDOK=`KXv9o0Bai0O{``b6~vzKF-d5tH47^8I8*+5=|Vg4WsIN>Cc7N+t(`|4Swc^#0%QPLymmWo_Tvc zQ4kW|JRnZo8bR!En+NC(0+$~~B}2weH-PJ}e<>F28Fs0|l>2ahaQ0QJXUE2(z()N+ z%+SD(qJl})q}{{EfuoiV08YqWrY7@ewc32_5h%n<_YYA?gHXoD$s5QOSq7`if49JZ z`K^PaThAHxlOz&kmx|y0^j1u=g+#^#>+^*Y7=H-D<}6;?fCyoiw=w)bU6T ziJO3mNV-WBW5d-KhKodwOXWg$+19(VvfQTM8q{Vw^J9D_mvS&;;^a6qL%;@`>iyAd zvAwvx7Mn}Kg_)~x=FvJ`G!Ca*`tye@Qrib(i4K1p_windN722{T6wctygtRfd|~^zAfIjU+Y-IDn1<#oJ>l4zx~1TKI$bTe-UF0qaKE#Dro;l4Gf4%iIy)J zzj!`QmAUNUbEVEMdWiMQ`SE)H3t_5aN92#YmICP)BM{r~Srf4g1cy$oUcar@4+y;u z?{;*|8M)VHhZ~&2WA37s1zTTi8UiHm#&_eo>Nl@i?pEFHBw?BO4z79|f*!VjU*g$N znX__wr?~JQ*5$L8O~nP4zv21I&!5&mP24caK*jQ&0r=PvBl-VbSVOOFLNO(uzUJf0 zMIn@$TcML`3;>JasTw)As>|ghtk)IF>Ze=7Qf&TGR8&=~vwhGOn0YU%Nt6r<0g!u3c((0hCfI-#^E{c7;D9_-d)Lp)$ z%`5yBqG6L*MwH75+Lr#6BZ_!KsQhCm0h$+M%M8HceLQkN4v6#AA5MC`aYwdg>`T=9 zjjBpE47o?G$ea%pe-V?X=~crfEtsf5=Ehz7-TuuhD$jFlP}9P!%9TvAi^j>U6c^Vq zi=)c1S)#0>~i*_}{p7c&PgI4}|Bc=9&+a56?_)YuFsy-X_$ zN529dlFLG)hl z1PGH-IlgzU#ZM|A81Vig#w0MeH$4ILFF@B7`!Wy(3+>fW=KsZD(o_a-K(t5n$JZ|- zY{&Y40JOk7gweFy{Tnu0mYrgq8zY$RT0^8~#g>8$?&Wjb+>p5OU0U4wx3a&nWqjRM z;igw7qz0QNdzBk=pcyTz4^?UxjCqQiDRMyl(qJUN)1949l(i>z$V(zT{v}KMS8W4& zS2OULr_HMok?{pE)MAYCGfCyIKF1`EkcEM+R+|+H5f^b6Ec~Q_!!3@)%1}%mftCOn&0u|Oz>2E4hj`V|m zUweLR?zu9EQu$DX%VB_xKuN0|MsK6+CwK`7*-R zK^R%7rxAD35+!%LCNHH;NVu&^^>k!SetdS?t$m}HKA7#KmgAPJQ1phkj+`M!u31o= zAn3mx*Y9HouP!FQOVJn@ft+I5I>_LuVH_)VNrlDliB0M}9w1koa5Y931KJFlG3u4l z*1~X{?o-drm!4$8s8N$R%7BL>6u@(iLu-`|ln6w~OQa9MBLblgFuXl2R@ke9SIn5T z67^~ab$ii*h+87%|D{Swt^QH`lc{#rrQI}Ew%6)JQYsei*h`zJ%~s|vY6`{7A~WNE zimo7I9r=22^T?_5=qZ0oc|jby|9`l0{ui!wJ#WOh&!dfEOBE>_m^j`hzSa!^4!%x= zZ->P#m(POD+X-AHuyDF}Cn(h&J;=yso58vIoXE}8T2n-UQsq;!r5Ok(JK%})M;j>S zwS}?Bo)6u_&M9bak~Bg^Mr$r5VMK)ozPW#UM6vIBxBHcwKIq1p6Vf(^7vPF2nxsvi ztVNPQSe1dkWEy?b`$MvIuMC#7Rs&76&4{-6c_)U00uP3M86cnNj}v&cY9M+mgT*Jx z7tFvATJvckvg?~}(~XCr&x^_>oR$Z>HVQ&?a3`faOFCVtuaP^s~rU>`%Da5!2 zV20uX^)1W~j@|^GE?&YK7NgfZR4F+B|MLO_IYV*p<>v^;rq2Ojm3*4Mlj(gvEN5ne z#1We=tf^I=5Ys~%vE_%q5L+C4vWUu`+Q6u~9&&zJld*B3Pu{|@c&-Y&sdSB0iKW-Q z;?bEO5Ucyh?r*Rdf)PagUY}1$2wGiNDD3?liOGd)Ke!okBCiY%J{h(pJV_KMRO*MK zxX4SowC~i3yqxD7kak$$**~Ttrft~gr^H$F2ol{l{1>FNn&QyjMVf$H)OGKzwbp~F zPg&l7pd|n|(w27LD7<$Wfj9uk!tpz%_#!zoVj3+;*aX;`p3l90hAki30(;qd_{hC3 z5?Gfe1TW&`ej_w`|JBPwjqio18Tq*3zI*P=bo#YmRKLGX9g(|SW>4@@S)hAAzI+I1 zuK20EYsltZv$d|??@+T5)sa%!+v#z$i|+OR&Q{am_63LC)ps|(@OXrVdJ5*xNZ_>m zK0pOVN~;1eCnLhf4-Wwxj-H4^uG+7=ayQ)6i#kA)q^;NM?uWvdh@i>k%`O=-q?jG8 zM#sF{hfeUCCV)oq{Y5oW$G0>QSDQDY{71zym864e3t7bYS?2*uO|qu;Bs{!U!6lJu zSDF0TbijN)D7laKvN@T4fXbdk&alJd)Y}@!s@va|gSH>R=<&HpsqGOkbNHM-?-w3^8~<5I79SFs#mv%VTFWjO-xQhp+s{ zLY1UHoUvq;SpR9f@Wje*%ihjhiFdFLW19*xPgJhig} zB9D>6{g&3Z_rB*3lsa!MSLF1*w-Z|Z2ThPiIzEXCJCT$2Oiu~gzIHr6?O}7oI1XJ@ zx8i@krXc*KaAH%N=_aM0E4eKda`pozIPT$=C36R2^erqzy>GZIti{x`gy1Mv`e*oU zd1$cd*)W`aYY8&ykKKN37ZcYK0)K_S2~uS=LeH63x?56Y4jL+`_d@GoJg4ZO=Ra7a z?JCXIf{*zL{@*#gv41V7v!V6@r)ws6LaRm00QiSwtC3v?z>4pY1Kq42D>$cG2;-~g_iPqk(#^Z|FYngP_nEZ z3#70q<$1dRQ|AZ(GN(3zE(ek>rz(zarvNld27~O30VQWy{etoFhqeJg8}x_MCn{yV zxIruQL;_WHmfE7x_+!bjwk7bx!f;T7X?J!JfHcVN$LPRuIc#<ei@EIL3)p)2#k|35IzaPw8wi8#g1Md4P(6f7H&_mI zw0(EHxz!nr#*rmm6Mxy^b2A+v5sqUQ$Ixk_fgJ}>gd%}4(3A8iLQz%G*%i%`_g1$p zw~K83_R5op#hU;!J`mKaK44MhAnp{`Kh2X#F*(Fu3Q1m{cvbj$QBod|CtbSDwm;XNs;{+vEw zhM{I{1r|R6#MP)gGDWm8lsRChrP)Y zq*BPM!L93&LY7{^;7tZ_7E&*8Z5HitLz_v>#r?t`D98z_uaX4(KZXDq7oOJfrEqYz znw7cxHVkwhL?*C>^0i?kP~O`^AD{lJA#+RWy%rudFr*Vd9~E1tq|<%^XCy(ZP`9}(n9EgVM{-r! zw2~eK0Emq{z;Y?K{^{oNSnq205Bin{vOA;^(70W@dm;c2llXl#9L%n`SuU9yJVsAU zTTqvekm>{Se+g8dcUuoHQOrGUcASe;V~5kPbt8OM=7QgUK5Q5u(GvDnl^v(iI&&;9 z&pO(_?-mGTdgBdmt3ncSfuLh$RrE0^RHW`bgCb+3sf4I~W zf!L7naP2Y2(J*j*vXkQw=7iP#e2SU2YP|bwnDv!NwIBry(%-$V=(vh@*!nmCbo|Ty z-+~ytIv@Vsi{kt0;0I#~Hz*fakFX67Mgf=a%Sgb|gd(cqNeuvvLbd5<7D23v5=|1Q zT;pP>a}()EVEuhSfis2z1y9sAW-37J#G4UVDo)JMp_N?U^UZ3t0@5!&b)Hd&m6#0{HBh~r;r(ifzlt<})5 z;Wgd;5Pr%xMmP;Gnd*L?1G)W_2;#DJ)H@K;*@>N04aP4{!f`%b{{&C z*43(5#+R1#tU*nhU&|{}5k|I8S}M{jd6dlqO#6Vixwl?0tSf4L34T(gG)S_WZM;$9 zN&iF0gJ?-&SedtNaPv*%&MPuS&+x|P{?ZzmC79u6iSj_S@p-(#5Afw`bk>6lFW}yg8I^_^tzV6d70UO;1cK3; zdv{BaE_=}>K~_EAUY_Qh5?Q zhFM$$8tT7DT9_{iW8&Ga^Iny<%dkJ|Sd4~%Nm=V2nn=&TCJ%5x9icUNUuF`DW^NZa ztifscwc*oGwBCQimv&B=y&A%y*fSp}e$@oewcKTAi%kg&mx(_8_KgZMhW-WI`nVv3 z;?MRsvu`u|Ak7s-9aG=Q0b4Zr@uE$plH_}>yA~|dvu#$_7c}Us0&N(eT0C^eKm}5q zGo(O1pr*@FQd1^E(Wc}6T+k8O{=@E$2ISg4ou25=Xl+}4ua&$SlrKUcGt9&$La6p_ z#BLGd@sA~&i6qbAgO{)Jq_Qcie%MZ!2^5pbwc*^kus~r&9l?a6$&8Mc-T6X2#{m_h zeBgu_sh{6(ousI@xAw#2nF29^$@21KIXDQ?`ZGkd`oWY>nZKJr^x=RMr@*)5{4s8n zb6H&av6IQi6;$0HZj&tuiep04B@7TpsYD1!W```~Ht#-(-fyEHDvq?#HF~+I9vU7e zr&~ei=-nUgb@VLzJG|Hm`~ExQXTSBBz)pnmJ(4ncWa1}vTE4jIH8idLU-{>0Z)GGE zUTS4qmAbIRd;wrxl%y16%s_yr5kRXjG^nbIYVO|$V}d{lIOwPONN=pD5>X;X)f5;( z1C!SMtz*faN;m@N7>-8jbE6zWmEOF-hgRjqpBWs4mb)a_I=>kh4oMAqLfy4l2bWUS zp5v|^iOY^uo>;zyr!K|C&7xlIi|g$SVvjxa;SW<1tcWq)J6S zN0y$wi~~gw@pPi4+HVRf^{LdffdM&T%wKlgjUoz@!Q4i>tJ_B&hy_V7J7S>KkFtyl zfW9ASinzQYZy|GaMl*jO2B9bIyV#5>V&Wn6jD6O5JJdC`(n7WhJba0p4R`ns%u|pE zzwnfVd+u1%(g5MYYT*Oglr%Ty?`|0~IyJ0mwFo4JjT0MK2o!1LhAad=-6lZVE=oP+ zF>SISUuo^4HHh>9p7k~z{@`XZUG=8(z0&)KO|WUKMhDg!pDrMXX3cHz5=z`DikKiK zf;K1W8Y|G346Ym=j>gE+X3gds+hM7ob8m_A`QVGy*yulq z(O_S@Jz{p{dfZ567Z6_o(6FlXmy<5ykt-ohbff>DYeo6>D7*^x_Egw2WPGOzbeu;tZpi$ZG8%6UU!`C z{MrnICM2%gz}mC`Zr>c;Yu+zh{y8vc)lpohf!S-?TAIX#5y>H*P-^~G-YK$ebX6{7 zKn{US*)x#xGpXI&n}PENft6gYN4MpV$S{(R2NOs6D_wiD>*BOp zxO~EPpx;djVaRF+qoIZ>QNv77Sk9u+ieb7Wp!^=(aJ8$6w#oU>k9T_gu-?b= zunard{rWP3b-$7P`U_u2sW?(exoL?NM@Oi_s~}1HePY0pAWY?;fz>f=y`>M3%u%(Tc}L0w|&4 z^<<~-u|e3`E)d4%YcGJc*~9OS5v--K?(4D7`QEG!7t$#uAl-Gd1(k7Mo}MQ25FScm zrw98VDbvFO;RzEy`)ytcmj?_g*woUfy>a2eaEW7@$HEW848WA;pE=}-;hhA5 z^?QSHeZC?E=Y(Bku#_TLexQlhEEnB1;0j3$;!koco+lob%ctnMK5dSq$Zo9uN1JW8lY#REPti^t+|; z`1(zY63#z}Z7zPd`}}eEjm?%qfXDXpszevV!XmZw5REHeQX2U3T32G1rvI&Tri5-i zu+F9!jH}A#lE)$tdS$PIquG0FsLx+9M9*GLwaH%v`ityrDJO}HGjry;Fx%?)01n>C z-Ci#DbR#ag3_uFd0?rcD{?DDZBj&HZlnq`A^zIiD)`09K8{6q`ke}nK z*54BV>Mi{>k1k5wrv_yTWUxn|N~4B!*{}<(xzI?AOX;~}^!6&xUpBmA7uc?b8x}Ev))cDNaQ4Xwx@rE}+T#DELIe{HHoO1BfCzN!!i zm<6GuHgKq5zpN6xI@@W+xpVTR$J2c3dBex~W%wqPk?8_~{sZcp%m~Y@3rsfI`;-xD z%k|}*7>|Q77O}83w&4ByarK<{@fV3Vyn2ww7X?*f6JnTYLkmAn^6=JT04MWl5+41v zIcK8jXt>vl74CyjHrq0gN`_&iX}M>4T&$X(&Yjs<+-*3CZDqH3R;2$R#IjJe7vlM+ zH(`w&!7yO1koaSj^=B)->f`z@OWx_ybM5m9tG|DL1<0lqGbO>4QZ%Os4)V>9!)T4a zx8N|ybbyP*nr2;SyAHL|w-XtdKmCp$H)-ZdJ`Qykm3XFAcMnM2-D~ii&oK8~I2;pn z|K5JpOFu+HEohAfCy%w;@4l#i^Ig>=&O*s0q(^Fec@md1)BP`4BdGWsZMo|E@9n;n z>6I92a-1STBk3K9bFy%20(>&Ga0+6=TrsuaggF9{WX}05ix7HU0+pHb+I9Jw?nKZ|*eiqtm97!845nix2XfEe24L+%-w z)u@$EIZImO*+Mbauni>5sjOybThdQ2wVZ3;*6+a8E2}DE=h6~1s6*Q0h3uc0Fgw%> z@9=rsfZRtf-j`s}duC{&a8*ZB;O+%J!8!yB7{G8-cwx_UbC1}SiK=#J>J zAI5HJOF^ag(7B3)^chTvq$bMPlZmt|BZ(+cp>0J+buA!+2!qaTDEsD@cR7#ymY+89 z3C3&rQsq|WLg1z};bTlA8+f13_#G)8@qB~iSLXeeFFA41TFoIP)gd(0B@s`{Tq?2* z2>D!=b`2sl2G8jS?Gp95WtK445mY=m7T3+m9f!pTw8^!!@K}MU@INHJ{c_7c%PKyz zH%jap$!Y0dMn5ITKG^93*ZU$s9o>VWg0&zs^VWe|#d8GjnP>R1+TE$*t19?}5%_pb z>VS7;QNQ;F9nk)i4L?q$UmrEw=tOq-sTYg)c^vCwqi=F+^-LS}rU*_gB3>=r8BPXA zX;2IBMXBkXlm#(ybUKm_`ez|omBA)MS z!mS->)%3Ae2cc@V96I0}ob)kJ1E^t1H@IBGn(u8boU|(P*raF&#QC$St6~*i#qX2n zO5;_3HLu$~_oCM{2<5psv26!lE%V1Do-2HOk2 zf6v|Zq|{<*ib_uuz=IhcD+=)(LX)n00;gdl?t|4lRTvrs7J)`8Hm&w0$pGGZ zey5)`MUYRnoQ{eDS!g-xWzgq~3fqXSk6%9hy|%Hq|3#XVUDSKQP>@ux>|*}t6C;>) z``BW@Gr)0Cd6?0l#HwprzxNm&e9U`qXZ9&iy=43 zhhC1(yLZ%LcT;SnYNKxU%SSP)n*|S!(T}y?xoUe0pVyKdwYZ~|WsS6-8!A4-9&RRr ze|xY-$Y8z;aO25yr^|;$&ynM#6Ej*{sF99m};<=Ue63I7#<=$0z|C}ffBQ= z3NZuOkv*LS(88HGGiBcfH-=c;LDG(e$Z*xl42`&t`2;d?CGXSq8L~?v4EzfiNoxm^ z7#a1P9mowc(=n#$h*HCUpzbo^gotwgpWF5Hj*&u|@=gV$aWV|x4Zzd%g|Ed)db&vo zi$=I(nT-=6!S(Q#fmHc4@j#l;L#{m4qWi>1)mFYvtnnPW^Dl*Gr25pVg469TT85bGu;PaI2LTXD&y3B+wGL+tfF-!(s~`bu$L^&r5ymR{tf8q?I!2uB%^kPgptQTNHZ@utUVLyU9(`53~vBMS8iWamA9DZ&XZ7I^=CpaeJnS7Sq;Z( zx0=H)Ux{XUoO72tHgI&dh2aLltYZ-XO=Ve_VvNnEq6&xQFHSUjd&Y<%-Q|vZ>yw)r zj|RSaSkt7ce^iExV3VLlRo1IWG^M1mH7pK1HgSV|f+;EJs8KDRd~{t59hCBiWv)Fe zbMRS-!jhi!g@x8X#v4~NGL#%y!g5j`Tl=J@Je}IQe=2Qp`4KbUUx)DT@8)YquR~vX z4>$_&spN#Q*(cJ7#Jao8QqTKD*>(0}hLrDf4Xx`q+uyY=p6*b>+3j;z@^VxPWxXbW zGse>UMl-ned@+dfn}=ND5E^ge4(-ChqfZ%lmvsbtorzge4UvbQ%CU4hFioL>NK%Uu z&OR<#@W-IwHJ1C~eipQUw`jeY$~QyrzCN|dKya+kZb-wmA_(~l3AnXR`;OhZ zpN0w$Cd){`+(RzDE`rc}=Rdh5kR+HaoQ4q=Q4c83!A*dc=U_I^gr{PNq&e?LvVNbN z(#NGD;7Y}fwg>c15!m8(6XPH}6lAH;#0^tygBU-zPjp14T0LmNx+_AUSejtr#J<<7#d{N>}LCl8gy(I+Li z#O9L$y|SJ@um0O>Ba+pEyGXVB zQKn-w$WcJ)tfXa}Q%)TZv4U>c2R#`i@SAp?_w}ys4DRHjPp0&gfQ^Uf;hNmI&rTL9 z*2@{kzyp+L4_$|fN$Bwzz>>C%MNezNm?B?=sN^p!KJomlNEPVtrh3BEmKmy))-b18 z$(f_r0|n~}Em_)Wenv^mYus6@l+J57NAQSjWHeNJR?byz;(`7~-gE*Z)=XOyF5_6W zr5FcV02(b%o6%Q3eCzRHSnQ;opvQl#aD&3YKk3z|f=plZkYBo?hO@~k;H;(okN^in zp~MVSmG?Lnj%qz03C;I6pw*T@vTo8aSFQY*qh@)NbYw}})#)otvicb)b2}p`P%7l` z$9#RUrN5hWs5>qy!bU|aR?PB6THh20dW_D{a9nr_Xb+;KpIOY=C*WHd{gbCJx4CpN zXp$#M0)?{&8CXX~Y3BCW)-JT>t<1ND;+EN&Zb^0qup3#%qF*uSMbl7MH-Ala ztd=m}fs{)k5T3GZvZf9{mY%+C{c~;en$F|oIx6q9XSI|($%{3@M=xY=hAmNtm297L zPUpIFA_NsbQe;WhyPf>U=6FfX;(Tdo(buT4@u0F8k^Xn)mON$uro#|UY#!h0JYpny zzK_o*?kzDP)@V3C_H5_oHon`@k}<6$1)_?|a3FnTx{j6)>2XxR)S;=v8Gzcq_eOVz zaHim&n@(ascPWnZ8DI*LNVNf>)%Lw7yjDWNjlUzYu%qa*tQHcptY`-=JB4WR7^YC& zh!l084lv`&)!iOLh;y>&dW0m~DH8g?{I~JP%Bhmn|6+cKzcWZAdmgJ7VOF46k)iVv z^Pf(dfUf}&?!@_wZWfCNTu+3PWkU3gabMyUSG}U+JJ1B6wTFoa(@pHAnRo;MF!X_0 z(=l3TRfMCG+H91>@G}@;+}859BRX796q!3XiQA2gcb%#2sCk$=9Sq8t0eX7Jg)q`( z5T4tS7Sn|glg}n*NO2~O0NGsAjIIX|XXA_hQzk?tJ|)zKUbXiFB+pDmt~J*SSQA|G zp1^HgD8%vqX#toBVDmb_ZN+UXy`3;csa>tsHRYj4IVp`9BurdoQ2b6@w9ciYyUv8U zH&dijvN<1h^JjZ{1%qI-oMX(8;WT3#PwQI<)-A3ah||J_u0{t7^}5%QR^E zlB1cRGGH(CM{Ghg+`ME?!x@uxMXv*8i3Z`8FfR}d>xk3Ei-v2gVUDs-HJ>Y5heXfl7jzuI$mF|09?k35R)y6g#oV|2u~&>tHct53rlq%DIfu@cmo7u0csdZ zwQNRguTPW%Q4m#1)zY_5!xiF;e-Bk+b7kE4yzv+(tG$IYd8I9ITIS2?yV)|EENY;D zI#!Y4{O=${)^`<4>Yl?f-1@QKfKLBqgD=h^DMA?uAMi5f%KPlmxK&6~TwWmqZYiKh zrj`13{0x&`Y0tC=^#y+bQ64xC%p#&hE2c-bHqeUcMtzXgVjT`H6J|Hdh{KDi!2srC zRUXs4A*-+Co||`oP|w$d2+haFs>mPdykT6gJ=jdMg1%DJ2e{J5PJB3-EzO-y)f1Ie zQt7o-H)wnmvpAplh-8}(uo35JA9VX7uu%QAnN_b6 zOIo608Wg7-&YmG`cr6ol*ps=ioHxh3DXEp=7_H8vE5y7~E)?2v~p`rN+dA zWkc$r!Ic5hm)9W~(sPC;?a2y|xQUS-F*Gqz<+ZptyEY(HT{r;nB>mzT<`6EIbn@skJizHk8V z`p)3!;iHiB`OG3F%qU#V4?l7VkvejiBa-jHT%4^)#(d`kIx{0tvQhO|0$h9&Hi-S^ z@*!H#o(&-9qAWI8*~9l`NWsU+ar~iVezHsZR`armV}89crV>s#f3;3_>42Q1i`2L? z5(#BZt;d2_@iFTb8-NVh$TG${(4YeR#8QJZq#pR_wXqS@vrN8^T|R50X?VID-Z-GE z&ly0?MJ9$l=&7fJd$HP;nCx@< zEKJ|KE7sIwZ!C6uE7=_031D$$^a3LiK1_JZfxCE<(ACPk=A0z~o9^~VWv2L+uHc)p z627Wj0Y_bSG4Mra^$XfgcR$X(Q?!~0ko_|JrWXdrh&V_N#yB;0rjo8# zeCt^ouh{7#=hYAK*>=B^OLFg0Iu`MWX}X0lP^mZ``r}_YJeRLa!{lOKX#Q4i>9;CS zKsiNC4+VzgKox@C7F(x76^@bEZ`J5JjD?r;sHrf&@AGn&51~|Z`}MV)?Au$VlW7Zg zW7E5phFZ2lyb->BM1p&V-*>&y=m1&uH|MQyA-NvEdZDd=7y_(uwRdJ4csw)}W@p_8 zIN#8i)_qydRhNpWopKt@8JabRMXwas#@ z!ZVyLxm^r4cJwWBsepp-b_ZuMNN)65*_FQCk!pIYqL303b&7g@xEWkvu%+9xED|Fr zz4gz2O~7shX7Jgj(^a<`F9H5(uJ*pS8LOk-Fri68w*bCo8uHz|j-90;L@OWBoe}me zQl*HhpHfEZ@erMeQUqU$2pYaW_kwE5L(sP#i}<{bzvXo4QzLxSglRV2>8bkWV); z?KdArB6CdE80--`(o%rDI0u<^LX<9Tf|rh%0Df%of-bXlcZA$yQdKI&npdO*qPlT- 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�B@qyP2beU$x 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