diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/doctrees/environment.pickle b/doctrees/environment.pickle new file mode 100644 index 0000000..3b82022 Binary files /dev/null and b/doctrees/environment.pickle differ diff --git a/doctrees/index.doctree b/doctrees/index.doctree new file mode 100644 index 0000000..d5e2745 Binary files /dev/null and b/doctrees/index.doctree differ diff --git a/doctrees/modules.doctree b/doctrees/modules.doctree new file mode 100644 index 0000000..b93e93e Binary files /dev/null and b/doctrees/modules.doctree differ diff --git a/doctrees/pancax.bcs.doctree b/doctrees/pancax.bcs.doctree new file mode 100644 index 0000000..1489074 Binary files /dev/null and b/doctrees/pancax.bcs.doctree differ diff --git a/doctrees/pancax.bvps.doctree b/doctrees/pancax.bvps.doctree new file mode 100644 index 0000000..63495f5 Binary files /dev/null and b/doctrees/pancax.bvps.doctree differ diff --git a/doctrees/pancax.constitutive_models.doctree b/doctrees/pancax.constitutive_models.doctree new file mode 100644 index 0000000..d894f50 Binary files /dev/null and b/doctrees/pancax.constitutive_models.doctree differ diff --git a/doctrees/pancax.data.doctree b/doctrees/pancax.data.doctree new file mode 100644 index 0000000..644ca0b Binary files /dev/null and b/doctrees/pancax.data.doctree differ diff --git a/doctrees/pancax.doctree b/doctrees/pancax.doctree new file mode 100644 index 0000000..0d2bf50 Binary files /dev/null and b/doctrees/pancax.doctree differ diff --git a/doctrees/pancax.domains.doctree b/doctrees/pancax.domains.doctree new file mode 100644 index 0000000..629db48 Binary files /dev/null and b/doctrees/pancax.domains.doctree differ diff --git a/doctrees/pancax.fem.doctree b/doctrees/pancax.fem.doctree new file mode 100644 index 0000000..fe06a2d Binary files /dev/null and b/doctrees/pancax.fem.doctree differ diff --git a/doctrees/pancax.fem.elements.doctree b/doctrees/pancax.fem.elements.doctree new file mode 100644 index 0000000..155adcc Binary files /dev/null and b/doctrees/pancax.fem.elements.doctree differ diff --git a/doctrees/pancax.kernels.doctree b/doctrees/pancax.kernels.doctree new file mode 100644 index 0000000..861766f Binary files /dev/null and b/doctrees/pancax.kernels.doctree differ diff --git a/doctrees/pancax.loss_functions.doctree b/doctrees/pancax.loss_functions.doctree new file mode 100644 index 0000000..cf14539 Binary files /dev/null and b/doctrees/pancax.loss_functions.doctree differ diff --git a/doctrees/pancax.math.doctree b/doctrees/pancax.math.doctree new file mode 100644 index 0000000..169ef69 Binary files /dev/null and b/doctrees/pancax.math.doctree differ diff --git a/doctrees/pancax.networks.doctree b/doctrees/pancax.networks.doctree new file mode 100644 index 0000000..9e9bed0 Binary files /dev/null and b/doctrees/pancax.networks.doctree differ diff --git a/doctrees/pancax.optimizers.doctree b/doctrees/pancax.optimizers.doctree new file mode 100644 index 0000000..91f02ff Binary files /dev/null and b/doctrees/pancax.optimizers.doctree differ diff --git a/html/.buildinfo b/html/.buildinfo new file mode 100644 index 0000000..8d73133 --- /dev/null +++ b/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 030c48f1638182c071f4607d697d8ccf +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/html/_modules/index.html b/html/_modules/index.html new file mode 100644 index 0000000..b17cec1 --- /dev/null +++ b/html/_modules/index.html @@ -0,0 +1,184 @@ + + + + + + + + Overview: module code — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +

All modules for which code is available

+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/bcs/distance_functions.html b/html/_modules/pancax/bcs/distance_functions.html new file mode 100644 index 0000000..7336956 --- /dev/null +++ b/html/_modules/pancax/bcs/distance_functions.html @@ -0,0 +1,179 @@ + + + + + + + + pancax.bcs.distance_functions — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.bcs.distance_functions

+from jax import numpy as jnp
+from jax import vmap
+from typing import List
+
+
+
+[docs] +def get_edges(domain, sset_names: List[str]): + mesh = domain.fspace.mesh + ssets = [mesh.sideSets[name] for name in sset_names] + edges = jnp.vstack(ssets) + edges = jnp.sort(edges, axis=1) + edges = jnp.unique(edges, axis=0) # TODO not sure about this one + return edges
+ + +
+[docs] +def distance(x1, x2): + return jnp.sqrt( + jnp.power(x2[0] - x1[0], 2.) + + jnp.power(x2[1] - x1[1], 2.) + )
+ + +
+[docs] +def line_segment(x, segment): + x1 = segment[:, 0] + x2 = segment[:, 1] + L = distance(x1, x2) + x_c = (x1 + x2) / 2. + + f = (1. / L) * ( + (x[0] - x1[0]) * (x2[1] - x1[1]) - + (x[1] - x1[1]) * (x2[0] - x1[0]) + ) + t = (1. / L) * ( + jnp.power(L / 2., 2.) - + jnp.power(distance(x, x_c), 2.) + ) + varphi = jnp.sqrt( + jnp.power(t, 2.0) + + jnp.power(f, 4.0) + ) + phi = jnp.sqrt( + jnp.power(f, 2.0) + + (1. / 4.) * jnp.power(varphi - t, 2.) + ) + return phi
+ + + +
+[docs] +def distance_function(domain, ssets, m=1.0): + edges = get_edges(domain, ssets) + m = 1.0 + segments = domain.fspace.mesh.coords[edges, :] + def inner_func(x): + Rs = vmap(line_segment, in_axes=(None, 0))(x, segments) + Rs = vmap(lambda x: 1. / jnp.power(x, m))(Rs) + return 1. / jnp.power(jnp.sum(Rs), 1. / m) + return vmap(inner_func)
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/bcs/essential_bc.html b/html/_modules/pancax/bcs/essential_bc.html new file mode 100644 index 0000000..d723ade --- /dev/null +++ b/html/_modules/pancax/bcs/essential_bc.html @@ -0,0 +1,150 @@ + + + + + + + + pancax.bcs.essential_bc — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.bcs.essential_bc

+from jaxtyping import Array, Float
+from typing import Callable, List, Optional
+import equinox as eqx
+
+
+BCFunc = Callable[[Float[Array, "nd"], float], float]
+
+
+[docs] +class EssentialBC(eqx.Module): + """ + :param nodeSet: A name for a nodeset in the mesh + :param component: The dof to apply the essential bc to + :param function: A function f(x, t) = u that gives the value + to enforce on the (nodeset, component) of a field. + This defaults to the zero function + """ + nodeSet: str + component: int + function: Optional[BCFunc] = lambda x, t: 0.0 + +
+[docs] + def coordinates(self, mesh): + nodes = mesh.nodeSets[self.nodeSet] + coords = mesh.coords + return coords[nodes, :]
+
+ + + +
+[docs] +class EssentialBCSet(eqx.Module): + bcs: List[EssentialBC]
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/bcs/natural_bc.html b/html/_modules/pancax/bcs/natural_bc.html new file mode 100644 index 0000000..da67197 --- /dev/null +++ b/html/_modules/pancax/bcs/natural_bc.html @@ -0,0 +1,167 @@ + + + + + + + + pancax.bcs.natural_bc — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.bcs.natural_bc

+from jaxtyping import Array, Float
+from pancax.fem import surface
+from typing import Callable, Optional
+import equinox as eqx
+import jax
+import jax.numpy as jnp
+
+
+BCFunc = Callable[[Float[Array, "nd"], float], Float[Array, "nf"]]
+# remove component from the definition.
+# it doesn't appear to be doing anything
+# class NaturalBC(NamedTuple):
+
+[docs] +class NaturalBC(eqx.Module): + sideset: str + function: Optional[BCFunc] = lambda x, t: 0.0 + +
+[docs] + def coordinates(self, mesh, q_rule_1d): + xigauss, wgauss = q_rule_1d + edges = mesh.sideSets[self.sideset] + + def vmap_inner(edge): + edge_coords = surface.get_coords(mesh.coords, mesh.conns, edge) + jac = jnp.linalg.norm(edge_coords[0,:] - edge_coords[1,:]) + xgauss = edge_coords[0] + jnp.outer(xigauss, edge_coords[1] - edge_coords[0]) + return xgauss + + edge_coords = jax.vmap(vmap_inner)(edges) + edge_coords = jnp.vstack(edge_coords) + return edge_coords
+ + +
+[docs] + def normals(self, mesh, q_rule_1d): + xigauss, wgauss = q_rule_1d + edges = mesh.sideSets[self.sideset] + n_gauss_points = xigauss.shape[0] + + def vmap_inner(edge): + edge_coords = surface.get_coords(mesh.coords, mesh.conns, edge) + normal = surface.compute_normal(edge_coords) + normals = jnp.tile(normal, (n_gauss_points, 1)) + return normals + + edge_normals = jax.vmap(vmap_inner)(edges) + edge_normals = jnp.vstack(edge_normals) + return edge_normals
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/bvps/biaxial_tension.html b/html/_modules/pancax/bvps/biaxial_tension.html new file mode 100644 index 0000000..f438e68 --- /dev/null +++ b/html/_modules/pancax/bvps/biaxial_tension.html @@ -0,0 +1,146 @@ + + + + + + + + pancax.bvps.biaxial_tension — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.bvps.biaxial_tension

+
+[docs] +def BiaxialLinearRamp( + final_displacement_x: float, + final_displacement_y: float, + length_x: float, + length_y: float +): + def bc_func(xs, t, z): + x, y = xs[0], xs[1] + u_out = z + # u_out = u_out.at[0].set( + # x * (x - length_x) * t * z[0] / length_x**2 + \ + # x * t * final_displacement_x / length_x + # ) + # u_out = u_out.at[1].set( + # y * (y - length_y) * t * z[1] / length_y**2 + \ + # y * t * final_displacement_y / length_y + # ) + u_out = u_out.at[0].set( + (x * (x - length_x) * t / length_x**2 * \ + y * (y - length_y) * t / length_y**2) * z[0] + \ + x * t * final_displacement_x / length_x + ) + u_out = u_out.at[1].set( + (x * (x - length_x) * t / length_x**2 * \ + y * (y - length_y) * t / length_y**2) * z[1] + ) + return u_out + + return bc_func
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/bvps/simple_shear.html b/html/_modules/pancax/bvps/simple_shear.html new file mode 100644 index 0000000..7ee6d9b --- /dev/null +++ b/html/_modules/pancax/bvps/simple_shear.html @@ -0,0 +1,140 @@ + + + + + + + + pancax.bvps.simple_shear — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.bvps.simple_shear

+from typing import Optional
+
+
+[docs] +def SimpleShearLinearRamp( + final_displacement: float, + length: float, + direction: str +): + + if direction == 'xy': + def bc_func(xs, t, z): + x, y = xs[0], xs[1] + u_out = z + u_out = u_out.at[0].set( + x * (x - length) * t * z[0] / length**2 + ) + u_out = u_out.at[1].set( + x * t * final_displacement / length + x * (x - length) * t * z[1] / length**2 + ) + return u_out + else: + raise ValueError('Direction must be x or y for this BVP.') + + return bc_func
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/bvps/uniaxial_tension.html b/html/_modules/pancax/bvps/uniaxial_tension.html new file mode 100644 index 0000000..bd16cc4 --- /dev/null +++ b/html/_modules/pancax/bvps/uniaxial_tension.html @@ -0,0 +1,201 @@ + + + + + + + + pancax.bvps.uniaxial_tension — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.bvps.uniaxial_tension

+
+# TODO maybe have this read in a mesh
+# and use a bounding box to define these functions using xmin xmax etc.
+
+[docs] +def UniaxialTensionLinearRamp( + final_displacement: float, + length: float, + direction: str, + n_dimensions: int +): + + if n_dimensions == 2: + if direction == 'x': + def bc_func(xs, t, nn): + x, y = xs[0], xs[1] + u_out = nn + u_out = u_out.at[0].set( + x * t * final_displacement / length + x * (x - length) * t * nn[0] / length**2 + ) + u_out = u_out.at[1].set( + x * (x - length) * t * nn[1] / length**2 + ) + return u_out + elif direction == 'y': + def bc_func(xs, t, nn): + x, y = xs[0], xs[1] + u_out = nn + u_out = u_out.at[0].set( + y * (y - length) * t * nn[0] / length**2 + ) + u_out = u_out.at[1].set( + y * t * final_displacement / length + y * (y - length) * t * nn[1] / length**2 + ) + return u_out + else: + raise ValueError('Direction must be x or y for this BVP.') + elif n_dimensions == 3: + if direction == 'x': + def bc_func(xs, t, nn): + x, y, z = xs[0], xs[1], xs[2] + u_out = nn + u_out = u_out.at[0].set( + x * t * final_displacement / length + x * (x - length) * t * nn[0] / length**2 + ) + u_out = u_out.at[1].set( + x * (x - length) * t * nn[1] / length**2 + ) + u_out = u_out.at[2].set( + x * (x - length) * t * nn[2] / length**2 + ) + return u_out + elif direction == 'y': + def bc_func(xs, t, nn): + x, y, z = xs[0], xs[1], xs[2] + u_out = nn + u_out = u_out.at[0].set( + y * (y - length) * t * nn[0] / length**2 + ) + u_out = u_out.at[1].set( + y * t * final_displacement / length + y * (y - length) * t * nn[1] / length**2 + ) + u_out = u_out.at[2].set( + y * (y - length) * t * nn[2] / length**2 + ) + return u_out + elif direction == 'z': + def bc_func(xs, t, nn): + x, y, z = xs[0], xs[1], xs[2] + u_out = nn + u_out = u_out.at[0].set( + z * (z - length) * t * nn[0] / length**2 + ) + u_out = u_out.at[1].set( + z * (z - length) * t * nn[1] / length**2 + ) + u_out = u_out.at[2].set( + z * t * final_displacement / length + z * (z - length) * t * nn[2] / length**2 + ) + return u_out + else: + raise ValueError('Direction must be x, y, or z for this BVP.') + else: + raise ValueError('Dimensions can be either 2 or 3.') + + return bc_func
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/constitutive_models/base_constitutive_model.html b/html/_modules/pancax/constitutive_models/base_constitutive_model.html new file mode 100644 index 0000000..4467b61 --- /dev/null +++ b/html/_modules/pancax/constitutive_models/base_constitutive_model.html @@ -0,0 +1,274 @@ + + + + + + + + pancax.constitutive_models.base_constitutive_model — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.constitutive_models.base_constitutive_model

+from abc import ABC, abstractmethod
+from jaxtyping import Array, Float
+from typing import List
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class ConstitutiveModel(ABC): + """ + Base class for consistutive models. + + The interface to be defined by derived classes include + the energy method and the unpack_properties method. + + :param n_properties: The number of properties + :param property_names: The names of the properties + """ + n_properties: int + property_names: List[str] + +
+[docs] + def cauchy_stress(self, F: Float[Array, "3 3"], props: Float[Array, "np"]): + J = self.jacobian(F) + P = self.pk1_stress(F, props) + return (1. / J) * P @ F.T
+ + + # def deformation_gradient(self, grad_u: Float[Array, "3 3"]): + # return grad_u + jnp.eye(3) + +
+[docs] + @abstractmethod + def energy(self, F: Float[Array, "3 3"], props: Float[Array, "np"]): + """ + This method returns the algorithmic strain energy density. + """ + pass
+ + +
+[docs] + def invariants(self, F: Float[Array, "3 3"]): + I1 = self.I1(F) + I2 = self.I2(F) + I3 = self.jacobian(F)**2 + return jnp.array([I1, I2, I3])
+ + +
+[docs] + def jacobian(self, F: Float[Array, "3 3"]): + r""" + This simply calculate the jacobian but with guard rails + to return nonsensical numbers if a non-positive jacobian + is encountered during training. + + :param F: the deformation gradient + + .. math:: + J = det(\mathbf{F}) + + """ + J = jnp.linalg.det(F) + J = jax.lax.cond( + J <= 0.0, + lambda _: 1.0e3, + lambda x: x, + J + ) + return J
+ + +
+[docs] + def I1(self, F: Float[Array, "3 3"]): + r""" + Calculates the first invariant + + :param F: the deformation gradient + + .. math:: + I_1 = tr\left(\mathbf{F}^T\mathbf{F}\right) + """ + I1 = jnp.trace(F @ F.T) + return I1
+ + +
+[docs] + def I1_bar(self, F: Float[Array, "3 3"]): + r""" + Calculates the first distortional invariant + + :param F: the deformation gradient + + .. math:: + \bar{I}_1 = J^{-2/3}tr\left(\mathbf{F}^T\mathbf{F}\right) + """ + I1 = jnp.trace(F @ F.T) + J = self.jacobian(F) + return jnp.power(J, -2. / 3.) * I1
+ + +
+[docs] + def I2(self, F: Float[Array, "3 3"]): + C = F.T @ F + C2 = C @ C + I1 = jnp.trace(C) + I2 = 0.5 * (I1**2 - jnp.trace(C2)) + return I2
+ + +
+[docs] + def I2_bar(self, F: Float[Array, "3 3"]): + C = F.T @ F + C2 = C @ C + I1 = jnp.trace(C) + I2 = 0.5 * (I1**2 - jnp.trace(C2)) + J = self.jacobian(F) + return jnp.power(J, -4. / 3.) * I2
+ + +
+[docs] + def pk1_stress(self, F: Float[Array, "np"], props: Float[Array, "np"]): + return jax.grad(self.energy, argnums=0)(F, props)
+ + +
+[docs] + @abstractmethod + def unpack_properties(self, props: Float[Array, "np"]): + """ + This method unpacks properties from 'props' and returns + them with potentially static properties bound to the model. + """ + pass
+
+ + + +
+[docs] +class ConstitutiveModelFixedBulkModulus(ConstitutiveModel): + n_properties: int + property_names: List[str] + bulk_modulus: float + +
+[docs] + def __init__(self, bulk_modulus: float) -> None: + self.bulk_modulus = bulk_modulus
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/constitutive_models/blatz_ko.html b/html/_modules/pancax/constitutive_models/blatz_ko.html new file mode 100644 index 0000000..7577345 --- /dev/null +++ b/html/_modules/pancax/constitutive_models/blatz_ko.html @@ -0,0 +1,152 @@ + + + + + + + + pancax.constitutive_models.blatz_ko — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.constitutive_models.blatz_ko

+from .base_constitutive_model import ConstitutiveModel
+import jax.numpy as jnp
+
+
+
+[docs] +class BlatzKo(ConstitutiveModel): + r""" + Blatz-Ko model with the following model form + + .. math:: + \psi(\mathbf{F}) = \frac{1}{2}\mu\left(\frac{I_2}{I_3} + 2\sqrt{I_3} - 5\right) + """ + n_properties = 1 + property_names = [ + 'shear modulus' + ] + +
+[docs] + def energy(self, F, props): + G = self.unpack_properties(props) + + # kinematics + I2 = self.I2(F) + I3 = jnp.linalg.det(F.T @ F) + + # constitutive + W = (G / 2.) * (I2 / I3 + 2 * jnp.sqrt(I3) - 5.) + return W
+ + +
+[docs] + def unpack_properties(self, props): + return props[0]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/constitutive_models/gent.html b/html/_modules/pancax/constitutive_models/gent.html new file mode 100644 index 0000000..2146b1e --- /dev/null +++ b/html/_modules/pancax/constitutive_models/gent.html @@ -0,0 +1,186 @@ + + + + + + + + pancax.constitutive_models.gent — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.constitutive_models.gent

+from .base_constitutive_model import ConstitutiveModel, ConstitutiveModelFixedBulkModulus
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class Gent(ConstitutiveModel): + r""" + Gent model with the following model form + + .. math:: + \psi(\mathbf{F}) = \frac{1}{2}K\left[\frac{1}{2}\left(J^2 - \ln J\right)\right] - + \frac{1}{2}GJ_m\ln\left(1 - \frac{\bar{I}_1 - 3}{J_m}\right) + """ + n_properties = 3 + property_names = [ + 'bulk modulus', + 'shear modulus', + 'Jm parameter' + ] + +
+[docs] + def energy(self, F, props): + # unpack properties + K, G, Jm = self.unpack_properties(props) + + # kinematics + C = F.T @ F + J = self.jacobian(F) + I_1_bar = jnp.trace(jnp.power(J, -2. / 3.) * C) + + # guard rail + check_value = I_1_bar > Jm + 3.0 - 0.001 + I_1_bar = jax.lax.cond( + check_value, + lambda x: Jm + 3.0 - 0.001, + lambda x: x, + I_1_bar + ) + + # constitutive + W_vol = 0.5 * K * (0.5 * (J**2 - 1) - jnp.log(J)) + W_dev = -0.5 * G * Jm * jnp.log(1. - ((I_1_bar - 3.0) / Jm)) + return W_vol + W_dev
+ + +
+[docs] + def unpack_properties(self, props): + return props[0], props[1], props[2]
+
+ + + +
+[docs] +class GentFixedBulkModulus(Gent, ConstitutiveModelFixedBulkModulus): + n_properties = 2 + property_names = [ + 'shear modulus', + 'Jm parameter' + ] + bulk_modulus: float + +
+[docs] + def unpack_properties(self, props): + return self.bulk_modulus, props[0], props[1]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/constitutive_models/neohookean.html b/html/_modules/pancax/constitutive_models/neohookean.html new file mode 100644 index 0000000..d1daa20 --- /dev/null +++ b/html/_modules/pancax/constitutive_models/neohookean.html @@ -0,0 +1,176 @@ + + + + + + + + pancax.constitutive_models.neohookean — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.constitutive_models.neohookean

+from .base_constitutive_model import ConstitutiveModel, ConstitutiveModelFixedBulkModulus
+import jax.numpy as jnp
+
+
+
+[docs] +class NeoHookean(ConstitutiveModel): + r""" + NeoHookean model with the following model form + + .. math:: + \psi(\mathbf{F}) = \frac{1}{2}K\left[\frac{1}{2}\left(J^2 - \ln J\right)\right] + + \frac{1}{2}G\left(\bar{I}_1 - 3\right) + """ + n_properties = 2 + property_names = [ + 'bulk modulus', + 'shear modulus' + ] + +
+[docs] + def energy(self, F, props): + # unpack props + K, G = self.unpack_properties(props) + + # kinematics + C = F.T @ F + J = self.jacobian(F) + # I_1_bar = jnp.trace(jnp.power(J, -2. / 3.) * C) + I_1_bar = jnp.trace(1. / jnp.square(jnp.cbrt(J)) * C) + + # constitutive + W_vol = 0.5 * K * (0.5 * (J**2 - 1) - jnp.log(J)) + W_dev = 0.5 * G * (I_1_bar - 3.) + + return W_vol + W_dev
+ + +
+[docs] + def unpack_properties(self, props): + return props[0], props[1]
+
+ + + +
+[docs] +class NeoHookeanFixedBulkModulus(NeoHookean, ConstitutiveModelFixedBulkModulus): + n_properties = 1 + property_names = [ + 'shear modulus' + ] + bulk_modulus: float + +
+[docs] + def unpack_properties(self, props): + return self.bulk_modulus, props[0]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/constitutive_models/swanson.html b/html/_modules/pancax/constitutive_models/swanson.html new file mode 100644 index 0000000..5e61386 --- /dev/null +++ b/html/_modules/pancax/constitutive_models/swanson.html @@ -0,0 +1,294 @@ + + + + + + + + pancax.constitutive_models.swanson — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.constitutive_models.swanson

+from .base_constitutive_model import *
+import jax.numpy as jnp
+
+
+
+[docs] +class Swanson4(ConstitutiveModel): + r""" + Swanson model truncated to 4 parameters + + .. math:: + \psi(\mathbf{F}) = K\left(J\ln J - J + 1\right) + + \frac{3}{2}A_1\left(\frac{\bar{I}_1}{3} - 1\right)^{P_1} + + \frac{3}{2}C_1\left(\frac{\bar{I}_1}{3} - 1\right)^{R_1} + """ + n_properties = 5 + property_names = [ + 'bulk modulus', 'A1', 'P1', 'C1', 'R1' + ] + cutoff_strain: float + +
+[docs] + def __init__(self, cutoff_strain): + self.cutoff_strain = cutoff_strain
+ + +
+[docs] + def energy(self, F, props): + # unpack props + K, A1, P1, C1, R1 = self.unpack_properties(props) + tau_cutoff = (1. / 3.) * (3. + self.cutoff_strain**2) - 1. + + # kinematics + J = self.jacobian(F) + C = F.T @ F + C_bar = jnp.power(J, -2. / 3.) * C + I_1_bar = jnp.trace(C_bar) + tau_1 = (1. / 3.) * I_1_bar - 1. + tau_tilde_1 = tau_1 + tau_cutoff + + # constitutive + W_vol = K * (J * jnp.log(J) - J + 1.) + W_dev_tau = 3. / 2. * ( + A1 / (P1 + 1.) * (tau_tilde_1**(P1 + 1.)) + + C1 / (R1 + 1.) * (tau_tilde_1**(R1 + 1.)) + ) + W_dev_cutoff = 3. / 2. * ( + A1 / (P1 + 1.) * (tau_cutoff**(P1 + 1.)) + + C1 / (R1 + 1.) * (tau_cutoff**(R1 + 1.)) + ) + W_dev = W_dev_tau - W_dev_cutoff + return W_vol + W_dev
+ + +
+[docs] + def unpack_properties(self, props): + return props[0], props[1], props[2], props[3], props[4]
+
+ + + +
+[docs] +class Swanson4FixedBulkModulus(Swanson4, ConstitutiveModelFixedBulkModulus): + n_properties = 4 + property_names = [ + 'A1', 'P1', 'C1', 'R1' + ] + bulk_modulus: float + +
+[docs] + def __init__(self, bulk_modulus: float, cutoff_strain: float): + super().__init__(cutoff_strain) + self.bulk_modulus = bulk_modulus
+ + +
+[docs] + def unpack_properties(self, props): + return self.bulk_modulus, props[0], props[1], props[2], props[3]
+
+ + + +
+[docs] +class Swanson6(ConstitutiveModel): + r""" + Swanson model truncated to 6 parameters + + .. math:: + \psi(\mathbf{F}) = K\left(J\ln J - J + 1\right) + + \frac{3}{2}A_1\left(\frac{\bar{I}_1}{3} - 1\right)^{P_1} + + \frac{3}{2}B_1\left(\frac{\bar{I}_2}{3} - 1\right)^{Q_1} + + \frac{3}{2}C_1\left(\frac{\bar{I}_1}{3} - 1\right)^{R_1} + """ + n_properties = 7 + property_names = [ + 'bulk modulus', 'A1', 'P1', 'B1', 'Q1', 'C1', 'R1' + ] + cutoff_strain: float + +
+[docs] + def __init__(self, cutoff_strain: float): + self.cutoff_strain = cutoff_strain
+ + +
+[docs] + def energy(self, F, props): + # unpack props + K, A1, P1, B1, Q1, C1, R1 = self.unpack_properties(props) + tau_cutoff = (1. / 3.) * (3. + self.cutoff_strain**2) - 1. + + # kinematics + J = self.jacobian(F) + C = F.T @ F + C_bar = jnp.power(J, -2. / 3.) * C + C_bar_2 = C_bar @ C_bar + + I_1_bar = jnp.trace(C_bar) + I_2_bar = 0.5 * (I_1_bar**2 - jnp.trace(C_bar_2)) + tau_1 = (1. / 3.) * I_1_bar - 1. + tau_2 = (1. / 3.) * I_2_bar - 1. + tau_tilde_1 = tau_1 + tau_cutoff + tau_tilde_2 = tau_2 + tau_cutoff + + # constitutive + W_vol = K * (J * jnp.log(J) - J + 1.) + W_dev_tau = 3. / 2. * ( + A1 / (P1 + 1.) * (tau_tilde_1**(P1 + 1.)) + + B1 / (Q1 + 1.) * (tau_tilde_2**(Q1 + 1.)) + + C1 / (R1 + 1.) * (tau_tilde_1**(R1 + 1.)) + ) + W_dev_cutoff = 3. / 2. * ( + A1 / (P1 + 1.) * (tau_cutoff**(P1 + 1.)) + + B1 / (Q1 + 1.) * (tau_cutoff**(Q1 + 1.)) + + C1 / (R1 + 1.) * (tau_cutoff**(R1 + 1.)) + ) + W_dev = W_dev_tau - W_dev_cutoff + return W_vol + W_dev
+ + +
+[docs] + def unpack_properties(self, props): + return props[0], props[1], props[2], props[3], props[4], props[5], props[6]
+
+ + + +
+[docs] +class Swanson6FixedBulkModulus(Swanson6, ConstitutiveModelFixedBulkModulus): + n_properties = 6 + property_names = [ + 'A1', 'P1', 'B1', 'Q1', 'C1', 'R1' + ] + bulk_modulus: float + cutoff_strain: float + +
+[docs] + def __init__(self, bulk_modulus: float, cutoff_strain: float): + super().__init__(cutoff_strain) + self.bulk_modulus = bulk_modulus
+ + + +
+[docs] + def unpack_properties(self, props): + return self.bulk_modulus, props[0], props[1], props[2], props[3], props[4], props[5]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/data/full_field_data.html b/html/_modules/pancax/data/full_field_data.html new file mode 100644 index 0000000..238d26c --- /dev/null +++ b/html/_modules/pancax/data/full_field_data.html @@ -0,0 +1,175 @@ + + + + + + + + pancax.data.full_field_data — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.data.full_field_data

+from jaxtyping import Array
+from typing import List
+import equinox as eqx
+import jax.numpy as jnp
+import matplotlib.pyplot as plt
+import pandas
+
+
+
+[docs] +class FullFieldData(eqx.Module): + """ + Data structure to store full field data used as ground truth + for output fields of a PINN when solving inverse problems. + + :param inputs: Data that serves as inputs to the PINN + :param outputs: Data that serves as outputs of the PINN + :param n_time_steps: Variable used for book keeping + """ + inputs: Array + outputs: Array + n_time_steps: int + +
+[docs] + def __init__( + self, + data_file: str, + input_keys: List[str], + output_keys: List[str] + ): + df = pandas.read_csv(data_file) + df.columns = df.columns.str.strip() + self.inputs = jnp.array(df[input_keys].values) + self.outputs = jnp.array(df[output_keys].values) + self.n_time_steps = len(jnp.unique(self.inputs[:, -1]))
+ + + # TODO still need to test this +
+[docs] + def plot_registration(self, domain): + n_points_per_step = int(self.inputs.shape[0] / self.n_time_steps) + first_step = self.inputs[:n_points_per_step, :] + + plt.figure(1) + plt.scatter(first_step[:, 0], first_step[:, 1], color='blue', label='DIC') + plt.scatter(domain.coords[:, 0], domain.coords[:, 1], color='red', label='Mesh') + plt.xlabel('X coordinate (mm)') + plt.ylabel('Y coordinate (mm)') + plt.legend(loc='best') + plt.savefig('dic_data_mesh_registration.png') + plt.clf()
+ + +
+[docs] + def plot_data(self, domain, time_step): + pass
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/data/global_data.html b/html/_modules/pancax/data/global_data.html new file mode 100644 index 0000000..5dbd027 --- /dev/null +++ b/html/_modules/pancax/data/global_data.html @@ -0,0 +1,220 @@ + + + + + + + + pancax.data.global_data — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.data.global_data

+from jaxtyping import Array
+from typing import Optional, Union
+import equinox as eqx
+import exodus3 as exodus
+import jax.numpy as jnp
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas
+
+
+# TODO currently hardcoded to force which may be limiting
+# for others interested in doing other physics
+
+[docs] +class GlobalData(eqx.Module): + """ + Data structure that holds global data to be used as + ground truth for some global field calculated from + PINN outputs used in inverse modeling training + + :param times: A set of times used to compare to physics calculations + :param displacements: Currently hardcoded to use a displacement-force curve TODO + :param outputs: Field used as ground truth, hardcoded essentially to a reaction force now + :param n_nodes: Book-keeping variable for number of nodes on nodeset to measure global response from + :param n_time_steps: Book-keeping variable + :param reaction_nodes: Node set nodes for where to measure reaction forces + :param reaction_dof: Degree of freedom to use for reaction force calculation + """ + times: Array # change to inputs? + displacements: Array + outputs: Array + n_nodes: int + n_time_steps: int + reaction_nodes: Array + reaction_dof: int + +
+[docs] + def __init__( + self, + data_file: str, times_key: str, disp_key: str, force_key: str, + mesh_file: str, nset_id: int, reaction_dof: Union[int, str], + n_time_steps: int, + plotting: Optional[bool] = False + ): + # read in data + df = pandas.read_csv(data_file) + df.columns = df.columns.str.strip() + times_in = df[times_key].values + disps_in = df[disp_key].values + forces_in = df[force_key].values + # interpolate data onto times + times = np.linspace(np.min(times_in), np.max(times_in), n_time_steps) + disp_interp = np.interp(times, times_in, disps_in) + force_interp = np.interp(times, times_in, forces_in) + + if plotting: + plt.figure(1) + plt.plot(times_in, disps_in, label='Raw Data') + plt.plot(times, disp_interp, label='Interpolated', linestyle='None', marker='o') + plt.xlabel('Time (s)') + plt.ylabel('Displacement (mm)') + plt.savefig('mts_time_displacement.png') + plt.clf() + + plt.figure(2) + plt.plot(times_in, forces_in, label='Raw Data') + plt.plot(times, force_interp, label='Interpolated', linestyle='None', marker='o') + plt.xlabel('Time (s)') + plt.ylabel('Force (N)') + plt.savefig('mts_time_force.png') + plt.clf() + + plt.figure(3) + plt.plot(disps_in, forces_in, label='Raw Data') + plt.plot(disp_interp, force_interp, label='Interpolated', linestyle='None', marker='o') + plt.xlabel('Displacement (mm)') + plt.ylabel('Force (N)') + plt.savefig('mts_displacement_force.png') + plt.clf() + + # mesh related stuff + exo = exodus.exodus(mesh_file, 'r', array_type='numpy') + nodes = exo.get_node_set_nodes(nset_id) - 1 + reaction_nodes = jnp.array(nodes) + n_nodes = len(reaction_nodes) + + if reaction_dof == 'x': + reaction_dof = 0 + elif reaction_dof == 'y': + reaction_dof = 1 + elif reaction_dof == 'z': + reaction_dof = 2 + else: + raise ValueError('reaction_dof needs to be either x or y.') + + # set things + self.times = jnp.array(times) + self.displacements = jnp.array(disp_interp) + self.outputs = jnp.array(force_interp) + self.n_nodes = n_nodes + self.n_time_steps = len(times) + self.reaction_nodes = reaction_nodes + self.reaction_dof = reaction_dof
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/domains/base_domain.html b/html/_modules/pancax/domains/base_domain.html new file mode 100644 index 0000000..32ea5e9 --- /dev/null +++ b/html/_modules/pancax/domains/base_domain.html @@ -0,0 +1,210 @@ + + + + + + + + pancax.domains.base_domain — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.domains.base_domain

+from jax import vmap
+from jaxtyping import Array, Float
+from pancax.bcs import EssentialBC, NaturalBC
+from pancax.bcs import EssentialBCSet
+from pancax.fem import DofManager, Mesh, SimplexTriElement
+from pancax.fem import create_higher_order_mesh_from_simplex_mesh
+from pancax.fem import read_exodus_mesh
+from pancax.kernels import PhysicsKernel
+from pancax.timer import Timer
+from pancax.utils import find_mesh_file
+from typing import List, Optional, Union
+import equinox as eqx
+import jax.numpy as jnp
+
+
+
+
+[docs] +class BaseDomain(eqx.Module): + """ + Base domain for all problem types. + This holds essential things for the problem + such as a mesh to load a geometry from, + times, physics, bcs, etc. + + :param mesh: A mesh from an exodus file most likely + :param coords: An array of coordinates + :param times: An array of times + :param physics: An initialized physics object + :param essential_bcs: A list of EssentialBCs + :param natural_bcs: a list of NaturalBCs + :param dof_manager: A DofManager for keeping track of essential bcs + """ + mesh_file: str + mesh: Mesh + coords: Float[Array, "nn nd"] + times: Union[Float[Array, "nt"], Float[Array, "nn 1"]] + physics: PhysicsKernel + essential_bcs: List[EssentialBC] + natural_bcs: List[NaturalBC] + dof_manager: DofManager + +
+[docs] + def __init__( + self, + physics: PhysicsKernel, + essential_bcs: List[EssentialBC], + natural_bcs: any, # TODO figure out to handle this + mesh_file: str, + times: Float[Array, "nt"], + p_order: Optional[int] = 1 + ): + with Timer('BaseDomain.__init__'): + # setup + n_dofs = physics.n_dofs + + # mesh + mesh = read_exodus_mesh(mesh_file) + + # if tri mesh, we can make it higher order from lower order + if type(mesh.parentElement) == SimplexTriElement: + mesh = create_higher_order_mesh_from_simplex_mesh(mesh, p_order, copyNodeSets=True) + else: + print('WARNING: Ignoring polynomial order flag for non tri mesh') + + with Timer('move coordinates to device'): + coords = jnp.array(mesh.coords) + + # dof book keeping + dof_manager = DofManager(mesh, n_dofs, essential_bcs) + # TODO move below to dof manager + dof_manager.isUnknown = jnp.array(dof_manager.isUnknown, dtype=jnp.bool) + dof_manager.unknownIndices = jnp.array(dof_manager.unknownIndices) + + # setting all at once + self.mesh_file = mesh_file + self.mesh = mesh + self.coords = coords + self.times = times + self.physics = physics + # self.essential_bcs = essential_bcs + self.essential_bcs = EssentialBCSet(essential_bcs) + self.natural_bcs = natural_bcs + self.dof_manager = dof_manager
+ + +
+[docs] + def field_values(self, field_network, t): + us = vmap(self.physics.field_values, in_axes=(None, 0, None))( + field_network, self.coords, t + ) + return us
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/domains/collocation_domain.html b/html/_modules/pancax/domains/collocation_domain.html new file mode 100644 index 0000000..3078312 --- /dev/null +++ b/html/_modules/pancax/domains/collocation_domain.html @@ -0,0 +1,225 @@ + + + + + + + + pancax.domains.collocation_domain — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.domains.collocation_domain

+from .base_domain import BaseDomain
+from jaxtyping import Array, Float
+from pancax.bcs import EssentialBC, NaturalBC
+from pancax.fem import DofManager
+from pancax.fem import Mesh
+from pancax.fem import QuadratureRule
+from pancax.fem.elements import LineElement
+from pancax.kernels import PhysicsKernel
+from pancax.timer import Timer
+from typing import List, Optional, Union
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class CollocationDomain(BaseDomain): + """ + Base domain for all problem types. + This holds essential things for the problem + such as a mesh to load a geometry from, + times, physics, bcs, etc. + + :param mesh: A mesh from an exodus file most likely + :param coords: An array of coordinates + :param times: An array of times + :param physics: An initialized physics object + :param essential_bcs: A list of EssentialBCs + :param natural_bcs: a list of NaturalBCs + :param dof_manager: A DofManager for keeping track of essential bcs + """ + mesh: Mesh + coords: Float[Array, "nn nd"] + times: Union[Float[Array, "nt"], Float[Array, "nn 1"]] + physics: PhysicsKernel + essential_bcs: List[EssentialBC] + natural_bcs: List[NaturalBC] + dof_manager: DofManager + neumann_xs: Float[Array, "nn nd"] + neumann_ns: Float[Array, "nn nd"] + # neumann_outputs: Float[Array, "nn nf"] + +
+[docs] + def __init__( + self, + physics: PhysicsKernel, + essential_bcs: List[EssentialBC], + natural_bcs: List[NaturalBC], + mesh_file: str, + times: Float[Array, "nt"], + p_order: Optional[int] = 1, + q_order: Optional[int] = 2, + vectorize_over_time: Optional[bool] = False + ) -> None: + """ + :param physics: A ``PhysicsKernel`` object + :param essential_bcs: A list of ``EssentiablBC`` objects + :param natural_bcs: TODO + :param mesh_file: mesh file name as string + :param times: set of times + :param p_order: Polynomial order for mesh. Only hooked up to tri meshes. + :param q_order: Quadrature order to use. + :param vectorize_over_time: Flag to enable vectorization over time + this likely only makes sense for path-independent problems. + """ + with Timer('CollocationDomain.__init__'): + super().__init__( + physics, essential_bcs, natural_bcs, + mesh_file, times, + p_order=p_order + ) + + # TODO currently all of the below is busted for transient problems + + # TODO need to gather dirichlet inputs/outputs + # mesh = self.fspace.mesh + # if len(essential_bcs) > 0: + # self.dirichlet_xs = jnp.vstack([bc.coordinates(mesh) for bc in essential_bcs]) + # self.dirichlet_outputs = jnp.vstack([ + # jax.vmap(bc.function, in_axes=(0, None))(bc.coordinates(mesh), ) + # ]) + + # TODO below should eventually be move to the base class maybe? + # get neumann xs and ns + # mesh = self.fspace.mesh + mesh = self.mesh + if mesh.num_dimensions != 2: + raise ValueError( + 'Only 2D meshes currently supported for collocation problems. ' + 'Need to implement surface normal calculations on 3D elements.' + ) + # q_rule_1d = self.q_rule_1d + # currently only support 2D meshes + q_rule_1d = QuadratureRule(LineElement(1), q_order) + if len(natural_bcs) > 0: + self.neumann_xs = [bc.coordinates(mesh, q_rule_1d) for bc in natural_bcs] + self.neumann_ns = [bc.normals(mesh, q_rule_1d) for bc in natural_bcs] + print('Warning this neumann condition will fail for inhomogenous conditions with time') + # self.neumann_outputs = jnp.vstack([ + # jax.vmap(bc.function, in_axes=(0, None))(bc.coordinates(mesh, q_rule_1d), 0.0) \ + # for bc in natural_bcs + # ]) + else: + self.neumann_xs = [] + self.neumann_ns = []
+
+ + # self.neumann_xs = jnp.array([[]]) + # self.neumann_ns = jnp.array([[]]) + # self.neumann_outputs = jnp.array([[]]) +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/domains/delta_pinn_domain.html b/html/_modules/pancax/domains/delta_pinn_domain.html new file mode 100644 index 0000000..7ffda2d --- /dev/null +++ b/html/_modules/pancax/domains/delta_pinn_domain.html @@ -0,0 +1,261 @@ + + + + + + + + pancax.domains.delta_pinn_domain — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.domains.delta_pinn_domain

+from jax import vmap
+from jaxtyping import Array, Float, Int
+from pancax.bcs import EssentialBC, NaturalBC
+from pancax.fem import DofManager
+from pancax.fem import FunctionSpace
+from pancax.fem import Mesh
+from pancax.timer import Timer
+from pancax.kernels import LaplaceBeltrami, PhysicsKernel
+from pancax.networks import FixedProperties
+from pancax.physics import mass_matrix, stiffness_matrix
+from pancax.post_processor import PostProcessor
+from .variational_domain import VariationalDomain
+from typing import List, Optional, Union
+import jax.numpy as jnp
+import numpy as onp
+from scipy.sparse import linalg
+
+
+
+[docs] +class DeltaPINNDomain(VariationalDomain): + """ + Base domain for all problem types. + This holds essential things for the problem + such as a mesh to load a geometry from, + times, physics, bcs, etc. + + :param mesh: A mesh from an exodus file most likely + :param coords: An array of coordinates + :param times: An array of times + :param physics: An initialized physics object + :param essential_bcs: A list of EssentialBCs + :param natural_bcs: a list of NaturalBCs + :param dof_manager: A DofManager for keeping track of essential bcs + :param conns: An array of connectivities + :param fspace: A FunctionSpace to help with integration + :param fspace_centroid: A FunctionSpace to help with integration + :param n_eigen_values: Number of eigenvalues to use + """ + mesh: Mesh + coords: Float[Array, "nn nd"] + times: Union[Float[Array, "nt"], Float[Array, "nn 1"]] + physics: PhysicsKernel + essential_bcs: List[EssentialBC] + natural_bcs: List[NaturalBC] + dof_manager: DofManager + conns: Int[Array, "ne nnpe"] + fspace: FunctionSpace + fspace_centroid: FunctionSpace + n_eigen_values: int + eigen_modes: Float[Array, "nn nev"] + +
+[docs] + def __init__( + self, + physics: PhysicsKernel, + essential_bcs: List[EssentialBC], + natural_bcs: List[NaturalBC], + mesh_file: str, + times: Float[Array, "nt"], + n_eigen_values: int, + p_order: Optional[int] = 1, + q_order: Optional[int] = 2 + ) -> None: + """ + :param physics: A ``PhysicsKernel`` object + :param essential_bcs: A list of ``EssentiablBC`` objects + :param natural_bcs: TODO + :param mesh_file: mesh file name as string + :param times: set of times + :param p_order: Polynomial order for mesh. Only hooked up to tri meshes. + :param q_order: Quadrature order to use. + :param n_eigen_values: Number of eigenvalues to use + """ + if not physics.use_delta_pinn: + raise ValueError('Need a physics object set up for DeltaPINN') + + with Timer('DeltaPINNDomain.__init__'): + super().__init__( + physics, essential_bcs, natural_bcs, mesh_file, times, + p_order=p_order, q_order=q_order + ) + self.n_eigen_values = n_eigen_values + self.eigen_modes = self.solve_eigen_problem(mesh_file, p_order, q_order)
+ + +
+[docs] + def field_values(self, field_network, t): + us = vmap(self.physics.field_values, in_axes=(None, 0, None, 0))( + field_network, self.coords, t, self.eigen_modes + ) + return us
+ + +
+[docs] + def solve_eigen_problem(self, mesh_file, p_order, q_order): + with Timer('DeltaPINNDomain.solve_eigen_problem'): + times = jnp.zeros(1) + bc_func = lambda x, t, nn: nn + physics = LaplaceBeltrami(mesh_file, bc_func, self.n_eigen_values) + domain = VariationalDomain( + physics, [], [], mesh_file, times, + p_order=p_order, q_order=q_order + ) + props = FixedProperties([]) + Uu = jnp.zeros(domain.dof_manager.get_unknown_size()) + U = domain.dof_manager.create_field(Uu) + K = stiffness_matrix(domain, U, props) + M = mass_matrix(domain, U, props) + + with Timer('eigen solve'): + nModes = self.n_eigen_values + mu, modes = linalg.eigsh( + A=K, k=nModes, M=M, which='SM' + ) + + lambdas = 1. / mu + for n in range(len(lambdas)): + print(f' Eigen mode {n} = {1. / lambdas[n]}') + + with Timer('post-processing'): + pp = PostProcessor(mesh_file) + pp.init(domain, 'output-eigen.e', + node_variables=[ + 'eigenvector' + ] + ) + for n in range(len(lambdas)): + print(f' Post-processing eigenvector {n}') + field = domain.dof_manager.create_field(modes[:, n]) + field = onp.asarray(field) + pp.exo.put_time(n + 1, 1. / lambdas[n]) + pp.exo.put_node_variable_values('eigenvector', n + 1, field[:, 0]) + pp.close() + + # normalizing modes by default + modes = jnp.array(modes[:, 0:len(lambdas) - 1]) + print(modes.shape) + # modes = (modes - jnp.min(modes, axis=0)) / \ + # (jnp.max(modes, axis=0) - jnp.min(modes, axis=0)) + + return modes
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/domains/inverse_domain.html b/html/_modules/pancax/domains/inverse_domain.html new file mode 100644 index 0000000..8d5e338 --- /dev/null +++ b/html/_modules/pancax/domains/inverse_domain.html @@ -0,0 +1,185 @@ + + + + + + + + pancax.domains.inverse_domain — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.domains.inverse_domain

+from .variational_domain import VariationalDomain
+from jaxtyping import Array, Float
+from pancax.bcs import EssentialBC
+from pancax.data import FullFieldData, GlobalData
+from pancax.fem import DofManager
+from pancax.fem import FunctionSpace
+from pancax.kernels import PhysicsKernel
+from typing import List, Optional, Union
+
+
+
+[docs] +class InverseDomain(VariationalDomain): + """ + Inverse domain type derived from a ForwardDomain + + Note that currently this likely only supports single block meshes. + + :param physics: A physics kernel to use for physics calculations. + :param dof_manager: A DofManager to track what dofs are free/fixed. + :param fspace: A FunctionSpace to help with integration + :param q_rule_1d: A quadrature rule for line/surface integrations. TODO rename this + :param q_rule_2d: A quadrature rule for cell integrations. TODO rename this + :param coords: Nodal coordinates in the reference configuration. + :param conns: Element connectivity matrix + :param field_data: Data structure that holds the full field data. + :param global_data: Data structure that holds the global data. + """ + physics: PhysicsKernel + dof_manager: DofManager + fspace: FunctionSpace + fspace_centroid: FunctionSpace + coords: Float[Array, "nn nd"] + conns: Float[Array, "ne nnpe"] + times: Union[Float[Array, "nt"], Float[Array, "nn 1"]] + field_data: FullFieldData + global_data: GlobalData + +
+[docs] + def __init__( + self, + physics: PhysicsKernel, + essential_bcs: List[EssentialBC], + natural_bcs: any, # TODO figure out to handle this + mesh_file: str, + times: Float[Array, "nt"], + field_data: FullFieldData, + global_data: GlobalData, + p_order: Optional[int] = 1, + q_order: Optional[int] = 2 + ) -> None: + """ + :param physics: A ``PhysicsKernel`` object + :param essential_bcs: A list of ``EssentiablBC`` objects + :param natural_bcs: TODO + :param mesh_file: mesh file name as string + :param times: An array of time values to use + :param field_data: ``FieldData`` object + :param global_data: ``GlobalData`` object + :param p_order: Polynomial order for mesh. Only hooked up to tri meshes. + :param q_order: Quadrature order to use. + """ + super().__init__( + physics, essential_bcs, natural_bcs, mesh_file, times, + p_order=p_order, q_order=q_order + ) + self.field_data = field_data + self.global_data = global_data
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/domains/utils.html b/html/_modules/pancax/domains/utils.html new file mode 100644 index 0000000..6c02819 --- /dev/null +++ b/html/_modules/pancax/domains/utils.html @@ -0,0 +1,169 @@ + + + + + + + + pancax.domains.utils — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.domains.utils

+from copy import copy
+from copy import deepcopy
+from pancax.fem import Mesh
+import jax
+import jax.numpy as jnp
+
+
+
+# def make_mesh_time_dependent(mesh, n_time_steps):
+
+[docs] +def make_mesh_time_dependent(mesh, times): + n_time_steps = len(times) + + # some constants + n_elements = mesh.conns.shape[0] + n_nodes = mesh.coords.shape[0] + + # arrays to return in a new mesh object + coords = copy(mesh.coords) + conns = copy(mesh.conns) + simplexNodesOrdinals = copy(mesh.simplexNodesOrdinals) + blocks = deepcopy(mesh.blocks) + nodeSets = deepcopy(mesh.nodeSets) + sideSets = deepcopy(mesh.sideSets) + + for n in range(1, n_time_steps): + coords = jnp.vstack((coords, mesh.coords)) + conns = jnp.vstack((conns, mesh.conns + n * n_nodes)) + simplexNodeOrdinals = jnp.vstack((simplexNodesOrdinals, mesh.simplexNodesOrdinals)) + + for key in mesh.blocks.keys(): + blocks[key] = jnp.hstack((blocks[key], mesh.blocks[key] + n * n_elements)) + + for key in mesh.nodeSets.keys(): + nodeSets[key] = jnp.hstack((nodeSets[key], mesh.nodeSets[key] + n * n_nodes)) + + for key in mesh.sideSets.keys(): + sideSets[key] = jnp.hstack((sideSets[key], mesh.sideSets[key] + n * n_elements)) + + return Mesh( + coords=coords, conns=conns, simplexNodesOrdinals=simplexNodesOrdinals, + parentElement=mesh.parentElement, parentElement1d=mesh.parentElement1d, + blocks=blocks, nodeSets=nodeSets, sideSets=sideSets + )
+ + +
+[docs] +def make_times_column(n_nodes: int, times_in: jax.Array): + times = jnp.zeros(n_nodes * len(times_in), dtype=jnp.float64) + for n, time in enumerate(times_in): + times = times.at[n * n_nodes:(n + 1) * n_nodes].set(time * jnp.ones(n_nodes, dtype=jnp.float64)) + return times
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/domains/variational_domain.html b/html/_modules/pancax/domains/variational_domain.html new file mode 100644 index 0000000..e44d885 --- /dev/null +++ b/html/_modules/pancax/domains/variational_domain.html @@ -0,0 +1,196 @@ + + + + + + + + pancax.domains.variational_domain — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.domains.variational_domain

+from .base_domain import BaseDomain
+from jaxtyping import Array, Float, Int
+from pancax.bcs import EssentialBC, NaturalBC
+from pancax.fem import DofManager
+from pancax.fem import FunctionSpace
+from pancax.fem import Mesh
+from pancax.fem import NonAllocatedFunctionSpace
+from pancax.fem import QuadratureRule
+from pancax.timer import Timer
+from pancax.kernels import PhysicsKernel
+from typing import List, Optional, Union
+import jax.numpy as jnp
+
+
+
+[docs] +class VariationalDomain(BaseDomain): + """ + Base domain for all problem types. + This holds essential things for the problem + such as a mesh to load a geometry from, + times, physics, bcs, etc. + + :param mesh: A mesh from an exodus file most likely + :param coords: An array of coordinates + :param times: An array of times + :param physics: An initialized physics object + :param essential_bcs: A list of EssentialBCs + :param natural_bcs: a list of NaturalBCs + :param dof_manager: A DofManager for keeping track of essential bcs + :param conns: An array of connectivities + :param fspace: A FunctionSpace to help with integration + :param fspace_centroid: A FunctionSpace to help with integration + """ + mesh: Mesh + coords: Float[Array, "nn nd"] + times: Union[Float[Array, "nt"], Float[Array, "nn 1"]] + physics: PhysicsKernel + essential_bcs: List[EssentialBC] + natural_bcs: List[NaturalBC] + dof_manager: DofManager + conns: Int[Array, "ne nnpe"] + fspace: FunctionSpace + fspace_centroid: FunctionSpace + +
+[docs] + def __init__( + self, + physics: PhysicsKernel, + essential_bcs: List[EssentialBC], + natural_bcs: any, # TODO figure out to handle this + mesh_file: str, + times: Float[Array, "nt"], + p_order: Optional[int] = 1, + q_order: Optional[int] = 2 + ) -> None: + """ + :param physics: A ``PhysicsKernel`` object + :param essential_bcs: A list of ``EssentiablBC`` objects + :param natural_bcs: TODO + :param mesh_file: mesh file name as string + :param times: set of times + :param p_order: Polynomial order for mesh. Only hooked up to tri meshes. + :param q_order: Quadrature order to use. + """ + with Timer('VariationalDomain.__init__'): + super().__init__( + physics, essential_bcs, natural_bcs, mesh_file, times, + p_order=p_order + ) + with Timer('move connectivity to device'): + self.conns = jnp.array(self.mesh.conns) + + self.fspace = NonAllocatedFunctionSpace( + self.mesh, QuadratureRule(self.mesh.parentElement, q_order) + ) + self.fspace_centroid = NonAllocatedFunctionSpace( + self.mesh, QuadratureRule(self.mesh.parentElement, 1) + )
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/dof_manager.html b/html/_modules/pancax/fem/dof_manager.html new file mode 100644 index 0000000..ec259e7 --- /dev/null +++ b/html/_modules/pancax/fem/dof_manager.html @@ -0,0 +1,268 @@ + + + + + + + + pancax.fem.dof_manager — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.dof_manager

+from .function_space import FunctionSpace
+from jaxtyping import Array, Bool, Float, Int
+from pancax.bcs import EssentialBC
+from pancax.timer import Timer
+from typing import List, Tuple
+import jax.numpy as np
+import numpy as onp
+
+# TODO
+# getting some error when making this a child of eqx.Module
+
+[docs] +class DofManager: + """ + Collection of arrays needed to differentiate between + fixed and free dofs for fem like calculations. + + TODO better document the parameters in this guy + """ +
+[docs] + def __init__(self, mesh, dim: int, EssentialBCs: List[EssentialBC]) -> None: + """ + :param functionSpace: ``FunctionSpace`` object + :param dim: The number of dims (really the number of active dofs for the physics) + :param EssentialBCs: A list of of ``EssentialBC`` objects + """ + with Timer('DofManager.__init__'): + self.fieldShape = mesh.num_nodes, dim + self.isBc = onp.full(self.fieldShape, False, dtype=bool) + for ebc in EssentialBCs: + self.isBc[mesh.nodeSets[ebc.nodeSet], ebc.component] = True + + self.isUnknown = ~self.isBc + + self.ids = onp.arange(self.isBc.size).reshape(self.fieldShape) + + self.unknownIndices = self.ids[self.isUnknown] + self.bcIndices = self.ids[self.isBc] + + ones = onp.ones(self.isBc.size, dtype=int) * -1 + # self.dofToUnknown = ones.at[self.unknownIndices].set(np.arange(self.unknownIndices.size)) + self.dofToUnknown = ones + self.dofToUnknown[self.unknownIndices] = onp.arange(self.unknownIndices.size) + + self.HessRowCoords, self.HessColCoords = self._make_hessian_coordinates(onp.array(mesh.conns)) + + self.hessian_bc_mask = self._make_hessian_bc_mask(onp.array(mesh.conns))
+ + +
+[docs] + def get_bc_size(self) -> int: + """ + :return: the number of fixed dofs + """ + return np.sum(self.isBc).item() # item() method casts to Python int
+ + +
+[docs] + def get_unknown_size(self) -> int: + """ + :return: the size of the unkowns vector + """ + return np.sum(self.isUnknown).item() # item() method casts to Python int
+ + +
+[docs] + def create_field(self, Uu, Ubc=0.0) -> Float[Array, "nn nd"]: + """ + :param Uu: Vector of unknown values + :param Ubc: Values for bc to apply + :return: U, a field of unknowns and bcs combined. + """ + U = np.zeros(self.isBc.shape).at[self.isBc].set(Ubc) + return U.at[self.isUnknown].set(Uu)
+ + +
+[docs] + def get_bc_values(self, U) -> Float[Array, "nb"]: + """ + :param U: a nodal field + :return: the bc values in the field U + """ + return U[self.isBc]
+ + +
+[docs] + def get_unknown_values(self, U) -> Float[Array, "nu"]: + """ + :param U: a nodal field + :return: the unknown values in the field U + """ + return U[self.isUnknown]
+ + +
+[docs] + def slice_unknowns_with_dof_indices( + self, Uu: Float[Array, "nu"], dofIndexSlice: Int[Array, "nn"] + ) -> Float[Array, "nu_new"]: + i = self.isUnknown[dofIndexSlice] + j = self.dofToUnknown.reshape(self.fieldShape)[dofIndexSlice] + return Uu[j[i]]
+ + +
+[docs] + def _make_hessian_coordinates(self, conns: Int[Array, "ne nnpe"]) -> Tuple[Int[Array, "nn"], Int[Array, "nn"]]: + nElUnknowns = onp.zeros(conns.shape[0], dtype=int) + nHessianEntries = 0 + for e, eNodes in enumerate(conns): + elUnknownFlags = self.isUnknown[eNodes,:].ravel() + nElUnknowns[e] = onp.sum(elUnknownFlags) + nHessianEntries += onp.square(nElUnknowns[e]) + + rowCoords = onp.zeros(nHessianEntries, dtype=int) + colCoords = rowCoords.copy() + rangeBegin = 0 + for e,eNodes in enumerate(conns): + elDofs = self.ids[eNodes,:] + elUnknownFlags = self.isUnknown[eNodes,:] + elUnknowns = self.dofToUnknown[elDofs[elUnknownFlags]] + elHessCoords = onp.tile(elUnknowns, (nElUnknowns[e],1)) + + rangeEnd = rangeBegin + onp.square(nElUnknowns[e]) + + rowCoords[rangeBegin:rangeEnd] = elHessCoords.ravel() + colCoords[rangeBegin:rangeEnd] = elHessCoords.T.ravel() + + rangeBegin += onp.square(nElUnknowns[e]) + return rowCoords, colCoords
+ + +
+[docs] + def _make_hessian_bc_mask(self, conns: Int[Array, "ne nnpe"]) -> Bool[Array, "ne ndpe ndpe"]: + nElements, nNodesPerElement = conns.shape + nFields = self.ids.shape[1] + nDofPerElement = nNodesPerElement*nFields + + hessian_bc_mask = onp.full((nElements,nDofPerElement,nDofPerElement), + True, dtype=bool) + for e, eNodes in enumerate(conns): + eFlag = self.isBc[eNodes,:].ravel() + hessian_bc_mask[e,eFlag,:] = False + hessian_bc_mask[e,:,eFlag] = False + return hessian_bc_mask
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/base_element.html b/html/_modules/pancax/fem/elements/base_element.html new file mode 100644 index 0000000..e5c1f98 --- /dev/null +++ b/html/_modules/pancax/fem/elements/base_element.html @@ -0,0 +1,302 @@ + + + + + + + + pancax.fem.elements.base_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.base_element

+from abc import abstractmethod
+from jaxtyping import Array, Float, Int
+from scipy import special
+from typing import NamedTuple
+import jax.numpy as jnp
+import numpy as np
+import equinox as eqx
+
+
+
+[docs] +def get_lobatto_nodes_1d(degree): + p = np.polynomial.Legendre.basis(degree, domain=[0.0, 1.0]) + dp = p.deriv() + xInterior = dp.roots() + xn = jnp.hstack((jnp.array([0.0]), xInterior, jnp.array([1.0]))) + return xn
+ + + +
+[docs] +def pascal_triangle_monomials(degree): + p = [] + q = [] + for i in range(1, degree + 2): + monomialIndices = list(range(i)) + p += monomialIndices + monomialIndices.reverse() + q += monomialIndices + return np.column_stack((q,p))
+ + + +
+[docs] +def vander1d(x, degree): + x = np.asarray(x) + A = np.zeros((x.shape[0], degree + 1)) + dA = np.zeros((x.shape[0], degree + 1)) + domain = [0.0, 1.0] + for i in range(degree + 1): + p = np.polynomial.Legendre.basis(i, domain=domain) + p *= np.sqrt(2.0*i + 1.0) # keep polynomial orthonormal + A[:, i] = p(x) + dp = p.deriv() + dA[:, i] = dp(x) + return A, dA
+ + + +
+[docs] +def vander2d(x, degree): + x = np.asarray(x) + nNodes = (degree+1)*(degree+2)//2 + pq = pascal_triangle_monomials(degree) + + # It's easier to process if the input arrays + # always have the same shape + # If a 1D array is given (a single point), + # convert to the equivalent 2D array + x = x.reshape(-1,2) + + # switch to bi-unit triangle (-1,-1)--(1,-1)--(-1,1) + z = 2.0*x - 1.0 + + def map_from_tri_to_square(xi): + small = 1e-12 + # The mapping has a singularity at the vertex (-1, 1). + # Handle that point specially. + indexSingular = xi[:, 1] > 1.0 - small + xiShifted = xi.copy() + xiShifted[indexSingular, 1] = 1.0 - small + eta = np.zeros_like(xi) + eta[:, 0] = 2.0*(1.0 + xiShifted[:, 0])/(1.0 - xiShifted[:, 1]) - 1.0 + eta[:, 1] = xiShifted[:, 1] + eta[indexSingular, 0] = -1.0 + eta[indexSingular, 1] = 1.0 + + # Jacobian of map. + # Actually, deta is just the first row of the Jacobian. + # The second row is trivially [0, 1], so we don't compute it. + # We just use that fact directly in the derivative Vandermonde + # expressions. + deta = np.zeros_like(xi) + deta[:, 0] = 2/(1 - xiShifted[:, 1]) + deta[:, 1] = 2*(1 + xiShifted[:, 0])/(1 - xiShifted[:, 1])**2 + return eta, deta + + E, dE = map_from_tri_to_square(np.asarray(z)) + + A = np.zeros((x.shape[0], nNodes)) + Ax = A.copy() + Ay = A.copy() + N1D = np.polynomial.Polynomial([0.5, -0.5]) + for i in range(nNodes): + p = np.polynomial.Legendre.basis(pq[i, 0]) + + # SciPy's polynomials use the deprecated poly1d type + # of NumPy. To convert to the modern Polynomial type, + # we need to reverse the order of the coefficients. + qPoly1d = special.jacobi(pq[i, 1], 2*pq[i, 0] + 1, 0) + q = np.polynomial.Polynomial(qPoly1d.coef[::-1]) + + for j in range(pq[i, 0]): + q *= N1D + + # orthonormality weight + weight = np.sqrt((2*pq[i,0] + 1) * 2*(pq[i, 0] + pq[i, 1] + 1)) + + A[:, i] = weight*p(E[:, 0])*q(E[:, 1]) + + # derivatives + dp = p.deriv() + dq = q.deriv() + Ax[:, i] = 2*weight*dp(E[:, 0])*q(E[:, 1])*dE[:, 0] + Ay[:, i] = 2*weight*(dp(E[:, 0])*q(E[:, 1])*dE[:, 1] + + p(E[:, 0])*dq(E[:, 1])) + + return A, Ax, Ay
+ + + +# TODO add hessians maybe? +
+[docs] +class ShapeFunctions(NamedTuple): + """ + Shape functions and shape function gradients (in the parametric space). + + :param values: Values of the shape functions at a discrete set of points. + Shape is ``(nPts, nNodes)``, where ``nPts`` is the number of + points at which the shame functinos are evaluated, and ``nNodes`` + is the number of nodes in the element (which is equal to the + number of shape functions). + :param gradients: Values of the parametric gradients of the shape functions. + Shape is ``(nPts, nDim, nNodes)``, where ``nDim`` is the number + of spatial dimensions. Line elements are an exception, which + have shape ``(nPts, nNdodes)``. + """ + values: Float[Array, "np nn"] + gradients: Float[Array, "np nd nn"]
+ + + +
+[docs] +class BaseElement(eqx.Module): + """ + Base class for different element technologies + + :param elementType: Element type name + :param degree: Polynomial degree + :param coordinates: Nodal coordinates in the reference configuration + :param vertexNodes: Vertex node number, 0-based + :param faceNodes: Nodes associated with each face, 0-based + :param interiorNodes: Nodes in the interior, 0-based or empty + """ + elementType: str + degree: int + coordinates: Float[Array, "nn nd"] + vertexNodes: Int[Array, "nn"] + faceNodes: Int[Array, "nf nnpf"] + interiorNodes: Int[Array, "nni"] + + # def __init__(self, elementType, degree, coordinates, vertexNodes, faceNodes, interiorNodes): + # self.elementType = elementType + # self.degree = degree + # self.coordinates = coordinates + # self.vertexNodes = vertexNodes + # self.faceNodes = faceNodes + # self.interiorNodes = interiorNodes + +
+[docs] + @abstractmethod + def compute_shapes(self, nodalPoints, evaluationPoints): + """ + Method to be defined to calculate shape function values + and gradients given a list of nodal points (usually the vertexNodes) + and a list of evaluation points (usually the quadrature points). + """ + pass
+
+ + + # TODO figure out how to rope in quadrature rules into this class +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/hex8_element.html b/html/_modules/pancax/fem/elements/hex8_element.html new file mode 100644 index 0000000..ea7fdd1 --- /dev/null +++ b/html/_modules/pancax/fem/elements/hex8_element.html @@ -0,0 +1,222 @@ + + + + + + + + pancax.fem.elements.hex8_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.hex8_element

+from .base_element import BaseElement, ShapeFunctions
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class Hex8Element(BaseElement): + elementType = "hex8" + degree = 1 + coordinates = jnp.array( + [[-1.0, -1.0, -1.0], + [ 1.0, -1.0, -1.0], + [ 1.0, 1.0, -1.0], + [-1.0, 1.0, -1.0], + [-1.0, -1.0, 1.0], + [ 1.0, -1.0, 1.0], + [ 1.0, 1.0, 1.0], + [-1.0, 1.0, 1.0]] + ) + vertexNodes = jnp.arange(8) + faceNodes = jnp.array( + [[0, 1, 5, 6], + [1, 2, 6, 5], + [2, 3, 7, 6], + [0, 4, 7, 3], + [0, 3, 2, 1], + [4, 5, 6, 7]], + dtype=jnp.int32 + ) + interiorNodes = None + +
+[docs] + def __init__(self): + pass
+ + + # TODO what to do about NodalPoints? +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + def shape_function_values(xi): + N = (1. / 8.) * jnp.array([ + (1. - xi[0]) * (1. - xi[1]) * (1. - xi[2]), + (1. + xi[0]) * (1. - xi[1]) * (1. - xi[2]), + (1. + xi[0]) * (1. + xi[1]) * (1. - xi[2]), + (1. - xi[0]) * (1. + xi[1]) * (1. - xi[2]), + (1. - xi[0]) * (1. - xi[1]) * (1. + xi[2]), + (1. + xi[0]) * (1. - xi[1]) * (1. + xi[2]), + (1. + xi[0]) * (1. + xi[1]) * (1. + xi[2]), + (1. - xi[0]) * (1. + xi[1]) * (1. + xi[2])] + ) + return N + + def shape_function_gradients(xi): + grad_N_xi = (1. / 8.) * jnp.array( + [ + [ + -(1. - xi[1]) * (1. - xi[2]), + -(1. - xi[0]) * (1. - xi[2]), + -(1. - xi[0]) * (1. - xi[1]) + ], + [ + (1. - xi[1]) * (1. - xi[2]), + -(1. + xi[0]) * (1. - xi[2]), + -(1. + xi[0]) * (1. - xi[1]) + ], + [ + (1. + xi[1]) * (1. - xi[2]), + (1. + xi[0]) * (1. - xi[2]), + -(1. + xi[0]) * (1. + xi[1]) + ], + [ + -(1. + xi[1]) * (1. - xi[2]), + (1. - xi[0]) * (1. - xi[2]), + -(1. - xi[0]) * (1. + xi[1]) + ], + # positive z now + [ + -(1. - xi[1]) * (1. + xi[2]), + -(1. - xi[0]) * (1. + xi[2]), + (1. - xi[0]) * (1. - xi[1]) + ], + [ + (1. - xi[1]) * (1. + xi[2]), + -(1. + xi[0]) * (1. + xi[2]), + (1. + xi[0]) * (1. - xi[1]) + ], + [ + (1. + xi[1]) * (1. + xi[2]), + (1. + xi[0]) * (1. + xi[2]), + (1. + xi[0]) * (1. + xi[1]) + ], + [ + -(1. + xi[1]) * (1. + xi[2]), + (1. - xi[0]) * (1. + xi[2]), + (1. - xi[0]) * (1. + xi[1]) + ] + ] + ) + return grad_N_xi + + Ns = jax.vmap(shape_function_values, in_axes=(0,))(evaluationPoints) + dNs = jax.vmap(shape_function_gradients, in_axes=(0,))(evaluationPoints) + return ShapeFunctions(Ns, dNs)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/line_element.html b/html/_modules/pancax/fem/elements/line_element.html new file mode 100644 index 0000000..6255cbb --- /dev/null +++ b/html/_modules/pancax/fem/elements/line_element.html @@ -0,0 +1,150 @@ + + + + + + + + pancax.fem.elements.line_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.line_element

+from .base_element import BaseElement, ShapeFunctions
+from .base_element import get_lobatto_nodes_1d, vander1d
+from jaxtyping import Array, Float
+import jax.numpy as jnp
+import numpy as np
+
+
+
+[docs] +class LineElement(BaseElement): + elementType = "line" + degree: int + coordinates: Float[Array, "nn nd"] + vertexNodes: any + faceNodes = None + interiorNodes: any + +
+[docs] + def __init__(self, degree): + self.degree = degree + self.coordinates = get_lobatto_nodes_1d(degree) + self.vertexNodes = jnp.array([0, degree], dtype=jnp.int32) + self.interiorNodes = jnp.arange(1, degree, dtype=jnp.int32)
+ + +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + A,_ = vander1d(nodalPoints, self.degree) + nf, nfx = vander1d(evaluationPoints, self.degree) + shape = np.linalg.solve(A.T, nf.T) + dshape = np.linalg.solve(A.T, nfx.T) + return ShapeFunctions(jnp.array(shape), jnp.array(dshape))
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/quad4_element.html b/html/_modules/pancax/fem/elements/quad4_element.html new file mode 100644 index 0000000..530a98d --- /dev/null +++ b/html/_modules/pancax/fem/elements/quad4_element.html @@ -0,0 +1,173 @@ + + + + + + + + pancax.fem.elements.quad4_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.quad4_element

+from .base_element import BaseElement, ShapeFunctions
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class Quad4Element(BaseElement): + elementType = "quad4" + degree = 1 + coordinates = jnp.array( + [[-1.0, -1.0], + [ 1.0, -1.0], + [ 1.0, 1.0], + [-1.0, 1.0]] + ) + vertexNodes = jnp.arange(3) + faceNodes = jnp.array( + [[0, 1], + [1, 2], + [2, 3], + [3, 0]], + dtype=jnp.int32 + ) + interiorNodes = None + +
+[docs] + def __init__(self): + pass
+ + + # TODO what to do about NodalPoints? +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + def shape_function_values(xi): + N = (1. / 4.) * jnp.array([ + (1. - xi[0]) * (1. - xi[1]), + (1. + xi[0]) * (1. - xi[1]), + (1. + xi[0]) * (1. + xi[1]), + (1. - xi[0]) * (1. + xi[1])] + ) + return N + + def shape_function_gradients(xi): + grad_N_xi = (1. / 4.) * jnp.array( + [[-(1. - xi[1]), -(1. - xi[0])], + [(1. - xi[1]), -(1. + xi[0])], + [(1. + xi[1]), (1. + xi[0])], + [-(1. + xi[1]), (1. - xi[0])]] + ) + return grad_N_xi + + Ns = jax.vmap(shape_function_values, in_axes=(0,))(evaluationPoints) + dNs = jax.vmap(shape_function_gradients, in_axes=(0,))(evaluationPoints) + return ShapeFunctions(Ns, dNs)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/quad9_element.html b/html/_modules/pancax/fem/elements/quad9_element.html new file mode 100644 index 0000000..3c54fbe --- /dev/null +++ b/html/_modules/pancax/fem/elements/quad9_element.html @@ -0,0 +1,194 @@ + + + + + + + + pancax.fem.elements.quad9_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.quad9_element

+from .base_element import BaseElement, ShapeFunctions
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class Quad9Element(BaseElement): + elementType = "quad9" + degree = 2 + coordinates = jnp.array( + [[-1.0, -1.0], + [ 1.0, -1.0], + [ 1.0, 1.0], + [-1.0, 1.0], + [ 0.0, -1.0], + [ 1.0, 0.0], + [ 0.0, 1.0], + [-1.0, 0.0], + [ 0.0, 0.0]] + + ) + vertexNodes = jnp.arange(8) + faceNodes = jnp.array( + [[0, 4, 1], + [1, 5, 2], + [2, 6, 3], + [3, 7, 0]], + dtype=jnp.int32 + ) + interiorNodes = jnp.array([8], dtype=jnp.int32) + +
+[docs] + def __init__(self): + pass
+ + + # TODO what to do about NodalPoints? +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + def shape_function_values(xi_points): + xi, eta = xi_points[0], xi_points[1] + xi_sq, eta_sq = jnp.power(xi_points[0], 2), jnp.power(xi_points[1], 2) + + N = jnp.array([ + 0.25 * (xi_sq - xi) * (eta_sq - eta), + 0.25 * (xi_sq + xi) * (eta_sq - eta), + 0.25 * (xi_sq + xi) * (eta_sq + eta), + 0.25 * (xi_sq - xi) * (eta_sq + eta), + 0.5 * (eta_sq - eta) * (1. - xi_sq), + 0.5 * (xi_sq + xi) * (1. - eta_sq), + 0.5 * (eta_sq + eta) * (1. - xi_sq), + 0.5 * (xi_sq - xi) * (1. - eta_sq), + (1. - xi_sq) * (1. - eta_sq) + ]) + return N + + + def shape_function_gradients(xi_points): + xi, eta = xi_points[0], xi_points[1] + xi_sq, eta_sq = jnp.power(xi_points[0], 2), jnp.power(xi_points[1], 2) + grad_N_xi = jnp.array([[0.25 * (2. * xi - 1.) * (eta_sq - eta), 0.25 * (xi_sq - xi) * (2. * eta - 1.)], + [0.25 * (2. * xi + 1.) * (eta_sq - eta), 0.25 * (xi_sq + xi) * (2. * eta - 1.)], + [0.25 * (2. * xi + 1.) * (eta_sq + eta), 0.25 * (xi_sq + xi) * (2. * eta + 1.)], + [0.25 * (2. * xi - 1.) * (eta_sq + eta), 0.25 * (xi_sq - xi) * (2. * eta + 1.)], + [0.5 * (eta_sq - eta) * (-2. * xi), 0.5 * (2. * eta - 1.) * (1. - xi_sq)], + [0.5 * (2. * xi + 1.) * (1. - eta_sq), 0.5 * (xi_sq + xi) * (-2. * eta)], + [0.5 * (eta_sq + eta) * (-2. * xi), 0.5 * (2. * eta + 1.) * (1. - xi_sq)], + [0.5 * (2. * xi - 1.) * (1. - eta_sq), 0.5 * (xi_sq - xi) * (-2. * eta)], + [-2. * xi * (1. - eta_sq), -2. * eta * (1. - xi_sq)]]) + return grad_N_xi + + + Ns = jax.vmap(shape_function_values, in_axes=(0,))(evaluationPoints) + dNs = jax.vmap(shape_function_gradients, in_axes=(0,))(evaluationPoints) + return ShapeFunctions(Ns, dNs)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/simplex_tri_element.html b/html/_modules/pancax/fem/elements/simplex_tri_element.html new file mode 100644 index 0000000..ee765b1 --- /dev/null +++ b/html/_modules/pancax/fem/elements/simplex_tri_element.html @@ -0,0 +1,171 @@ + + + + + + + + pancax.fem.elements.simplex_tri_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.simplex_tri_element

+from .base_element import BaseElement, ShapeFunctions
+from .base_element import get_lobatto_nodes_1d, vander2d
+from jaxtyping import Array, Float
+import jax.numpy as jnp
+import numpy as np
+
+
+
+[docs] +class SimplexTriElement(BaseElement): + elementType = "simplex tri" + degree: int + coordinates: Float[Array, "nn nd"] + vertexNodes: any + faceNodes: any + interiorNodes: any + +
+[docs] + def __init__(self, degree): + self.degree = degree + + lobattoPoints = get_lobatto_nodes_1d(degree) + nPoints = int((degree + 1)*(degree + 2)/2) + points = np.zeros((nPoints, 2)) + point = 0 + for i in range(degree): + for j in range(degree + 1 - i): + k = degree - i - j + points[point, 0] = (1.0 + 2.0*lobattoPoints[k] - lobattoPoints[j] - lobattoPoints[i])/3.0 + points[point, 1] = (1.0 + 2.0*lobattoPoints[j] - lobattoPoints[i] - lobattoPoints[k])/3.0 + point += 1 + self.coordinates = jnp.asarray(points) + + self.vertexNodes = jnp.array([0, degree, nPoints - 1], dtype=jnp.int32) + + ii = np.arange(degree + 1) + jj = np.cumsum(np.flip(ii)) + ii + kk = np.flip(jj) - ii + self.faceNodes = jnp.array((ii,jj,kk), dtype=jnp.int32) + + interiorNodes = [i for i in range(nPoints) if i not in self.faceNodes.ravel()] + self.interiorNodes = np.array(interiorNodes, dtype=np.int32)
+ + +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + A, _, _ = vander2d(nodalPoints, self.degree) + nf, nfx, nfy = vander2d(evaluationPoints, self.degree) + shapes = np.linalg.solve(A.T, nf.T).T + dshapes = np.zeros(shapes.shape + (2,)) # shape is (nQuadPoints, nNodes, 2) + dshapes[:, :, 0] = np.linalg.solve(A.T, nfx.T).T + dshapes[:, :, 1] = np.linalg.solve(A.T, nfy.T).T + return ShapeFunctions(jnp.asarray(shapes), jnp.asarray(dshapes))
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/tet10_element.html b/html/_modules/pancax/fem/elements/tet10_element.html new file mode 100644 index 0000000..a4c573e --- /dev/null +++ b/html/_modules/pancax/fem/elements/tet10_element.html @@ -0,0 +1,197 @@ + + + + + + + + pancax.fem.elements.tet10_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.tet10_element

+from .base_element import BaseElement, ShapeFunctions
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class Tet10Element(BaseElement): + elementType = "tet10" + degree = 2 + coordinates = jnp.array([ + [0., 0., 0.], + [1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.], + [0.5, 0., 0.], + [0.5, 0.5, 0.], + [0., 0.5, 0.], + [0., 0., 0.5], + [0.5, 0., 0.5], + [0., 0.5, 0.5] + ]) + vertexNodes = jnp.arange(10) + faceNodes = jnp.array([ + [0, 4, 1, 8, 3, 7], + [1, 5, 2, 9, 3, 7], + [0, 7, 3, 9, 2, 6], + [0, 6, 2, 5, 1, 4] + ]) + interiorNodes = None + +
+[docs] + def __init__(self): + pass
+ + +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + def shape_function_values(xi): + t0 = 1 - xi[0] - xi[1] - xi[2] + t1 = xi[0] + t2 = xi[1] + t3 = xi[2] + N = jnp.array([ + t0 * (2 * t0 - 1), + t1 * (2 * t1 - 1), + t2 * (2 * t2 - 1), + t3 * (2 * t3 - 1), + 4 * t0 * t1, + 4 * t1 * t2, + 4 * t2 * t0, + 4 * t0 * t3, + 4 * t1 * t3, + 4 * t2 * t3 + ]) + return N + + def shape_function_gradients(xi): + t0 = 1 - xi[0] - xi[1] - xi[2] + t1 = xi[0] + t2 = xi[1] + t3 = xi[2] + grad_N_xi = jnp.array([ + [1 - 4 * t0, 1 - 4 * t0, 1 - 4 * t0], + [4 * t1 - 1, 0, 0], + [0, 4 * t2 - 1, 0], + [0, 0, 4 * t3 - 1], + [4 * (t0-t1), -4 * t1, -4 * t1], + [4 * t2, 4 * t1, 0], + [-4 * t2, 4 * (t0 - t2), -4 * t2], + [-4 * t3, -4 * t3, 4 * (t0 - t3)], + [4 * t3, 0, 4 * t1], + [0, 4 * t3, 4 * t2] + ]) + return grad_N_xi + + Ns = jax.vmap(shape_function_values, in_axes=(0,))(evaluationPoints) + dNs = jax.vmap(shape_function_gradients, in_axes=(0,))(evaluationPoints) + return ShapeFunctions(Ns, dNs)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/elements/tet4_element.html b/html/_modules/pancax/fem/elements/tet4_element.html new file mode 100644 index 0000000..37a3080 --- /dev/null +++ b/html/_modules/pancax/fem/elements/tet4_element.html @@ -0,0 +1,171 @@ + + + + + + + + pancax.fem.elements.tet4_element — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.elements.tet4_element

+from .base_element import BaseElement, ShapeFunctions
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class Tet4Element(BaseElement): + elementType = "tet4" + degree = 1 + coordinates = jnp.array([ + [0., 0., 0.], + [1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.] + ]) + vertexNodes = jnp.arange(4) + faceNodes = jnp.array([ + [0, 1, 3], + [1, 2, 3], + [0, 3, 2], + [0, 2, 1] + ]) + interiorNodes = None + +
+[docs] + def __init__(self): + pass
+ + +
+[docs] + def compute_shapes(self, nodalPoints, evaluationPoints): + def shape_function_values(xi): + N = jnp.array([ + 1. - xi[0] - xi[1] - xi[2], + xi[0], + xi[1], + xi[2] + ]) + return N + + def shape_function_gradients(xi): + grad_N_xi = jnp.array([ + [-1., -1., -1.], + [1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.] + ]) + return grad_N_xi + + Ns = jax.vmap(shape_function_values, in_axes=(0,))(evaluationPoints) + dNs = jax.vmap(shape_function_gradients, in_axes=(0,))(evaluationPoints) + return ShapeFunctions(Ns, dNs)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/function_space.html b/html/_modules/pancax/fem/function_space.html new file mode 100644 index 0000000..a735180 --- /dev/null +++ b/html/_modules/pancax/fem/function_space.html @@ -0,0 +1,611 @@ + + + + + + + + pancax.fem.function_space — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.function_space

+from jaxtyping import Array, Float, Int
+from .mesh import Mesh
+from pancax.fem.quadrature_rules import QuadratureRule
+from pancax.fem.elements.base_element import ShapeFunctions
+from pancax.timer import Timer
+import equinox as eqx
+import jax
+import jax.numpy as np
+
+
+# TODO need to do checks on inputs to make sure they're compatable
+
+[docs] +class NonAllocatedFunctionSpace(eqx.Module): + quadrature_rule: QuadratureRule + shape_functions: ShapeFunctions + +
+[docs] + def __init__(self, mesh: Mesh, q_rule: QuadratureRule) -> None: + with Timer("NonAllocatedFunctionSpace.__init__"): + self.quadrature_rule = q_rule + self.shape_functions = mesh.parentElement.compute_shapes( + mesh.parentElement.coordinates, q_rule.xigauss + )
+ + +
+[docs] + def compute_field_gradient(self, u, X): + """ + Takes in element level coordinates X and field u + """ + grad_Ns = self.shape_function_gradients(X) + return jax.vmap(lambda u, grad_N: u.T @ grad_N, in_axes=(None, 0))(u, grad_Ns)
+ + +
+[docs] + def evaluate_on_element(self, U, X, state, dt, props, func): + """ + Takes in element level field, coordinates, states, etc. + and evaluates the function func + """ + Ns = self.shape_function_values(X) + grad_Ns = self.shape_function_gradients(X) + + u_qs = jax.vmap(lambda u, N: u.T @ N, in_axes=(None, 0))(U, Ns) + grad_u_qs = jax.vmap(lambda u, grad_N: u.T @ grad_N, in_axes=(None, 0))(U, grad_Ns) + X_qs = jax.vmap(lambda X, N: X.T @ N, in_axes=(None, 0))(X, Ns) + func_vals = jax.vmap(func, in_axes=(0, 0, 0, None, 0, None))( + u_qs, grad_u_qs, state, props, X_qs, dt + ) + return func_vals
+ + +
+[docs] + def integrate_on_element(self, U, X, state, dt, props, func): + func_vals = self.evaluate_on_element(U, X, state, dt, props, func) + JxWs = self.JxWs(X) + return np.dot(JxWs, func_vals)
+ + +
+[docs] + def integrate_on_elements(self, U, X, state, dt, props, func): + el_vals = jax.vmap(self.integrate_on_element, in_axes=(0, 0, 0, None, None, None))( + U, X, state, dt, props, func + ) + return np.sum(el_vals)
+ + +
+[docs] + def JxWs(self, X: Float[Array, "nn nd"]) -> Float[Array, "nq"]: + Js = jax.vmap(lambda x, dN: (x.T @ dN).T, in_axes=(None, 0))(X, self.shape_functions.gradients) + return jax.vmap(lambda J, w: np.linalg.det(J) * w, in_axes=(0, 0))(Js, self.quadrature_rule.wgauss)
+ + +
+[docs] + def shape_function_values(self, X: Float[Array, "nn nd"]) -> Float[Array, "nq nnpe"]: + return self.shape_functions.values
+ + +
+[docs] + def shape_function_gradients(self, X: Float[Array, "nn nd"]) -> Float[Array, "nq nnpe nd"]: + Js = jax.vmap(lambda x, dN: (x.T @ dN).T, in_axes=(None, 0))(X, self.shape_functions.gradients) + Jinvs = jax.vmap(lambda J: np.linalg.inv(J), in_axes=(0,))(Js) + return jax.vmap(lambda Jinv, dN: (Jinv @ dN.T).T, in_axes=(0, 0))(Jinvs, self.shape_functions.gradients)
+
+ + + +
+[docs] +class FunctionSpace(eqx.Module): + """ + Data needed for calculus on functions in the discrete function space. + + In describing the shape of the attributes, ``ne`` is the number of + elements in the mesh, ``nqpe`` is the number of quadrature points per + element, ``npe`` is the number of nodes per element, and ``nd`` is the + spatial dimension of the domain. + + :param shapes: Shape function values on each element, shape (ne, nqpe, npe) + :param vols: Volume attributed to each quadrature point. That is, the + quadrature weight (on the parameteric element domain) multiplied by + the Jacobian determinant of the map from the parent element to the + element in the domain. Shape (ne, nqpe). + :param shapeGrads: Derivatives of the shape functions with respect to the + spatial coordinates of the domain. Shape (ne, nqpe, npe, nd). + :param mesh: The ``Mesh`` object of the domain. + :param quadratureRule: The ``QuadratureRule`` on which to sample the shape + functions. + :param isAxisymmetric: boolean indicating if the function space data are + axisymmetric. + """ + shapes: Float[Array, "ne nqpe npe"] + vols: Float[Array, "ne nqpe"] + shapeGrads: Float[Array, "ne nqpe npe nd"] + # mesh: any + conns: Int[Array, "ne nnpe"] + quadratureRule: QuadratureRule + isAxisymmetric: bool
+ + + +
+[docs] +def construct_function_space(mesh, quadratureRule, mode2D='cartesian'): + """Construct a discrete function space. + + Parameters + ---------- + :param mesh: The mesh of the domain. + :param quadratureRule: The quadrature rule to be used for integrating on the + domain. + :param mode2D: A string indicating how the 2D domain is interpreted for + integration. Valid values are ``cartesian`` and ``axisymmetric``. + Axisymetric mode will include the factor of 2*pi*r in the ``vols`` + attribute. + + Returns + ------- + The ``FunctionSpace`` object. + """ + with Timer('construct_function_space'): + # shapeOnRef = interpolants.compute_shapes(mesh.parentElement, quadratureRule.xigauss) + shapeOnRef = mesh.parentElement.compute_shapes(mesh.parentElement.coordinates, quadratureRule.xigauss) + return construct_function_space_from_parent_element(mesh, shapeOnRef, quadratureRule, mode2D)
+ + + +
+[docs] +def construct_function_space_from_parent_element(mesh, shapeOnRef, quadratureRule, mode2D='cartesian'): + """ + Construct a function space with precomputed shape function data on the parent element. + + This version of the function space constructor is Jax-transformable, + and in particular can be jitted. The computation of the shape function + values and derivatives on the parent element is not transformable in + general. However, the mapping of the shape function data to the elements in + the mesh is transformable. One can precompute the parent element shape + functions once and for all, and then use this special factory function to + construct the function space and avoid the non-transformable part of the + operation. The primary use case is for shape sensitivities: the coordinates + of the mesh change, and we want Jax to pick up the sensitivities of the + shape function derivatives in space to the coordinate changes + (which occurs through the mapping from the parent element to the spatial + domain). + + Parameters + ---------- + :param mesh: The mesh of the domain. + :param shapeOnRef: A tuple of the shape function values and gradients on the + parent element, evaluated at the quadrature points. The caller must + take care to ensure the shape functions are evaluated at the same + points as contained in the ``quadratureRule`` parameter. + :param quadratureRule: The quadrature rule to be used for integrating on the + domain. + :param mode2D: A string indicating how the 2D domain is interpreted for + integration. See the default factory function for details. + + Returns + ------- + The ``FunctionSpace`` object. + """ + + shapes = jax.vmap(lambda elConns, elShape: elShape, (0, None))(mesh.conns, shapeOnRef.values) + + shapeGrads = jax.vmap(map_element_shape_grads, (None, 0, None, None))( + mesh.coords, mesh.conns, mesh.parentElement, shapeOnRef.gradients + ) + + if mode2D == 'cartesian': + el_vols = compute_element_volumes + isAxisymmetric = False + elif mode2D == 'axisymmetric': + el_vols = compute_element_volumes_axisymmetric + isAxisymmetric = True + vols = jax.vmap(el_vols, (None, 0, None, None, None, None))( + mesh.coords, mesh.conns, mesh.parentElement, shapeOnRef.values, shapeOnRef.gradients, quadratureRule.wgauss + ) + + # return FunctionSpace(shapes, vols, shapeGrads, mesh, quadratureRule, isAxisymmetric) + return FunctionSpace(shapes, vols, shapeGrads, mesh.conns, quadratureRule, isAxisymmetric)
+ + + +
+[docs] +def map_element_shape_grads(coordField, nodeOrdinals, parentElement, shapeGradients): + # coords here should be 3 x 2 + # shapegrads shoudl be 3 x 2 + # need J to be 2 x 2 but be careful about transpose + # below from Cthonios + # J = (X_el * ∇N_ξ)' + # J_inv = inv(J) + # ∇N_X = (J_inv * ∇N_ξ')' + Xn = coordField.take(nodeOrdinals,0) + Js = jax.vmap(lambda x, dN: (x.T @ dN).T, in_axes=(None, 0))(Xn, shapeGradients) + Jinvs = jax.vmap(lambda J: np.linalg.inv(J), in_axes=(0,))(Js) + return jax.vmap(lambda Jinv, dN: (Jinv @ dN.T).T, in_axes=(0, 0))(Jinvs, shapeGradients)
+ + + +
+[docs] +def compute_element_volumes(coordField, nodeOrdinals, parentElement, shapes, shapeGradients, weights): + Xn = coordField.take(nodeOrdinals,0) + Js = jax.vmap(lambda x, dN: (x.T @ dN).T, in_axes=(None, 0))(Xn, shapeGradients) + return jax.vmap(lambda J, w: np.linalg.det(J) * w, in_axes=(0, 0))(Js, weights)
+ + + +# TODO make this work for arbitrary elements +# currently not used for any PINN stuff +
+[docs] +def compute_element_volumes_axisymmetric(coordField, nodeOrdinals, parentElement, shapes, shapeGradients, weights): + vols = compute_element_volumes(coordField, nodeOrdinals, parentElement, shapes, weights) + Xn = coordField.take(nodeOrdinals,0) + Rs = shapes@Xn[:,0] + return 2*np.pi*Rs*vols
+ + + +
+[docs] +def default_modify_element_gradient(elemGrads, elemShapes, elemVols, elemNodalDisps, elemNodalCoords): + return elemGrads
+ + + +
+[docs] +def compute_field_gradient(functionSpace, nodalField, nodalCoords, modify_element_gradient=default_modify_element_gradient): + return jax.vmap(compute_element_field_gradient, (None,None,0,0,0,0,None))(nodalField, nodalCoords, functionSpace.shapes, functionSpace.shapeGrads, functionSpace.vols, functionSpace.conns, modify_element_gradient)
+ + + +
+[docs] +def interpolate_to_points(functionSpace, nodalField): + # return jax.vmap(interpolate_to_element_points, (None, 0, 0))(nodalField, functionSpace.shapes, functionSpace.mesh.conns) + return jax.vmap(interpolate_to_element_points, (None, 0, 0))(nodalField, functionSpace.shapes, functionSpace.conns)
+ + + + +
+[docs] +def integrate_over_block(functionSpace, U, X, stateVars, props, dt, func, block, + *params, modify_element_gradient=default_modify_element_gradient): + """ + Integrates a density function over a block of the mesh. + + :param functionSpace: Function space object to do the integration with. + :param U: The vector of dofs for the primal field in the functional. + :param X: Nodal coordinates + :param stateVars: Internal state variable array. + :param dt: Current time increment + :param func: Lagrangian density function to integrate, Must have the signature + ``func(u, dudx, q, x, *params) -> scalar``, where ``u`` is the primal field, ``q`` is the + value of the internal variables, ``x`` is the current point coordinates, and ``*params`` is + a variadic set of additional parameters, which correspond to the ``*params`` argument. + block: Group of elements to integrate over. This is an array of element indices. For + performance, the elements within the block should be numbered consecutively. + :param modify_element_gradient: Optional function that modifies the gradient at the element level. + This can be to set the particular 2D mode, and additionally to enforce volume averaging + on the gradient operator. This is a keyword-only argument. + + Returns + A scalar value for the integral of the density functional ``func`` integrated over the + block of elements. + """ + # below breaks the sphinx doc stuff + # :param *params: Optional parameter fields to pass into Lagrangian density function. These are + + + vals = evaluate_on_block(functionSpace, U, X, stateVars, props, dt, func, block, *params, modify_element_gradient=modify_element_gradient) + return np.dot(vals.ravel(), functionSpace.vols[block].ravel())
+ + + +# def evaluate_on_block(functionSpace, U, stateVars, dt, props, func, block, +# *params, modify_element_gradient=default_modify_element_gradient): +
+[docs] +def evaluate_on_block(functionSpace, U, X, stateVars, dt, props, func, block, + *params, modify_element_gradient=default_modify_element_gradient): + """Evaluates a density function at every quadrature point in a block of the mesh. + + :param functionSpace: Function space object to do the evaluation with. + :param U: The vector of dofs for the primal field in the functional. + :param X: Nodal coordinates + :param stateVars: Internal state variable array. + :param dt: Current time increment + :param func: Lagrangian density function to evaluate, Must have the signature + ```func(u, dudx, q, x, *params) -> scalar```, where ```u``` is the primal field, ```q``` is the + value of the internal variables, ```x``` is the current point coordinates, and ```*params``` is + a variadic set of additional parameters, which correspond to the ```*params``` argument. + :param block: Group of elements to evaluate over. This is an array of element indices. For + performance, the elements within the block should be numbered consecutively. + + :param modify_element_gradient: Optional function that modifies the gradient at the element level. + This can be to set the particular 2D mode, and additionally to enforce volume averaging + on the gradient operator. This is a keyword-only argument. + + Returns + An array of shape (numElements, numQuadPtsPerElement) that contains the scalar values of the + density functional ```func``` at every quadrature point in the block. + """ + # below breaks sphinx doc stuff + # :param *params: Optional parameter fields to pass into Lagrangian density function. These are + # represented as a single value per element. + fs = functionSpace + compute_elem_values = jax.vmap(evaluate_on_element, (None, None, 0, None, None, 0, 0, 0, 0, None, None, *tuple(0 for p in params))) + + blockValues = compute_elem_values(U, X, stateVars[block], props, dt, fs.shapes[block], + fs.shapeGrads[block], fs.vols[block], + fs.conns[block], func, modify_element_gradient, *params) + return blockValues
+ + + +
+[docs] +def integrate_element_from_local_field(elemNodalField, elemNodalCoords, elemStates, dt, elemShapes, elemShapeGrads, elemVols, func, modify_element_gradient=default_modify_element_gradient): + """ + Integrate over element with element nodal field as input. + This allows element residuals and element stiffness matrices to computed. + """ + elemVals = jax.vmap(interpolate_to_point, (None,0))(elemNodalField, elemShapes) + elemGrads = jax.vmap(compute_quadrature_point_field_gradient, (None,0))(elemNodalField, elemShapeGrads) + elemGrads = modify_element_gradient(elemGrads, elemShapes, elemVols, elemNodalField, elemNodalCoords) + elemPoints = jax.vmap(interpolate_to_point, (None,0))(elemNodalCoords, elemShapes) + fVals = jax.vmap(func, (0, 0, 0, 0, None))(elemVals, elemGrads, elemStates, elemPoints, dt) + return np.dot(fVals, elemVols)
+ + + +
+[docs] +def compute_element_field_gradient(U, coords, elemShapes, elemShapeGrads, elemVols, elemConnectivity, modify_element_gradient): + elemNodalDisps = U[elemConnectivity] + elemGrads = jax.vmap(compute_quadrature_point_field_gradient, (None, 0))(elemNodalDisps, elemShapeGrads) + elemNodalCoords = coords[elemConnectivity] + elemGrads = modify_element_gradient(elemGrads, elemShapes, elemVols, elemNodalDisps, elemNodalCoords) + return elemGrads
+ + + +
+[docs] +def compute_quadrature_point_field_gradient(u, shapeGrad): + dg = np.tensordot(u, shapeGrad, axes=[0,0]) + return dg
+ + + +
+[docs] +def interpolate_to_point(elementNodalValues, shape): + return np.dot(shape, elementNodalValues)
+ + + +
+[docs] +def interpolate_to_element_points(U, elemShapes, elemConnectivity): + elemU = U[elemConnectivity] + return jax.vmap(interpolate_to_point, (None, 0))(elemU, elemShapes)
+ + + +
+[docs] +def integrate_element(U, coords, elemStates, elemShapes, elemShapeGrads, elemVols, elemConn, func, modify_element_gradient): + elemVals = interpolate_to_element_points(U, elemShapes, elemConn) + elemGrads = compute_element_field_gradient(U, coords, elemShapes, elemShapeGrads, elemVols, elemConn, modify_element_gradient) + elemXs = interpolate_to_element_points(coords, elemShapes, elemConn) + fVals = jax.vmap(func)(elemVals, elemGrads, elemStates, elemXs) + return np.dot(fVals, elemVols)
+ + + +
+[docs] +def evaluate_on_element(U, coords, elemStates, props, dt, elemShapes, elemShapeGrads, elemVols, elemConn, kernelFunc, modify_element_gradient, *params): + elemVals = interpolate_to_element_points(U, elemShapes, elemConn) + elemGrads = compute_element_field_gradient(U, coords, elemShapes, elemShapeGrads, elemVols, elemConn, modify_element_gradient) + elemXs = interpolate_to_element_points(coords, elemShapes, elemConn) + vmapArgs = 0, 0, 0, None, 0, None, *tuple(None for p in params) + fVals = jax.vmap(kernelFunc, vmapArgs)(elemVals, elemGrads, elemStates, props, elemXs, dt, *params) + return fVals
+ + + +
+[docs] +def project_quadrature_field_to_element_field(functionSpace, quadField): + return jax.vmap(average_quadrature_field_over_element)(quadField, functionSpace.vols)
+ + + +
+[docs] +def average_quadrature_field_over_element(elemQPData, vols): + S = np.tensordot(vols, elemQPData, axes=[0,0]) + elVol = np.sum(vols) + return S/elVol
+ + + +
+[docs] +def get_nodal_values_on_edge(functionSpace, nodalField, edge): + """ + Get nodal values of a field on an element edge. + + :param functionSpace: a FunctionSpace object + :param nodalField: The nodal vector defined over the mesh (shape is number of + nodes by number of field components) + :param edge: tuple containing the element number containing the edge and the + permutation (0, 1, or 2) of the edge within the triangle + """ + edgeNodes = functionSpace.mesh.parentElement.faceNodes[edge[1], :] + nodes = functionSpace.mesh.conns[edge[0], edgeNodes] + return nodalField[nodes]
+ + + +
+[docs] +def interpolate_nodal_field_on_edge(functionSpace, U, interpolationPoints, edge): + """ + Interpolate a nodal field to specified points on an element edge. + + :param functionSpace: a FunctionSpace object + :param U: the nodal values array + :param interpolationPoints: coordinates of points (in the 1D parametric space) to + interpolate to + :param edge: tuple containing the element number containing the edge and the + permutation (0, 1, or 2) of the edge within the triangle + """ + # edgeShapes = interpolants.compute_shapes(functionSpace.mesh.parentElement1d, interpolationPoints) + edgeShapes = functionSpace.mesh.parentElement1d.compute_shapes( + functionSpace.mesh.parentElement1d.coordinates, interpolationPoints + ) + edgeU = get_nodal_values_on_edge(functionSpace, U, edge) + return edgeShapes.values.T@edgeU
+ + + +
+[docs] +def integrate_function_on_edge(functionSpace, func, U, quadRule, edge): + uq = interpolate_nodal_field_on_edge(functionSpace, U, quadRule.xigauss, edge) + Xq = interpolate_nodal_field_on_edge(functionSpace, functionSpace.mesh.coords, quadRule.xigauss, edge) + edgeCoords = Mesh.get_edge_coords(functionSpace.mesh, edge) + _, normal, jac = Mesh.compute_edge_vectors(functionSpace.mesh, edgeCoords) + integrand = jax.vmap(func, (0, 0, None))(uq, Xq, normal) + return np.dot(integrand, jac*quadRule.wgauss)
+ + + +
+[docs] +def integrate_function_on_edges(functionSpace, func, U, quadRule, edges): + integrate_on_edges = jax.vmap(integrate_function_on_edge, (None, None, None, None, 0)) + return np.sum(integrate_on_edges(functionSpace, func, U, quadRule, edges))
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/mesh.html b/html/_modules/pancax/fem/mesh.html new file mode 100644 index 0000000..e8da231 --- /dev/null +++ b/html/_modules/pancax/fem/mesh.html @@ -0,0 +1,567 @@ + + + + + + + + pancax.fem.mesh — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.mesh

+from jax import vmap
+from jaxtyping import Array, Float
+from pancax.fem.elements import LineElement, SimplexTriElement
+from typing import Dict, List, Optional
+import equinox as eqx
+import jax.numpy as np
+import numpy as onp
+
+
+
+[docs] +class Mesh(eqx.Module): + """ + Triangle mesh representing a domain. + + :param coords: Coordinates of the nodes, shape ``(nNodes, nDim)``. + :param conns: Nodal connectivity table of the elements. + :param simplexNodesOrdinals: Indices of the nodes that are vertices. + :param parentElement: A ``ParentElement`` that is the element type in + parametric space. A mesh can contain only 1 element type. + :param parentElement1d: + :param blocks: A dictionary mapping element block names to the indices of the + elements in the block. + :param nodeSets: A dictionary mapping node set names to the indices of the + nodes. + :param sideSets: A dictionary mapping side set names to the edges. The + edge data structure is a tuple of the element index and the local + number of the edge within that element. For example, triangle + elements will have edge 0, 1, or 2 for this entry. + """ + coords: Float[Array, "nn nd"] + conns: Float[Array, "ne nnpe"] + simplexNodesOrdinals: Float[Array, "ne 3"] + # TODO finish out the typing below + parentElement: any + parentElement1d: any + blocks: Optional[Dict[str, Float]] = None + nodeSets: Optional[Dict[str, Float]] = None + sideSets: Optional[Dict[str, Float]] = None + +
+[docs] + def get_blocks(self, blockNames: List[str]): + return tuple(self.blocks[name] for name in blockNames)
+ + + @property + def num_dimensions(self) -> int: + """ + :return: dimension number of mesh + """ + return self.coords.shape[1] + + @property + def num_elements(self) -> int: + """ + :return: number of elements in mesh + """ + return self.conns.shape[0] + + @property + def num_nodes(self) -> int: + """ + number of nodes in mesh + """ + return self.coords.shape[0]
+ + + +
+[docs] +def create_structured_mesh_data(Nx, Ny, xExtent, yExtent): + xs = np.linspace(xExtent[0], xExtent[1], Nx) + ys = np.linspace(yExtent[0], yExtent[1], Ny) + + Ex = Nx-1 + Ey = Ny-1 + + coords = [ [xs[nx], ys[ny]] for ny in range(Ny) for nx in range(Nx) ] + + conns = [] + for ex in range(Ex): + for ey in range(Ey): + conns.append([ex + Nx*ey, ex+1 + Nx*ey, ex+1 + Nx*(ey+1)]) + conns.append([ex + Nx*ey, ex+1 + Nx*(ey+1), ex + Nx*(ey+1)]) + + coords = np.array(coords) + conns = np.array(conns) + return (coords, conns)
+ + + +
+[docs] +def construct_mesh_from_basic_data(coords, conns, blocks, nodeSets=None, sideSets=None): + # element, element1d = interpolants.make_parent_elements(degree=1) + print('Warning: This only works for tri meshes currently') + element = SimplexTriElement(degree=1) + element1d = LineElement(degree=1) + vertexNodes = np.arange(coords.shape[0]) + return Mesh(coords, conns, vertexNodes, + element, element1d, blocks, nodeSets, sideSets)
+ + + +
+[docs] +def construct_structured_mesh(Nx, Ny, xExtent, yExtent, elementOrder=1, useBubbleElement=False): + coords, conns = create_structured_mesh_data(Nx, Ny, xExtent, yExtent) + blocks = {'block_0': np.arange(conns.shape[0])} + mesh = construct_mesh_from_basic_data(coords, conns, blocks) + if elementOrder > 1: + mesh = create_higher_order_mesh_from_simplex_mesh(mesh, elementOrder, useBubbleElement) + return mesh
+ + + +# def get_blocks(mesh, blockNames): +# return tuple(mesh.blocks[name] for name in blockNames) + + +
+[docs] +def combine_nodesets(set1, set2, nodeOffset): + newSet = {} + if set1!=None: + for key in set1: + newSet[key] = set1[key] + if set2!=None: + for key in set2: + newSet[key] = set2[key] + nodeOffset + return newSet
+ + + +
+[docs] +def combine_sidesets(set1, set2, elemOffset): + newSet = {} + if set1!=None: + for key in set1: + val = set1[key] + newSet[key] = val + if set2!=None: + for key in set2: + val = set2[key] + newSet[key] = val.at[:,0].add(elemOffset) if len(val)>0 else np.array([]) + return newSet
+ + + +
+[docs] +def combine_blocks(set1, set2, elemOffset): + # meshes are required to have at least one block + newSet = {} + + for key in set1: + val = set1[key] + newSet[key] = val + + for key in set2: + val = set2[key] + newSet[key] = val + elemOffset + return newSet
+ + + +
+[docs] +def combine_mesh(m1, m2): + # need to implement block combining + + mesh1, disp1 = m1 + mesh2, disp2 = m2 + + # Only handle 2 linear element meshes + assert mesh1.parentElement.degree == 1 + assert mesh2.parentElement.degree == 1 + + numNodes1 = mesh1.coords.shape[0] + # numElems1 = num_elements(mesh1) + numElems1 = mesh1.num_elements + + coords = np.concatenate((mesh1.coords, mesh2.coords), axis=0) + conns = np.concatenate((mesh1.conns, mesh2.conns+numNodes1), axis=0) + disp = np.concatenate((disp1, disp2), axis=0) + + nodeSets = None + if mesh1.nodeSets!=None or mesh2.nodeSets!=None: + nodeSets = combine_nodesets(mesh1.nodeSets, mesh2.nodeSets, numNodes1) + + sideSets = None + if mesh1.sideSets!=None or mesh2.sideSets!=None: + sideSets = combine_sidesets(mesh1.sideSets, mesh2.sideSets, numElems1) + + simplexNodeOrdinals = np.arange(coords.shape[0]) + + blocks = combine_blocks(mesh1.blocks, mesh2.blocks, numElems1) + + return Mesh(coords, conns, simplexNodeOrdinals, + mesh1.parentElement, mesh1.parentElement1d, blocks, + nodeSets, sideSets), disp
+ + + +
+[docs] +def mesh_with_coords(mesh, coords): + return Mesh(coords, mesh.conns,mesh.simplexNodesOrdinals, + mesh.parentElement, mesh.parentElement1d, mesh.blocks, mesh.nodeSets, mesh.sideSets)
+ + + +
+[docs] +def mesh_with_nodesets(mesh, nodeSets): + return Mesh(mesh.coords, mesh.conns, + mesh.simplexNodesOrdinals, + mesh.parentElement, mesh.parentElement1d, + mesh.blocks, nodeSets, mesh.sideSets)
+ + + +
+[docs] +def mesh_with_blocks(mesh, blocks): + return Mesh(mesh.coords, mesh.conns, + mesh.simplexNodesOrdinals, + mesh.parentElement, mesh.parentElement1d, + blocks, mesh.nodeSets, mesh.sideSets)
+ + + +
+[docs] +def create_edges(conns): + """Generate topological information about edges in a triangulation. + + Parameters + ---------- + conns : (nTriangles, 3) array + Connectivity table of the triangulation. + + Returns + ------- + edgeConns : (nEdges, 2) array + Vertices of each edge. Boundary edges are always in the + counter-clockwise sense, so that the interior of the body is on the left + side when walking from the first vertex to the second. + edges : (nEdges, 4) array + Edge-to-triangle topological information. Each row provides the + follwing information for each edge: [leftT, leftP, rightT, rightP], + where leftT is the ID of the triangle to the left, leftP is the + permutation of the edge in the left triangle (edge 0, 1, or 2), rightT + is the ID of the triangle to the right, and rightP is the permutation + of the edge in the right triangle. If the edge is a boundary edge, the + values of rightT and rightP are -1. + """ + nTris = conns.shape[0] + allTriFaces = onp.vstack((conns[:, (0,1)], conns[:, (1,2)], conns[:, (2,0)])) + foo = onp.sort(allTriFaces, axis=1) + bar, i = onp.unique(foo, return_index=True, axis=0) + edgeConns = (allTriFaces[i,:]) + + nEdges = edgeConns.shape[0] + edges = -onp.ones((nEdges, 4), dtype=onp.int_) + edgeElementIds = onp.tile(np.arange(nTris), 3) + edges[:,0] = edgeElementIds[i] + edges[:,1] = i // nTris + + for i, ec in enumerate(edgeConns): + rowsMatch = onp.all(onp.flip(ec) == allTriFaces, axis=1) + if onp.any(rowsMatch): + j = onp.where(rowsMatch)[0][0] + # there should only be one matching row, but take element 0 + # because j will have the same number of axes (2) as + # rowsMatch. + edges[i, 2] = edgeElementIds[j] + edges[i, 3] = j // nTris + + return edgeConns, edges
+ + + +
+[docs] +def create_higher_order_mesh_from_simplex_mesh(mesh, order, useBubbleElement=False, copyNodeSets=False, createNodeSetsFromSideSets=False): + if order==1: return mesh + + # parentElement1d = interpolants.make_parent_element_1d(order) + parentElement1d = LineElement(order) + + if useBubbleElement: + raise ValueError('Bubble elements arent supported right now') + # basis = interpolants.make_parent_element_2d_with_bubble(order) + else: + # basis = interpolants.make_parent_element_2d(order) + basis = SimplexTriElement(order) + + # conns = np.zeros((num_elements(mesh), basis.coordinates.shape[0]), dtype=np.int_) + conns = np.zeros((mesh.num_elements, basis.coordinates.shape[0]), dtype=np.int_) + + # step 1/3: vertex nodes + conns = conns.at[:,basis.vertexNodes].set(mesh.conns) + simplexNodesOrdinals = np.arange(mesh.coords.shape[0]) + + nodeOrdinalOffset = mesh.coords.shape[0] # offset for later node numbering + + # step 2/3: mid-edge nodes (excluding vertices) + edgeConns, edges = create_edges(mesh.conns) + A = np.column_stack((1.0-parentElement1d.coordinates[parentElement1d.interiorNodes], + parentElement1d.coordinates[parentElement1d.interiorNodes])) + edgeCoords = vmap(lambda edgeConn: np.dot(A, mesh.coords[edgeConn,:]))(edgeConns) + + nNodesPerEdge = parentElement1d.interiorNodes.size + for e, edge in enumerate(edges): + edgeNodeOrdinals = nodeOrdinalOffset + np.arange(e*nNodesPerEdge,(e+1)*nNodesPerEdge) + + elemLeft = edge[0] + sideLeft = edge[1] + edgeMasterNodes = basis.faceNodes[sideLeft][parentElement1d.interiorNodes] + conns = conns.at[elemLeft, edgeMasterNodes].set(edgeNodeOrdinals) + + elemRight = edge[2] + if elemRight >= 0: + sideRight = edge[3] + edgeMasterNodes = basis.faceNodes[sideRight][parentElement1d.interiorNodes] + conns = conns.at[elemRight, edgeMasterNodes].set(np.flip(edgeNodeOrdinals)) + + nEdges = edges.shape[0] + nodeOrdinalOffset += nEdges*nNodesPerEdge # for offset of interior node numbering + + # step 3/3: interior nodes + nInNodesPerTri = basis.interiorNodes.shape[0] + if nInNodesPerTri > 0: + N0 = basis.coordinates[basis.interiorNodes,0] + N1 = basis.coordinates[basis.interiorNodes,1] + N2 = 1.0 - N0 - N1 + A = np.column_stack((N0,N1,N2)) + interiorCoords = vmap(lambda triConn: np.dot(A, mesh.coords[triConn]))(mesh.conns) + + def add_element_interior_nodes(conn, newNodeOrdinals): + return conn.at[basis.interiorNodes].set(newNodeOrdinals) + + nTri = conns.shape[0] + newNodeOrdinals = np.arange(nTri*nInNodesPerTri).reshape(nTri,nInNodesPerTri) \ + + nodeOrdinalOffset + + conns = vmap(add_element_interior_nodes)(conns, newNodeOrdinals) + else: + interiorCoords = np.zeros((0,2)) + + + coords = np.vstack((mesh.coords,edgeCoords.reshape(-1,2),interiorCoords.reshape(-1,2))) + nodeSets = mesh.nodeSets if copyNodeSets else None + + newMesh = Mesh(coords, conns, simplexNodesOrdinals, basis, + parentElement1d, mesh.blocks, nodeSets, mesh.sideSets) + + if createNodeSetsFromSideSets: + nodeSets = create_nodesets_from_sidesets(newMesh) + newMesh = mesh_with_nodesets(newMesh, nodeSets) + + return newMesh
+ + + +
+[docs] +def create_nodesets_from_sidesets(mesh): + nodeSets = {} + print(mesh) + def get_nodes_from_edge(edge): + elemOrdinal = edge[0] + sideOrdinal = edge[1] + return mesh.conns[elemOrdinal, mesh.parentElement.faceNodes[sideOrdinal,:]] + + for setName, sideSet in mesh.sideSets.items(): + nodes = vmap(get_nodes_from_edge)(sideSet) + nodeSets[setName] = np.unique(nodes.ravel()) + + return nodeSets
+ + + +# def num_elements(mesh): +# return mesh.conns.shape[0] + + +
+[docs] +def num_nodes(mesh): + return mesh.coords.shape[0]
+ + + +
+[docs] +def get_edge_node_indices(mesh : Mesh, edge): + edgeNodes = mesh.parentElement.faceNodes[edge[1], :] + return mesh.conns[edge[0], edgeNodes]
+ + + +
+[docs] +def get_edge_field(mesh : Mesh, edge, field): + """ + Evaluate field on nodes of an element edge. + Arguments: + + :param mesh: a Mesh object + :param edge: tuple containing the element number containing the edge and the + permutation (0, 1, or 2) of the edge within the triangle + """ + return field[get_edge_node_indices(mesh, edge)]
+ + + +
+[docs] +def get_edge_coords(mesh : Mesh, edge): + return get_edge_field(mesh, edge, mesh.coords)
+ + + +
+[docs] +def compute_edge_vectors(mesh : Mesh, edgeCoords): + """ + Get geometric vectors for an element edge. + + Assumes that the edgs has a constant shape jacobian, that is, the + transformation from the parent element is affine. + + Arguments + :param mesh: a Mesh object + :param edgeCoords: coordinates of all nodes on the edge, in the order + defined by the 1D parent element convention + + Returns + tuple (t, n, j) with + :return t: the unit tangent vector + :return n: the outward unit normal vector + :return j: jacobian of the transformation from parent to physical space + """ + Xv = edgeCoords[mesh.parentElement1d.vertexNodes, :] + tangent = Xv[1] - Xv[0] + normal = np.array([tangent[1], -tangent[0]]) + jac = np.linalg.norm(tangent) + return tangent/jac, normal/jac, jac
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/quadrature_rules.html b/html/_modules/pancax/fem/quadrature_rules.html new file mode 100644 index 0000000..88aa96e --- /dev/null +++ b/html/_modules/pancax/fem/quadrature_rules.html @@ -0,0 +1,532 @@ + + + + + + + + pancax.fem.quadrature_rules — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.quadrature_rules

+from .elements import *
+from .elements.base_element import BaseElement
+from jax.lax import switch
+from jaxtyping import Array, Float
+from pancax.timer import Timer
+import equinox as eqx
+import jax.numpy as jnp
+import math
+import numpy as ojnp
+import scipy.special
+
+
+# TODO 
+# think about moving this stuff into elements
+
+
+[docs] +class QuadratureRule(eqx.Module): + """ + Quadrature rule points and weights. + A ``namedtuple`` containing ``xigauss``, a numpy array of the + coordinates of the sample points in the reference domain, and + ``wgauss``, a numpy array with the weights. + + :param xigauss: coordinates of gauss points in reference element + :param wgauss: weights of gauss points in reference element + """ + xigauss: Float[Array, "nq nd"] + wgauss: Float[Array, "nq"] + +
+[docs] + def __init__(self, parentElement: BaseElement, degree: int) -> None: + with Timer('QuadratureRule.__init__'): + if type(parentElement) == Hex8Element: + xi, w = create_quadrature_rule_on_hex(degree) + elif type(parentElement) == LineElement: + xi, w = create_quadrature_rule_1D(degree) + elif type(parentElement) == Quad4Element or \ + type(parentElement) == Quad9Element: + xi, w = create_quadrature_rule_on_quad(degree) + elif type(parentElement) == SimplexTriElement: + xi, w = create_quadrature_rule_on_triangle(degree) + elif type(parentElement) == Tet4Element or \ + type(parentElement) == Tet10Element: + xi, w = create_quadrature_rule_on_tet(degree) + else: + raise TypeError(f'Element type {type(parentElement)} does not ' + 'have a supported quadrature rule.') + self.xigauss = xi + self.wgauss = w
+ + + # TODO maybe there's a better way? + # TODO below is just so we don't have to change any tests for now + def __iter__(self): + yield self.xigauss + yield self.wgauss + + def __len__(self): + return self.xigauss.shape[0]
+ + + +
+[docs] +def create_quadrature_rule_1D(degree: int) -> QuadratureRule: + """Creates a Gauss-Legendre quadrature on the unit interval. + + The rule can exactly integrate polynomials of degree up to + ``degree``. + + Parameters + ---------- + degree: Highest degree polynomial to be exactly integrated by the quadrature rule + + Returns + ------- + A ``QuadratureRule`` named tuple containing the quadrature point coordinates + and the weights. + """ + + n = math.ceil((degree + 1)/2) + xi, w = scipy.special.roots_sh_legendre(n) + return xi, w
+ + + +# TODO is this being used at all +
+[docs] +def eval_at_iso_points(xigauss, field): + fields = jnp.array([field[0,:] + (field[1,:]-field[0,:]) * xi for xi in xigauss]) + return fields
+ + + +
+[docs] +def create_quadrature_rule_on_hex(quad_degree: int) -> QuadratureRule: + if quad_degree == 1: + xi = jnp.array([[0.0, 0.0, 0.0]]) + w = 8.0 * jnp.ones(1) + elif quad_degree == 2: + xi = jnp.sqrt(1. / 3.) * jnp.array( + [[-1., -1., -1.], + [1., -1., -1.], + [1., 1., -1.], + [-1., 1., -1.], + [-1., -1., 1.], + [1., -1., 1.], + [1., 1., 1.], + [-1., 1., 1.]], + ) + w = jnp.ones(8) + else: + raise ValueError(f'Unsupported quadrature degree {quad_degree} on hex element.') + + return xi, w
+ + + +
+[docs] +def create_quadrature_rule_on_quad(quad_degree: int) -> QuadratureRule: + """ + :param quad_degree: degree of quadrature rule to create + """ + if quad_degree == 1: + xi = jnp.array([[0.0, 0.0]]) + w = 4.0 * jnp.ones(1) + elif quad_degree == 2: + xi = jnp.sqrt(1. / 3.) * jnp.array([ + [-1., -1.], + [1., -1.], + [1., 1.], + [-1., 1.] + ]) + w = jnp.ones(4) + elif quad_degree == 3: + # TODO not quite accurate currently for some reason? + # TODO + # TODO + xi = jnp.array([ + [-jnp.sqrt(3. / 5.), -jnp.sqrt(3. / 5.)], + [0., -jnp.sqrt(3. / 5.)], + [jnp.sqrt(3. / 5.), -jnp.sqrt(3. / 5.)], + [-jnp.sqrt(3. / 5.), 0.], + [0., 0.], + [jnp.sqrt(3. / 5.), 0.], + [-jnp.sqrt(3. / 5.), jnp.sqrt(3. / 5.)], + [0., jnp.sqrt(3. / 5.)], + [jnp.sqrt(3. / 5.), jnp.sqrt(3. / 5.)] + ]) + w = jnp.array([ + 25. / 81., + 40. / 81., + 25. / 81., + 40. / 81., + 64. / 81., + 40. / 81., + 25. / 81., + 40. / 81., + 25. / 80. + ]) + else: + raise ValueError('Invalid quadrature degree: %s' % quad_degree) + + return xi, w
+ + + +
+[docs] +def create_quadrature_rule_on_tet(degree: int) -> QuadratureRule: + if degree == 1: + xi = jnp.array([ + [1. / 4., 1. / 4., 1. / 4.] + ]) + w = jnp.array([1. / 6.]) + elif degree == 2: + xi = jnp.array([ + [1. / 4., 1. / 4., 1. / 4.], + [1. / 6., 1. / 6., 1. / 6.], + [1. / 6., 1. / 6., 1. / 2.], + [1. / 6., 1. / 2., 1. / 6.], + [1. / 2., 1. / 6., 1. / 6.] + ]) + w = jnp.array([-2. / 15., 3. / 40., 3. / 40., 3. / 40., 3. / 40.]) + else: + raise ValueError('Invalid quadrature degree: %s' % degree) + + return xi, w
+ + + +
+[docs] +def create_quadrature_rule_on_triangle(degree: int) -> QuadratureRule: + """Creates a Gauss-Legendre quadrature on the unit triangle. + + The rule can exactly integrate 2D polynomials up to the value of + ``degree``. The domain is the triangle between the vertices + (0, 0)-(1, 0)-(0, 1). The rules here are guaranteed to be + cyclically symmetric in triangular coordinates and to have strictly + positive weights. + + Parameters + ---------- + degree: Highest degree polynomial to be exactly integrated by the quadrature rule + + Returns + ------- + A ``QuadratureRule`` named tuple containing the quadrature point coordinates + and the weights. + """ + if degree == 1: + xi = ojnp.array([[3.33333333333333333E-01, 3.33333333333333333E-01]]) + + w = ojnp.array([ 5.00000000000000000E-01 ]) + elif degree == 2: + xi = ojnp.array([[6.66666666666666667E-01, 1.66666666666666667E-01], + [1.66666666666666667E-01, 6.66666666666666667E-01], + [1.66666666666666667E-01, 1.66666666666666667E-01]]) + + w = ojnp.array([1.66666666666666666E-01, + 1.66666666666666667E-01, + 1.66666666666666667E-01]) + elif degree <= 4: + xi = ojnp.array([[1.081030181680700E-01, 4.459484909159650E-01], + [4.459484909159650E-01, 1.081030181680700E-01], + [4.459484909159650E-01, 4.459484909159650E-01], + [8.168475729804590E-01, 9.157621350977100E-02], + [9.157621350977100E-02, 8.168475729804590E-01], + [9.157621350977100E-02, 9.157621350977100E-02]]) + + w = ojnp.array([1.116907948390055E-01, + 1.116907948390055E-01, + 1.116907948390055E-01, + 5.497587182766100E-02, + 5.497587182766100E-02, + 5.497587182766100E-02]) + elif degree <= 5: + xi = ojnp.array([[3.33333333333333E-01, 3.33333333333333E-01], + [5.97158717897700E-02, 4.70142064105115E-01], + [4.70142064105115E-01, 5.97158717897700E-02], + [4.70142064105115E-01, 4.70142064105115E-01], + [7.97426985353087E-01, 1.01286507323456E-01], + [1.01286507323456E-01, 7.97426985353087E-01], + [1.01286507323456E-01, 1.01286507323456E-01]]) + + w = ojnp.array([1.12500000000000E-01, + 6.61970763942530E-02, + 6.61970763942530E-02, + 6.61970763942530E-02, + 6.29695902724135E-02, + 6.29695902724135E-02, + 6.29695902724135E-02]) + elif degree <= 6: + xi = ojnp.array([[5.01426509658179E-01, 2.49286745170910E-01], + [2.49286745170910E-01, 5.01426509658179E-01], + [2.49286745170910E-01, 2.49286745170910E-01], + [8.73821971016996E-01, 6.30890144915020E-02], + [6.30890144915020E-02, 8.73821971016996E-01], + [6.30890144915020E-02, 6.30890144915020E-02], + [5.31450498448170E-02, 3.10352451033784E-01], + [6.36502499121399E-01, 5.31450498448170E-02], + [3.10352451033784E-01, 6.36502499121399E-01], + [5.31450498448170E-02, 6.36502499121399E-01], + [6.36502499121399E-01, 3.10352451033784E-01], + [3.10352451033784E-01, 5.31450498448170E-02]]) + + w = ojnp.array([5.83931378631895E-02, + 5.83931378631895E-02, + 5.83931378631895E-02, + 2.54224531851035E-02, + 2.54224531851035E-02, + 2.54224531851035E-02, + 4.14255378091870E-02, + 4.14255378091870E-02, + 4.14255378091870E-02, + 4.14255378091870E-02, + 4.14255378091870E-02, + 4.14255378091870E-02]) + elif degree <= 10: + xi = ojnp.array([[0.33333333333333333E+00, 0.33333333333333333E+00], + [0.4269134091050342E-02, 0.49786543295447483E+00], + [0.49786543295447483E+00, 0.4269134091050342E-02], + [0.49786543295447483E+00, 0.49786543295447483E+00], + [0.14397510054188759E+00, 0.42801244972905617E+00], + [0.42801244972905617E+00, 0.14397510054188759E+00], + [0.42801244972905617E+00, 0.42801244972905617E+00], + [0.6304871745135507E+00, 0.18475641274322457E+00], + [0.18475641274322457E+00, 0.6304871745135507E+00], + [0.18475641274322457E+00, 0.18475641274322457E+00], + [0.9590375628566448E+00, 0.20481218571677562E-01], + [0.20481218571677562E-01, 0.9590375628566448E+00], + [0.20481218571677562E-01, 0.20481218571677562E-01], + [0.3500298989727196E-01, 0.1365735762560334E+00], + [0.1365735762560334E+00, 0.8284234338466947E+00], + [0.8284234338466947E+00, 0.3500298989727196E-01], + [0.1365735762560334E+00, 0.3500298989727196E-01], + [0.8284234338466947E+00, 0.1365735762560334E+00], + [0.3500298989727196E-01, 0.8284234338466947E+00], + [0.37549070258442674E-01, 0.3327436005886386E+00], + [0.3327436005886386E+00, 0.6297073291529187E+00], + [0.6297073291529187E+00, 0.37549070258442674E-01], + [0.3327436005886386E+00, 0.37549070258442674E-01], + [0.6297073291529187E+00, 0.3327436005886386E+00], + [0.37549070258442674E-01, 0.6297073291529187E+00]]) + + w = ojnp.array([0.4176169990259819E-01, + 0.36149252960283717E-02, + 0.36149252960283717E-02, + 0.36149252960283717E-02, + 0.3724608896049025E-01, + 0.3724608896049025E-01, + 0.3724608896049025E-01, + 0.39323236701554264E-01, + 0.39323236701554264E-01, + 0.39323236701554264E-01, + 0.3464161543553752E-02, + 0.3464161543553752E-02, + 0.3464161543553752E-02, + 0.147591601673897E-01, + 0.147591601673897E-01, + 0.147591601673897E-01, + 0.147591601673897E-01, + 0.147591601673897E-01, + 0.147591601673897E-01, + 0.1978968359803062E-01, + 0.1978968359803062E-01, + 0.1978968359803062E-01, + 0.1978968359803062E-01, + 0.1978968359803062E-01, + 0.1978968359803062E-01]) + else: + raise ValueError("Quadrature of precision this high is not implemented.") + + return xi, w
+ + + +# TODO remove this stuff +
+[docs] +def create_padded_quadrature_rule_1D(degree): + """Creates 1D Gauss quadrature rule data that are padded to maintain a + uniform size, which makes this function jit-able. + + This function is inteded to be used only when jit compilation of calls to the + quadrature rules are needed. Otherwise, prefer to use the standard quadrature + rules. The standard rules do not contain extra 0s for padding, which makes + them more efficient when used repeatedly (such as in the global energy). + + Args: + degree: degree of highest polynomial to be integrated exactly + """ + + jnpts = jnp.ceil((degree + 1)/2).astype(int) + xi,w = switch(jnpts, + [_gauss_quad_1D_1pt, _gauss_quad_1D_2pt, _gauss_quad_1D_3pt, + _gauss_quad_1D_4pt, _gauss_quad_1D_5pt], + None) + return 0.5 * (xi + 1.0), 0.5 * w
+ + + +
+[docs] +def _gauss_quad_1D_1pt(_): + xi = jnp.array([0., 0., 0., 0., 0.]) + w = jnp.array([2., 0., 0., 0., 0.]) + return xi,w
+ + + +
+[docs] +def _gauss_quad_1D_2pt(_): + xi = jnp.array([-0.5773502691896257, 0.5773502691896257, 0., + 0., 0.]) + w = jnp.array([ 1., 1. , 0., + 0., 0.]) + return xi,w
+ + + +
+[docs] +def _gauss_quad_1D_3pt(_): + xi = jnp.array([-0.7745966692414834, 0. , 0.7745966692414834, + 0., 0.]) + w = jnp.array([ 0.5555555555555557, 0.8888888888888888, 0.5555555555555557, + 0., 0.]) + return xi,w
+ + + +
+[docs] +def _gauss_quad_1D_4pt(_): + xi = jnp.array([-0.8611363115940526 , -0.33998104358485626, 0.33998104358485626, + 0.8611363115940526 , 0.]) + w = jnp.array([ 0.3478548451374537 , 0.6521451548625462 , 0.6521451548625462 , + 0.3478548451374537, 0.]) + return xi,w
+ + + +
+[docs] +def _gauss_quad_1D_5pt(_): + xi = jnp.array([-0.906179845938664 , -0.5384693101056831, 0. , 0.5384693101056831, 0.906179845938664 ]) + w = jnp.array([ 0.23692688505618942, 0.4786286704993662, 0.568888888888889 , 0.4786286704993662, 0.23692688505618942]) + + return xi,w
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/read_exodus_mesh.html b/html/_modules/pancax/fem/read_exodus_mesh.html new file mode 100644 index 0000000..d81cf13 --- /dev/null +++ b/html/_modules/pancax/fem/read_exodus_mesh.html @@ -0,0 +1,324 @@ + + + + + + + + pancax.fem.read_exodus_mesh — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.read_exodus_mesh

+from .elements import *
+from .mesh import *
+from pancax.timer import Timer
+import netCDF4
+import numpy as onp
+
+exodusToNativeTri6NodeOrder = np.array([0, 3, 1, 5, 4, 2])
+
+
+
+[docs] +def read_exodus_mesh(fileName: str): + """ + :param fileName: file name of exodus mesh to read + :return: A mesh object + """ + with Timer('read_exodus_mesh'): + with netCDF4.Dataset(fileName) as exData: + coords = _read_coordinates(exData) + conns, blocks = _read_blocks(exData) + nodeSets = _read_node_sets(exData) + sideSets = _read_side_sets(exData) + + elementType = _read_element_type(exData).lower() + if elementType == "hex8" or elementType == "hex": + basis = Hex8Element() + basis1d = Quad4Element() + simplexNodesOrdinals = np.arange(coords.shape[0]) + elif elementType == "quad4": + basis = Quad4Element() + basis1d = LineElement(degree=1) + simplexNodesOrdinals = np.arange(coords.shape[0]) + elif elementType == "quad9": + basis = Quad9Element() + basis1d = LineElement(degree=2) + simplexNodesOrdinals = np.arange(coords.shape[0]) + elif elementType == "tet4": + basis = Tet4Element() + basis1d = SimplexTriElement(degree=1) + simplexNodesOrdinals = np.arange(coords.shape[0]) + elif elementType == "tet10": + basis = Tet10Element() + basis1d = SimplexTriElement(degree=1) + simplexNodesOrdinals = np.arange(coords.shape[0]) + elif elementType == "tri3" or elementType == "tri": + basis = SimplexTriElement(degree=1) + basis1d = LineElement(degree=1) + simplexNodesOrdinals = np.arange(coords.shape[0]) + elif elementType == "tri6": + basis = SimplexTriElement(degree=2) + basis1d = LineElement(degree=2) + simplexNodesOrdinals = _get_vertex_nodes_from_exodus_tri6_mesh(conns) + conns = conns[:, exodusToNativeTri6NodeOrder] + else: + raise ValueError(f'Unsupported element type: {elementType}') + + return Mesh(coords, conns, simplexNodesOrdinals, basis, basis1d, + blocks, nodeSets, sideSets)
+ + + +# TODO add support for 3D +
+[docs] +def _read_coordinates(exodusDataset): + nNodes = len(exodusDataset.dimensions['num_nodes']) + nDims = len(exodusDataset.dimensions['num_dim']) + # assert nDims == 2 + + coordsX = exodusDataset.variables['coordx'][:] + coordsY = exodusDataset.variables['coordy'][:] + + if nDims == 2: + return np.array(onp.column_stack([coordsX, coordsY])) + elif nDims == 3: + coordsZ = exodusDataset.variables['coordz'][:] + return np.array(onp.column_stack([coordsX, coordsY, coordsZ]))
+ + + + +
+[docs] +def _read_block_conns(exodusDataset, blockOrdinal): + key = 'connect' + str(blockOrdinal + 1) + record = exodusDataset.variables[key] + record.set_auto_mask(False) + + nElemsInBlock = len(exodusDataset.dimensions['num_el_in_blk' + str(blockOrdinal + 1)]) + return np.array(record[:] - 1)
+ + + +
+[docs] +def _read_blocks(exodusDataset): + nodesPerElem = len(exodusDataset.dimensions['num_nod_per_el1']) + + blockNames = _read_names_list(exodusDataset, 'eb_names') + # give unnamed blocks an auto-generated name + for i, name in enumerate(blockNames): + if not name: + blockNames[i] = "block_" + str(i+1) + + nBlocks = len(exodusDataset.dimensions['num_el_blk']) + blockConns = [] + blocks = {} + firstElemInBlock = 0 + for i in range(nBlocks): + nodesPerElemInBlock = len(exodusDataset.dimensions['num_nod_per_el' + str(i+1)]) + assert nodesPerElemInBlock == nodesPerElem + + blockConns.append(_read_block_conns(exodusDataset, i)) + + nElemsInBlock = len(exodusDataset.dimensions['num_el_in_blk' + str(i + 1)]) + elemRange = np.arange(firstElemInBlock, firstElemInBlock + nElemsInBlock) + blocks[blockNames[i]] = elemRange + firstElemInBlock += nElemsInBlock + + conns = np.vstack(blockConns) + return conns, blocks
+ + + +
+[docs] +def _read_node_sets(exodusDataset): + if "num_node_sets" in exodusDataset.dimensions: + nodeSetNames = _read_names_list(exodusDataset, "ns_names") + for i, name in enumerate(nodeSetNames): + if not name: + nodeSetNames[i] = "nodeset_" + str(i+1) + + nodeSetNodes = [] + nNodeSets = len(exodusDataset.dimensions["num_node_sets"]) + for i in range(nNodeSets): + key = 'node_ns' + str(i + 1) + record = exodusDataset.variables[key] + record.set_auto_mask(False) + nodeSetNodes.append(record[:] - 1) + nodeSets = dict(zip(nodeSetNames, nodeSetNodes)) + else: + nodeSets = {} + + return nodeSets
+ + + +
+[docs] +def _read_side_sets(exodusDataset): + if "num_side_sets" in exodusDataset.dimensions: + sideSetNames = _read_names_list(exodusDataset, 'ss_names') + for i, name in enumerate(sideSetNames): + if not name: + sideSetNames[i] = "sideset_" + str(i+1) + + nSideSets = len(exodusDataset.dimensions['num_side_sets']) + sideSetEntries = [] + for i in range(nSideSets): + key = 'elem_ss' + str(i + 1) + record = exodusDataset.variables[key] + record.set_auto_mask(False) + sideSetElems = np.array(record[:] - 1) + + key = 'side_ss' + str(i + 1) + record = exodusDataset.variables[key] + record.set_auto_mask(False) + sideSetSides = np.array(record[:] - 1) + + sideSetEntries.append(np.column_stack((sideSetElems, sideSetSides))) + sideSets = dict(zip(sideSetNames, sideSetEntries)) + else: + sideSets = {} + + return sideSets
+ + + +
+[docs] +def _read_element_type(exodusDataset): + elemType = exodusDataset.variables['connect1'].elem_type + + nBlocks = len(exodusDataset.dimensions['num_el_blk']) + for i in range(nBlocks): + key = 'connect' + str(i + 1) + blockElemType = exodusDataset[key].elem_type + assert (blockElemType == elemType), 'Different element types present in exodus file' + return elemType
+ + + +
+[docs] +def _read_names_list(exodusDataset, recordName): + record = exodusDataset.variables[recordName] + record.set_auto_mask(False) + namesList = [b"".join(c).decode("UTF-8") for c in record[:]] + return namesList
+ + + +
+[docs] +def _get_vertex_nodes_from_exodus_tri6_mesh(conns): + vertexSet = set(conns[:,:3].ravel().tolist()) + vertices = [v for v in vertexSet] + return np.array(vertices, dtype = np.int_)
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/sparse_matrix_assembler.html b/html/_modules/pancax/fem/sparse_matrix_assembler.html new file mode 100644 index 0000000..5ee0f8d --- /dev/null +++ b/html/_modules/pancax/fem/sparse_matrix_assembler.html @@ -0,0 +1,131 @@ + + + + + + + + pancax.fem.sparse_matrix_assembler — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.fem.sparse_matrix_assembler

+from scipy.sparse import coo_matrix
+
+
+
+[docs] +def assemble_sparse_stiffness_matrix(kValues, conns, dofManager): + nElements, nNodesPerElement = conns.shape + nFields = kValues.shape[2] + nDofPerElement = nNodesPerElement * nFields + + kValues = kValues.reshape((nElements, nDofPerElement, nDofPerElement)) + + nUnknowns = dofManager.unknownIndices.size + + K = coo_matrix((kValues[dofManager.hessian_bc_mask], (dofManager.HessRowCoords, dofManager.HessColCoords)), shape = (nUnknowns, nUnknowns)) + return K.tocsc()
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/surface.html b/html/_modules/pancax/fem/surface.html new file mode 100644 index 0000000..fe8371a --- /dev/null +++ b/html/_modules/pancax/fem/surface.html @@ -0,0 +1,243 @@ + + + + + + + + pancax.fem.surface — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.surface

+from jax import vmap
+import jax.numpy as np
+
+
+
+[docs] +def create_edges(coords, conns, edge_is_potentially_in_contact): + edges = [] + for e,elem in enumerate(conns): + edgeCoords = coords.take(elem,0) + for n in range(3): + nn = (n+1)%3 + edgeConn = np.array([n,nn]) + if (edge_is_potentially_in_contact(edgeCoords[edgeConn])): + edges.append([e,n]) + return np.array(edges)
+ + + +# def get_coords(mesh, side): +# elem = mesh.conns[side[0],:] +# lSide = side[1] +# elemCoords = mesh.coords.take(elem,0) +# return elemCoords[ np.array([lSide, (lSide+1)%3]), : ] + +
+[docs] +def get_coords(coords, conns, side): + elem = conns[side[0],:] + lSide = side[1] + elemCoords = coords.take(elem,0) + return elemCoords[ np.array([lSide, (lSide+1)%3]), : ]
+ + + +
+[docs] +def interpolate_nodal_field_on_edge(mesh, U, interpolationPoints, edge): + # This function isn't used yet. + # We may want to replicate parts of FunctionSpace to do surface integrals. + # + fieldIndex = Surface.get_field_index(edge, mesh.conns) + nodalValues = Surface.eval_field(U, fieldIndex) + return 0.0
+ + + +
+[docs] +def integrate_values(quadratureRule, coords, gaussField): + xigauss, wgauss = quadratureRule + jac = np.linalg.norm(coords[0,:] - coords[1,:]) + xgauss = np.array([coords[0] + (coords[1] - coords[0])*xi for xi in xigauss]) + dx = jac*wgauss + + res = dx.dot(gaussField) + return res
+ + + +
+[docs] +def integrate_function(quadratureRule, coords, field_func): + xigauss, wgauss = quadratureRule + jac = np.linalg.norm(coords[0,:] - coords[1,:]) + xgauss = np.array([coords[0] + (coords[1] - coords[0])*xi for xi in xigauss]) + dx = jac*wgauss + return np.dot(vmap(field_func)(xgauss), dx)
+ + + +
+[docs] +def integrate_function_on_surface(quadratureRule, edges, mesh, func): + F = vmap(integrate_function_on_edge, (None,0,None,None)) + return np.sum(F(quadratureRule, edges, mesh, func))
+ + + +
+[docs] +def integrate_function_on_edge(quadratureRule, edge, mesh, func): + edgeCoords = get_coords(mesh.coords, mesh.conns, edge) + xigauss, wgauss = quadratureRule + jac = np.linalg.norm(edgeCoords[0,:] - edgeCoords[1,:]) + xgauss = edgeCoords[0] + np.outer(xigauss, edgeCoords[1] - edgeCoords[0]) + dx = jac*wgauss + normal = compute_normal(edgeCoords) + return np.dot(vmap(func, (0,None))(xgauss, normal), dx)
+ + + +
+[docs] +def compute_normal(edgeCoords): + tangent = edgeCoords[1]-edgeCoords[0] + normal = np.array([tangent[1], -tangent[0]]) + return normal / np.linalg.norm(normal)
+ + + +
+[docs] +def get_field_index(edge, conns): + elemIndex = edge[0] + elemConns = conns[elemIndex] + n1 = edge[1] + n2 = (n1+1)%3 + return elemConns, np.array([n1,n2])
+ + + +
+[docs] +def eval_field(field, fieldIndex): + return field[fieldIndex[0]][fieldIndex[1]]
+ + + +
+[docs] +def compute_edge_vectors(edgeCoords): + tangent = edgeCoords[1]-edgeCoords[0] + normal = np.array([tangent[1], -tangent[0]]) + jac = np.linalg.norm(tangent) + return tangent/jac, normal/jac, jac
+ + + +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/fem/traction_bc.html b/html/_modules/pancax/fem/traction_bc.html new file mode 100644 index 0000000..7b6ec1b --- /dev/null +++ b/html/_modules/pancax/fem/traction_bc.html @@ -0,0 +1,162 @@ + + + + + + + + pancax.fem.traction_bc — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.fem.traction_bc

+import jax
+import jax.numpy as np
+
+import pancax.fem.quadrature_rules as quadrature_rules
+import pancax.fem.surface as surface
+
+# def interpolate_nodal_field_on_edge(mesh, U, quadRule, edge):
+#     fieldIndex = Surface.get_field_index(edge, mesh.conns)  
+
+[docs] +def interpolate_nodal_field_on_edge(conns, U, quadRule, edge): + fieldIndex = surface.get_field_index(edge, conns) + nodalValues = surface.eval_field(U, fieldIndex) + return quadrature_rules.eval_at_iso_points(quadRule.xigauss, nodalValues)
+ + + +# def compute_traction_potential_energy_on_edge(mesh, U, quadRule, edge, load, time): +# uq = interpolate_nodal_field_on_edge(mesh, U, quadRule, edge) +# Xq = interpolate_nodal_field_on_edge(mesh, mesh.coords, quadRule, edge) +# edgeCoords = Surface.get_coords(mesh, edge) +
+[docs] +def compute_traction_potential_energy_on_edge(coords, conns, U, quadRule, edge, load, time): + uq = interpolate_nodal_field_on_edge(conns, U, quadRule, edge) + Xq = interpolate_nodal_field_on_edge(conns, coords, quadRule, edge) + edgeCoords = surface.get_coords(coords, conns, edge) + edgeNormal = surface.compute_normal(edgeCoords) + tq = jax.vmap(load, (0, None, None))(Xq, edgeNormal, time) + integrand = jax.vmap(lambda u,t: u@t)(uq, tq) + return -surface.integrate_values(quadRule, edgeCoords, integrand)
+ + + +# def compute_traction_potential_energy(mesh, U, quadRule, edges, load, time=0.0): +# return np.sum(jax.vmap( +# compute_traction_potential_energy_on_edge, +# (None,None,None,0,None,None) +# )(mesh, U, quadRule, edges, load, time) ) + +
+[docs] +def compute_traction_potential_energy(coords, conns, U, quadRule, edges, load, time=0.0): + return np.sum(jax.vmap( + compute_traction_potential_energy_on_edge, + (None, None, None, None, 0, None, None) + )(coords, conns, U, quadRule, edges, load, time))
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/history_writer.html b/html/_modules/pancax/history_writer.html new file mode 100644 index 0000000..08f3463 --- /dev/null +++ b/html/_modules/pancax/history_writer.html @@ -0,0 +1,304 @@ + + + + + + + + pancax.history_writer — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.history_writer

+from abc import abstractmethod
+from pathlib import Path
+from typing import List
+import equinox as eqx
+import pandas
+
+
+
+[docs] +class BaseHistoryWriter(eqx.Module): + log_every: int + write_every: int + +
+[docs] + @abstractmethod + def to_csv(self): + pass
+ + +
+[docs] + def write_data(self, key: str, val: float) -> None: + if key in self.data_dict.keys(): + self.data_dict[key].append(val) + else: + self.data_dict[key] = [val]
+ + +
+[docs] + @abstractmethod + def write_aux_values(self, loss): + pass
+ + +
+[docs] + @abstractmethod + def write_epoch(self, epoch): + pass
+ + +
+[docs] + def write_history(self, loss, epoch: int): + if epoch % self.log_every == 0: + self.write_aux_values(loss) + self.write_epoch(epoch) + self.write_loss(loss) + + if epoch % self.write_every == 0: + self.to_csv()
+ + +
+[docs] + @abstractmethod + def write_loss(self, loss): + pass
+
+ + + +
+[docs] +class HistoryWriter(BaseHistoryWriter): + log_every: int + write_every: int + data_dict: dict + history_file: Path + +
+[docs] + def __init__(self, history_file: str, log_every: int, write_every: int) -> None: + super().__init__(log_every, write_every) + self.history_file = Path(history_file) + self.data_dict = dict()
+ + +
+[docs] + def to_csv(self) -> None: + df = pandas.DataFrame(self.data_dict) + df.to_csv(self.history_file, index=False)
+ + +
+[docs] + def write_aux_values(self, loss): + for key, val in loss[1].items(): + if key == 'props': + for prop_num, prop_val in enumerate(val): + self.write_data(f'property_{prop_num}', prop_val.item()) + elif key == 'dprops': + for prop_num, prop_val in enumerate(val): + self.write_data(f'dproperty_{prop_num}', prop_val.item()) + else: + self.write_data(key, val.item())
+ + +
+[docs] + def write_epoch(self, epoch): + self.write_data('epoch', epoch)
+ + +
+[docs] + def write_loss(self, loss): + self.write_data('loss', loss[0].item())
+ + + +
+[docs] + def _write_loss(self, loss, epoch: int, log_every=1, save_every=1000): + if epoch % log_every == 0: + self.write_data('epoch', epoch) + self.write_data('loss', loss[0].item()) + for key, val in loss[1].items(): + if key == 'props': + for prop_num, prop_val in enumerate(val): + self.write_data(f'property_{prop_num}', prop_val.item()) + elif key == 'dprops': + for prop_num, prop_val in enumerate(val): + self.write_data(f'dproperty_{prop_num}', prop_val.item()) + else: + self.write_data(key, val.item()) + + if epoch % save_every == 0: + print(f'Saving history buffer to {self.history_file}') + self.to_csv(self.history_file)
+
+ + + +
+[docs] +class EnsembleHistoryWriter(BaseHistoryWriter): + log_every: int + write_every: int + history_writers: List[HistoryWriter] + +
+[docs] + def __init__(self, base_name: str, n_pinns: int, log_every: int, write_every: int) -> None: + super().__init__(log_every, write_every) + self.history_writers = [ + HistoryWriter(f'{base_name}_{n}.csv', log_every, write_every) for n in range(n_pinns) + ]
+ + +
+[docs] + def to_csv(self): + for writer in self.history_writers: + writer.to_csv()
+ + +
+[docs] + def write_aux_values(self, loss): + for key, val in loss[1].items(): + for n, writer in enumerate(self.history_writers): + if key == 'props': + # for prop_num, prop_val in enumerate(val): + # writer.write_data(f'property_{prop_num}', prop_val[n].item()) + # writer.write_data(f'property_{prop_num}') + for prop_num, prop_val in enumerate(val[n]): + writer.write_data(f'property_{prop_num}', prop_val.item()) + # writer.write_data(f'property_') + else: + writer.write_data(key, val[n].item())
+ + +
+[docs] + def write_epoch(self, epoch): + for writer in self.history_writers: + writer.write_epoch(epoch)
+ + +
+[docs] + def write_loss(self, loss): + for n, writer in enumerate(self.history_writers): + writer.write_data('loss', loss[0][n].item())
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/kernels/base_kernel.html b/html/_modules/pancax/kernels/base_kernel.html new file mode 100644 index 0000000..60de774 --- /dev/null +++ b/html/_modules/pancax/kernels/base_kernel.html @@ -0,0 +1,393 @@ + + + + + + + + pancax.kernels.base_kernel — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.kernels.base_kernel

+from abc import ABC
+from abc import abstractmethod
+from jax import hessian, jacfwd, vmap
+from jax import numpy as jnp
+from pancax.fem import read_exodus_mesh
+from pancax.fem.function_space import compute_field_gradient
+from typing import Callable, Dict, List, Union
+import equinox as eqx
+
+
+
+[docs] +def vector_names(base_name: str, dim: int): + pass
+ + + +
+[docs] +def full_tensor_names(base_name: str): + """ + Provides a full list of tensorial variable component names + :param base_name: base name for a tensor variable e.g. base_name_xx + """ + return [ + f'{base_name}_xx', f'{base_name}_xy', f'{base_name}_xz', + f'{base_name}_yx', f'{base_name}_yy', f'{base_name}_yz', + f'{base_name}_zx', f'{base_name}_zy', f'{base_name}_zz' + ]
+ + + +
+[docs] +def full_tensor_names_2D(base_name: str): + """ + Provides a full list of tensorial variable component names + :param base_name: base name for a tensor variable e.g. base_name_xx + """ + return [ + f'{base_name}_xx', f'{base_name}_xy', + f'{base_name}_yx', f'{base_name}_yy' + ]
+ + +# TODO improve this +
+[docs] +def element_pp(func, has_props=False, jit=True): + """ + :param func: Function to use for an element property output variable + :param has_props: Whether or not this function need properties + :param jit: Whether or not to jit this function + """ + if jit: + return eqx.filter_jit(func) + else: + return func
+ + + +
+[docs] +def nodal_pp(func, has_props=False, jit=True): + """ + :param func: Function to use for a nodal property output variable + :param has_props: Whether or not this function need properties + :param jit: Whether or not to jit this function + """ + if has_props: + # new_func = lambda p, d, t: vmap( + # func, in_axes=(None, 0, None, None) + # )(p.fields, d.coords, t, p.properties) + new_func = lambda p, d, t: vmap( + func, in_axes=(None, 0, None) + )(p, d.coords, t) + else: + new_func = lambda p, d, t: vmap( + func, in_axes=(None, 0, None) + )(p.fields, d.coords, t) + + if jit: + return eqx.filter_jit(new_func) + else: + return new_func
+ + + +# make a standard pp method that just has nodal fields, element grads, etc. +
+[docs] +def standard_pp(physics): + d = { + 'field_values': { + 'method': nodal_pp(physics.field_values), + 'names' : physics.field_value_names + } + } + return d
+ + + +
+[docs] +class PhysicsKernel(ABC): + n_dofs: int + field_value_names: List[str] + bc_func: Callable # further type this guy + var_name_to_method: Dict[str, Dict[str, Union[Callable, List[str]]]] = {} + use_delta_pinn: bool + +
+[docs] + def __init__( + self, + mesh_file, + bc_func, + use_delta_pinn + ) -> None: + self.bc_func = bc_func + self.use_delta_pinn = use_delta_pinn + + # currently a dumb setup + mesh = read_exodus_mesh(mesh_file) + + self.x_mins = jnp.min(mesh.coords, axis=0) + self.x_maxs = jnp.max(mesh.coords, axis=0) + + print('Bounding box for mesh:') + print(f' x_mins = {self.x_mins}') + print(f' x_maxs = {self.x_maxs}') + + if self.use_delta_pinn: + def field_basis(self, basis_network, x, t, v): + inputs = jnp.hstack((v, t)) + z = basis_network(inputs) + return z + + def field_values(field_network, x, t, v): + # TODO assume here for now that modes are normalized + # v_temp = (v - jnp.min(v, axis=0)) / (jnp.max(v, axis=0) - jnp.min(v, axis=0)) + # inputs = jnp.hstack((v_temp, t)) + inputs = jnp.hstack((v, t)) + z = field_network(inputs) + u = self.bc_func(x, t, z) + return u + else: + def field_basis(self, basis_network, x, t): + x = (x - self.x_mins) / (self.x_maxs - self.x_mins) + inputs = jnp.hstack((x, t)) + z = basis_network(inputs) + return z + + def field_values(field_network, x, t): + x_temp = (x - self.x_mins) / (self.x_maxs - self.x_mins) + inputs = jnp.hstack((x_temp, t)) + z = field_network(inputs) + u = self.bc_func(x, t, z) + return u + + self.field_basis = field_basis + self.field_values = field_values
+
+ + + +
+[docs] +class StrongFormPhysicsKernel(PhysicsKernel): + n_dofs: int + field_value_names: List[str] + bc_func: Callable # further type this guy + use_delta_pinn: bool + +
+[docs] + def __init__(self, mesh_file, bc_func, use_delta_pinn) -> None: + # if use_delta_pinn: + # raise ValueError('DeltaPINNs are currently not supported with collocation PINNs.') + super().__init__(mesh_file, bc_func, use_delta_pinn)
+ + +
+[docs] + def field_gradients(self, field_network, x, t): + return jacfwd(self.field_values, argnums=1)(field_network, x, t)
+ + +
+[docs] + def field_hessians(self, field_network, x, t): + return hessian(self.field_values, argnums=1)(field_network, x, t)
+ + +
+[docs] + def field_laplacians(self, field_network, x, t): + return jnp.trace(self.field_hessians(field_network, x, t), axis1=1, axis2=2)
+ + +
+[docs] + def field_time_derivatives(self, field_network, x, t): + return jacfwd(self.field_values, argnums=2)(field_network, x, t)
+ + +
+[docs] + def field_second_time_derivatives(self, field_network, x, t): + return jacfwd(self.field_time_derivatives, argnums=2)(field_network, x, t)
+ + +
+[docs] + @abstractmethod + def strong_form_neumann_bc(self, params, x, t, n): + pass
+ + +
+[docs] + @abstractmethod + def strong_form_residual(self, params, x, t): + pass
+
+ + + +
+[docs] +class WeakFormPhysicsKernel(PhysicsKernel): + n_dofs: int + field_value_names: List[str] + bc_func: Callable # further type this guy + use_delta_pinn: bool + +
+[docs] + def __init__(self, mesh_file, bc_func, use_delta_pinn) -> None: + super().__init__(mesh_file, bc_func, use_delta_pinn)
+ + +
+[docs] + def element_field_gradient(self, params, domain, t): + us = self.field_values(params, domain.coords, t) + grads = compute_field_gradient(domain.fspace, us, domain.coords) + return grads
+ + + # newer methods +
+[docs] + def element_quantity(self, f, fspace, x_el, u_el, props): + Ns = fspace.shape_function_values(x_el) + grad_Ns = fspace.shape_function_gradients(x_el) + JxWs = fspace.JxWs(x_el) + return jnp.sum(vmap(f, in_axes=(None, None, 0, 0, 0, None))(x_el, u_el, Ns, grad_Ns, JxWs, props))
+ + +
+[docs] + def element_quantity_grad(self, f, fspace, x_el, u_el, props): + return jacfwd(self.element_quantity, argnums=3)(f, fspace, x_el, u_el, props)
+ + +
+[docs] + def element_quantity_hessian(self, f, fspace, x_el, u_el, props): + return hessian(self.element_quantity, argnums=3)(f, fspace, x_el, u_el, props)
+ + +
+[docs] + @abstractmethod + def energy(self, x_el, u_el, N, grad_N, JxW, props): + pass
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/kernels/laplace_beltrami.html b/html/_modules/pancax/kernels/laplace_beltrami.html new file mode 100644 index 0000000..fa65421 --- /dev/null +++ b/html/_modules/pancax/kernels/laplace_beltrami.html @@ -0,0 +1,158 @@ + + + + + + + + pancax.kernels.laplace_beltrami — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.kernels.laplace_beltrami

+from .base_kernel import WeakFormPhysicsKernel
+from .base_kernel import nodal_pp
+from typing import Optional
+import jax.numpy as jnp
+
+
+
+[docs] +class LaplaceBeltrami(WeakFormPhysicsKernel): + n_dofs = 1 + field_names = ['eigenvector'] + use_delta_pinn: bool + +
+[docs] + def __init__(self, mesh_file, bc_func, n_eigs: int, use_delta_pinn: Optional[bool] = False): + super().__init__(mesh_file, bc_func, use_delta_pinn) + self.n_eigs = n_eigs + self.var_name_to_method = { + 'eigenvector': { + 'method': nodal_pp(self.field_values), + 'names' : self.field_names + } + }
+ + +
+[docs] + def energy(self, x_el, u_el, N, grad_N, JxW, props): + # caclulate quadrature level fields + grad_u_q = (grad_N.T @ u_el).T + + # kernel specific stuff here + pi_q = 0.5 * jnp.dot(grad_u_q, grad_u_q.T) + + return JxW * pi_q
+ + +
+[docs] + def kinetic_energy(self, x_el, u_el, N, grad_N, JxW, props): + return JxW * 0.5 * jnp.dot(u_el.T, u_el)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/kernels/linear_elasticity.html b/html/_modules/pancax/kernels/linear_elasticity.html new file mode 100644 index 0000000..db382a3 --- /dev/null +++ b/html/_modules/pancax/kernels/linear_elasticity.html @@ -0,0 +1,199 @@ + + + + + + + + pancax.kernels.linear_elasticity — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.kernels.linear_elasticity

+from .base_kernel import StrongFormPhysicsKernel, WeakFormPhysicsKernel
+from .base_kernel import nodal_pp, standard_pp, full_tensor_names_2D
+from jax import jacfwd
+from typing import Callable, Optional
+import jax.numpy as jnp
+
+
+
+[docs] +class LinearElasticity2D(StrongFormPhysicsKernel, WeakFormPhysicsKernel): + n_dofs = 2 + field_value_names = ['displ_x', 'displ_y'] + use_delta_pinn: bool + +
+[docs] + def __init__( + self, + mesh_file: str, + bc_func: Callable, + body_force: Callable = lambda x, t: jnp.zeros(2), + use_delta_pinn: Optional[bool] = False + ) -> None: + super().__init__(mesh_file, bc_func, use_delta_pinn) + self.body_force = body_force + self.var_name_to_method = standard_pp(self) + self.var_name_to_method['field_gradients'] = { + 'names': full_tensor_names_2D('grad_displ'), + 'method': nodal_pp(self.field_gradients) + } + self.var_name_to_method['linear_strain'] = { + 'names': full_tensor_names_2D('linear_strain'), + 'method': nodal_pp(self.linear_strain) + } + self.var_name_to_method['cauchy_stress'] = { + 'names': full_tensor_names_2D('cauchy_stress'), + 'method': nodal_pp(self.cauchy_stress, has_props=True) + }
+ + +
+[docs] + def energy(self, x_el, u_el, N, grad_N, JxW, props): + lambda_, mu = props() + grad_u_q = (grad_N.T @ u_el).T + strain = 0.5 * (grad_u_q + grad_u_q.T) + return 0.5 * lambda_ * jnp.trace(strain)**2 + \ + mu * jnp.trace(strain @ strain)
+ + +
+[docs] + def strong_form_residual(self, params, x, t): + div_stress = jacfwd(self.cauchy_stress, argnums=1)(params, x, t) + div_stress = jnp.trace(div_stress, axis1=1, axis2=2) + f = self.body_force(x, t) + return div_stress + f
+ + +
+[docs] + def strong_form_neumann_bc(self, params, x, t, n): + sigma = self.cauchy_stress(params, x, t) + traction = sigma @ n + return traction
+ + +
+[docs] + def linear_strain(self, field_network, x, t): + grad_u = self.field_gradients(field_network, x, t) + return 0.5 * (grad_u + grad_u.T)
+ + +
+[docs] + def cauchy_stress(self, params, x, t): + field_network, props = params + lambda_, mu = props() + strain = self.linear_strain(field_network, x, t) + stress = lambda_ * jnp.trace(strain) * jnp.eye(2) + \ + 2. * mu * strain + return stress
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/kernels/poisson.html b/html/_modules/pancax/kernels/poisson.html new file mode 100644 index 0000000..a0e0eb1 --- /dev/null +++ b/html/_modules/pancax/kernels/poisson.html @@ -0,0 +1,172 @@ + + + + + + + + pancax.kernels.poisson — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.kernels.poisson

+from .base_kernel import StrongFormPhysicsKernel, WeakFormPhysicsKernel
+from .base_kernel import standard_pp
+from typing import Callable, Optional
+import jax.numpy as jnp
+
+
+
+[docs] +class Poisson(StrongFormPhysicsKernel, WeakFormPhysicsKernel): + n_dofs = 1 + field_value_names = ['u'] + use_delta_pinn: bool + +
+[docs] + def __init__( + self, + mesh_file, + bc_func: Callable, + f: Callable, + use_delta_pinn: Optional[bool] = False + ): + super().__init__(mesh_file, bc_func, use_delta_pinn) + self.f = f + self.var_name_to_method = standard_pp(self)
+ + +
+[docs] + def energy(self, x_el, u_el, N, grad_N, JxW, props): + # caclulate quadrature level fields + x_q = jnp.dot(N, x_el) + u_q = jnp.dot(N, u_el) + grad_u_q = (grad_N.T @ u_el).T + + # kernel specific stuff here + f_q = self.f(x_q) + pi_q = 0.5 * jnp.dot(grad_u_q, grad_u_q.T) - f_q * u_q + return JxW * pi_q
+ + +
+[docs] + def strong_form_residual(self, params, x, t): + field_network, props = params + delta_u = self.field_laplacians(field_network, x, t)[0] + f = self.f(x) + return -delta_u - f
+ + +
+[docs] + def strong_form_neumann_bc(self, params, x, t, n): + field_network, props = params + grad_u = self.field_gradients(field_network, x, t) + return -jnp.dot(grad_u, n)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/kernels/solid_mechanics.html b/html/_modules/pancax/kernels/solid_mechanics.html new file mode 100644 index 0000000..0ae70a5 --- /dev/null +++ b/html/_modules/pancax/kernels/solid_mechanics.html @@ -0,0 +1,411 @@ + + + + + + + + pancax.kernels.solid_mechanics — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.kernels.solid_mechanics

+from abc import ABC, abstractmethod
+from ..constitutive_models import ConstitutiveModel
+from .base_kernel import StrongFormPhysicsKernel, WeakFormPhysicsKernel
+from .base_kernel import element_pp, full_tensor_names, nodal_pp
+from pancax.fem.function_space import compute_field_gradient
+from pancax.math.tensor_math import *
+from typing import Callable, List, Optional
+import jax
+import jax.numpy as jnp
+
+
+# different formulations e.g. plane strain/stress, axisymmetric etc.
+
+[docs] +class BaseMechanicsFormulation(ABC): + n_dimensions: int + +
+[docs] + @abstractmethod + def modify_field_gradient(self, grad_u): + pass
+
+ + + +# note for this formulation we're getting NaNs if the +# reference configuration is used during calculation +# of the loss function +
+[docs] +class IncompressiblePlaneStress(BaseMechanicsFormulation): + n_dimensions = 2 + +
+[docs] + def __init__(self) -> None: + print('WARNING: Do not include a time of 0.0 with this formulation. You will get NaNs.')
+ + +
+[docs] + def deformation_gradient(self, grad_u): + F = tensor_2D_to_3D(grad_u) + jnp.eye(3) + F = F.at[2, 2].set(1. / jnp.linalg.det(grad_u + jnp.eye(2))) + return F
+ + +
+[docs] + def modify_field_gradient(self, grad_u): + F = self.deformation_gradient(grad_u) + return F - jnp.eye(3)
+
+ + + +
+[docs] +class PlaneStrain(BaseMechanicsFormulation): + n_dimensions = 2 + +
+[docs] + def extract_stress(self, P): + return P[0:2, 0:2]
+ + +
+[docs] + def modify_field_gradient(self, grad_u): + return tensor_2D_to_3D(grad_u)
+
+ + + +
+[docs] +class ThreeDimensional(BaseMechanicsFormulation): + n_dimensions = 3 + +
+[docs] + def modify_field_gradient(self, grad_u): + return grad_u
+
+ + + +# actual mechanics kernel +
+[docs] +class SolidMechanics(StrongFormPhysicsKernel, WeakFormPhysicsKernel): + n_dofs: int + field_values_names: List[str] + bc_func: Callable + constitutive_model: ConstitutiveModel + formulation: BaseMechanicsFormulation + var_name_to_method: dict + use_delta_pinn: bool + +
+[docs] + def __init__( + self, + mesh, + bc_func, + constitutive_model, + formulation, + use_delta_pinn: Optional[bool] = False + ): + super().__init__(mesh, bc_func, use_delta_pinn) + self.n_dofs = formulation.n_dimensions + self.field_value_names = [ + 'displ_x', 'displ_y' + ] + if self.n_dofs == 3: + self.field_value_names.append('displ_z') + + self.constitutive_model = constitutive_model + self.formulation = formulation + self.var_name_to_method = { + 'displacement': { + 'method': nodal_pp(self.field_values), + 'names' : self.field_value_names + }, + 'element_cauchy_stress': { + 'method': element_pp(self.element_quantity_from_func( + self.constitutive_model.cauchy_stress, with_props=True + )), + 'names' : full_tensor_names('cauchy_stress') + }, + 'element_displacement_gradient': { + 'method': element_pp(self.element_field_gradient), + 'names' : full_tensor_names('displ_grad') + }, + 'element_deformation_gradient': { + 'method': element_pp(self.element_quantity_from_func( + lambda x: x + )), + 'names' : full_tensor_names('deformation_gradient') + }, + 'element_invariants': { + 'method': element_pp(self.element_quantity_from_func( + self.constitutive_model.invariants + )), + 'names' : ['I1', 'I2', 'I3'] + }, + 'element_pk1_stress': { + 'method': element_pp(self.element_quantity_from_func( + self.constitutive_model.pk1_stress, with_props=True + )), + 'names' : full_tensor_names('pk1_stress') + } + }
+ + + # TODO move these to base weakform class if possible? +
+[docs] + def element_field_gradient(self, params, domain, t): + us = vmap(self.field_values, in_axes=(None, 0, None))( + params.fields, domain.coords, t + ) + # grads = compute_field_gradient(domain.fspace, us, domain.coords) + # grads = domain.fspace.compute_field_gradient(domain.coords, us, domain.conns) + grads = jax.vmap(domain.fspace.compute_field_gradient, in_axes=(0, 0))( + us[domain.conns, :], domain.coords[domain.conns, :] + ) + modify_field_grad = self.formulation.modify_field_gradient + func = lambda grad: modify_field_grad(grad).flatten() + return vmap(vmap(func))(grads)
+ + +
+[docs] + def element_quantity_from_func(self, func: Callable, with_props: Optional[bool] = False): + if with_props: + def new_func(params, domain, t): + us = vmap(self.field_values, in_axes=(None, 0, None))( + params.fields, domain.coords, t + ) + props = params.properties() + # grads = compute_field_gradient(domain.fspace, us, domain.coords) + # grads = domain.fspace.compute_field_gradient(domain.coords, us, domain.conns) + grads = jax.vmap(domain.fspace.compute_field_gradient, in_axes=(0, 0))( + us[domain.conns, :], domain.coords[domain.conns, :] + ) + modify_field_grad = self.formulation.modify_field_gradient + grads = vmap(vmap(modify_field_grad))(grads) + Fs = vmap(vmap(lambda grad: grad + jnp.eye(3)))(grads) + temp_func = lambda F: func(F, props).flatten() + return vmap(vmap(temp_func))(Fs) + else: + def new_func(params, domain, t): + us = vmap(self.field_values, in_axes=(None, 0, None))( + params.fields, domain.coords, t + ) + # grads = compute_field_gradient(domain.fspace, us, domain.coords) + # grads = domain.fspace.compute_field_gradient(domain.coords, us, domain.conns) + grads = jax.vmap(domain.fspace.compute_field_gradient, in_axes=(0, 0))( + us[domain.conns, :], domain.coords[domain.conns, :] + ) + modify_field_grad = self.formulation.modify_field_gradient + grads = vmap(vmap(modify_field_grad))(grads) + Fs = vmap(vmap(lambda grad: grad + jnp.eye(3)))(grads) + temp_func = lambda grad: func(grad).flatten() + return vmap(vmap(temp_func))(Fs) + return new_func
+ + +
+[docs] + def energy(self, x_el, u_el, N, grad_N, JxW, props): + + # caclulate quadrature level fields + grad_u_q = self.formulation.modify_field_gradient((grad_N.T @ u_el).T) + F_q = grad_u_q + jnp.eye(3) + W = self.constitutive_model.energy(F_q, props) + return JxW * W
+ + + # trying out enforcing detF = 1 +
+[docs] + def nodal_incompressibility_constraint(self, field_network, x, t): + grad_u = self.field_gradients(field_network, x, t) + grad_u = self.formulation.modify_field_gradient(grad_u) + F = grad_u + jnp.eye(3) + return (jnp.linalg.det(F) - 1.)**2
+ + +
+[docs] + def quadrature_incompressibility_constraint(self, x_el, u_el, N, grad_N, JxW, props): + grad_u_q = self.formulation.modify_field_gradient((grad_N.T @ u_el).T) + F_q = grad_u_q + jnp.eye(3) + J_q = self.constitutive_model.jacobian(F_q) + return 0.5 * JxW * (J_q - 1.)**2
+ + + # TODO good code below just commenting out for now. +
+[docs] + def pk1_stress_weak_form(self, x_el, u_el, N, grad_N, JxW, props): + grad_u_q = self.formulation.modify_field_gradient((grad_N.T @ u_el).T) + F_q = grad_u_q + jnp.eye(3) + P = jax.grad(self.constitutive_model.energy)(F_q, props) + return P
+ + +
+[docs] + def strong_form_residual(self, params, x, t): + div_stress = jax.jacfwd(self.pk1_stress, argnums=1)(params, x, t) + div_stress = jnp.trace(div_stress, axis1=1, axis2=2) + return div_stress
+ + +
+[docs] + def strong_form_neumann_bc(self, params, x, t, n): + P = self.pk1_stress(params, x, t) + # P = self.formulation.extract_stress(P) + # n = jnp.hstack((n, jnp.zeros(1, dtype=jnp.float64))) + traction = P @ n + return traction
+ + +
+[docs] + def pk1_stress(self, params, x, t): + field_network, props = params + grad_u = self.field_gradients(field_network, x, t) + # grad_u = self.formulation.modify_field_gradient(grad_u) + # F = grad_u + jnp.eye(3) + F = grad_u + jnp.eye(2) + + def const_model(F, props): + props = props() + K, G = props[0], props[1] + # kinematics + C = F.T @ F + # J = self.jacobian(F) + J = jnp.linalg.det(F) + # I_1_bar = jnp.trace(jnp.power(J, -2. / 3.) * C) + I_1_bar = jnp.trace(1. / jnp.square(jnp.sqrt(J)) * C) + + # constitutive + W_vol = 0.5 * K * (0.5 * (J**2 - 1) - jnp.log(J)) + W_dev = 0.5 * G * (I_1_bar - 2.) + return W_vol + W_dev + P = jax.grad(const_model, argnums=0)(F, props) + # P = jax.grad(self.constitutive_model.energy)(F, props) + return P
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/kinematics.html b/html/_modules/pancax/kinematics.html new file mode 100644 index 0000000..958c6fd --- /dev/null +++ b/html/_modules/pancax/kinematics.html @@ -0,0 +1,222 @@ + + + + + + + + pancax.kinematics — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.kinematics

+from jax import hessian
+from jax import jacfwd
+from jax import vmap
+from .math.tensor_math import tensor_2D_to_3D
+import jax.numpy as jnp
+
+
+# single point methods
+# def field_value(network, x, t):e
+
+
+[docs] +def create_field_methods(domain, bc_func): + # normalization up front + # TODO currently hard-coded to min-max normalization + # TODO make this selectable + x_mins = jnp.min(domain.coords, axis=0) + x_maxs = jnp.max(domain.coords, axis=0) + + # single point methods + def field_value(network, x, t): + x_normalized = (x - x_mins) / (x_maxs - x_mins) + z = network(jnp.hstack((x_normalized, t))) + u = bc_func(x, t, z) + return u + + def field_gradient(network, x, t): + return jacfwd(field_value, argnums=1)(network, x, t) + + def field_hessian(network, x, t): + return hessian(field_value, argnums=1)(network, x, t) + + def field_time_derivative(network, x, t): + return jacfwd(field_value, argnums=2)(network, x, t) + + return field_value, field_gradient, field_hessian, field_time_derivative
+ + # all point methods at single time step + # def field_values(network, xs, t): + # return vmap(field_value, in_axes=(None, 0, None))(network, xs, t) + + # def field_gradients(network, xs, t): + # return vmap(field_gradient, in_axes=(None, 0, None))(network, xs, t) + + # def field_hessians(network, xs, t): + # return vmap(field_hessian, in_axes=(None, 0, None))(network, xs, t) + + # def field_time_derivatives(network, xs, t): + # return vmap(field_time_derivative, in_axes=(None, 0, None))(network, xs, t) + + # return field_values, field_gradients, field_hessians, field_time_derivatives + + +
+[docs] +def deformation_gradients(grad_us, formulation): + temp = vmap(lambda x: tensor_2D_to_3D(x) + jnp.eye(3))(grad_us) + # temp = tensor_2D_to_3D(grad_us) + jnp.eye(3) + Fs = vmap(lambda x: formulation(x), in_axes=(0,))(temp) + return Fs
+ + + +
+[docs] +def invariants_old(grad_us, formulation): + Fs = deformation_gradients(grad_us, formulation) + Cs = vmap(lambda F: F.T @ F, in_axes=(0,))(Fs) + Cs_squared = vmap(lambda C: C @ C, in_axes=(0,))(Cs) + I1s = vmap(lambda C: jnp.trace(C), in_axes=(0,))(Cs) + I2s = vmap(lambda I1, C_squared: 0.5 * (I1**2 - jnp.trace(C_squared)), in_axes=(0, 0))(I1s, Cs_squared) + I3s = vmap(lambda C: jnp.linalg.det(C), in_axes=(0,))(Cs) + return I1s, I2s, I3s
+ + + +
+[docs] +def invariants(grad_u): + F = grad_u + jnp.eye(3) + C = F.T @ F + C_squared = C @ C + I1 = jnp.trace(C) + I2 = 0.5 * (I1**2 - jnp.trace(C_squared)) + I3 = jnp.linalg.det(C) + return I1, I2, I3
+ + + +
+[docs] +def plane_strain(F): + return F
+ + + +
+[docs] +def incompressible_plane_stress(F): + F_33 = 1.0 / (F[0, 0] * F[1, 1] - F[0, 1] * F[1, 0]) + return jnp.array( + [ + [F[0, 0], F[0, 1], 0.0], + [F[1, 0], F[1, 1], 0.0], + [0.0 , 0.0 , F_33] + ] + )
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/logging.html b/html/_modules/pancax/logging.html new file mode 100644 index 0000000..6c5c161 --- /dev/null +++ b/html/_modules/pancax/logging.html @@ -0,0 +1,270 @@ + + + + + + + + pancax.logging — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.logging

+from abc import abstractmethod
+from pathlib import Path
+from typing import List
+import equinox as eqx
+
+
+
+[docs] +def log_loss(loss, n, log_every): + if n % log_every == 0: + print(f'Epoch {n}:') + print(f'\tLoss = {loss[0].item()}') + for key, val in loss[1].items(): + if key == 'props' or key == 'dprops': + print(f'\t{key} = {val}') + else: + print(f'\t{key} = {val.item()}')
+ + + +
+[docs] +class BaseLogger(eqx.Module): + log_every: int + +
+[docs] + @abstractmethod + def flush(self): + pass
+ + +
+[docs] + def log_loss(self, loss, epoch): + if epoch % self.log_every == 0: + self.write_epoch_value(epoch) + self.write_loss_value(loss) + self.write_aux_values(loss) + self.flush()
+ + +
+[docs] + @abstractmethod + def write_aux_values(self, loss): + pass
+ + +
+[docs] + @abstractmethod + def write_epoch_value(self, epoch): + pass
+ + +
+[docs] + @abstractmethod + def write_loss_value(self, loss): + pass
+
+ + + +
+[docs] +class Logger(BaseLogger): + log_file: any + +
+[docs] + def __init__(self, log_file_in: str, log_every: int) -> None: + super().__init__(log_every) + log_file_in = Path(log_file_in) + self.log_file = open(log_file_in, 'w')
+ + + def __exit__(self, exc_type, exc_value, exc_traceback): + print(f'Closing log file.') + self.log_file.close() + +
+[docs] + def flush(self): + self.log_file.flush()
+ + +
+[docs] + def write_aux_values(self, loss): + for key, val in loss[1].items(): + if key == 'props' or key == 'dprops': + self.log_file.write(f' {key} = {val}\n') + else: + self.log_file.write(f' {key} = {val.item()}\n')
+ + +
+[docs] + def write_epoch_value(self, epoch): + self.log_file.write(f'Epoch {epoch}:\n')
+ + +
+[docs] + def write_loss_value(self, loss): + self.log_file.write(f' Loss = {loss[0].item()}\n')
+
+ + + +
+[docs] +class EnsembleLogger(BaseLogger): + loggers: List[Logger] + +
+[docs] + def __init__(self, base_name: str, n_pinns: int, log_every: int) -> None: + super().__init__(log_every) + self.loggers = [Logger(f'{base_name}_{n}.log', log_every) for n in range(n_pinns)]
+ + +
+[docs] + def flush(self): + for logger in self.loggers: + logger.flush()
+ + +
+[docs] + def write_aux_values(self, loss): + for key, val in loss[1].items(): + for n, logger in enumerate(self.loggers): + if key == 'props' or key == 'dprops': + logger.log_file.write(f' {key} = {val[n]}\n') + else: + logger.log_file.write(f' {key} = {val[n].item()}\n')
+ + +
+[docs] + def write_epoch_value(self, epoch): + for logger in self.loggers: + logger.write_epoch_value(epoch)
+ + +
+[docs] + def write_loss_value(self, loss): + for n, val in enumerate(loss[0]): + self.loggers[n].log_file.write(f' Loss = {val.item()}\n')
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/base_loss_function.html b/html/_modules/pancax/loss_functions/base_loss_function.html new file mode 100644 index 0000000..ea7f246 --- /dev/null +++ b/html/_modules/pancax/loss_functions/base_loss_function.html @@ -0,0 +1,172 @@ + + + + + + + + pancax.loss_functions.base_loss_function — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.loss_functions.base_loss_function

+from abc import abstractmethod
+import equinox as eqx
+
+
+
+[docs] +class BaseLossFunction(eqx.Module): + """ + Base class for loss functions. + Currently does nothing but helps build a + type hierarchy. + """ + +
+[docs] + def filtered_loss(self, diff_params, static_params, domain): + params = eqx.combine(diff_params, static_params) + return self.__call__(params, domain)
+
+ + + +
+[docs] +class BCLossFunction(BaseLossFunction): + """ + Base class for boundary condition loss functions. + + A ``load_step`` method is expect with the following + type signature + ``load_step(self, params, domain, t)`` + """ +
+[docs] + @abstractmethod + def load_step(self, params, domain, t): + pass
+
+ + + +
+[docs] +class PhysicsLossFunction(BaseLossFunction): + """ + Base class for physics loss functions. + + A ``load_step`` method is expect with the following + type signature + ``load_step(self, params, domain, t)`` + """ +
+[docs] + @abstractmethod + def load_step(self, params, domain, t): + pass
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/bc_loss_functions.html b/html/_modules/pancax/loss_functions/bc_loss_functions.html new file mode 100644 index 0000000..89c7006 --- /dev/null +++ b/html/_modules/pancax/loss_functions/bc_loss_functions.html @@ -0,0 +1,198 @@ + + + + + + + + pancax.loss_functions.bc_loss_functions — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.loss_functions.bc_loss_functions

+from .base_loss_function import BCLossFunction
+from jax import vmap
+from typing import Optional
+import jax.numpy as jnp
+
+
+
+[docs] +class DirichletBCLoss(BCLossFunction): + weight: float + +
+[docs] + def __init__(self, weight: Optional[float] = 1.0): + self.weight = weight
+ + + def __call__(self, params, domain): + error = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ).mean() + return self.weight * error, dict(dirichlet_bc=error) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + # TODO switch to using a jax.lax.scan below + # error = 0.0 + # for bc in domain.essential_bcs: + # coords = domain.coords[domain.mesh.nodeSets[bc.nodeSet]] + # us_predicted = vmap(domain.physics.field_values, in_axes=(None, 0, None))( + # field_network, coords, t + # )[:, bc.component] + # us_expected = vmap(bc.function, in_axes=(0, None))(coords, t) + # error += jnp.square(us_predicted - us_expected).mean() + + # print(type(domain.essential_bcs)) + def vmap_func(bc): + coords = domain.coords[domain.mesh.nodeSets[bc.nodeSet]] + us_predicted = vmap(domain.physics.field_values, in_axes=(None, 0, None))( + field_network, coords, t + )[:, bc.component] + us_expected = vmap(bc.function, in_axes=(0, None))(coords, t) + return jnp.square(us_predicted - use_expected).mean() + + errors = vmap(vmap_func)(domain.essential_bcs) + error = jnp.sum(errors) + return error
+
+ + + +# NOTE below only supports zero neumann conditions currently +# NOTE this will break on delta PINNs maybe? +
+[docs] +class NeumannBCLoss(BCLossFunction): + weight: float + +
+[docs] + def __init__(self, weight: Optional[float] = 1.0): + self.weight = weight
+ + + def __call__(self, params, domain): + error = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ).mean() + return self.weight * error, dict(neumann_bc=error) + +
+[docs] + def load_step(self, params, domain, t): + func = domain.physics.strong_form_neumann_bc + xs = domain.neumann_xs + ns = domain.neumann_ns + error = jnp.square(vmap(func, in_axes=(None, 0, None, 0))( + params, xs, t, ns + )).mean() + return error
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/data_loss_functions.html b/html/_modules/pancax/loss_functions/data_loss_functions.html new file mode 100644 index 0000000..b757b98 --- /dev/null +++ b/html/_modules/pancax/loss_functions/data_loss_functions.html @@ -0,0 +1,150 @@ + + + + + + + + pancax.loss_functions.data_loss_functions — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.loss_functions.data_loss_functions

+from .base_loss_function import BaseLossFunction
+from jax import vmap
+from typing import Optional
+import jax.numpy as jnp
+
+
+
+[docs] +class FullFieldDataLoss(BaseLossFunction): + weight: float + +
+[docs] + def __init__( + self, + weight: Optional[float] = 1.0 + ): + self.weight = weight
+ + + def __call__(self, params, domain): + field_network, _ = params + n_dims = domain.coords.shape[1] + xs = domain.field_data.inputs[:, 0:n_dims] + # TODO need time normalization + ts = domain.field_data.inputs[:, n_dims] + # TODO below is currenlty the odd ball for the field_value API + u_pred = vmap(domain.physics.field_values, in_axes=(None, 0, 0))( + field_network, xs, ts + ) + + # TODO add output normalization + loss = jnp.square(u_pred - domain.field_data.outputs).mean() + aux = {'field_data_loss': loss} + return self.weight * loss, aux
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/physics_loss_functions_strong_form.html b/html/_modules/pancax/loss_functions/physics_loss_functions_strong_form.html new file mode 100644 index 0000000..a233864 --- /dev/null +++ b/html/_modules/pancax/loss_functions/physics_loss_functions_strong_form.html @@ -0,0 +1,175 @@ + + + + + + + + pancax.loss_functions.physics_loss_functions_strong_form — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.loss_functions.physics_loss_functions_strong_form

+from jax import vmap
+from pancax.physics import nodal_incompressibility_constraint
+from typing import Optional
+import jax.numpy as jnp
+
+
+
+[docs] +def StrongFormResidualLoss(weight: Optional[float] = 1.0): + def loss_func(params, domain): + times = domain.times + func = domain.physics.strong_form_residual + xs = domain.coords + def vmap_func(params, xs, t): + residuals = vmap(func, in_axes=(None, 0, None))(params, xs, t) + residuals = residuals[domain.dof_manager.unknownIndices].flatten() + residual = jnp.square(residuals).mean() + return residual + residual = vmap(vmap_func, in_axes=(None, None, 0))(params, xs, times) + residual = residual.mean() + return weight * residual, dict(residual=residual) + return loss_func
+ + + +# def StrongFormDirichletBCLoss(weight: Optional[float] = 1.0): +# def loss_func(params, domain): +# times = domain.times +# func = domain.physics.field_values + + +# TODO need to add support for inhomogeneous neumann conditions +
+[docs] +def StrongFormNeumannBCLoss(weight: Optional[float] = 1.0): + def loss_func(params, domain): + times = domain.times + func = domain.physics.strong_form_neumann_bc + xs = domain.neumann_inputs + ns = domain.neumann_normals + def vmap_func(params, xs, t, ns): + residuals = vmap(func, in_axes=(None, 0, None, 0))(params, xs, t, ns) + residual = jnp.square(residuals - domain.neumann_outputs).mean() + return residual + residual = vmap(vmap_func, in_axes=(None, None, 0, None))(params, xs, times, ns) + residual = residual.mean() + return weight * residual, dict(neumann=residual) + return loss_func
+ + + +
+[docs] +def StrongFormIncompressibilityConstraint(weight: Optional[bool] = 1.0): + def loss_func(params, domain): + def vmap_func(params, domain, time): + return nodal_incompressibility_constraint(params, domain, time) + loss = jnp.mean(vmap(vmap_func, in_axes=(None, None, 0))(params, domain, domain.times)) + return weight * loss, dict(incompressibility_error=loss) + return loss_func
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/strong_form_loss_functions.html b/html/_modules/pancax/loss_functions/strong_form_loss_functions.html new file mode 100644 index 0000000..9c113d5 --- /dev/null +++ b/html/_modules/pancax/loss_functions/strong_form_loss_functions.html @@ -0,0 +1,147 @@ + + + + + + + + pancax.loss_functions.strong_form_loss_functions — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.loss_functions.strong_form_loss_functions

+from .base_loss_function import PhysicsLossFunction
+from jax import vmap
+from typing import Optional
+import jax.numpy as jnp
+
+
+# NOTE this probably does not currently dsupport deltaPINNs
+
+[docs] +class StrongFormResidualLoss(PhysicsLossFunction): + weight: float + +
+[docs] + def __init__(self, weight: Optional[float] = 1.0): + self.weight = weight
+ + + def __call__(self, params, domain): + residual = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ).mean() + return self.weight * residual, dict(residual=residual) + +
+[docs] + def load_step(self, params, domain, t): + func = domain.physics.strong_form_residual + # TODO this will fail on delta PINNs currently + residuals = vmap(func, in_axes=(None, 0, None))(params, domain.coords, t) + return jnp.square(residuals).mean()
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/utils.html b/html/_modules/pancax/loss_functions/utils.html new file mode 100644 index 0000000..7583274 --- /dev/null +++ b/html/_modules/pancax/loss_functions/utils.html @@ -0,0 +1,147 @@ + + + + + + + + pancax.loss_functions.utils — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.loss_functions.utils

+from .base_loss_function import BaseLossFunction
+
+
+
+[docs] +class CombineLossFunctions(BaseLossFunction): + funcs: any + with_props: bool + +
+[docs] + def __init__(self, *funcs, with_props=False): + temp_funcs = [] + for f in funcs: + temp_funcs.append(f) + self.funcs = funcs + self.with_props = with_props
+ + + def __call__(self, params, domain): + loss = 0.0 + aux = dict() + for f in self.funcs: + temp_loss, temp_aux = f(params, domain) + loss = loss + temp_loss + aux.update(temp_aux) + + if self.with_props: + props = params.properties() + aux.update({'props': props}) + + return loss, aux
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/loss_functions/weak_form_loss_functions.html b/html/_modules/pancax/loss_functions/weak_form_loss_functions.html new file mode 100644 index 0000000..128d2e2 --- /dev/null +++ b/html/_modules/pancax/loss_functions/weak_form_loss_functions.html @@ -0,0 +1,443 @@ + + + + + + + + pancax.loss_functions.weak_form_loss_functions — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + + +
  • +
  • +
+
+
+
+
+ +

Source code for pancax.loss_functions.weak_form_loss_functions

+from .base_loss_function import PhysicsLossFunction
+from jax import vmap
+from pancax.physics import potential_energy, potential_energy_and_residual
+from pancax.physics import incompressible_energy, incompressible_energy_and_residual
+from pancax.physics import potential_energy_residual_and_reaction_force
+from pancax.physics import quadrature_incompressibility_constraint
+from pancax.physics import residual_mse
+from typing import Optional
+import equinox as eqx
+import jax.numpy as jnp
+
+
+
+[docs] +class EnergyLoss(PhysicsLossFunction): + r""" + Energy loss function akin to the deep energy method. + + Calculates the following quantity + + .. math:: + \mathcal{L} = w\Pi\left[u\right] = w\int_\Omega\psi\left(\mathbf{F}\right) + + :param weight: weight for this loss function + """ + weight: float + +
+[docs] + def __init__(self, weight: Optional[float] = 1.0): + self.weight = weight
+ + + def __call__(self, params, domain): + energies = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ) + energy = jnp.sum(energies) + loss = energy + return self.weight * loss, dict(energy=energy) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + pi = potential_energy(domain, us, props) + return pi
+
+ + + +
+[docs] +class EnergyAndResidualLoss(PhysicsLossFunction): + r""" + Energy and residual loss function used in Hamel et. al + + Calculates the following quantity + + .. math:: + \mathcal{L} = w_1\Pi\left[u\right] + w_2\delta\Pi\left[u\right]_{free} + + :param energy_weight: Weight for the energy w_1 + :param residual_weight: Weight for the residual w_2 + """ + energy_weight: float + residual_weight: float + +
+[docs] + def __init__( + self, + energy_weight: Optional[float] = 1.0, + residual_weight: Optional[float] = 1.0 + ): + self.energy_weight = energy_weight + self.residual_weight = residual_weight
+ + + def __call__(self, params, domain): + pis, Rs = vmap(self.load_step, in_axes=(None, None, 0))(params, domain, domain.times) + pi, R = jnp.sum(pis), jnp.sum(Rs) + loss = self.energy_weight * pi + self.residual_weight * R + return loss, dict(energy=pi, residual=R) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + pi, R = potential_energy_and_residual(domain, us, props) + return pi, R
+
+ + + +
+[docs] +class EnergyResidualAndReactionLoss(PhysicsLossFunction): + energy_weight: float + residual_weight: float + reaction_weight: float + +
+[docs] + def __init__( + self, + energy_weight: Optional[float] = 1.0, + residual_weight: Optional[float] = 1.0, + reaction_weight: Optional[float] = 1.0 + ): + self.energy_weight = energy_weight + self.residual_weight = residual_weight + self.reaction_weight = reaction_weight
+ + + def __call__(self, params, domain): + pis, Rs, reactions = vmap(self.load_step, in_axes=(None, None, 0))(params, domain, domain.times) + pi, R = jnp.sum(pis), jnp.sum(Rs) / len(domain.times) + reaction_loss = jnp.square(reactions - domain.global_data.outputs).mean() + loss = self.energy_weight * pi + \ + self.residual_weight * R + \ + self.reaction_weight * reaction_loss + return loss, dict(energy=pi, residual=R, global_data_loss=reaction_loss) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + return potential_energy_residual_and_reaction_force(domain, us, props)
+
+ + + +
+[docs] +class QuadratureIncompressibilityConstraint(PhysicsLossFunction): + weight: float + +
+[docs] + def __init__(self, weight: Optional[float] = 1.0): + self.weight = weight
+ + + def __call__(self, params, domain): + losses = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ) + loss = jnp.mean(losses) + return self.weight * loss, dict(incompressibility_error=loss) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + return quadrature_incompressibility_constraint(domain, us, props)
+
+ + + +# class QuadratureIncompressibilityConstraintWithForce(PhysicsLossFunction): +# energy_weight: float +# residual_weight: float + +# def __init__( +# self, +# energy_weight: Optional[float] = 1.0, +# residual_weight: Optional[float] = 1.0 +# ): +# self.energy_weight = energy_weight +# self.residual_weight = residual_weight + +# def __call__(self, params, domain): +# losses, residuals = vmap(self.load_step, in_axes=(None, None, 0))( +# params, domain, domain.times +# ) +# loss, R = jnp.sum(losses), jnp.sum(residuals) +# # return self.weight * loss, dict(incompressibility_error=loss) +# loss = self.energy_weight * loss + self.residual_weight * R +# return loss, dict(constraint_energy=loss, constraint_force=R) + +# def load_step(self, params, domain, t): +# field_network, props = params +# us = domain.field_values(field_network, t) +# props = props() +# return quadrature_incompressibility_constraint_energy_and_residual(domain, us, props) + +# def __call__(self, params, domain): +# pis, Rs = vmap(self.load_step, in_axes=(None, None, 0))(params, domain, domain.times) +# pi, R = jnp.sum(pis), jnp.sum(Rs) +# loss = self.energy_weight * pi + self.residual_weight * R +# return loss, dict(energy=pi, residual=R) + +# def load_step(self, params, domain, t): +# field_network, props = params +# us = domain.field_values(field_network, t) +# props = props() +# pi, R = potential_energy_and_residual(domain, us, props) +# return pi, R + + +
+[docs] +class ResidualMSELoss(PhysicsLossFunction): + weight: float + +
+[docs] + def __init__( + self, + weight: Optional[float] = 1.0 + ): + self.weight = weight
+ + + def __call__(self, params, domain): + residuals = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ) + residual = jnp.sum(residuals) + loss = residual + return self.weight * loss, dict(residual=residual) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + R = residual_mse(domain, us, props) + return R
+
+ + + +
+[docs] +class IncompressibleEnergyLoss(PhysicsLossFunction): + r""" + Energy loss function akin to the deep energy method. + + Calculates the following quantity + + .. math:: + \mathcal{L} = w\Pi\left[u\right] = w\int_\Omega\psi\left(\mathbf{F}\right) + + :param weight: weight for this loss function + """ + weight: float + +
+[docs] + def __init__(self, weight: Optional[float] = 1.0): + self.weight = weight
+ + + def __call__(self, params, domain): + energies = vmap(self.load_step, in_axes=(None, None, 0))( + params, domain, domain.times + ) + energy = jnp.sum(energies) + loss = energy + return self.weight * loss, dict(energy=energy) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + pi = incompressible_energy(domain, us, props) + return pi
+
+ + + +
+[docs] +class IncompressibleEnergyAndResidualLoss(PhysicsLossFunction): + r""" + Energy and residual loss function used in Hamel et. al + + Calculates the following quantity + + .. math:: + \mathcal{L} = w_1\Pi\left[u\right] + w_2\delta\Pi\left[u\right]_{free} + + :param energy_weight: Weight for the energy w_1 + :param residual_weight: Weight for the residual w_2 + """ + energy_weight: float + residual_weight: float + +
+[docs] + def __init__( + self, + energy_weight: Optional[float] = 1.0, + residual_weight: Optional[float] = 1.0 + ): + self.energy_weight = energy_weight + self.residual_weight = residual_weight
+ + + def __call__(self, params, domain): + pis, Rs = vmap(self.load_step, in_axes=(None, None, 0))(params, domain, domain.times) + pi, R = jnp.sum(pis), jnp.sum(Rs) + loss = self.energy_weight * pi + self.residual_weight * R + return loss, dict(energy=pi, residual=R) + +
+[docs] + def load_step(self, params, domain, t): + field_network, props = params + us = domain.field_values(field_network, t) + props = props() + pi, R = incompressible_energy_and_residual(domain, us, props) + return pi, R
+
+ + +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/math/math.html b/html/_modules/pancax/math/math.html new file mode 100644 index 0000000..e1f4816 --- /dev/null +++ b/html/_modules/pancax/math/math.html @@ -0,0 +1,265 @@ + + + + + + + + pancax.math.math — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.math.math

+from jax import custom_jvp
+from jax import lax
+import jax.numpy as np
+
+# constants
+# Assumes IEEE double precision
+_DBL_PRECISION_SIGNIFICAND_BITS = 53
+
+# equivalent to ceil(_DBL_PRECISION_SIGNIFICAND_BITS / 2) as an integer
+_SPLIT_S = -(-_DBL_PRECISION_SIGNIFICAND_BITS // 2)
+_SPLIT_FACTOR = 1<<_SPLIT_S + 1
+
+@custom_jvp
+def safe_sqrt(x):
+    return np.sqrt(x)
+
+
+
+[docs] +@safe_sqrt.defjvp +def safe_sqrt_jvp(xt, vt): + x, = xt + v, = vt + f = safe_sqrt(x) + df = v * lax.cond( x <= 0, + lambda x: 0., + lambda x: 0.5/f, + x ) + return f, df
+ + + +
+[docs] +def sum2(a): + """ + Sum a vector to much higher accuracy than numpy.sum. + + Parameters + ---------- + a : ndarray, with only one axis (shape [n,]) + + Returns + ------- + sum : real + The sum of the numbers in the array + + + This special sum method computes the result as accurate as if + computed in quadruple precision. + + Reference: + T. Ogita, S. M. Rump, and S. Oishi. Accurate sum and dot product. + SIAM J. Sci. Comput., Vol 26, No 6, pp. 1955-1988. + doi: 10.1137/030601818 + """ + def f(carry, ai): + p, sigma = carry + p, q = _two_sum(p, ai) + sigma += q + return (p, sigma), p + + total = 0.0 + c = 0.0 + (total, c), partialSums = lax.scan(f, (total, c), a) + return total + c
+ + + +
+[docs] +def _two_sum(a, b): + x = a + b + z = x - a + y = (a - (x - z)) + (b - z) + return x, y
+ + + +
+[docs] +def dot2(x, y): + """ + Compute inner product of 2 vectors to much higher accuracy than numpy.dot. + + Parameters + ---------- + :param x: ndarray, with only one axis (shape [n,]) + :param y: ndarray, with only one axis (shape [n,]) + + Returns + ------- + :return dotprod: real + The inner product of the input vectors. + + + This special inner product method computes the result as accurate + as if computed in quadruple precision. This algorithm is useful to + computing objective functions from numerical integration. It avoids + accumulation of floating point cancellation error that can obscure + whether an objective function has truly decreased. + + The environment variable setting + 'XLA_FLAGS = "--xla_cpu_enable_fast_math=false"' + is critical for this function to work on the CPU. Otherwise, xla + apparently sets a flag for LLVM that allows unsafe floating point + optimizations that can change associativity. + + Reference + T. Ogita, S. M. Rump, and S. Oishi. Accurate sum and dot product. + SIAM J. Sci. Comput., Vol 26, No 6, pp. 1955-1988. + doi 10.1137/030601818 + + """ + def f(carry, xy): + p, s = carry + xi, yi = xy + h, r = _two_product(xi, yi) + p, q = _two_sum(p, h) + s = s + (q + r) + return (p, s), p + + rawTotal = 0.0 + compensation = 0.0 + X = np.column_stack((x,y)) + (rawTotal, compensation), partialSums = lax.scan(f, + (rawTotal, compensation), + X) + return rawTotal + compensation
+ + + +
+[docs] +def _two_product(a, b): + x = a*b + a1, a2 = _float_split(a) + b1, b2 = _float_split(b) + y = a2*b2 - (((x - a1*b1) - a2*b1) - a1*b2) + return x, y
+ + + +
+[docs] +def _float_split(a): + c = _SPLIT_FACTOR*a + x = c - (c - a) + y = a - x + return x, y
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/math/tensor_math.html b/html/_modules/pancax/math/tensor_math.html new file mode 100644 index 0000000..ff0eaa5 --- /dev/null +++ b/html/_modules/pancax/math/tensor_math.html @@ -0,0 +1,886 @@ + + + + + + + + pancax.math.tensor_math — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.math.tensor_math

+from functools import partial
+from jax import custom_jvp
+from jax import jacfwd
+from jax import lax
+from jax import vmap
+from jax.lax import while_loop
+from jax.scipy import linalg
+from pancax.fem.quadrature_rules import create_padded_quadrature_rule_1D
+from pancax.math import math
+import jax.numpy as np
+
+
+
+[docs] +def if_then_else(cond, val1, val2): + return lax.cond(cond, + lambda x: val1, + lambda x: val2, + None)
+ + + +
+[docs] +def compute_deviatoric_tensor(strain): + dil = np.trace(strain) + return strain - (dil/3.)*np.identity(3)
+ + + +
+[docs] +def dev(strain): return compute_deviatoric_tensor(strain)
+ + + +
+[docs] +def tensor_norm(tensor): + return np.linalg.norm(tensor, ord='fro')
+ + + +
+[docs] +def norm_of_deviator_squared(tensor): + dev = compute_deviatoric_tensor(tensor) + return np.tensordot(dev,dev)
+ + + +
+[docs] +def norm_of_deviator(tensor): + return tensor_norm( compute_deviatoric_tensor(tensor) )
+ + + +
+[docs] +def mises_equivalent_stress(stress): + return np.sqrt(1.5)*norm_of_deviator(stress)
+ + + +
+[docs] +def triaxiality(A): + mean_normal = np.trace(A)/3.0 + mises_norm = mises_equivalent_stress(A) + # avoid division by zero in case of spherical tensor + mises_norm += np.finfo(np.dtype("float64")).eps + return mean_normal/mises_norm
+ + + +
+[docs] +def sym(A): + return 0.5*(A + A.T)
+ + + +
+[docs] +def logh(A): + d,V = linalg.eigh(A) + return logh_from_eigen(d,V)
+ + + +
+[docs] +def logh_from_eigen(eVals, eVecs): + return eVecs@np.diag(np.log(eVals))@eVecs.T
+ + + +
+[docs] +def tensor_2D_to_3D(H): + return np.zeros((3,3)).at[ 0:H.shape[0], 0:H.shape[1] ].set(H)
+ + + +# Compute eigen values and vectors of a symmetric 3x3 tensor +# Note, returned eigen vectors may not be unit length +# +# Note, this routine involves high powers of the input tensor (~M^8). +# Thus results can start to denormalize when the infinity norm of the input +# tensor falls outside the range 1.0e-40 to 1.0e+40. +# +# Outside this range use eigen_sym33_unit +
+[docs] +def eigen_sym33_non_unit(tensor): + cxx = tensor[0,0] + cyy = tensor[1,1] + czz = tensor[2,2] + cxy = 0.5*(tensor[0,1]+tensor[1,0]) + cyz = 0.5*(tensor[1,2]+tensor[2,1]) + czx = 0.5*(tensor[2,0]+tensor[0,2]) + + c1 = (cxx + cyy + czz)/(3.0) + cxx -= c1 + cyy -= c1 + czz -= c1 + + cxy_cxy = cxy*cxy + cyz_cyz = cyz*cyz + czx_czx = czx*czx + cxx_cyy = cxx*cyy + + c2 = cxx_cyy + cyy*czz + czz*cxx - cxy_cxy - cyz_cyz - czx_czx + + c2Negative = c2 < 0 + denom = np.where(c2Negative, c2, 1.0) + ThreeOverA = np.where(c2Negative, -3.0/denom, 1.0) + sqrtThreeOverA = np.where(c2Negative, np.sqrt(ThreeOverA), 1.0) + + c3 = cxx*cyz_cyz + cyy*czx_czx - 2.0*cxy*cyz*czx + czz*(cxy_cxy - cxx_cyy) + + rr = -0.5*c3*ThreeOverA*sqrtThreeOverA + + arg = np.minimum(abs(rr), 1.0) # Check in the case rr = -1-eps + + cos_thd3 = cos_of_acos_divided_by_3(arg) + + two_cos_thd3 = 2.0*cos_thd3*np.sign(rr) + + eval2 = np.where(c2Negative, two_cos_thd3/sqrtThreeOverA, 1.0) + + crow0 = np.array([cxx - eval2, cxy, czx ]) + crow1 = np.array([cxy, cyy - eval2, cyz ]) + crow2 = np.array([czx, cyz, czz - eval2]) + + # + # do QR decomposition with column pivoting + # + k0 = crow0[0]*crow0[0] + cxy_cxy + czx_czx + k1 = cxy_cxy + crow1[1]*crow1[1] + cyz_cyz + k2 = czx_czx + cyz_cyz + crow2[2]*crow2[2] + + # returns zero or nan + k0gk1 = k1<=k0 + k0gk2 = k2<=k0 + k1gk2 = k2<=k1 + + k0_largest = k0gk1 & k0gk2 + k1_largest = k1gk2 & (~ k0gk1) + k2_largest = ~ (k0_largest | k1_largest) + k_largest = np.array([k0_largest, k1_largest, k2_largest]) + + k_row1_0 = if_then_else(k0_largest, crow0[0], 0.0) \ + + if_then_else(k1_largest, crow1[0], 0.0) \ + + if_then_else(k2_largest, crow2[0], 0.0) + + k_row1_1 = if_then_else(k0_largest, crow0[1], 0.0) \ + + if_then_else(k1_largest, crow1[1], 0.0) \ + + if_then_else(k2_largest, crow2[1], 0.0) + + k_row1_2 = if_then_else(k0_largest, crow0[2], 0.0) \ + + if_then_else(k1_largest, crow1[2], 0.0) \ + + if_then_else(k2_largest, crow2[2], 0.0) + + k_row1 = np.array([k_row1_0, k_row1_1, k_row1_2]) + + row2_0 = if_then_else(k0_largest, crow1[0], crow0[0]) + row2_1 = if_then_else(k0_largest, crow1[1], crow0[1]) + row2_2 = if_then_else(k0_largest, crow1[2], crow0[2]) + row2 = np.array([row2_0, row2_1, row2_2]) + + row3_0 = if_then_else(k2_largest, crow1[0], crow2[0]) + row3_1 = if_then_else(k2_largest, crow1[1], crow2[1]) + row3_2 = if_then_else(k2_largest, crow1[2], crow2[2]) + row3 = np.array([row3_0, row3_1, row3_2]) + + ki_ki = 1.0 / ( if_then_else(k0_largest, k0, 0.0) \ + + if_then_else(k1_largest, k1, 0.0) \ + + if_then_else(k2_largest, k2, 0.0) ) + + ki_dpr1 = ki_ki*(k_row1[0]*row2[0] + k_row1[1]*row2[1] + k_row1[2]*row2[2]) + ki_dpr2 = ki_ki*(k_row1[0]*row3[0] + k_row1[1]*row3[1] + k_row1[2]*row3[2]) + + row2 = row2 - ki_dpr1*k_row1 + row3 = row3 - ki_dpr2*k_row1 + + a0 = row2[0]*row2[0] + row2[1]*row2[1] + row2[2]*row2[2] + a1 = row3[0]*row3[0] + row3[1]*row3[1] + row3[2]*row3[2] + + a0lea1 = a0 <= a1 + + a_row2 = if_then_else(a0lea1, row3, row2) + ai_ai = 1.0 / if_then_else(a0lea1, a1, a0) + + evec2 = np.array([k_row1[1]*a_row2[2] - k_row1[2]*a_row2[1], + k_row1[2]*a_row2[0] - k_row1[0]*a_row2[2], + k_row1[0]*a_row2[1] - k_row1[1]*a_row2[0]]) + + k_atr11 = cxx*k_row1[0] + cxy*k_row1[1] + czx*k_row1[2] + k_atr21 = cxy*k_row1[0] + cyy*k_row1[1] + cyz*k_row1[2] + k_atr31 = czx*k_row1[0] + cyz*k_row1[1] + czz*k_row1[2] + + a_atr12 = cxx*a_row2[0] + cxy*a_row2[1] + czx*a_row2[2] + a_atr22 = cxy*a_row2[0] + cyy*a_row2[1] + cyz*a_row2[2] + a_atr32 = czx*a_row2[0] + cyz*a_row2[1] + czz*a_row2[2] + + rm2xx = (k_row1[0]*k_atr11 + k_row1[1]*k_atr21 + k_row1[2]*k_atr31)*ki_ki + k_a_rm2xy = (k_row1[0]*a_atr12 + k_row1[1]*a_atr22 + k_row1[2]*a_atr32) + rm2yy = (a_row2[0]*a_atr12 + a_row2[1]*a_atr22 + a_row2[2]*a_atr32)*ai_ai + rm2xy_rm2xy = k_a_rm2xy*k_a_rm2xy*ai_ai*ki_ki + + # + # Wilkinson shift + # + b = 0.5*(rm2xx-rm2yy) + + sqrtTerm = math.safe_sqrt(b*b+rm2xy_rm2xy)*np.sign(b) + #sqrtTerm = np.sqrt(b*b+rm2xy_rm2xy)*np.sign(b) + + eval0 = rm2yy + b - sqrtTerm + eval1 = rm2xx + rm2yy - eval0 + + rm2xx -= eval0 + rm2yy -= eval0 + + rm2xx2 = rm2xx*rm2xx + rm2yy2 = rm2yy*rm2yy + + fac1 = if_then_else(rm2xx2 < rm2yy2, k_a_rm2xy*ai_ai, rm2xx) + fac2 = if_then_else(rm2xx2 < rm2yy2, rm2yy, ki_ki*k_a_rm2xy) + + evec0 = fac1*a_row2 - fac2*k_row1 + + rm2xx2iszero = rm2xx2 == (0.0) + rm2xy_rm2xyiszero = rm2xy_rm2xy == (0.0) + both_zero = rm2xx2iszero & rm2xy_rm2xyiszero + + # check degeneracy + + evec0 = if_then_else(both_zero, a_row2, evec0) + + evec1 = np.array([evec2[1]*evec0[2] - evec2[2]*evec0[1], + evec2[2]*evec0[0] - evec2[0]*evec0[2], + evec2[0]*evec0[1] - evec2[1]*evec0[0]]) + + eval0 = eval0 + c1 + eval1 = eval1 + c1 + eval2 = eval2 + c1 + + c2tol = (c1*c1)*(-1.0e-30) + + c2lsmall_neg = c2 < c2tol + + eval0 = if_then_else(c2lsmall_neg, eval0, c1) + eval1 = if_then_else(c2lsmall_neg, eval1, c1) + eval2 = if_then_else(c2lsmall_neg, eval2, c1) + + evec0 = if_then_else(c2lsmall_neg, evec0, np.array([1.0, 0.0, 0.0])) + evec1 = if_then_else(c2lsmall_neg, evec1, np.array([0.0, 1.0, 0.0])) + evec2 = if_then_else(c2lsmall_neg, evec2, np.array([0.0, 0.0, 1.0])) + + evals = np.array([eval0, eval1, eval2]) + evecs = np.column_stack((evec0,evec1,evec2)) + + #idx = np.arange(3) # np.argsort(evals) + idx = np.argsort(evals) + + return evals[idx],evecs[:,idx]
+ + + +
+[docs] +def eigen_sym33_unit(tensor): + cmax = np.linalg.norm(tensor, ord=np.inf) + cmaxInv = if_then_else(cmax > 0.0, 1.0/cmax, 1.0) + scaledTensor = cmaxInv * tensor + + evals, evecs = eigen_sym33_non_unit(scaledTensor) + + evec0 = evecs[:,0]/np.linalg.norm(evecs[:,0]) + evec1 = evecs[:,1]/np.linalg.norm(evecs[:,1]) + evec2 = evecs[:,2]/np.linalg.norm(evecs[:,2]) + + evecs = np.column_stack((evec0,evec1,evec2)) + evals = cmax*evals + + return (evals,evecs)
+ + + +# Helper function for 3x3 spectral decompositions +# Pade approximation to cos( acos(x)/3 ) +# was obtained from Mathematica with the following commands: +# +# Needs["FunctionApproximations`"] +# r1 = MiniMaxApproximation[Cos[ArcCos[x]/3], {x, {0, 1}, 6, 5}, WorkingPrecision -> 18, MaxIterations -> 500] +# +# 6 and 5 indicate the polynomial order in the numerator and denominator. +
+[docs] +def cos_of_acos_divided_by_3(x): + + x2 = x*x; + x4 = x2*x2; + + numer = 0.866025403784438713 + 2.12714890259493060 * x + \ + ( ( 1.89202064815951569 + 0.739603278343401613 * x ) * x2 + \ + ( 0.121973926953064794 + x * (0.00655637626263929360 + 0.0000390884982780803443 * x) ) *x4 ) + + denom = 1.0 + 2.26376989330935617* x + \ + ( ( 1.80461009751278976 + 0.603976798217196003 * x ) * x2 + \ + ( 0.0783255761115461708 + 0.00268525944538021629 * x) * x4 ) + + return numer/denom
+ + + +@custom_jvp +def mtk_log_sqrt(A): + lam,V = eigen_sym33_unit(A) + return V @ np.diag(0.5*np.log(lam)) @ V.T + + +
+[docs] +@mtk_log_sqrt.defjvp +def mtk_log_sqrt_jvp(Cpack, Hpack): + C, = Cpack + H, = Hpack + + logSqrtC = mtk_log_sqrt(C) + lam,V = eigen_sym33_unit(C) + + lam1 = lam[0] + lam2 = lam[1] + lam3 = lam[2] + + e1 = V[:,0] + e2 = V[:,1] + e3 = V[:,2] + + hHat = 0.5 * (V.T @ H @ V) + + l1111 = hHat[0,0] / lam1 + l2222 = hHat[1,1] / lam2 + l3333 = hHat[2,2] / lam3 + + l1212 = 0.5*(hHat[0,1]+hHat[1,0]) * relative_log_difference(lam1, lam2) + l2323 = 0.5*(hHat[1,2]+hHat[2,1]) * relative_log_difference(lam2, lam3) + l3131 = 0.5*(hHat[2,0]+hHat[0,2]) * relative_log_difference(lam3, lam1) + + t00 = l1111 * e1[0] * e1[0] + l2222 * e2[0] * e2[0] + l3333 * e3[0] * e3[0] + \ + 2 * l1212 * e1[0] * e2[0] + \ + 2 * l2323 * e2[0] * e3[0] + \ + 2 * l3131 * e3[0] * e1[0] + t11 = l1111 * e1[1] * e1[1] + l2222 * e2[1] * e2[1] + l3333 * e3[1] * e3[1] + \ + 2 * l1212 * e1[1] * e2[1] + \ + 2 * l2323 * e2[1] * e3[1] + \ + 2 * l3131 * e3[1] * e1[1] + t22 = l1111 * e1[2] * e1[2] + l2222 * e2[2] * e2[2] + l3333 * e3[2] * e3[2] + \ + 2 * l1212 * e1[2] * e2[2] + \ + 2 * l2323 * e2[2] * e3[2] + \ + 2 * l3131 * e3[2] * e1[2] + + t01 = l1111 * e1[0] * e1[1] + l2222 * e2[0] * e2[1] + l3333 * e3[0] * e3[1] + \ + l1212 * (e1[0] * e2[1] + e2[0] * e1[1]) + \ + l2323 * (e2[0] * e3[1] + e3[0] * e2[1]) + \ + l3131 * (e3[0] * e1[1] + e1[0] * e3[1]) + t12 = l1111 * e1[1] * e1[2] + l2222 * e2[1] * e2[2] + l3333 * e3[1] * e3[2] + \ + l1212 * (e1[1] * e2[2] + e2[1] * e1[2]) + \ + l2323 * (e2[1] * e3[2] + e3[1] * e2[2]) + \ + l3131 * (e3[1] * e1[2] + e1[1] * e3[2]) + t20 = l1111 * e1[2] * e1[0] + l2222 * e2[2] * e2[0] + l3333 * e3[2] * e3[0] + \ + l1212 * (e1[2] * e2[0] + e2[2] * e1[0]) + \ + l2323 * (e2[2] * e3[0] + e3[2] * e2[0]) + \ + l3131 * (e3[2] * e1[0] + e1[2] * e3[0]) + + sol = np.array([ [t00, t01, t20], + [t01, t11, t12], + [t20, t12, t22] ]) + + return logSqrtC, sol
+ + + +@partial(custom_jvp, nondiff_argnums=(1,)) +def mtk_pow(A,m): + lam,V = eigen_sym33_unit(A) + return V @ np.diag(np.power(lam,m)) @ V.T + + +
+[docs] +@mtk_pow.defjvp +def mtk_pow_jvp(m, Cpack, Hpack): + C, = Cpack + H, = Hpack + + powC = mtk_pow(C,m) + lam,V = eigen_sym33_unit(C) + + lam1 = lam[0] + lam2 = lam[1] + lam3 = lam[2] + + e1 = V[:,0] + e2 = V[:,1] + e3 = V[:,2] + + hHat = m * (V.T @ H @ V) + + l1111 = hHat[0,0] * np.power(lam1, m-1) + l2222 = hHat[1,1] * np.power(lam2, m-1) + l3333 = hHat[2,2] * np.power(lam3, m-1) + + l1212 = 0.5*(hHat[0,1]+hHat[1,0]) * relative_log_difference(lam1, lam2) + l2323 = 0.5*(hHat[1,2]+hHat[2,1]) * relative_log_difference(lam2, lam3) + l3131 = 0.5*(hHat[2,0]+hHat[0,2]) * relative_log_difference(lam3, lam1) + + t00 = l1111 * e1[0] * e1[0] + l2222 * e2[0] * e2[0] + l3333 * e3[0] * e3[0] + \ + 2 * l1212 * e1[0] * e2[0] + \ + 2 * l2323 * e2[0] * e3[0] + \ + 2 * l3131 * e3[0] * e1[0] + t11 = l1111 * e1[1] * e1[1] + l2222 * e2[1] * e2[1] + l3333 * e3[1] * e3[1] + \ + 2 * l1212 * e1[1] * e2[1] + \ + 2 * l2323 * e2[1] * e3[1] + \ + 2 * l3131 * e3[1] * e1[1] + t22 = l1111 * e1[2] * e1[2] + l2222 * e2[2] * e2[2] + l3333 * e3[2] * e3[2] + \ + 2 * l1212 * e1[2] * e2[2] + \ + 2 * l2323 * e2[2] * e3[2] + \ + 2 * l3131 * e3[2] * e1[2] + + t01 = l1111 * e1[0] * e1[1] + l2222 * e2[0] * e2[1] + l3333 * e3[0] * e3[1] + \ + l1212 * (e1[0] * e2[1] + e2[0] * e1[1]) + \ + l2323 * (e2[0] * e3[1] + e3[0] * e2[1]) + \ + l3131 * (e3[0] * e1[1] + e1[0] * e3[1]) + t12 = l1111 * e1[1] * e1[2] + l2222 * e2[1] * e2[2] + l3333 * e3[1] * e3[2] + \ + l1212 * (e1[1] * e2[2] + e2[1] * e1[2]) + \ + l2323 * (e2[1] * e3[2] + e3[1] * e2[2]) + \ + l3131 * (e3[1] * e1[2] + e1[1] * e3[2]) + t20 = l1111 * e1[2] * e1[0] + l2222 * e2[2] * e2[0] + l3333 * e3[2] * e3[0] + \ + l1212 * (e1[2] * e2[0] + e2[2] * e1[0]) + \ + l2323 * (e2[2] * e3[0] + e3[2] * e2[0]) + \ + l3131 * (e3[2] * e1[0] + e1[2] * e3[0]) + + sol = np.array([ [t00, t01, t20], + [t01, t11, t12], + [t20, t12, t22] ]) + + return powC, sol
+ + + +
+[docs] +def relative_log_difference_taylor(lam1, lam2): + # Compute a more accurate (mtk::log(lam1) - log(lam2)) / (lam1-lam2) as lam1 -> lam2 + third2 = 2.0 / 3.0 + fifth2 = 2.0 / 5.0 + seventh2 = 2.0 / 7.0 + ninth2 = 2.0 / 9.0 + + frac = (lam1 - lam2) / (lam1 + lam2) + frac2 = frac*frac + frac4 = frac2*frac2 + + # relative tolerance of 0.05 for this approx (with more terms its valid over larger range) + return (2.0 + third2 * frac2 + fifth2 * frac4 + seventh2 * frac4 * frac2 + ninth2 * frac4 * frac4) / (lam1 + lam2)
+ + + +
+[docs] +def relative_log_difference_no_tolerance_check(lam1, lam2): + return np.log(lam1 / lam2) / (lam1 - lam2)
+ + + +
+[docs] +def relative_log_difference(lam1, lam2): + haveLargeDiff = np.abs(lam1 - lam2) > 0.05 * np.minimum(lam1, lam2) + lamFake = np.where(haveLargeDiff, lam2, 2.0*lam2) + return np.where(haveLargeDiff, + relative_log_difference_no_tolerance_check(lam1, lamFake), + relative_log_difference_taylor(lam1, lam2))
+ + + +# C must be symmetric! +@custom_jvp +def log_sqrt(C): + return 0.5*logh(C) + + +
+[docs] +@log_sqrt.defjvp +def log_jvp(Cpack, Hpack): + C, = Cpack + H, = Hpack + + logSqrtC = log_sqrt(C) + lam,V = linalg.eigh(C) + + lam1 = lam[0] + lam2 = lam[1] + lam3 = lam[2] + + e1 = V[:,0] + e2 = V[:,1] + e3 = V[:,2] + + hHat = 0.5 * (V.T @ H @ V) + + l1111 = hHat[0,0] / lam1 + l2222 = hHat[1,1] / lam2 + l3333 = hHat[2,2] / lam3 + + l1212 = 0.5*(hHat[0,1]+hHat[1,0]) * relative_log_difference(lam1, lam2) + l2323 = 0.5*(hHat[1,2]+hHat[2,1]) * relative_log_difference(lam2, lam3) + l3131 = 0.5*(hHat[2,0]+hHat[0,2]) * relative_log_difference(lam3, lam1) + + t00 = l1111 * e1[0] * e1[0] + l2222 * e2[0] * e2[0] + l3333 * e3[0] * e3[0] + \ + 2 * l1212 * e1[0] * e2[0] + \ + 2 * l2323 * e2[0] * e3[0] + \ + 2 * l3131 * e3[0] * e1[0] + t11 = l1111 * e1[1] * e1[1] + l2222 * e2[1] * e2[1] + l3333 * e3[1] * e3[1] + \ + 2 * l1212 * e1[1] * e2[1] + \ + 2 * l2323 * e2[1] * e3[1] + \ + 2 * l3131 * e3[1] * e1[1] + t22 = l1111 * e1[2] * e1[2] + l2222 * e2[2] * e2[2] + l3333 * e3[2] * e3[2] + \ + 2 * l1212 * e1[2] * e2[2] + \ + 2 * l2323 * e2[2] * e3[2] + \ + 2 * l3131 * e3[2] * e1[2] + + t01 = l1111 * e1[0] * e1[1] + l2222 * e2[0] * e2[1] + l3333 * e3[0] * e3[1] + \ + l1212 * (e1[0] * e2[1] + e2[0] * e1[1]) + \ + l2323 * (e2[0] * e3[1] + e3[0] * e2[1]) + \ + l3131 * (e3[0] * e1[1] + e1[0] * e3[1]) + t12 = l1111 * e1[1] * e1[2] + l2222 * e2[1] * e2[2] + l3333 * e3[1] * e3[2] + \ + l1212 * (e1[1] * e2[2] + e2[1] * e1[2]) + \ + l2323 * (e2[1] * e3[2] + e3[1] * e2[2]) + \ + l3131 * (e3[1] * e1[2] + e1[1] * e3[2]) + t20 = l1111 * e1[2] * e1[0] + l2222 * e2[2] * e2[0] + l3333 * e3[2] * e3[0] + \ + l1212 * (e1[2] * e2[0] + e2[2] * e1[0]) + \ + l2323 * (e2[2] * e3[0] + e3[2] * e2[0]) + \ + l3131 * (e3[2] * e1[0] + e1[2] * e3[0]) + + sol = np.array([ [t00, t01, t20], + [t01, t11, t12], + [t20, t12, t22] ]) + + return logSqrtC, sol
+ + + +@custom_jvp +def sqrtm(A): + sqrtA,_ = sqrtm_dbp(A) + return sqrtA + + +
+[docs] +@sqrtm.defjvp +def jvp_sqrtm(primals, tangents): + A, = primals + H, = tangents + sqrtA = sqrtm(A) + dim = A.shape[0] + # TODO(brandon): Use a stable algorithm for solving a Sylvester equation. + # See https://en.wikipedia.org/wiki/Bartels%E2%80%93Stewart_algorithm + # The following will only reliably work for small matrices. + I = np.identity(dim) + M = np.kron(sqrtA.T, I) + np.kron(I, sqrtA) + Hvec = H.T.ravel() + return sqrtA, (linalg.solve(M, Hvec)).reshape((dim,dim)).T
+ + + +
+[docs] +def sqrtm_dbp(A): + """ Matrix square root by product form of Denman-Beavers iteration. + + Translated from the Matrix Function Toolbox + http://www.ma.man.ac.uk/~higham/mftoolbox + Nicholas J. Higham, Functions of Matrices: Theory and Computation, + SIAM, Philadelphia, PA, USA, 2008. ISBN 978-0-898716-46-7, + """ + dim = A.shape[0] + tol = 0.5 * np.sqrt(dim) * np.finfo(np.dtype("float64")).eps + maxIters = 32 + scaleTol = 0.01 + + def scaling(M): + d = np.abs(linalg.det(M))**(1.0/(2.0*dim)) + g = 1.0 / d + return g + + def cond_f(loopData): + _,_,error,k,_ = loopData + p = np.array([k < maxIters, error > tol], dtype=bool) + return np.all(p) + + def body_f(loopData): + X, M, error, k, diff = loopData + g = np.where(diff >= scaleTol, + scaling(M), + 1.0) + + X *= g + M *= g * g + + Y = X + N = linalg.inv(M) + I = np.identity(dim) + X = 0.5 * X @ (I + N) + M = 0.5 * (I + 0.5 * (M + N)) + error = np.linalg.norm(M - I, 'fro') + diff = np.linalg.norm(X - Y, 'fro') / np.linalg.norm(X, 'fro') + k += 1 + return (X, M, error, k, diff) + + X0 = A + M0 = A + error0 = np.finfo(np.dtype("float64")).max + k0 = 0 + diff0 = 2.0*scaleTol # want to force scaling on first iteration + loopData0 = (X0, M0, error0, k0, diff0) + + X,_,_,k,_ = while_loop(cond_f, body_f, loopData0) + + return X,k
+ + + +@custom_jvp +def logm_iss(A): + X,k,m = _logm_iss(A) + return (1 << k) * log_pade_pf(X - np.identity(A.shape[0]), m) + + +
+[docs] +@logm_iss.defjvp +def logm_jvp(primals, tangents): + A, = primals + H, = tangents + logA = logm_iss(A) + DexpLogA = jacfwd(linalg.expm)(logA) + dim = A.shape[0] + JVP = linalg.solve(DexpLogA.reshape(dim*dim,-1), H.ravel()) + return logA, JVP.reshape(dim,dim)
+ + + +
+[docs] +def _logm_iss(A): + """Logarithmic map by inverse scaling and squaring and Padé approximants + + Translated from the Matrix Function Toolbox + http://www.ma.man.ac.uk/~higham/mftoolbox + Nicholas J. Higham, Functions of Matrices: Theory and Computation, + SIAM, Philadelphia, PA, USA, 2008. ISBN 978-0-898716-46-7, + """ + dim = A.shape[0] + c15 = log_pade_coefficients[15] + + def cond_f(loopData): + _,_,k,_,_,converged = loopData + conditions = np.array([~converged, k < 16], dtype = bool) + return conditions.all() + + def compute_pade_degree(diff, j, itk): + j += 1 + # Manually force the return type of searchsorted to be 64-bit int, because it + # returns 32-bit ints, ignoring the global `jax_enable_x64` flag. This looks + # like a bug. I filed an issue (#11375) with Jax to correct this. + # If they fix it, the conversions on p and q can be removed. + p = np.searchsorted(log_pade_coefficients[2:16], diff, side='right').astype(np.int64) + p += 2 + q = np.searchsorted(log_pade_coefficients[2:16], diff/2.0, side='right').astype(np.int64) + q += 2 + m,j,converged = if_then_else((2 * (p - q) // 3 < itk) | (j == 2), + (p+1,j,True), (0,j,False)) + return m,j,converged + + def body_f(loopData): + X,j,k,m,itk,converged = loopData + diff = np.linalg.norm(X - np.identity(dim), ord=1) + m,j,converged = if_then_else(diff < c15, + compute_pade_degree(diff, j, itk), + (m, j, converged)) + X,itk = sqrtm_dbp(X) + k += 1 + return X,j,k,m,itk,converged + + X = A + j = 0 + k = 0 + m = 0 + itk = 5 + converged = False + X,j,k,m,itk,converged = while_loop(cond_f, body_f, (X,j,k,m,itk,converged)) + return X,k,m
+ + + +
+[docs] +def log_pade_pf(A, n): + """Logarithmic map by Padé approximant and partial fractions + """ + I = np.identity(A.shape[0]) + X = np.zeros_like(A) + quadPrec = 2*n - 1 + xs,ws = create_padded_quadrature_rule_1D(quadPrec) + + def get_log_inc(A, x, w): + B = I + x*A + dXT = w*linalg.solve(B.T, A.T) + return dXT + + dXsTransposed = vmap(get_log_inc, (None, 0, 0))(A, xs, ws) + X = np.sum(dXsTransposed, axis=0).T + + return X
+ + + +log_pade_coefficients = np.array([ + 1.100343044625278e-05, 1.818617533662554e-03, 1.620628479501567e-02, 5.387353263138127e-02, + 1.135280226762866e-01, 1.866286061354130e-01, 2.642960831111435e-01, 3.402172331985299e-01, + 4.108235000556820e-01, 4.745521256007768e-01, 5.310667521178455e-01, 5.806887133441684e-01, + 6.240414344012918e-01, 6.618482563071411e-01, 6.948266172489354e-01, 7.236382701437292e-01, + 7.488702930926310e-01, 7.710320825151814e-01, 7.905600074925671e-01, 8.078252198050853e-01, + 8.231422814010787e-01, 8.367774696147783e-01, 8.489562661576765e-01, 8.598698723737197e-01, + 8.696807597657327e-01, 8.785273397512191e-01, 8.865278635527148e-01, 8.937836659824918e-01, + 9.003818585631236e-01, 9.063975647545747e-01, 9.118957765024351e-01, 9.169328985287867e-01, + 9.215580354375991e-01, 9.258140669835052e-01, 9.297385486977516e-01, 9.333644683151422e-01, + 9.367208829050256e-01, 9.398334570841484e-01, 9.427249190039424e-01, 9.454154478075423e-01, + 9.479230038146050e-01, 9.502636107090112e-01, 9.524515973891873e-01, 9.544998058228285e-01, + 9.564197701703862e-01, 9.582218715590143e-01, 9.599154721638511e-01, 9.615090316568806e-01, + 9.630102085912245e-01, 9.644259488813590e-01, 9.657625632018019e-01, 9.670257948457799e-01, + 9.682208793510226e-01, 9.693525970039069e-01, 9.704253191689650e-01, 9.714430492527785e-01, + 9.724094589950460e-01, 9.733279206814576e-01, 9.742015357899175e-01, 9.750331605111618e-01, + 9.758254285248543e-01, 9.765807713611383e-01, 9.773014366339591e-01, 9.779895043950849e-01 ]) +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks.html b/html/_modules/pancax/networks.html new file mode 100644 index 0000000..52a21a8 --- /dev/null +++ b/html/_modules/pancax/networks.html @@ -0,0 +1,130 @@ + + + + + + + + pancax.networks — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks

+from .elm import ELM, ELM2
+from .field_property_pair import FieldPropertyPair
+from .mlp import Linear
+from .mlp import MLP
+from .mlp import MLPBasis
+from .properties import *
+from .rbf import RBFBasis
+from .rbf import rbf_normalization
+from .initialization import *
+
+
+[docs] +def Network(network_type, *args, **kwargs): + return network_type(*args, **kwargs)
+ + +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks/elm.html b/html/_modules/pancax/networks/elm.html new file mode 100644 index 0000000..3db048f --- /dev/null +++ b/html/_modules/pancax/networks/elm.html @@ -0,0 +1,172 @@ + + + + + + + + pancax.networks.elm — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks.elm

+from typing import Callable
+import equinox as eqx
+import jax
+
+
+
+[docs] +def activation(x): + alpha = 3. + return 1. / (1. + jax.numpy.exp(-alpha * x))
+ + + +
+[docs] +class ELM(eqx.Module): + layer: any + beta: any + n_outputs: int + +
+[docs] + def __init__(self, n_inputs, n_outputs, n_neurons, key): + radius = 3. + # setup linear layer to have normal distribtuion + layer = eqx.nn.Linear(n_inputs, n_neurons, use_bias=True, key=key) + k1, k2 = jax.random.split(key, 2) + new_weight = radius * jax.random.normal(k1, (n_neurons, n_inputs)) + new_bias = radius * jax.random.normal(k2, (n_neurons,)) + layer = eqx.tree_at(lambda m: m.weight, layer, new_weight) + layer = eqx.tree_at(lambda m: m.bias, layer, new_bias) + self.layer = layer + self.beta = jax.numpy.zeros((n_outputs * n_neurons,)) + self.n_outputs = n_outputs
+ + + def __call__(self, x): + n_neurons = self.layer.out_features + beta_temp = self.beta.reshape((n_neurons, self.n_outputs)) + H = activation(self.layer(x)) + return H @ beta_temp
+ + + +
+[docs] +class ELM2(eqx.Module): + layer: any + beta: any + n_outputs: int + + def __call__(self, x): + n_neurons = self.layer.out_features + beta_temp = self.beta.reshape((n_neurons, self.n_outputs)) + H = activation(self.layer(x)) + return H @ beta_temp
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks/field_property_pair.html b/html/_modules/pancax/networks/field_property_pair.html new file mode 100644 index 0000000..9ac863b --- /dev/null +++ b/html/_modules/pancax/networks/field_property_pair.html @@ -0,0 +1,181 @@ + + + + + + + + pancax.networks.field_property_pair — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks.field_property_pair

+import equinox as eqx
+import jax.tree_util as jtu
+
+
+
+[docs] +class BasePancaxModel(eqx.Module): + """ + Base class for pancax model parameters. + + This includes a few helper methods + """ +
+[docs] + def serialise(self, base_name, epoch): + file_name = f'{base_name}_{str(epoch).zfill(7)}.eqx' + print(f'Serialising current parameters to {file_name}') + eqx.tree_serialise_leaves(file_name, self)
+
+ + + +
+[docs] +class FieldPropertyPair(BasePancaxModel): + """ + Data structure for storing a set of field network + parameters and a set of material properties + + :param fields: field network parameters object + :param properties: property parameters object + """ + fields: eqx.Module + properties: eqx.Module + + def __iter__(self): + """ + Iterator for user friendliness + """ + return iter((self.fields, self.properties)) + +
+[docs] + def freeze_fields_filter(self): + filter_spec = jtu.tree_map(lambda _: False, self) + filter_spec = eqx.tree_at( + lambda tree: tree.properties.prop_params, + filter_spec, + replace=True + ) + return filter_spec
+ + +
+[docs] + def freeze_props_filter(self): + filter_spec = jtu.tree_map(lambda _: False, self) + for n in range(len(self.fields.layers)): + filter_spec = eqx.tree_at( + lambda tree: (tree.fields.layers[n].weight, tree.fields.layers[n].bias), + filter_spec, + replace=(True, True), + ) + return filter_spec
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks/initialization.html b/html/_modules/pancax/networks/initialization.html new file mode 100644 index 0000000..2a49ea7 --- /dev/null +++ b/html/_modules/pancax/networks/initialization.html @@ -0,0 +1,252 @@ + + + + + + + + pancax.networks.initialization — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks.initialization

+from jaxtyping import Array, Float
+from typing import Callable
+import equinox as eqx
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +def zero_init(key: jax.random.PRNGKey, shape) -> Float[Array, "no ni"]: + """ + :param weight: current weight array for sizing + :param key: rng key + :return: A new set of weights + """ + out, in_ = weight.shape + return jnp.zeros(shape, dtype=jnp.float64)
+ + + +
+[docs] +def trunc_init(key: jax.random.PRNGKey, shape) -> Float[Array, "no ni"]: + """ + :param weight: current weight array for sizing + :param key: rng key + :return: A new set of weights + """ + stddev = jnp.sqrt(1 / shape[0]) + return stddev * jax.random.truncated_normal(key, shape=shape, lower=-2, upper=2)
+ + + +
+[docs] +def init_linear_weight(model: eqx.Module, init_fn: Callable, key: jax.random.PRNGKey) -> eqx.Module: + """ + :param model: equinox model + :param init_fn: function to initialize weigth with + :param key: rng key + :return: a new equinox model + """ + is_linear = lambda x: isinstance(x, eqx.nn.Linear) + get_weights = lambda m: [ + x.weight + for x in jax.tree_util.tree_leaves(m, is_leaf=is_linear) + if is_linear(x) + ] + weights = get_weights(model) + new_weights = [ + init_fn(subkey, weight.shape) + for subkey, weight in zip(jax.random.split(key, len(weights)), weights) + ] + new_model = eqx.tree_at(get_weights, model, new_weights) + return new_model
+ + + +
+[docs] +def init_linear(model: eqx.Module, init_fn: Callable, key: jax.random.PRNGKey): + """ + :param model: equinox model + :param init_fn: function to initialize weigth with + :param key: rng key + :return: a new equinox model + """ + is_linear = lambda x: isinstance(x, eqx.nn.Linear) + get_biases = lambda m: [ + x.bias + for x in jax.tree_util.tree_leaves(m, is_leaf=is_linear) + if is_linear(x) + ] + get_weights = lambda m: [ + x.weight + for x in jax.tree_util.tree_leaves(m, is_leaf=is_linear) + if is_linear(x) + ] + get_layers = lambda m: [ + x + for x in jax.tree_util.tree_leaves(m, is_leaf=is_linear) + if is_linear(x) + ] + layers = get_layers(model) + weights = get_weights(model) + biases = get_biases(model) + new_layers = [ + init_fn(layer, subkey) + for layer, subkey in zip(layers, jax.random.split(key, len(layers))) + ] + new_weights = [x[0] for x in new_layers] + new_biases = [x[1] for x in new_layers] + new_model = eqx.tree_at(get_weights, model, new_weights) + new_model = eqx.tree_at(get_biases, model, new_biases) + return new_model
+ + + +
+[docs] +def box_init(layer: eqx.nn.Linear, key: jax.random.PRNGKey): + in_size = layer.in_features + out_size = layer.out_features + k1, k2 = jax.random.split(key, 2) + p = jax.random.uniform(k1, (out_size, in_size)) + n = jax.random.normal(k2, (out_size, in_size)) + + # normalize normals + # for i in range(n.shape[0]): + # n = n.at[i, :].set(n[i, :] / jnp.linalg.norm(n[i, :])) + + # calculate p_max + # p_max = jnp.max(jnp.sign(n)) + # p_max = jnp.max(jnp.array([0.0, p_max])) + + # setup A and b one vector at a time + A = jnp.zeros((out_size, in_size)) + b = jnp.zeros((out_size,)) + for i in range(n.shape[0]): + p_temp = p[i, :] + n_temp = n[i, :] / jnp.linalg.norm(n[i, :]) + p_max = jnp.max(jnp.array([0.0, jnp.max(jnp.sign(n_temp))])) + k = 1. / jnp.sum((p_max - p_temp) * n_temp) + A = A.at[i, :].set(k * n_temp) + b = b.at[i].set(k * jnp.dot(p_temp, n_temp)) + + # k = jnp.zeros((n.shape[0],)) + # for i in range(n.shape[0]): + # k = k.at[i].set(1. / jnp.sum((p_max - p[i, :]) * n[i, :])) + + # A = jax.vmap(lambda k, n: k * n, in_axes=(0, 0))(k, n) + # b = k * jax.vmap(lambda x: jnp.sum(x), in_axes=(1,))(n @ p.T) + # print(A) + # print(b) + # assert False + return A, b
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks/mlp.html b/html/_modules/pancax/networks/mlp.html new file mode 100644 index 0000000..9fa6a36 --- /dev/null +++ b/html/_modules/pancax/networks/mlp.html @@ -0,0 +1,227 @@ + + + + + + + + pancax.networks.mlp — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks.mlp

+from .initialization import *
+from typing import Callable
+from typing import Optional
+import equinox as eqx
+import jax
+
+
+# TODO should we convert these to actual classes?
+
+
+[docs] +def Linear( + n_inputs: int, + n_outputs: int, + key: jax.random.PRNGKey +): + """ + :param n_inputs: Number of inputs to linear layer + :param n_outputs: Number of outputs of the linear layer + :param key: rng key + :return: Equinox Linear layer + """ + model = eqx.nn.Linear( + n_inputs, n_outputs, + use_bias=False, + key=key + ) + model = eqx.tree_at(lambda l: l.weight, model, jnp.zeros((n_outputs, n_inputs), dtype=jnp.float64)) + return model
+ + + +
+[docs] +def MLP( + n_inputs: int, + n_outputs: int, + n_neurons: int, + n_layers: int, + activation: Callable, + key: jax.random.PRNGKey, + use_final_bias: Optional[bool] = False, + init_func: Optional[Callable] = trunc_init +): + """ + :param n_inputs: Number of inputs to the MLP + :param n_outputs: Number of outputs of the MLP + :param n_neurons: Number of neurons in each hidden layer of the MLP + :param n_layers: Number of hidden layers in the MLP + :param activation: Activation function, e.g. tanh or relu + :param key: rng key + :param use_final_bias: Boolean for whether or not to use a bias + vector in the final layer + :return: Equinox MLP layer + """ + model = eqx.nn.MLP( + n_inputs, n_outputs, n_neurons, n_layers, + activation=activation, + use_final_bias=use_final_bias, + key=key + ) + # model = init_linear_weight(model, init_func, key) + # model = init_linear(model, init_func, key) + return model
+ + + +
+[docs] +def MLPBasis( + n_inputs: int, + n_neurons: int, + n_layers: int, + activation: Callable, + key: jax.random.PRNGKey, + init_func: Optional[Callable] = trunc_init +): + return MLP( + n_inputs, n_neurons, n_neurons, n_layers, + activation=activation, + use_final_bias=True, + key=key, + init_func=init_func + )
+ + + +# class MLP(BaseNetwork): +# mlp: eqx.nn.MLP + +# def __init__( +# self, +# n_inputs: int, +# n_outputs: int, +# n_neurons: int, +# n_layers: int, +# activation: Callable, +# key: jax.random.PRNGKey, +# use_final_bias: Optional[bool] = False +# ): +# super().__init__(self) +# model = eqx.nn.MLP( +# n_inputs, n_outputs, n_neurons, n_layers, +# activation=activation, +# use_final_bias=use_final_bias, +# key=key +# ) +# model = init_linear_weight(model, trunc_init, key) +# self.mlp = model + +# def __call__(self, params, x): +# return self.mlp(params, x) +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks/properties.html b/html/_modules/pancax/networks/properties.html new file mode 100644 index 0000000..973cdbb --- /dev/null +++ b/html/_modules/pancax/networks/properties.html @@ -0,0 +1,182 @@ + + + + + + + + pancax.networks.properties — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks.properties

+from jax._src.random import PRNGKey as PRNGKey
+from jax import random
+from jaxtyping import Array, Float
+from typing import Callable, Optional
+import equinox as eqx
+import jax
+import jax.numpy as jnp
+
+
+
+
+[docs] +class Properties(eqx.Module): + """ + :param prop_mins: Minimum allowable properties + :param prop_maxs: Maximum allowable properties + :param prop_params: Actual tunable parameters + """ + prop_mins: jax.Array = eqx.field(static=True) + prop_maxs: jax.Array = eqx.field(static=True) + prop_params: jax.Array + activation_func: Callable + +
+[docs] + def __init__( + self, + prop_mins: jax.Array, + prop_maxs: jax.Array, + key: jax.random.PRNGKey, + activation_func: Optional[Callable] = jax.nn.sigmoid + ) -> None: + """ + :param prop_mins: Minimum allowable properties + :param prop_maxs: Maximum allowable properties + :param key: rng key + """ + + self.prop_mins = jnp.array(prop_mins) + self.prop_maxs = jnp.array(prop_maxs) + self.prop_params = jax.random.uniform(key, self.prop_mins.shape) + self.activation_func = activation_func
+ + + def __call__(self) -> Float[Array, "np"]: + """ + :return: Predicted properties + """ + props = self.prop_mins + \ + (self.prop_maxs - self.prop_mins) * self.activation_func(self.prop_params) + return props
+ + + +
+[docs] +class FixedProperties(Properties): +
+[docs] + def __init__(self, props: jax.Array) -> None: + """ + :param props: Property values to be fixed + """ + key = random.key(0) + super().__init__(props, props, key)
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/networks/rbf.html b/html/_modules/pancax/networks/rbf.html new file mode 100644 index 0000000..7f11548 --- /dev/null +++ b/html/_modules/pancax/networks/rbf.html @@ -0,0 +1,151 @@ + + + + + + + + pancax.networks.rbf — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.networks.rbf

+import equinox as eqx
+import jax
+import jax.numpy as jnp
+
+
+
+[docs] +class RBFBasis(eqx.Module): + center: jax.Array + sigma: jax.Array + +
+[docs] + def __init__( + self, + n_inputs: int, + n_neurons: int, + key: jax.random.PRNGKey + ) -> None: + ckey, skey = jax.random.split(key) + self.center = jax.random.normal(ckey, (n_neurons, n_inputs)) + self.sigma = 1.0 * jnp.ones((n_neurons,), dtype=jnp.float64)
+ + + def __call__(self, x): + out = self.center - x + out = jax.vmap(lambda a: jnp.dot(a, a))(out) + out = jnp.exp(-out / jnp.square(self.sigma)) + return out
+ + +
+[docs] +def rbf_normalization(hidden): + return hidden / jnp.sum(hidden, axis=1)[:, None]
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/optimizers/adam.html b/html/_modules/pancax/optimizers/adam.html new file mode 100644 index 0000000..d17f4f8 --- /dev/null +++ b/html/_modules/pancax/optimizers/adam.html @@ -0,0 +1,189 @@ + + + + + + + + pancax.optimizers.adam — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.optimizers.adam

+from .base import Optimizer
+from typing import Callable
+from typing import Optional
+import equinox as eqx
+import optax
+
+
+
+[docs] +class Adam(Optimizer): +
+[docs] + def __init__( + self, + loss_function: Callable, + has_aux: Optional[bool] = False, + jit: Optional[bool] = True, + learning_rate: Optional[float] = 1.0e-3, + transition_steps: Optional[int] = 500, + decay_rate: Optional[float] = 0.99, + clip_gradients: Optional[bool] = False, + filter_spec: Optional[Callable] = None + ) -> None: + super().__init__(loss_function, has_aux, jit) + scheduler = optax.exponential_decay( + init_value=learning_rate, + transition_steps=transition_steps, + decay_rate=decay_rate + ) + if clip_gradients: + self.opt = optax.chain( + optax.clip_by_global_norm(1.0), + optax.scale_by_adam(), + optax.scale_by_schedule(scheduler), + optax.scale(-1.0) + ) + else: + self.opt = optax.chain( + optax.scale_by_adam(), + optax.scale_by_schedule(scheduler), + optax.scale(-1.0) + ) + + if filter_spec is None: + self.loss_and_grads = eqx.filter_value_and_grad(self.loss_function, has_aux=self.has_aux) + else: + self.loss_and_grads = eqx.filter_value_and_grad(self.loss_function.filtered_loss, has_aux=self.has_aux) + self.filter_spec = filter_spec
+ + +
+[docs] + def make_step_method(self): + if self.filter_spec is None: + def step(params, domain, opt_st): + loss, grads = self.loss_and_grads(params, domain) + updates, opt_st = self.opt.update(grads, opt_st) + params = eqx.apply_updates(params, updates) + # add grad props to output + loss[1].update({'dprops': grads.properties.prop_params}) + return params, opt_st, loss + else: + def step(params, domain, opt_st): + diff_params, static_params = eqx.partition(params, self.filter_spec) + loss, grads = self.loss_and_grads(diff_params, static_params, domain) + updates, opt_st = self.opt.update(grads, opt_st) + params = eqx.apply_updates(params, updates) + + # add grad props to output + # loss[1].update({'dprops': grads.properties()}) + return params, opt_st, loss + + return step
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/optimizers/base.html b/html/_modules/pancax/optimizers/base.html new file mode 100644 index 0000000..58b1ce5 --- /dev/null +++ b/html/_modules/pancax/optimizers/base.html @@ -0,0 +1,226 @@ + + + + + + + + pancax.optimizers.base — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.optimizers.base

+from abc import ABC
+from abc import abstractmethod
+from pancax.logging import log_loss
+from typing import Callable
+from typing import Optional
+import equinox as eqx
+
+
+
+[docs] +class Optimizer(ABC): +
+[docs] + def __init__( + self, + loss_function: Callable, + has_aux: Optional[bool] = False, + jit: Optional[bool] = True + ) -> None: + self.loss_function = loss_function + self.has_aux = has_aux + self.jit = jit + self.step = None + self.epoch = 0
+ + +
+[docs] + @abstractmethod + def make_step_method(self, params): + pass
+ + +
+[docs] + def ensemble_init(self, params): + self.step = self.make_step_method() + # if self.jit: + # self.step = eqx.filter_jit(self.step) + + # need to now make an ensemble wrapper our self.step + # but make sure not to jit it until after the vmap + def ensemble_step(params, domain, opt_st): + params, opt_st, loss = eqx.filter_vmap( + self.step, in_axes=(eqx.if_array(0), None, eqx.if_array(0)) + )(params, domain, opt_st) + return params, opt_st, loss + + if self.jit: + self.ensemble_step = eqx.filter_jit(ensemble_step) + + def vmap_func(p): + return self.opt.init(eqx.filter(p, eqx.is_array)) + + opt_st = eqx.filter_vmap(vmap_func, in_axes=(eqx.if_array(0),))(params) + return opt_st
+ + +
+[docs] + def ensemble_step_old(self, params, domain, opt_st): + params, opt_st, loss = eqx.filter_vmap( + self.step, in_axes=(eqx.if_array(0), None, eqx.if_array(0)) + )(params, domain, opt_st) + return params, opt_st, loss
+ + +
+[docs] + def init(self, params): + self.step = self.make_step_method() + if self.jit: + self.step = eqx.filter_jit(self.step) + + opt_st = self.opt.init(eqx.filter(params, eqx.is_array)) + # opt_st = self.opt.init(eqx.filter(params, filter_spec)) + return opt_st
+ + + # def train(self, params, opt_st, domain, n_epochs, log_every): + # for n in range(n_epochs): + # params, opt_st, loss = self.step(params, domain, opt_st) + # log_loss(loss, self.epoch, log_every) + # self.epoch = self.epoch + 1 + # return params, opt_st +
+[docs] + def train( + self, + params, domain, times, opt, logger, history, pp, + n_epochs, + log_every: Optional[int] = 100, + serialise_every: Optional[int] = 10000, + postprocess_every: Optional[int] = 10000 + ): + opt_st = opt.init(params) + for epoch in range(int(n_epochs)): + params, opt_st, loss = opt.step(params, domain, opt_st) + logger.log_loss(loss, epoch, log_every) + history.write_loss(loss, epoch) + + if epoch % serialise_every == 0: + params.serialise('checkpoint', epoch) + + if epoch % postprocess_every == 0: + pp.init(params, domain, f'output_{str(epoch).zfill(6)}.e') + pp.write_outputs(params, domain, times, [ + 'displacement', + ]) + pp.close()
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/optimizers/lbfgs.html b/html/_modules/pancax/optimizers/lbfgs.html new file mode 100644 index 0000000..7ebd4d5 --- /dev/null +++ b/html/_modules/pancax/optimizers/lbfgs.html @@ -0,0 +1,217 @@ + + + + + + + + pancax.optimizers.lbfgs — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.optimizers.lbfgs

+from .base import Optimizer
+from optax import tree_utils as otu
+# from optimistix._misc import filter_cond
+from typing import Any, Callable, Optional
+import equinox as eqx
+import jax
+import jax.numpy as jnp
+import optax
+
+
+
+[docs] +def value_and_grad_from_state(value_fn): + def _value_and_grad( + params, domain, + *fn_args: Any, + state, + **fn_kwargs: dict[str, Any], + ): + value = otu.tree_get(state, 'value') + grad = otu.tree_get(state, 'grad') + aux = dict(energy=jnp.array(0.0), residual=jnp.array(1000.0)) + if (value is None) or (grad is None): + raise ValueError( + 'Value or gradient not found in the state. ' + 'Make sure that these values are stored in the state by the ' + 'optimizer.' + ) + # (value, aux), grad = filter_cond( + # (~jnp.isinf(value)) & (~jnp.isnan(value)), + # lambda p, a, kwa: ((value, aux), grad), + # lambda p, a, kwa: eqx.filter_value_and_grad(value_fn, has_aux=True)(p, domain, *a, **kwa), + # params, + # fn_args, + # fn_kwargs, + # ) + print(value) + (value, aux), grad = filter_cond( + (~jnp.isinf(value)) & (~jnp.isnan(value)), + lambda p: ((value, aux), grad), + # lambda p: (value, grad), + lambda p: eqx.filter_value_and_grad(value_fn, has_aux=True)(p, domain), + params + ) + # TODO + # probably really slow right now + # value, grad = eqx.filter_value_and_grad(value_fn, has_aux=True)(params, domain) + return (value, aux), grad + + return _value_and_grad
+ + + +
+[docs] +class LBFGS(Optimizer): +
+[docs] + def __init__( + self, + loss_function: Callable, + has_aux: Optional[bool] = False, + jit: Optional[bool] = False, + learning_rate: Optional[float] = 1.0e-1 + ) -> None: + super().__init__(loss_function, has_aux, jit) + + # TODO setup up optimizer stuff here + linesearch = optax.scale_by_backtracking_linesearch( + max_backtracking_steps=15, store_grad=True + ) + # self.opt = optax.chain( + + # ) + self.opt = optax.lbfgs( + learning_rate=learning_rate, + linesearch=linesearch + ) + + # self.loss_and_grads = eqx.filter_value_and_grad(self.loss_function, has_aux=self.has_aux) + self.loss_and_grads = value_and_grad_from_state(self.loss_function)
+ + +
+[docs] + def make_step_method(self): + def step(params, domain, opt_st): + loss, grads = self.loss_and_grads(params, domain, state=opt_st) + updates, opt_st = self.opt.update( + grads, opt_st, params, value=loss, grad=grads, + value_fn=self.loss_function + ) + print('here') + print(updates) + print('here') + print(opt_st) + print('here') + params = eqx.apply_updates(params, updates) + return params, opt_st, loss + + return step
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/optimizers/utils.html b/html/_modules/pancax/optimizers/utils.html new file mode 100644 index 0000000..204fdf2 --- /dev/null +++ b/html/_modules/pancax/optimizers/utils.html @@ -0,0 +1,161 @@ + + + + + + + + pancax.optimizers.utils — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.optimizers.utils

+from typing import Optional
+import equinox as eqx
+import jax
+
+
+
+[docs] +def trainable_filter( + params: any, + # freeze_fields: Optional[bool] = False, + freeze_properties: Optional[bool] = True, + freeze_basis: Optional[bool] = False, + # freeze_linear_layer: Optional[bool] = False +): + # TODO there's some logic to work out here + filter_spec = jax.tree_util.tree_map( + lambda _: True, params + ) + + # filter_spec = eqx.tree_at( + # lambda tree: tree.fields, + # filter_spec, + # replace=not freeze_fields + # ) + filter_spec = eqx.tree_at( + lambda tree: tree.properties.prop_params, + filter_spec, + replace=not freeze_properties + ) + + if freeze_basis: + try: + filter_spec = eqx.tree_at( + lambda tree: (tree.fields.basis.weight, tree.fields.basis.bias), + filter_spec, + replace=(not freeze_basis, not freeze_basis) + ) + filter_spec = eqx.tree_at( + lambda tree: (tree.fields.linear.weight, tree.fields.linear.bias), + filter_spec, + replace=(True, True) + ) + except: + raise AttributeError('This network does not have a basis!') + + return filter_spec
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/physics.html b/html/_modules/pancax/physics.html new file mode 100644 index 0000000..5b4d589 --- /dev/null +++ b/html/_modules/pancax/physics.html @@ -0,0 +1,320 @@ + + + + + + + + pancax.physics — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.physics

+from jax import grad
+from jax import hessian
+from jax import jacfwd
+from jax import value_and_grad
+from jax import vmap
+from pancax.fem import assemble_sparse_stiffness_matrix
+from pancax.timer import Timer
+import jax.numpy as jnp
+import numpy as onp
+
+
+# TODO remove above and start using this method below
+
+[docs] +def element_quantity(f, x, u, conn, N, grad_N, JxW, props): + x_el = x[conn, :] + u_el = u[conn, :] + return vmap(f, in_axes=(None, None, 0, 0, 0, None))(x_el, u_el, N, grad_N, JxW, props)
+ + + +
+[docs] +def element_quantity_new(f, fspace, x_el, u_el, props): + Ns = fspace.shape_function_values(x_el) + grad_Ns = fspace.shape_function_gradients(x_el) + JxWs = fspace.JxWs(x_el) + return jnp.sum(vmap(f, in_axes=(None, None, 0, 0, 0, None))(x_el, u_el, Ns, grad_Ns, JxWs, props))
+ + + +element_quantity_grad = jacfwd(element_quantity_new, argnums=3) +element_quantity_hessian = hessian(element_quantity_new, argnums=3) + + +
+[docs] +def potential_energy(domain, us, props): + + # unpack some stuff + us = us[domain.conns, :] + coords = domain.coords[domain.conns, :] + func = domain.physics.energy + + pis = vmap(element_quantity_new, in_axes=(None, None, 0, 0, None))( + func, domain.fspace, coords, us, props + ) + return jnp.sum(pis)
+ + + +
+[docs] +def residual_mse(domain, us, props): + # unpack some stuff + us = us[domain.conns, :] + coords = domain.coords[domain.conns, :] + kernel = domain.physics + + func = element_quantity_grad + fs = vmap(func, in_axes=(None, None, 0, 0, None))( + kernel.energy, domain.fspace, coords, us, props + ) + def vmap_func(f, unknowns): + return jnp.square(jnp.where(unknowns, f, 0)).mean() + + return vmap(vmap_func, in_axes=(0, 0))(fs, domain.dof_manager.isUnknown[domain.conns, :]).mean()
+ + + +
+[docs] +def mass_matrix(domain, us, props): + with Timer('mass matrix assembly'): + us = us[domain.conns, :] + coords = domain.coords[domain.conns, :] + kernel = domain.physics + + func = element_quantity_hessian + fs = vmap(func, in_axes=(None, None, 0, 0, None))( + kernel.kinetic_energy, domain.fspace, coords, us, props + ) + return assemble_sparse_stiffness_matrix( + onp.asarray(fs), onp.asarray(domain.conns), domain.dof_manager + )
+ + + +
+[docs] +def stiffness_matrix(domain, us, props): + with Timer('stiffness matrix assembly'): + us = us[domain.conns, :] + coords = domain.coords[domain.conns, :] + kernel = domain.physics + + func = element_quantity_hessian + fs = vmap(func, in_axes=(None, None, 0, 0, None))( + kernel.energy, domain.fspace, coords, us, props + ) + return assemble_sparse_stiffness_matrix( + onp.asarray(fs), onp.asarray(domain.conns), domain.dof_manager + )
+ + + +# TODO +
+[docs] +def traction_energy(): + pass
+ + + +# internal force methods +internal_force = grad(potential_energy, argnums=1) + +# residual methods +residual = lambda x, y, z: jnp.linalg.norm(internal_force(x, y, z).flatten()[x.dof_manager.unknownIndices]) + +# combined methods +potential_energy_and_internal_force = value_and_grad(potential_energy, argnums=1) + + +
+[docs] +def potential_energy_and_residual(domain, us, props): + pi, f = potential_energy_and_internal_force(domain, us, props) + return pi, jnp.linalg.norm(f.flatten()[domain.dof_manager.unknownIndices])
+ + + +
+[docs] +def potential_energy_residual_and_reaction_force(domain, us, props): + pi, f = potential_energy_and_internal_force(domain, us, props) + R = jnp.linalg.norm(f.flatten()[domain.dof_manager.unknownIndices]) + reaction = jnp.sum(f[domain.global_data.reaction_nodes, domain.global_data.reaction_dof]) + return pi, R, reaction
+ + + +
+[docs] +def strong_form_residual(params, domain, t): + residuals = vmap(domain.physics.strong_form, in_axes=(None, 0, None))(params, domain.coords, t) + residual = jnp.square(residuals.flatten()[domain.dof_manager.unknownIndices]).mean() + return residual
+ + + +# test +
+[docs] +def nodal_incompressibility_constraint(params, domain, t): + vals = vmap(domain.physics.nodal_incompressibility_constraint, in_axes=(None, 0, None))( + params.fields, domain.coords, t + ) + return jnp.sum(vals)
+ + # return domain.physics.nodal_incompressibility_constraint(params, domain, t) + + +
+[docs] +def quadrature_incompressibility_constraint(domain, us, props): + # unpack some stuff + us = us[domain.conns, :] + coords = domain.coords[domain.conns, :] + func = domain.physics.quadrature_incompressibility_constraint + + # vmap over elements + vals = vmap(element_quantity_new, in_axes=(None, None, 0, 0, None))( + func, domain.fspace_centroid, coords, us, props + ) + # return jnp.mean(vals) + return jnp.sum(vals)
+ + +# quadrature_incompressibility_constraint_energy_and_residual = grad( +# quadrature_incompressibility_constraint, argnums=1 +# ) + +# def quadrature_incompressibility_constraint_energy_and_residual(domain, us, props): +# loss, f = quadrature_incompressibility_constraint_energy_and_residual(domain, us, props) +# return loss, jnp.linalg.norm(f.flatten()[domain.dof_manager.unknownIndices]) + + +
+[docs] +def incompressible_energy(domain, us, props): + K = 100.0 + pi = potential_energy(domain, us, props) + constraint = quadrature_incompressibility_constraint(domain, us, props) + return pi + K * constraint
+ + +incompressible_internal_force = grad(incompressible_energy, argnums=1) +incompressible_energy_and_internal_force = value_and_grad(incompressible_energy, argnums=1) + +
+[docs] +def incompressible_energy_and_residual(domain, us, props): + pi, f = incompressible_energy_and_internal_force(domain, us, props) + return pi, jnp.linalg.norm(f.flatten()[domain.dof_manager.unknownIndices])
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/post_processor.html b/html/_modules/pancax/post_processor.html new file mode 100644 index 0000000..a3a262e --- /dev/null +++ b/html/_modules/pancax/post_processor.html @@ -0,0 +1,286 @@ + + + + + + + + pancax.post_processor — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.post_processor

+from pancax.physics import incompressible_internal_force, internal_force
+from typing import List, Optional
+import exodus3 as exodus
+import jax
+import os
+import numpy as onp
+
+
+
+[docs] +class PostProcessor: +
+[docs] + def __init__(self, mesh_file: str) -> None: + self.mesh_file = mesh_file + self.exo = None + self.node_variables = None + self.element_variables = None
+ + +
+[docs] + def check_variable_names(self, domain, variables) -> None: + for var in variables: + if var == 'internal_force' or var == 'incompressible_internal_force': + continue + + if var not in domain.physics.var_name_to_method.keys(): + str = f'Unsupported variable requested for output {var}.\n' + str += f'Supported variables include:\n' + for v in domain.physics.var_name_to_method.keys(): + str += f' {v}\n' + raise ValueError(str)
+ + +
+[docs] + def close(self) -> None: + self.exo.close()
+ + +
+[docs] + def copy_mesh(self, output_file: str) -> None: + if os.path.isfile(output_file): + os.remove(output_file) + + exo_temp = exodus.copy_mesh(self.mesh_file, output_file) + exo_temp.close() + self.exo = exodus.exodus(output_file, mode='a', array_type='numpy')
+ + +
+[docs] + def get_node_variable_number(self, domain, variables) -> int: + n = 0 + for var in variables: + if var == 'internal_force' or var == 'incompressible_internal_force': + n = n + len(domain.physics.field_value_names) + else: + n = n + len(domain.physics.var_name_to_method[var]['names']) + + return n
+ + +
+[docs] + def get_element_variable_number(self, domain, variables) -> int: + n = 0 + for var in variables: + n = n + len(domain.physics.var_name_to_method[var]['names']) + if n > 0: + q_points = len(domain.fspace.quadrature_rule) + return n * q_points + else: + return 0
+ + +
+[docs] + def init( + self, + domain, output_file: str, + node_variables: List[str], + element_variables: Optional[List[str]] = [] + ) -> None: + self.copy_mesh(output_file) + self.check_variable_names(domain, node_variables) + self.check_variable_names(domain, element_variables) + self.node_variables = node_variables + self.element_variables = element_variables + self.exo.set_node_variable_number( + self.get_node_variable_number(domain, node_variables) + ) + self.exo.set_element_variable_number( + self.get_element_variable_number(domain, element_variables) + ) + n = 1 + for var in self.node_variables: + if var == 'internal_force' or var == 'incompressible_internal_force': + self.exo.put_node_variable_name('internal_force_x', n) + self.exo.put_node_variable_name('internal_force_y', n + 1) + self.exo.put_node_variable_name('internal_force_z', n + 2) + n = n + 3 + else: + for v in domain.physics.var_name_to_method[var]['names']: + self.exo.put_node_variable_name(v, n) + n = n + 1 + + if len(element_variables) > 0: + q_points = len(domain.fspace.quadrature_rule) + n = 1 + for var in self.element_variables: + for v in domain.physics.var_name_to_method[var]['names']: + for q in range(q_points): + name = f'{v}_{q + 1}' + self.exo.put_element_variable_name(name, n) + n = n + 1
+ + +
+[docs] + def index_to_component(self, index): + if index == 0: + string = 'x' + elif index == 1: + string = 'y' + elif index == 2: + string = 'z' + else: + raise ValueError('Should be 0, 1, or 2') + return string
+ + +
+[docs] + def write_outputs(self, params, domain) -> None: + physics = domain.physics + times = domain.times + for n, time in enumerate(times): + self.exo.put_time(n + 1, time) + + for var in self.node_variables: + if var == 'internal_force' or var == 'incompressible_internal_force': + us = jax.vmap(physics.field_values, in_axes=(None, 0, None))(params.fields, domain.coords, time) + fs = onp.array(internal_force(domain, us, params.properties())) + for i in range(fs.shape[1]): + self.exo.put_node_variable_values(f'internal_force_{self.index_to_component(i)}', n + 1, fs[:, i]) + else: + output = physics.var_name_to_method[var] + pred = onp.array(output['method'](params, domain, time)) + if len(pred.shape) > 2: + for i in range(pred.shape[1]): + for j in range(pred.shape[2]): + k = pred.shape[1] * i + j + self.exo.put_node_variable_values(output['names'][k], n + 1, pred[:, i, j]) + else: + for i in range(pred.shape[1]): + self.exo.put_node_variable_values(output['names'][i], n + 1, pred[:, i]) + + if len(self.element_variables) > 0: + n_q_points = len(domain.fspace.quadrature_rule) + for var in self.element_variables: + output = physics.var_name_to_method[var] + pred = onp.array(output['method'](params, domain, time)) + for q in range(n_q_points): + for i in range(pred.shape[2]): + name = f'{output["names"][i]}_{q + 1}' + # NOTE this will only work on a single block + self.exo.put_element_variable_values(1, name, n + 1, pred[:, q, i])
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/timer.html b/html/_modules/pancax/timer.html new file mode 100644 index 0000000..27d6f67 --- /dev/null +++ b/html/_modules/pancax/timer.html @@ -0,0 +1,186 @@ + + + + + + + + pancax.timer — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.timer

+from contextlib import ContextDecorator
+from dataclasses import dataclass, field
+import time
+from typing import Any, Callable, ClassVar, Dict, Optional
+
+
+
+[docs] +class TimerError(Exception): + """A custom exception used to report errors in use of Timer class"""
+ + + +
+[docs] +@dataclass +class Timer(ContextDecorator): + """Time your code using a class, context manager, or decorator""" + + timers: ClassVar[Dict[str, float]] = dict() + name: Optional[str] = None + text: str = "Time in {name}: {:0.8f} seconds" + logger: Optional[Callable[[str], None]] = print + _start_time: Optional[float] = field(default=None, init=False, repr=False) + + def __post_init__(self) -> None: + """Initialization: add timer to dict of timers""" + if self.name: + self.timers.setdefault(self.name, 0) + +
+[docs] + def start(self) -> None: + """Start a new timer""" + if self._start_time is not None: + raise TimerError(f"Timer is running. Use .stop() to stop it") + + self._start_time = time.perf_counter()
+ + +
+[docs] + def stop(self) -> float: + """Stop the timer, and report the elapsed time""" + if self._start_time is None: + raise TimerError(f"Timer is not running. Use .start() to start it") + + # Calculate elapsed time + elapsed_time = time.perf_counter() - self._start_time + self._start_time = None + + # Report elapsed time + if self.logger: + if (self.name): + self.logger(self.text.format(elapsed_time, name=self.name)) + else: + self.logger(self.text.format(elapsed_time, name='')) + if self.name: + self.timers[self.name] += elapsed_time + + return elapsed_time
+ + + def __enter__(self) -> "Timer": + """Start a new timer as a context manager""" + self.start() + return self + + def __exit__(self, *exc_info: Any) -> None: + """Stop the context manager timer""" + self.stop()
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/trainer.html b/html/_modules/pancax/trainer.html new file mode 100644 index 0000000..a11f8b7 --- /dev/null +++ b/html/_modules/pancax/trainer.html @@ -0,0 +1,213 @@ + + + + + + + + pancax.trainer — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.trainer

+from pancax.history_writer import HistoryWriter
+from pancax.logging import Logger
+from pancax.post_processor import PostProcessor
+from pancax.utils import set_checkpoint_file
+from pathlib import Path
+import os
+
+# TODO make this a proper equinox module
+
+[docs] +class Trainer: +
+[docs] + def __init__( + self, + domain, + opt, + checkpoint_base = 'checkpoint', + history_file = 'history.csv', + log_file = 'pinn.log', + output_file_base = 'output', + output_node_variables = [], + output_element_variables = [], + log_every = 1000, + output_every = 10000, + serialise_every = 10000, + workdir = os.getcwd() + ) -> None: + try: + os.makedirs(Path(os.path.join(workdir, 'checkpoint'))) + os.makedirs(Path(os.path.join(workdir, 'history'))) + os.makedirs(Path(os.path.join(workdir, 'log'))) + os.makedirs(Path(os.path.join(workdir, 'results'))) + except FileExistsError: + pass + + self.domain = domain + self.opt = opt + self.checkpoint_base = Path(os.path.join(workdir, 'checkpoint', checkpoint_base)) + self.serialise_every = serialise_every + self.history = HistoryWriter(Path(os.path.join(workdir, 'history', history_file)), log_every, log_every) + self.logger = Logger(Path(os.path.join(workdir, 'log', log_file)), log_every) + self.output_every = output_every + self.output_file_base = Path(os.path.join(workdir, 'results', output_file_base)) + self.output_node_variables = output_node_variables + self.output_element_variables = output_element_variables + self.pp = PostProcessor(domain.mesh_file) + self.epoch = 0
+ + +
+[docs] + def init(self, params): + opt_st = self.opt.init(params) + return opt_st
+ + +
+[docs] + def serialise(self, params): + if self.epoch % self.serialise_every == 0: + params.serialise(self.checkpoint_base, self.epoch)
+ + +
+[docs] + def step(self, params, opt_st): + params, opt_st, loss = self.opt.step(params, self.domain, opt_st) + self.history.write_history(loss, self.epoch) + self.logger.log_loss(loss, self.epoch) + self.serialise(params) + self.write_outputs(params) + self.epoch = self.epoch + 1 + return params, opt_st
+ + +
+[docs] + def train(self, params, n_epochs): + opt_st = self.init(params) + for epoch in range(n_epochs): + params, opt_st = self.step(params, opt_st) + return params
+ + +
+[docs] + def write_outputs(self, params): + if self.epoch % self.output_every == 0: + self.pp.init( + self.domain, + f'{self.output_file_base}_{str(self.epoch).zfill(8)}.e', + node_variables=self.output_node_variables, + element_variables=self.output_element_variables + ) + self.pp.write_outputs(params, self.domain) + self.pp.close()
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_modules/pancax/utils.html b/html/_modules/pancax/utils.html new file mode 100644 index 0000000..7dc3322 --- /dev/null +++ b/html/_modules/pancax/utils.html @@ -0,0 +1,209 @@ + + + + + + + + pancax.utils — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for pancax.utils

+from pathlib import Path
+import inspect
+import os
+
+
+
+[docs] +class DataFileNotFoundException(Exception): + pass
+ + + +
+[docs] +class MeshFileNotFoundException(Exception): + pass
+ + + +
+[docs] +def find_data_file(data_file_in: str): + call_file = Path(inspect.stack()[1].filename) + call_file_dir = call_file.parent + + data_file = Path(os.path.join( + call_file_dir, 'data', data_file_in + )) + + if not data_file.is_file(): + data_file = Path(os.path.join(call_file_dir, data_file)) + if not data_file.is_file(): + raise DataFileNotFoundException( + f'Could not find data file {data_file_in} in either ' + f'{call_file_dir} or {call_file_dir}/data' + ) + + print(f'Found {data_file_in} in {data_file.parent}') + return data_file
+ + + +
+[docs] +def find_mesh_file(mesh_file_in: str): + call_file = Path(inspect.stack()[1].filename) + call_file_dir = call_file.parent + + mesh_file = Path(os.path.join( + call_file_dir, 'mesh', mesh_file_in + )) + + if not mesh_file.is_file(): + mesh_file = Path(os.path.join(call_file_dir, mesh_file)) + if not mesh_file.is_file(): + raise MeshFileNotFoundException( + f'Could not find data file {mesh_file_in} in either ' + f'{call_file_dir} or {call_file_dir}/mesh' + ) + + print(f'Found {mesh_file_in} in {mesh_file.parent}') + return mesh_file
+ + + +
+[docs] +def set_checkpoint_file(checkpoint_file_base: str): + call_file = Path(inspect.stack()[3].filename) + call_file_dir = call_file.parent + + checkpoint_dir = Path(os.path.join( + call_file_dir, 'checkpoint' + )) + + if not checkpoint_dir.is_dir(): + os.makedirs(checkpoint_dir) + + + checkpoint_file = Path(os.path.join( + checkpoint_dir, checkpoint_file_base + )) + + # if not mesh_file.is_file(): + # mesh_file = Path(os.path.join(call_file_dir, mesh_file)) + # if not mesh_file.is_file(): + # raise MeshFileNotFoundException( + # f'Could not find data file {mesh_file_in} in either ' + # f'{call_file_dir} or {call_file_dir}/mesh' + # ) + + # print(f'Found {mesh_file_in} in {mesh_file.parent}') + # return mesh_file + return checkpoint_file
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/_sources/index.rst.txt b/html/_sources/index.rst.txt new file mode 100644 index 0000000..b61a3e8 --- /dev/null +++ b/html/_sources/index.rst.txt @@ -0,0 +1,24 @@ +Pancax +======================================= +.. toctree:: + :maxdepth: 2 + + modules + pancax.bcs + pancax.bvps + pancax.constitutive_models + pancax.data + pancax.domains + pancax.fem + pancax.kernels + pancax.loss_functions + pancax.math + pancax.networks + pancax.optimizers + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/html/_sources/modules.rst.txt b/html/_sources/modules.rst.txt new file mode 100644 index 0000000..dc79a09 --- /dev/null +++ b/html/_sources/modules.rst.txt @@ -0,0 +1,7 @@ +pancax +====== + +.. toctree:: + :maxdepth: 4 + + pancax diff --git a/html/_sources/pancax.bcs.rst.txt b/html/_sources/pancax.bcs.rst.txt new file mode 100644 index 0000000..800d640 --- /dev/null +++ b/html/_sources/pancax.bcs.rst.txt @@ -0,0 +1,41 @@ +pancax.bcs package +================== + +Submodules +---------- + +pancax.bcs.distance\_functions module +------------------------------------- + +.. automodule:: pancax.bcs.distance_functions + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.bcs.essential\_bc module +------------------------------- + +.. automodule:: pancax.bcs.essential_bc + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.bcs.natural\_bc module +----------------------------- + +.. automodule:: pancax.bcs.natural_bc + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.bcs + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.bvps.rst.txt b/html/_sources/pancax.bvps.rst.txt new file mode 100644 index 0000000..d07e860 --- /dev/null +++ b/html/_sources/pancax.bvps.rst.txt @@ -0,0 +1,41 @@ +pancax.bvps package +=================== + +Submodules +---------- + +pancax.bvps.biaxial\_tension module +----------------------------------- + +.. automodule:: pancax.bvps.biaxial_tension + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.bvps.simple\_shear module +-------------------------------- + +.. automodule:: pancax.bvps.simple_shear + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.bvps.uniaxial\_tension module +------------------------------------ + +.. automodule:: pancax.bvps.uniaxial_tension + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.bvps + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.constitutive_models.rst.txt b/html/_sources/pancax.constitutive_models.rst.txt new file mode 100644 index 0000000..42f5cf1 --- /dev/null +++ b/html/_sources/pancax.constitutive_models.rst.txt @@ -0,0 +1,59 @@ +pancax.constitutive\_models package +=================================== + +Submodules +---------- + +pancax.constitutive\_models.base\_constitutive\_model module +------------------------------------------------------------ + +.. automodule:: pancax.constitutive_models.base_constitutive_model + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.constitutive\_models.blatz\_ko module +-------------------------------------------- + +.. automodule:: pancax.constitutive_models.blatz_ko + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.constitutive\_models.gent module +--------------------------------------- + +.. automodule:: pancax.constitutive_models.gent + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.constitutive\_models.neohookean module +--------------------------------------------- + +.. automodule:: pancax.constitutive_models.neohookean + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.constitutive\_models.swanson module +------------------------------------------ + +.. automodule:: pancax.constitutive_models.swanson + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.constitutive_models + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.data.rst.txt b/html/_sources/pancax.data.rst.txt new file mode 100644 index 0000000..3b2f0ff --- /dev/null +++ b/html/_sources/pancax.data.rst.txt @@ -0,0 +1,32 @@ +pancax.data package +=================== + +Submodules +---------- + +pancax.data.full\_field\_data module +------------------------------------ + +.. automodule:: pancax.data.full_field_data + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.data.global\_data module +------------------------------- + +.. automodule:: pancax.data.global_data + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.data + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.domains.rst.txt b/html/_sources/pancax.domains.rst.txt new file mode 100644 index 0000000..9e8d9a1 --- /dev/null +++ b/html/_sources/pancax.domains.rst.txt @@ -0,0 +1,68 @@ +pancax.domains package +====================== + +Submodules +---------- + +pancax.domains.base\_domain module +---------------------------------- + +.. automodule:: pancax.domains.base_domain + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.domains.collocation\_domain module +----------------------------------------- + +.. automodule:: pancax.domains.collocation_domain + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.domains.delta\_pinn\_domain module +----------------------------------------- + +.. automodule:: pancax.domains.delta_pinn_domain + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.domains.inverse\_domain module +------------------------------------- + +.. automodule:: pancax.domains.inverse_domain + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.domains.utils module +--------------------------- + +.. automodule:: pancax.domains.utils + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.domains.variational\_domain module +----------------------------------------- + +.. automodule:: pancax.domains.variational_domain + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.domains + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.fem.elements.rst.txt b/html/_sources/pancax.fem.elements.rst.txt new file mode 100644 index 0000000..3134a2d --- /dev/null +++ b/html/_sources/pancax.fem.elements.rst.txt @@ -0,0 +1,86 @@ +pancax.fem.elements package +=========================== + +Submodules +---------- + +pancax.fem.elements.base\_element module +---------------------------------------- + +.. automodule:: pancax.fem.elements.base_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.hex8\_element module +---------------------------------------- + +.. automodule:: pancax.fem.elements.hex8_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.line\_element module +---------------------------------------- + +.. automodule:: pancax.fem.elements.line_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.quad4\_element module +----------------------------------------- + +.. automodule:: pancax.fem.elements.quad4_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.quad9\_element module +----------------------------------------- + +.. automodule:: pancax.fem.elements.quad9_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.simplex\_tri\_element module +------------------------------------------------ + +.. automodule:: pancax.fem.elements.simplex_tri_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.tet10\_element module +----------------------------------------- + +.. automodule:: pancax.fem.elements.tet10_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.elements.tet4\_element module +---------------------------------------- + +.. automodule:: pancax.fem.elements.tet4_element + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.fem.elements + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.fem.rst.txt b/html/_sources/pancax.fem.rst.txt new file mode 100644 index 0000000..4c96e1d --- /dev/null +++ b/html/_sources/pancax.fem.rst.txt @@ -0,0 +1,94 @@ +pancax.fem package +================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + pancax.fem.elements + +Submodules +---------- + +pancax.fem.dof\_manager module +------------------------------ + +.. automodule:: pancax.fem.dof_manager + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.function\_space module +--------------------------------- + +.. automodule:: pancax.fem.function_space + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.mesh module +---------------------- + +.. automodule:: pancax.fem.mesh + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.quadrature\_rules module +----------------------------------- + +.. automodule:: pancax.fem.quadrature_rules + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.read\_exodus\_mesh module +------------------------------------ + +.. automodule:: pancax.fem.read_exodus_mesh + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.sparse\_matrix\_assembler module +------------------------------------------- + +.. automodule:: pancax.fem.sparse_matrix_assembler + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.surface module +------------------------- + +.. automodule:: pancax.fem.surface + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.fem.traction\_bc module +------------------------------ + +.. automodule:: pancax.fem.traction_bc + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.fem + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.kernels.rst.txt b/html/_sources/pancax.kernels.rst.txt new file mode 100644 index 0000000..057766b --- /dev/null +++ b/html/_sources/pancax.kernels.rst.txt @@ -0,0 +1,59 @@ +pancax.kernels package +====================== + +Submodules +---------- + +pancax.kernels.base\_kernel module +---------------------------------- + +.. automodule:: pancax.kernels.base_kernel + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.kernels.laplace\_beltrami module +--------------------------------------- + +.. automodule:: pancax.kernels.laplace_beltrami + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.kernels.linear\_elasticity module +---------------------------------------- + +.. automodule:: pancax.kernels.linear_elasticity + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.kernels.poisson module +----------------------------- + +.. automodule:: pancax.kernels.poisson + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.kernels.solid\_mechanics module +-------------------------------------- + +.. automodule:: pancax.kernels.solid_mechanics + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.kernels + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.loss_functions.rst.txt b/html/_sources/pancax.loss_functions.rst.txt new file mode 100644 index 0000000..e1c03dd --- /dev/null +++ b/html/_sources/pancax.loss_functions.rst.txt @@ -0,0 +1,77 @@ +pancax.loss\_functions package +============================== + +Submodules +---------- + +pancax.loss\_functions.base\_loss\_function module +-------------------------------------------------- + +.. automodule:: pancax.loss_functions.base_loss_function + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.loss\_functions.bc\_loss\_functions module +------------------------------------------------- + +.. automodule:: pancax.loss_functions.bc_loss_functions + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.loss\_functions.data\_loss\_functions module +--------------------------------------------------- + +.. automodule:: pancax.loss_functions.data_loss_functions + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.loss\_functions.physics\_loss\_functions\_strong\_form module +-------------------------------------------------------------------- + +.. automodule:: pancax.loss_functions.physics_loss_functions_strong_form + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.loss\_functions.strong\_form\_loss\_functions module +----------------------------------------------------------- + +.. automodule:: pancax.loss_functions.strong_form_loss_functions + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.loss\_functions.utils module +----------------------------------- + +.. automodule:: pancax.loss_functions.utils + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.loss\_functions.weak\_form\_loss\_functions module +--------------------------------------------------------- + +.. automodule:: pancax.loss_functions.weak_form_loss_functions + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.loss_functions + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.math.rst.txt b/html/_sources/pancax.math.rst.txt new file mode 100644 index 0000000..df1e3f7 --- /dev/null +++ b/html/_sources/pancax.math.rst.txt @@ -0,0 +1,32 @@ +pancax.math package +=================== + +Submodules +---------- + +pancax.math.math module +----------------------- + +.. automodule:: pancax.math.math + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.math.tensor\_math module +------------------------------- + +.. automodule:: pancax.math.tensor_math + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.math + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.networks.rst.txt b/html/_sources/pancax.networks.rst.txt new file mode 100644 index 0000000..e6d26da --- /dev/null +++ b/html/_sources/pancax.networks.rst.txt @@ -0,0 +1,68 @@ +pancax.networks package +======================= + +Submodules +---------- + +pancax.networks.elm module +-------------------------- + +.. automodule:: pancax.networks.elm + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.networks.field\_property\_pair module +-------------------------------------------- + +.. automodule:: pancax.networks.field_property_pair + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.networks.initialization module +------------------------------------- + +.. automodule:: pancax.networks.initialization + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.networks.mlp module +-------------------------- + +.. automodule:: pancax.networks.mlp + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.networks.properties module +--------------------------------- + +.. automodule:: pancax.networks.properties + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.networks.rbf module +-------------------------- + +.. automodule:: pancax.networks.rbf + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.networks + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.optimizers.rst.txt b/html/_sources/pancax.optimizers.rst.txt new file mode 100644 index 0000000..635e252 --- /dev/null +++ b/html/_sources/pancax.optimizers.rst.txt @@ -0,0 +1,50 @@ +pancax.optimizers package +========================= + +Submodules +---------- + +pancax.optimizers.adam module +----------------------------- + +.. automodule:: pancax.optimizers.adam + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.optimizers.base module +----------------------------- + +.. automodule:: pancax.optimizers.base + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.optimizers.lbfgs module +------------------------------ + +.. automodule:: pancax.optimizers.lbfgs + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.optimizers.utils module +------------------------------ + +.. automodule:: pancax.optimizers.utils + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax.optimizers + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_sources/pancax.rst.txt b/html/_sources/pancax.rst.txt new file mode 100644 index 0000000..f1edbd7 --- /dev/null +++ b/html/_sources/pancax.rst.txt @@ -0,0 +1,113 @@ +pancax package +============== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + pancax.bcs + pancax.bvps + pancax.constitutive_models + pancax.data + pancax.domains + pancax.fem + pancax.kernels + pancax.loss_functions + pancax.math + pancax.networks + pancax.optimizers + +Submodules +---------- + +pancax.\_\_main\_\_ module +-------------------------- + +.. automodule:: pancax.__main__ + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.history\_writer module +----------------------------- + +.. automodule:: pancax.history_writer + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.kinematics module +------------------------ + +.. automodule:: pancax.kinematics + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.logging module +--------------------- + +.. automodule:: pancax.logging + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.physics module +--------------------- + +.. automodule:: pancax.physics + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.post\_processor module +----------------------------- + +.. automodule:: pancax.post_processor + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.timer module +------------------- + +.. automodule:: pancax.timer + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.trainer module +--------------------- + +.. automodule:: pancax.trainer + :members: + :undoc-members: + :show-inheritance: + :private-members: + +pancax.utils module +------------------- + +.. automodule:: pancax.utils + :members: + :undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: pancax + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/html/_static/_sphinx_javascript_frameworks_compat.js b/html/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8141580 --- /dev/null +++ b/html/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/html/_static/basic.css b/html/_static/basic.css new file mode 100644 index 0000000..7ebbd6d --- /dev/null +++ b/html/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/html/_static/check-solid.svg b/html/_static/check-solid.svg new file mode 100644 index 0000000..92fad4b --- /dev/null +++ b/html/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/html/_static/clipboard.min.js b/html/_static/clipboard.min.js new file mode 100644 index 0000000..54b3c46 --- /dev/null +++ b/html/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/html/_static/copybutton.css b/html/_static/copybutton.css new file mode 100644 index 0000000..f1916ec --- /dev/null +++ b/html/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/html/_static/copybutton.js b/html/_static/copybutton.js new file mode 100644 index 0000000..2ea7ff3 --- /dev/null +++ b/html/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/html/_static/copybutton_funcs.js b/html/_static/copybutton_funcs.js new file mode 100644 index 0000000..dbe1aaa --- /dev/null +++ b/html/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/html/_static/css/badge_only.css b/html/_static/css/badge_only.css new file mode 100644 index 0000000..88ba55b --- /dev/null +++ b/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/html/_static/css/fonts/Roboto-Slab-Bold.woff b/html/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/html/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/html/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/html/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/html/_static/css/fonts/Roboto-Slab-Regular.woff b/html/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/html/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/html/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/html/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/html/_static/css/fonts/fontawesome-webfont.eot b/html/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/html/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/html/_static/css/fonts/fontawesome-webfont.svg b/html/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/html/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/html/_static/css/fonts/fontawesome-webfont.ttf b/html/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/html/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/html/_static/css/fonts/fontawesome-webfont.woff b/html/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/html/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/html/_static/css/fonts/fontawesome-webfont.woff2 b/html/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/html/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/html/_static/css/fonts/lato-bold-italic.woff b/html/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/html/_static/css/fonts/lato-bold-italic.woff differ diff --git a/html/_static/css/fonts/lato-bold-italic.woff2 b/html/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/html/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/html/_static/css/fonts/lato-bold.woff b/html/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/html/_static/css/fonts/lato-bold.woff differ diff --git a/html/_static/css/fonts/lato-bold.woff2 b/html/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/html/_static/css/fonts/lato-bold.woff2 differ diff --git a/html/_static/css/fonts/lato-normal-italic.woff b/html/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/html/_static/css/fonts/lato-normal-italic.woff differ diff --git a/html/_static/css/fonts/lato-normal-italic.woff2 b/html/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/html/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/html/_static/css/fonts/lato-normal.woff b/html/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/html/_static/css/fonts/lato-normal.woff differ diff --git a/html/_static/css/fonts/lato-normal.woff2 b/html/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/html/_static/css/fonts/lato-normal.woff2 differ diff --git a/html/_static/css/theme.css b/html/_static/css/theme.css new file mode 100644 index 0000000..0f14f10 --- /dev/null +++ b/html/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/html/_static/doctools.js b/html/_static/doctools.js new file mode 100644 index 0000000..0398ebb --- /dev/null +++ b/html/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/html/_static/documentation_options.js b/html/_static/documentation_options.js new file mode 100644 index 0000000..b15f8b4 --- /dev/null +++ b/html/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.0.2', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/html/_static/file.png b/html/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/html/_static/file.png differ diff --git a/html/_static/fonts/Lato/lato-bold.eot b/html/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 0000000..3361183 Binary files /dev/null and b/html/_static/fonts/Lato/lato-bold.eot differ diff --git a/html/_static/fonts/Lato/lato-bold.ttf b/html/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 0000000..29f691d Binary files /dev/null and b/html/_static/fonts/Lato/lato-bold.ttf differ diff --git a/html/_static/fonts/Lato/lato-bold.woff b/html/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/html/_static/fonts/Lato/lato-bold.woff differ diff --git a/html/_static/fonts/Lato/lato-bold.woff2 b/html/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/html/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/html/_static/fonts/Lato/lato-bolditalic.eot b/html/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 0000000..3d41549 Binary files /dev/null and b/html/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/html/_static/fonts/Lato/lato-bolditalic.ttf b/html/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 0000000..f402040 Binary files /dev/null and b/html/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/html/_static/fonts/Lato/lato-bolditalic.woff b/html/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/html/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/html/_static/fonts/Lato/lato-bolditalic.woff2 b/html/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/html/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/html/_static/fonts/Lato/lato-italic.eot b/html/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 0000000..3f82642 Binary files /dev/null and b/html/_static/fonts/Lato/lato-italic.eot differ diff --git a/html/_static/fonts/Lato/lato-italic.ttf b/html/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 0000000..b4bfc9b Binary files /dev/null and b/html/_static/fonts/Lato/lato-italic.ttf differ diff --git a/html/_static/fonts/Lato/lato-italic.woff b/html/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/html/_static/fonts/Lato/lato-italic.woff differ diff --git a/html/_static/fonts/Lato/lato-italic.woff2 b/html/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/html/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/html/_static/fonts/Lato/lato-regular.eot b/html/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 0000000..11e3f2a Binary files /dev/null and b/html/_static/fonts/Lato/lato-regular.eot differ diff --git a/html/_static/fonts/Lato/lato-regular.ttf b/html/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 0000000..74decd9 Binary files /dev/null and b/html/_static/fonts/Lato/lato-regular.ttf differ diff --git a/html/_static/fonts/Lato/lato-regular.woff b/html/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/html/_static/fonts/Lato/lato-regular.woff differ diff --git a/html/_static/fonts/Lato/lato-regular.woff2 b/html/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/html/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 0000000..79dc8ef Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 0000000..df5d1df Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 0000000..2f7ca78 Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 0000000..eb52a79 Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/html/_static/jquery.js b/html/_static/jquery.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/html/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t +
Languages
+ ${config.projects.translations + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} + + `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/html/_static/language_data.js b/html/_static/language_data.js new file mode 100644 index 0000000..c7fe6c6 --- /dev/null +++ b/html/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/html/_static/minus.png b/html/_static/minus.png new file mode 100644 index 0000000..d96755f Binary files /dev/null and b/html/_static/minus.png differ diff --git a/html/_static/plus.png b/html/_static/plus.png new file mode 100644 index 0000000..7107cec Binary files /dev/null and b/html/_static/plus.png differ diff --git a/html/_static/pygments.css b/html/_static/pygments.css new file mode 100644 index 0000000..84ab303 --- /dev/null +++ b/html/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/html/_static/searchtools.js b/html/_static/searchtools.js new file mode 100644 index 0000000..2c774d1 --- /dev/null +++ b/html/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/html/_static/sphinx_highlight.js b/html/_static/sphinx_highlight.js new file mode 100644 index 0000000..8a96c69 --- /dev/null +++ b/html/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/html/genindex.html b/html/genindex.html new file mode 100644 index 0000000..c62a6b1 --- /dev/null +++ b/html/genindex.html @@ -0,0 +1,2845 @@ + + + + + + + + Index — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + | X + | Z + +
+

_

+ + + +
+ +

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + + +
+ +

K

+ + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

O

+ + + +
+ +

P

+ + + +
    +
  • + pancax + +
  • +
  • + pancax.bcs + +
  • +
  • + pancax.bcs.distance_functions + +
  • +
  • + pancax.bcs.essential_bc + +
  • +
  • + pancax.bcs.natural_bc + +
  • +
  • + pancax.bvps + +
  • +
  • + pancax.bvps.biaxial_tension + +
  • +
  • + pancax.bvps.simple_shear + +
  • +
  • + pancax.bvps.uniaxial_tension + +
  • +
  • + pancax.constitutive_models + +
  • +
  • + pancax.constitutive_models.base_constitutive_model + +
  • +
  • + pancax.constitutive_models.blatz_ko + +
  • +
  • + pancax.constitutive_models.gent + +
  • +
  • + pancax.constitutive_models.neohookean + +
  • +
  • + pancax.constitutive_models.swanson + +
  • +
  • + pancax.data + +
  • +
  • + pancax.data.full_field_data + +
  • +
  • + pancax.data.global_data + +
  • +
  • + pancax.domains + +
  • +
  • + pancax.domains.base_domain + +
  • +
  • + pancax.domains.collocation_domain + +
  • +
  • + pancax.domains.delta_pinn_domain + +
  • +
  • + pancax.domains.inverse_domain + +
  • +
  • + pancax.domains.utils + +
  • +
  • + pancax.domains.variational_domain + +
  • +
  • + pancax.fem + +
  • +
  • + pancax.fem.dof_manager + +
  • +
  • + pancax.fem.elements + +
  • +
  • + pancax.fem.elements.base_element + +
  • +
  • + pancax.fem.elements.hex8_element + +
  • +
  • + pancax.fem.elements.line_element + +
  • +
  • + pancax.fem.elements.quad4_element + +
  • +
  • + pancax.fem.elements.quad9_element + +
  • +
  • + pancax.fem.elements.simplex_tri_element + +
  • +
  • + pancax.fem.elements.tet10_element + +
  • +
  • + pancax.fem.elements.tet4_element + +
  • +
  • + pancax.fem.function_space + +
  • +
  • + pancax.fem.mesh + +
  • +
  • + pancax.fem.quadrature_rules + +
  • +
  • + pancax.fem.read_exodus_mesh + +
  • +
  • + pancax.fem.sparse_matrix_assembler + +
  • +
  • + pancax.fem.surface + +
  • +
  • + pancax.fem.traction_bc + +
  • +
  • + pancax.history_writer + +
  • +
  • + pancax.kernels + +
  • +
  • + pancax.kernels.base_kernel + +
  • +
  • + pancax.kernels.laplace_beltrami + +
  • +
  • + pancax.kernels.linear_elasticity + +
  • +
  • + pancax.kernels.poisson + +
  • +
  • + pancax.kernels.solid_mechanics + +
  • +
+ +

Q

+ + + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ +

W

+ + + +
+ +

X

+ + +
+ +

Z

+ + +
+ + + +
+
+
+ +
+ +
+

© Copyright 2024, Craig M. Hamel.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..aa0a736 --- /dev/null +++ b/html/index.html @@ -0,0 +1,244 @@ + + + + + + + + + Pancax — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Pancax

+
+ +
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/modules.html b/html/modules.html new file mode 100644 index 0000000..b33ceed --- /dev/null +++ b/html/modules.html @@ -0,0 +1,406 @@ + + + + + + + + + pancax — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax

+
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/objects.inv b/html/objects.inv new file mode 100644 index 0000000..82682f3 Binary files /dev/null and b/html/objects.inv differ diff --git a/html/pancax.bcs.html b/html/pancax.bcs.html new file mode 100644 index 0000000..9453437 --- /dev/null +++ b/html/pancax.bcs.html @@ -0,0 +1,334 @@ + + + + + + + + + pancax.bcs package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.bcs package

+
+

Submodules

+
+
+

pancax.bcs.distance_functions module

+
+
+pancax.bcs.distance_functions.get_edges(domain, sset_names: List[str])[source]
+
+ +
+
+pancax.bcs.distance_functions.distance(x1, x2)[source]
+
+ +
+
+pancax.bcs.distance_functions.line_segment(x, segment)[source]
+
+ +
+
+pancax.bcs.distance_functions.distance_function(domain, ssets, m=1.0)[source]
+
+ +
+
+

pancax.bcs.essential_bc module

+
+
+class pancax.bcs.essential_bc.EssentialBC(nodeSet: str, component: int, function: ~typing.Callable[[~jaxtyping.Float[Array, 'nd'], float], float] | None = <function EssentialBC.<lambda>>)[source]
+

Bases: Module

+
+
Parameters:
+
    +
  • nodeSet – A name for a nodeset in the mesh

  • +
  • component – The dof to apply the essential bc to

  • +
  • function – A function f(x, t) = u that gives the value +to enforce on the (nodeset, component) of a field. +This defaults to the zero function

  • +
+
+
+
+
+nodeSet: str
+
+ +
+
+component: int
+
+ +
+
+function(t)
+
+ +
+
+coordinates(mesh)[source]
+
+ +
+
+__init__(nodeSet: str, component: int, function: ~typing.Callable[[~jaxtyping.Float[Array, 'nd'], float], float] | None = <function EssentialBC.<lambda>>) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.bcs.essential_bc.EssentialBCSet(bcs: List[pancax.bcs.essential_bc.EssentialBC])[source]
+

Bases: Module

+
+
+bcs: List[EssentialBC]
+
+ +
+
+__init__(bcs: List[EssentialBC]) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.bcs.natural_bc module

+
+
+class pancax.bcs.natural_bc.NaturalBC(sideset: str, function: Optional[Callable[[jaxtyping.Float[Array, 'nd'], float], jaxtyping.Float[Array, 'nf']]] = <function NaturalBC.<lambda> at 0x7f199ccec900>)[source]
+

Bases: Module

+
+
+sideset: str
+
+ +
+
+function(t)
+
+ +
+
+coordinates(mesh, q_rule_1d)[source]
+
+ +
+
+normals(mesh, q_rule_1d)[source]
+
+ +
+
+__init__(sideset: str, function: ~typing.Callable[[~jaxtyping.Float[Array, 'nd'], float], ~jaxtyping.Float[Array, 'nf']] | None = <function NaturalBC.<lambda>>) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.bvps.html b/html/pancax.bvps.html new file mode 100644 index 0000000..e094339 --- /dev/null +++ b/html/pancax.bvps.html @@ -0,0 +1,200 @@ + + + + + + + + + pancax.bvps package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.bvps package

+
+

Submodules

+
+
+

pancax.bvps.biaxial_tension module

+
+
+pancax.bvps.biaxial_tension.BiaxialLinearRamp(final_displacement_x: float, final_displacement_y: float, length_x: float, length_y: float)[source]
+
+ +
+
+

pancax.bvps.simple_shear module

+
+
+pancax.bvps.simple_shear.SimpleShearLinearRamp(final_displacement: float, length: float, direction: str)[source]
+
+ +
+
+

pancax.bvps.uniaxial_tension module

+
+
+pancax.bvps.uniaxial_tension.UniaxialTensionLinearRamp(final_displacement: float, length: float, direction: str, n_dimensions: int)[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.constitutive_models.html b/html/pancax.constitutive_models.html new file mode 100644 index 0000000..9f42fa6 --- /dev/null +++ b/html/pancax.constitutive_models.html @@ -0,0 +1,801 @@ + + + + + + + + + pancax.constitutive_models package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.constitutive_models package

+
+

Submodules

+
+
+

pancax.constitutive_models.base_constitutive_model module

+
+
+class pancax.constitutive_models.base_constitutive_model.ConstitutiveModel[source]
+

Bases: ABC

+

Base class for consistutive models.

+

The interface to be defined by derived classes include +the energy method and the unpack_properties method.

+
+
Parameters:
+
    +
  • n_properties – The number of properties

  • +
  • property_names – The names of the properties

  • +
+
+
+
+
+n_properties: int
+
+ +
+
+property_names: List[str]
+
+ +
+
+cauchy_stress(F: Float[Array, '3 3'], props: Float[Array, 'np'])[source]
+
+ +
+
+abstract energy(F: Float[Array, '3 3'], props: Float[Array, 'np'])[source]
+

This method returns the algorithmic strain energy density.

+
+ +
+
+invariants(F: Float[Array, '3 3'])[source]
+
+ +
+
+jacobian(F: Float[Array, '3 3'])[source]
+

This simply calculate the jacobian but with guard rails +to return nonsensical numbers if a non-positive jacobian +is encountered during training.

+
+
Parameters:
+

F – the deformation gradient

+
+
+
+\[J = det(\mathbf{F})\]
+
+ +
+
+I1(F: Float[Array, '3 3'])[source]
+

Calculates the first invariant

+
+
Parameters:
+

F – the deformation gradient

+
+
+
+\[I_1 = tr\left(\mathbf{F}^T\mathbf{F}\right)\]
+
+ +
+
+I1_bar(F: Float[Array, '3 3'])[source]
+

Calculates the first distortional invariant

+
+
Parameters:
+

F – the deformation gradient

+
+
+
+\[\bar{I}_1 = J^{-2/3}tr\left(\mathbf{F}^T\mathbf{F}\right)\]
+
+ +
+
+I2(F: Float[Array, '3 3'])[source]
+
+ +
+
+I2_bar(F: Float[Array, '3 3'])[source]
+
+ +
+
+pk1_stress(F: Float[Array, 'np'], props: Float[Array, 'np'])[source]
+
+ +
+
+abstract unpack_properties(props: Float[Array, 'np'])[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus(bulk_modulus: float)[source]
+

Bases: ConstitutiveModel

+
+
+n_properties: int
+
+ +
+
+property_names: List[str]
+
+ +
+
+__init__(bulk_modulus: float) None[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+bulk_modulus: float
+
+ +
+ +
+
+

pancax.constitutive_models.blatz_ko module

+
+
+class pancax.constitutive_models.blatz_ko.BlatzKo[source]
+

Bases: ConstitutiveModel

+

Blatz-Ko model with the following model form

+
+\[\psi(\mathbf{F}) = \frac{1}{2}\mu\left(\frac{I_2}{I_3} + 2\sqrt{I_3} - 5\right)\]
+
+
+n_properties: int = 1
+
+ +
+
+property_names: List[str] = ['shear modulus']
+
+ +
+
+energy(F, props)[source]
+

This method returns the algorithmic strain energy density.

+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.constitutive_models.gent module

+
+
+class pancax.constitutive_models.gent.Gent[source]
+

Bases: ConstitutiveModel

+

Gent model with the following model form

+
+\[\psi(\mathbf{F}) = \frac{1}{2}K\left[\frac{1}{2}\left(J^2 - \ln J\right)\right] - + \frac{1}{2}GJ_m\ln\left(1 - \frac{\bar{I}_1 - 3}{J_m}\right)\]
+
+
+n_properties: int = 3
+
+ +
+
+property_names: List[str] = ['bulk modulus', 'shear modulus', 'Jm parameter']
+
+ +
+
+energy(F, props)[source]
+

This method returns the algorithmic strain energy density.

+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.constitutive_models.gent.GentFixedBulkModulus(bulk_modulus: float)[source]
+

Bases: Gent, ConstitutiveModelFixedBulkModulus

+
+
+n_properties: int = 2
+
+ +
+
+property_names: List[str] = ['shear modulus', 'Jm parameter']
+
+ +
+
+bulk_modulus: float
+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.constitutive_models.neohookean module

+
+
+class pancax.constitutive_models.neohookean.NeoHookean[source]
+

Bases: ConstitutiveModel

+

NeoHookean model with the following model form

+
+\[\psi(\mathbf{F}) = \frac{1}{2}K\left[\frac{1}{2}\left(J^2 - \ln J\right)\right] + + \frac{1}{2}G\left(\bar{I}_1 - 3\right)\]
+
+
+n_properties: int = 2
+
+ +
+
+property_names: List[str] = ['bulk modulus', 'shear modulus']
+
+ +
+
+energy(F, props)[source]
+

This method returns the algorithmic strain energy density.

+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus(bulk_modulus: float)[source]
+

Bases: NeoHookean, ConstitutiveModelFixedBulkModulus

+
+
+n_properties: int = 1
+
+ +
+
+property_names: List[str] = ['shear modulus']
+
+ +
+
+bulk_modulus: float
+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.constitutive_models.swanson module

+
+
+class pancax.constitutive_models.swanson.Swanson4(cutoff_strain)[source]
+

Bases: ConstitutiveModel

+

Swanson model truncated to 4 parameters

+
+\[\psi(\mathbf{F}) = K\left(J\ln J - J + 1\right) + + \frac{3}{2}A_1\left(\frac{\bar{I}_1}{3} - 1\right)^{P_1} + + \frac{3}{2}C_1\left(\frac{\bar{I}_1}{3} - 1\right)^{R_1}\]
+
+
+n_properties: int = 5
+
+ +
+
+property_names: List[str] = ['bulk modulus', 'A1', 'P1', 'C1', 'R1']
+
+ +
+
+__init__(cutoff_strain)[source]
+
+ +
+
+cutoff_strain: float
+
+ +
+
+energy(F, props)[source]
+

This method returns the algorithmic strain energy density.

+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.constitutive_models.swanson.Swanson4FixedBulkModulus(bulk_modulus: float, cutoff_strain: float)[source]
+

Bases: Swanson4, ConstitutiveModelFixedBulkModulus

+
+
+n_properties: int = 4
+
+ +
+
+property_names: List[str] = ['A1', 'P1', 'C1', 'R1']
+
+ +
+
+__init__(bulk_modulus: float, cutoff_strain: float)[source]
+
+ +
+
+bulk_modulus: float
+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.constitutive_models.swanson.Swanson6(cutoff_strain: float)[source]
+

Bases: ConstitutiveModel

+

Swanson model truncated to 6 parameters

+
+
+\[\psi(\mathbf{F}) = K\left(J\ln J - J + 1\right) + + \frac{3}{2}A_1\left(\frac{\bar{I}_1}{3} - 1\right)^{P_1} + + \frac{3}{2}B_1\left(\frac{\bar{I}_2}{3} - 1\right)^{Q_1} + + \frac{3}{2}C_1\left(\frac{\bar{I}_1}{3} - 1\right)^{R_1}\]
+
+
+
+n_properties: int = 7
+
+ +
+
+property_names: List[str] = ['bulk modulus', 'A1', 'P1', 'B1', 'Q1', 'C1', 'R1']
+
+ +
+
+__init__(cutoff_strain: float)[source]
+
+ +
+
+cutoff_strain: float
+
+ +
+
+energy(F, props)[source]
+

This method returns the algorithmic strain energy density.

+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.constitutive_models.swanson.Swanson6FixedBulkModulus(bulk_modulus: float, cutoff_strain: float)[source]
+

Bases: Swanson6, ConstitutiveModelFixedBulkModulus

+
+
+n_properties: int = 6
+
+ +
+
+property_names: List[str] = ['A1', 'P1', 'B1', 'Q1', 'C1', 'R1']
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+cutoff_strain: float
+
+ +
+
+__init__(bulk_modulus: float, cutoff_strain: float)[source]
+
+ +
+
+bulk_modulus: float
+
+ +
+
+unpack_properties(props)[source]
+

This method unpacks properties from ‘props’ and returns +them with potentially static properties bound to the model.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.data.html b/html/pancax.data.html new file mode 100644 index 0000000..b71a0c6 --- /dev/null +++ b/html/pancax.data.html @@ -0,0 +1,317 @@ + + + + + + + + + pancax.data package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.data package

+
+

Submodules

+
+
+

pancax.data.full_field_data module

+
+
+class pancax.data.full_field_data.FullFieldData(data_file: str, input_keys: List[str], output_keys: List[str])[source]
+

Bases: Module

+

Data structure to store full field data used as ground truth +for output fields of a PINN when solving inverse problems.

+
+
Parameters:
+
    +
  • inputs – Data that serves as inputs to the PINN

  • +
  • outputs – Data that serves as outputs of the PINN

  • +
  • n_time_steps – Variable used for book keeping

  • +
+
+
+
+
+__init__(data_file: str, input_keys: List[str], output_keys: List[str])[source]
+
+ +
+
+inputs: Array
+
+ +
+
+outputs: Array
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+n_time_steps: int
+
+ +
+
+plot_registration(domain)[source]
+
+ +
+
+plot_data(domain, time_step)[source]
+
+ +
+ +
+
+

pancax.data.global_data module

+
+
+class pancax.data.global_data.GlobalData(data_file: str, times_key: str, disp_key: str, force_key: str, mesh_file: str, nset_id: int, reaction_dof: int | str, n_time_steps: int, plotting: bool | None = False)[source]
+

Bases: Module

+

Data structure that holds global data to be used as +ground truth for some global field calculated from +PINN outputs used in inverse modeling training

+
+
Parameters:
+
    +
  • times – A set of times used to compare to physics calculations

  • +
  • displacements – Currently hardcoded to use a displacement-force curve TODO

  • +
  • outputs – Field used as ground truth, hardcoded essentially to a reaction force now

  • +
  • n_nodes – Book-keeping variable for number of nodes on nodeset to measure global response from

  • +
  • n_time_steps – Book-keeping variable

  • +
  • reaction_nodes – Node set nodes for where to measure reaction forces

  • +
  • reaction_dof – Degree of freedom to use for reaction force calculation

  • +
+
+
+
+
+__init__(data_file: str, times_key: str, disp_key: str, force_key: str, mesh_file: str, nset_id: int, reaction_dof: int | str, n_time_steps: int, plotting: bool | None = False)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+times: Array
+
+ +
+
+displacements: Array
+
+ +
+
+outputs: Array
+
+ +
+
+n_nodes: int
+
+ +
+
+n_time_steps: int
+
+ +
+
+reaction_nodes: Array
+
+ +
+
+reaction_dof: int
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.domains.html b/html/pancax.domains.html new file mode 100644 index 0000000..fc992f5 --- /dev/null +++ b/html/pancax.domains.html @@ -0,0 +1,772 @@ + + + + + + + + + pancax.domains package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.domains package

+
+

Submodules

+
+
+

pancax.domains.base_domain module

+
+
+class pancax.domains.base_domain.BaseDomain(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: any, mesh_file: str, times: Float[Array, 'nt'], p_order: int | None = 1)[source]
+

Bases: Module

+

Base domain for all problem types. +This holds essential things for the problem +such as a mesh to load a geometry from, +times, physics, bcs, etc.

+
+
Parameters:
+
    +
  • mesh – A mesh from an exodus file most likely

  • +
  • coords – An array of coordinates

  • +
  • times – An array of times

  • +
  • physics – An initialized physics object

  • +
  • essential_bcs – A list of EssentialBCs

  • +
  • natural_bcs – a list of NaturalBCs

  • +
  • dof_manager – A DofManager for keeping track of essential bcs

  • +
+
+
+
+
+__init__(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: any, mesh_file: str, times: Float[Array, 'nt'], p_order: int | None = 1)[source]
+
+ +
+
+mesh_file: str
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+mesh: Mesh
+
+ +
+
+coords: Float[Array, 'nn nd']
+
+ +
+
+times: Float[Array, 'nt'] | Float[Array, 'nn 1']
+
+ +
+
+physics: PhysicsKernel
+
+ +
+
+essential_bcs: List[EssentialBC]
+
+ +
+
+natural_bcs: List[NaturalBC]
+
+ +
+
+dof_manager: DofManager
+
+ +
+
+field_values(field_network, t)[source]
+
+ +
+ +
+
+

pancax.domains.collocation_domain module

+
+
+class pancax.domains.collocation_domain.CollocationDomain(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: List[NaturalBC], mesh_file: str, times: Float[Array, 'nt'], p_order: int | None = 1, q_order: int | None = 2, vectorize_over_time: bool | None = False)[source]
+

Bases: BaseDomain

+

Base domain for all problem types. +This holds essential things for the problem +such as a mesh to load a geometry from, +times, physics, bcs, etc.

+
+
Parameters:
+
    +
  • mesh – A mesh from an exodus file most likely

  • +
  • coords – An array of coordinates

  • +
  • times – An array of times

  • +
  • physics – An initialized physics object

  • +
  • essential_bcs – A list of EssentialBCs

  • +
  • natural_bcs – a list of NaturalBCs

  • +
  • dof_manager – A DofManager for keeping track of essential bcs

  • +
+
+
+
+
+mesh: Mesh
+
+ +
+
+coords: Float[Array, 'nn nd']
+
+ +
+
+times: Float[Array, 'nt'] | Float[Array, 'nn 1']
+
+ +
+
+physics: PhysicsKernel
+
+ +
+
+essential_bcs: List[EssentialBC]
+
+ +
+
+natural_bcs: List[NaturalBC]
+
+ +
+
+dof_manager: DofManager
+
+ +
+
+__init__(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: List[NaturalBC], mesh_file: str, times: Float[Array, 'nt'], p_order: int | None = 1, q_order: int | None = 2, vectorize_over_time: bool | None = False) None[source]
+
+
Parameters:
+
    +
  • physics – A PhysicsKernel object

  • +
  • essential_bcs – A list of EssentiablBC objects

  • +
  • natural_bcs – TODO

  • +
  • mesh_file – mesh file name as string

  • +
  • times – set of times

  • +
  • p_order – Polynomial order for mesh. Only hooked up to tri meshes.

  • +
  • q_order – Quadrature order to use.

  • +
  • vectorize_over_time – Flag to enable vectorization over time +this likely only makes sense for path-independent problems.

  • +
+
+
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+neumann_xs: Float[Array, 'nn nd']
+
+ +
+
+neumann_ns: Float[Array, 'nn nd']
+
+ +
+ +
+
+

pancax.domains.delta_pinn_domain module

+
+
+class pancax.domains.delta_pinn_domain.DeltaPINNDomain(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: List[NaturalBC], mesh_file: str, times: Float[Array, 'nt'], n_eigen_values: int, p_order: int | None = 1, q_order: int | None = 2)[source]
+

Bases: VariationalDomain

+

Base domain for all problem types. +This holds essential things for the problem +such as a mesh to load a geometry from, +times, physics, bcs, etc.

+
+
Parameters:
+
    +
  • mesh – A mesh from an exodus file most likely

  • +
  • coords – An array of coordinates

  • +
  • times – An array of times

  • +
  • physics – An initialized physics object

  • +
  • essential_bcs – A list of EssentialBCs

  • +
  • natural_bcs – a list of NaturalBCs

  • +
  • dof_manager – A DofManager for keeping track of essential bcs

  • +
  • conns – An array of connectivities

  • +
  • fspace – A FunctionSpace to help with integration

  • +
  • fspace_centroid – A FunctionSpace to help with integration

  • +
  • n_eigen_values – Number of eigenvalues to use

  • +
+
+
+
+
+mesh: Mesh
+
+ +
+
+coords: Float[Array, 'nn nd']
+
+ +
+
+times: Float[Array, 'nt'] | Float[Array, 'nn 1']
+
+ +
+
+physics: PhysicsKernel
+
+ +
+
+essential_bcs: List[EssentialBC]
+
+ +
+
+natural_bcs: List[NaturalBC]
+
+ +
+
+dof_manager: DofManager
+
+ +
+
+conns: Int[Array, 'ne nnpe']
+
+ +
+
+fspace: FunctionSpace
+
+ +
+
+fspace_centroid: FunctionSpace
+
+ +
+
+__init__(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: List[NaturalBC], mesh_file: str, times: Float[Array, 'nt'], n_eigen_values: int, p_order: int | None = 1, q_order: int | None = 2) None[source]
+
+
Parameters:
+
    +
  • physics – A PhysicsKernel object

  • +
  • essential_bcs – A list of EssentiablBC objects

  • +
  • natural_bcs – TODO

  • +
  • mesh_file – mesh file name as string

  • +
  • times – set of times

  • +
  • p_order – Polynomial order for mesh. Only hooked up to tri meshes.

  • +
  • q_order – Quadrature order to use.

  • +
  • n_eigen_values – Number of eigenvalues to use

  • +
+
+
+
+ +
+
+n_eigen_values: int
+
+ +
+
+eigen_modes: Float[Array, 'nn nev']
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+field_values(field_network, t)[source]
+
+ +
+
+solve_eigen_problem(mesh_file, p_order, q_order)[source]
+
+ +
+ +
+
+

pancax.domains.inverse_domain module

+
+
+class pancax.domains.inverse_domain.InverseDomain(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: any, mesh_file: str, times: Float[Array, 'nt'], field_data: FullFieldData, global_data: GlobalData, p_order: int | None = 1, q_order: int | None = 2)[source]
+

Bases: VariationalDomain

+

Inverse domain type derived from a ForwardDomain

+

Note that currently this likely only supports single block meshes.

+
+
Parameters:
+
    +
  • physics – A physics kernel to use for physics calculations.

  • +
  • dof_manager – A DofManager to track what dofs are free/fixed.

  • +
  • fspace – A FunctionSpace to help with integration

  • +
  • q_rule_1d – A quadrature rule for line/surface integrations. TODO rename this

  • +
  • q_rule_2d – A quadrature rule for cell integrations. TODO rename this

  • +
  • coords – Nodal coordinates in the reference configuration.

  • +
  • conns – Element connectivity matrix

  • +
  • field_data – Data structure that holds the full field data.

  • +
  • global_data – Data structure that holds the global data.

  • +
+
+
+
+
+physics: PhysicsKernel
+
+ +
+
+dof_manager: DofManager
+
+ +
+
+fspace: FunctionSpace
+
+ +
+
+fspace_centroid: FunctionSpace
+
+ +
+
+coords: Float[Array, 'nn nd']
+
+ +
+
+conns: Float[Array, 'ne nnpe']
+
+ +
+
+times: Float[Array, 'nt'] | Float[Array, 'nn 1']
+
+ +
+
+__init__(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: any, mesh_file: str, times: Float[Array, 'nt'], field_data: FullFieldData, global_data: GlobalData, p_order: int | None = 1, q_order: int | None = 2) None[source]
+
+
Parameters:
+
    +
  • physics – A PhysicsKernel object

  • +
  • essential_bcs – A list of EssentiablBC objects

  • +
  • natural_bcs – TODO

  • +
  • mesh_file – mesh file name as string

  • +
  • times – An array of time values to use

  • +
  • field_dataFieldData object

  • +
  • global_dataGlobalData object

  • +
  • p_order – Polynomial order for mesh. Only hooked up to tri meshes.

  • +
  • q_order – Quadrature order to use.

  • +
+
+
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+field_data: FullFieldData
+
+ +
+
+global_data: GlobalData
+
+ +
+ +
+
+

pancax.domains.utils module

+
+
+pancax.domains.utils.make_mesh_time_dependent(mesh, times)[source]
+
+ +
+
+pancax.domains.utils.make_times_column(n_nodes: int, times_in: Array)[source]
+
+ +
+
+

pancax.domains.variational_domain module

+
+
+class pancax.domains.variational_domain.VariationalDomain(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: any, mesh_file: str, times: Float[Array, 'nt'], p_order: int | None = 1, q_order: int | None = 2)[source]
+

Bases: BaseDomain

+

Base domain for all problem types. +This holds essential things for the problem +such as a mesh to load a geometry from, +times, physics, bcs, etc.

+
+
Parameters:
+
    +
  • mesh – A mesh from an exodus file most likely

  • +
  • coords – An array of coordinates

  • +
  • times – An array of times

  • +
  • physics – An initialized physics object

  • +
  • essential_bcs – A list of EssentialBCs

  • +
  • natural_bcs – a list of NaturalBCs

  • +
  • dof_manager – A DofManager for keeping track of essential bcs

  • +
  • conns – An array of connectivities

  • +
  • fspace – A FunctionSpace to help with integration

  • +
  • fspace_centroid – A FunctionSpace to help with integration

  • +
+
+
+
+
+mesh: Mesh
+
+ +
+
+coords: Float[Array, 'nn nd']
+
+ +
+
+times: Float[Array, 'nt'] | Float[Array, 'nn 1']
+
+ +
+
+physics: PhysicsKernel
+
+ +
+
+essential_bcs: List[EssentialBC]
+
+ +
+
+natural_bcs: List[NaturalBC]
+
+ +
+
+dof_manager: DofManager
+
+ +
+
+__init__(physics: PhysicsKernel, essential_bcs: List[EssentialBC], natural_bcs: any, mesh_file: str, times: Float[Array, 'nt'], p_order: int | None = 1, q_order: int | None = 2) None[source]
+
+
Parameters:
+
    +
  • physics – A PhysicsKernel object

  • +
  • essential_bcs – A list of EssentiablBC objects

  • +
  • natural_bcs – TODO

  • +
  • mesh_file – mesh file name as string

  • +
  • times – set of times

  • +
  • p_order – Polynomial order for mesh. Only hooked up to tri meshes.

  • +
  • q_order – Quadrature order to use.

  • +
+
+
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+conns: Int[Array, 'ne nnpe']
+
+ +
+
+fspace: FunctionSpace
+
+ +
+
+fspace_centroid: FunctionSpace
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.fem.elements.html b/html/pancax.fem.elements.html new file mode 100644 index 0000000..6e8e7ad --- /dev/null +++ b/html/pancax.fem.elements.html @@ -0,0 +1,740 @@ + + + + + + + + + pancax.fem.elements package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.fem.elements package

+
+

Submodules

+
+
+

pancax.fem.elements.base_element module

+
+
+pancax.fem.elements.base_element.get_lobatto_nodes_1d(degree)[source]
+
+ +
+
+pancax.fem.elements.base_element.pascal_triangle_monomials(degree)[source]
+
+ +
+
+pancax.fem.elements.base_element.vander1d(x, degree)[source]
+
+ +
+
+pancax.fem.elements.base_element.vander2d(x, degree)[source]
+
+ +
+
+class pancax.fem.elements.base_element.ShapeFunctions(values: Float[Array, 'np nn'], gradients: Float[Array, 'np nd nn'])[source]
+

Bases: NamedTuple

+

Shape functions and shape function gradients (in the parametric space).

+
+
Parameters:
+
    +
  • values – Values of the shape functions at a discrete set of points. +Shape is (nPts, nNodes), where nPts is the number of +points at which the shame functinos are evaluated, and nNodes +is the number of nodes in the element (which is equal to the +number of shape functions).

  • +
  • gradients – Values of the parametric gradients of the shape functions. +Shape is (nPts, nDim, nNodes), where nDim is the number +of spatial dimensions. Line elements are an exception, which +have shape (nPts, nNdodes).

  • +
+
+
+
+
+values: Float[Array, 'np nn']
+

Alias for field number 0

+
+ +
+
+gradients: Float[Array, 'np nd nn']
+

Alias for field number 1

+
+ +
+
+_asdict()
+

Return a new dict which maps field names to their values.

+
+ +
+
+_field_defaults = {}
+
+ +
+
+_fields = ('values', 'gradients')
+
+ +
+
+classmethod _make(iterable)
+

Make a new ShapeFunctions object from a sequence or iterable

+
+ +
+
+_replace(**kwds)
+

Return a new ShapeFunctions object replacing specified fields with new values

+
+ +
+ +
+
+class pancax.fem.elements.base_element.BaseElement(elementType: str, degree: int, coordinates: Float[Array, 'nn nd'], vertexNodes: Int[Array, 'nn'], faceNodes: Int[Array, 'nf nnpf'], interiorNodes: Int[Array, 'nni'])[source]
+

Bases: Module

+

Base class for different element technologies

+
+
Parameters:
+
    +
  • elementType – Element type name

  • +
  • degree – Polynomial degree

  • +
  • coordinates – Nodal coordinates in the reference configuration

  • +
  • vertexNodes – Vertex node number, 0-based

  • +
  • faceNodes – Nodes associated with each face, 0-based

  • +
  • interiorNodes – Nodes in the interior, 0-based or empty

  • +
+
+
+
+
+elementType: str
+
+ +
+
+degree: int
+
+ +
+
+coordinates: Float[Array, 'nn nd']
+
+ +
+
+vertexNodes: Int[Array, 'nn']
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf']
+
+ +
+
+interiorNodes: Int[Array, 'nni']
+
+ +
+
+abstract compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+
+__init__(elementType: str, degree: int, coordinates: Float[Array, 'nn nd'], vertexNodes: Int[Array, 'nn'], faceNodes: Int[Array, 'nf nnpf'], interiorNodes: Int[Array, 'nni']) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.fem.elements.hex8_element module

+
+
+class pancax.fem.elements.hex8_element.Hex8Element[source]
+

Bases: BaseElement

+
+
+elementType: str = 'hex8'
+
+ +
+
+degree: int = 1
+
+ +
+
+coordinates: Float[Array, 'nn nd'] = Array([[-1., -1., -1.],        [ 1., -1., -1.],        [ 1.,  1., -1.],        [-1.,  1., -1.],        [-1., -1.,  1.],        [ 1., -1.,  1.],        [ 1.,  1.,  1.],        [-1.,  1.,  1.]], dtype=float32)
+
+ +
+
+vertexNodes: Int[Array, 'nn'] = Array([0, 1, 2, 3, 4, 5, 6, 7], dtype=int32)
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf'] = Array([[0, 1, 5, 6],        [1, 2, 6, 5],        [2, 3, 7, 6],        [0, 4, 7, 3],        [0, 3, 2, 1],        [4, 5, 6, 7]], dtype=int32)
+
+ +
+
+interiorNodes: Int[Array, 'nni'] = None
+
+ +
+
+__init__()[source]
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.fem.elements.line_element module

+
+
+class pancax.fem.elements.line_element.LineElement(degree)[source]
+

Bases: BaseElement

+
+
+elementType: str = 'line'
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf'] = None
+
+ +
+
+__init__(degree)[source]
+
+ +
+
+degree: int
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+coordinates: Float[Array, 'nn nd']
+
+ +
+
+vertexNodes: any
+
+ +
+
+interiorNodes: any
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+ +
+
+

pancax.fem.elements.quad4_element module

+
+
+class pancax.fem.elements.quad4_element.Quad4Element[source]
+

Bases: BaseElement

+
+
+elementType: str = 'quad4'
+
+ +
+
+degree: int = 1
+
+ +
+
+coordinates: Float[Array, 'nn nd'] = Array([[-1., -1.],        [ 1., -1.],        [ 1.,  1.],        [-1.,  1.]], dtype=float32)
+
+ +
+
+vertexNodes: Int[Array, 'nn'] = Array([0, 1, 2], dtype=int32)
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf'] = Array([[0, 1],        [1, 2],        [2, 3],        [3, 0]], dtype=int32)
+
+ +
+
+interiorNodes: Int[Array, 'nni'] = None
+
+ +
+
+__init__()[source]
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.fem.elements.quad9_element module

+
+
+class pancax.fem.elements.quad9_element.Quad9Element[source]
+

Bases: BaseElement

+
+
+elementType: str = 'quad9'
+
+ +
+
+degree: int = 2
+
+ +
+
+coordinates: Float[Array, 'nn nd'] = Array([[-1., -1.],        [ 1., -1.],        [ 1.,  1.],        [-1.,  1.],        [ 0., -1.],        [ 1.,  0.],        [ 0.,  1.],        [-1.,  0.],        [ 0.,  0.]], dtype=float32)
+
+ +
+
+vertexNodes: Int[Array, 'nn'] = Array([0, 1, 2, 3, 4, 5, 6, 7], dtype=int32)
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf'] = Array([[0, 4, 1],        [1, 5, 2],        [2, 6, 3],        [3, 7, 0]], dtype=int32)
+
+ +
+
+interiorNodes: Int[Array, 'nni'] = Array([8], dtype=int32)
+
+ +
+
+__init__()[source]
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.fem.elements.simplex_tri_element module

+
+
+class pancax.fem.elements.simplex_tri_element.SimplexTriElement(degree)[source]
+

Bases: BaseElement

+
+
+elementType: str = 'simplex tri'
+
+ +
+
+__init__(degree)[source]
+
+ +
+
+degree: int
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+coordinates: Float[Array, 'nn nd']
+
+ +
+
+vertexNodes: any
+
+ +
+
+faceNodes: any
+
+ +
+
+interiorNodes: any
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+ +
+
+

pancax.fem.elements.tet10_element module

+
+
+class pancax.fem.elements.tet10_element.Tet10Element[source]
+

Bases: BaseElement

+
+
+elementType: str = 'tet10'
+
+ +
+
+degree: int = 2
+
+ +
+
+coordinates: Float[Array, 'nn nd'] = Array([[0. , 0. , 0. ],        [1. , 0. , 0. ],        [0. , 1. , 0. ],        [0. , 0. , 1. ],        [0.5, 0. , 0. ],        [0.5, 0.5, 0. ],        [0. , 0.5, 0. ],        [0. , 0. , 0.5],        [0.5, 0. , 0.5],        [0. , 0.5, 0.5]], dtype=float32)
+
+ +
+
+vertexNodes: Int[Array, 'nn'] = Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf'] = Array([[0, 4, 1, 8, 3, 7],        [1, 5, 2, 9, 3, 7],        [0, 7, 3, 9, 2, 6],        [0, 6, 2, 5, 1, 4]], dtype=int32)
+
+ +
+
+interiorNodes: Int[Array, 'nni'] = None
+
+ +
+
+__init__()[source]
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.fem.elements.tet4_element module

+
+
+class pancax.fem.elements.tet4_element.Tet4Element[source]
+

Bases: BaseElement

+
+
+elementType: str = 'tet4'
+
+ +
+
+degree: int = 1
+
+ +
+
+coordinates: Float[Array, 'nn nd'] = Array([[0., 0., 0.],        [1., 0., 0.],        [0., 1., 0.],        [0., 0., 1.]], dtype=float32)
+
+ +
+
+vertexNodes: Int[Array, 'nn'] = Array([0, 1, 2, 3], dtype=int32)
+
+ +
+
+faceNodes: Int[Array, 'nf nnpf'] = Array([[0, 1, 3],        [1, 2, 3],        [0, 3, 2],        [0, 2, 1]], dtype=int32)
+
+ +
+
+interiorNodes: Int[Array, 'nni'] = None
+
+ +
+
+__init__()[source]
+
+ +
+
+compute_shapes(nodalPoints, evaluationPoints)[source]
+

Method to be defined to calculate shape function values +and gradients given a list of nodal points (usually the vertexNodes) +and a list of evaluation points (usually the quadrature points).

+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.fem.html b/html/pancax.fem.html new file mode 100644 index 0000000..f7ed3c6 --- /dev/null +++ b/html/pancax.fem.html @@ -0,0 +1,1489 @@ + + + + + + + + + pancax.fem package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.fem package

+
+

Subpackages

+
+ +
+
+
+

Submodules

+
+
+

pancax.fem.dof_manager module

+
+
+class pancax.fem.dof_manager.DofManager(mesh, dim: int, EssentialBCs: List[EssentialBC])[source]
+

Bases: object

+

Collection of arrays needed to differentiate between +fixed and free dofs for fem like calculations.

+

TODO better document the parameters in this guy

+
+
+__init__(mesh, dim: int, EssentialBCs: List[EssentialBC]) None[source]
+
+
Parameters:
+
    +
  • functionSpaceFunctionSpace object

  • +
  • dim – The number of dims (really the number of active dofs for the physics)

  • +
  • EssentialBCs – A list of of EssentialBC objects

  • +
+
+
+
+ +
+
+get_bc_size() int[source]
+
+
Returns:
+

the number of fixed dofs

+
+
+
+ +
+
+get_unknown_size() int[source]
+
+
Returns:
+

the size of the unkowns vector

+
+
+
+ +
+
+create_field(Uu, Ubc=0.0) Float[Array, 'nn nd'][source]
+
+
Parameters:
+
    +
  • Uu – Vector of unknown values

  • +
  • Ubc – Values for bc to apply

  • +
+
+
Returns:
+

U, a field of unknowns and bcs combined.

+
+
+
+ +
+
+get_bc_values(U) Float[Array, 'nb'][source]
+
+
Parameters:
+

U – a nodal field

+
+
Returns:
+

the bc values in the field U

+
+
+
+ +
+
+get_unknown_values(U) Float[Array, 'nu'][source]
+
+
Parameters:
+

U – a nodal field

+
+
Returns:
+

the unknown values in the field U

+
+
+
+ +
+
+slice_unknowns_with_dof_indices(Uu: Float[Array, 'nu'], dofIndexSlice: Int[Array, 'nn']) Float[Array, 'nu_new'][source]
+
+ +
+
+_make_hessian_coordinates(conns: Int[Array, 'ne nnpe']) Tuple[Int[Array, 'nn'], Int[Array, 'nn']][source]
+
+ +
+
+_make_hessian_bc_mask(conns: Int[Array, 'ne nnpe']) Bool[Array, 'ne ndpe ndpe'][source]
+
+ +
+ +
+
+

pancax.fem.function_space module

+
+
+class pancax.fem.function_space.NonAllocatedFunctionSpace(mesh: pancax.fem.mesh.Mesh, q_rule: pancax.fem.quadrature_rules.QuadratureRule)[source]
+

Bases: Module

+
+
+__init__(mesh: Mesh, q_rule: QuadratureRule) None[source]
+
+ +
+
+quadrature_rule: QuadratureRule
+
+ +
+
+shape_functions: ShapeFunctions
+
+ +
+
+compute_field_gradient(u, X)[source]
+

Takes in element level coordinates X and field u

+
+ +
+
+evaluate_on_element(U, X, state, dt, props, func)[source]
+

Takes in element level field, coordinates, states, etc. +and evaluates the function func

+
+ +
+
+integrate_on_element(U, X, state, dt, props, func)[source]
+
+ +
+
+integrate_on_elements(U, X, state, dt, props, func)[source]
+
+ +
+
+JxWs(X: Float[Array, 'nn nd']) Float[Array, 'nq'][source]
+
+ +
+
+shape_function_values(X: Float[Array, 'nn nd']) Float[Array, 'nq nnpe'][source]
+
+ +
+
+shape_function_gradients(X: Float[Array, 'nn nd']) Float[Array, 'nq nnpe nd'][source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.fem.function_space.FunctionSpace(shapes: Float[Array, 'ne nqpe npe'], vols: Float[Array, 'ne nqpe'], shapeGrads: Float[Array, 'ne nqpe npe nd'], conns: Int[Array, 'ne nnpe'], quadratureRule: QuadratureRule, isAxisymmetric: bool)[source]
+

Bases: Module

+

Data needed for calculus on functions in the discrete function space.

+

In describing the shape of the attributes, ne is the number of +elements in the mesh, nqpe is the number of quadrature points per +element, npe is the number of nodes per element, and nd is the +spatial dimension of the domain.

+
+
Parameters:
+
    +
  • shapes – Shape function values on each element, shape (ne, nqpe, npe)

  • +
  • vols – Volume attributed to each quadrature point. That is, the +quadrature weight (on the parameteric element domain) multiplied by +the Jacobian determinant of the map from the parent element to the +element in the domain. Shape (ne, nqpe).

  • +
  • shapeGrads – Derivatives of the shape functions with respect to the +spatial coordinates of the domain. Shape (ne, nqpe, npe, nd).

  • +
  • mesh – The Mesh object of the domain.

  • +
  • quadratureRule – The QuadratureRule on which to sample the shape +functions.

  • +
  • isAxisymmetric – boolean indicating if the function space data are +axisymmetric.

  • +
+
+
+
+
+shapes: Float[Array, 'ne nqpe npe']
+
+ +
+
+vols: Float[Array, 'ne nqpe']
+
+ +
+
+shapeGrads: Float[Array, 'ne nqpe npe nd']
+
+ +
+
+conns: Int[Array, 'ne nnpe']
+
+ +
+
+quadratureRule: QuadratureRule
+
+ +
+
+isAxisymmetric: bool
+
+ +
+
+__init__(shapes: Float[Array, 'ne nqpe npe'], vols: Float[Array, 'ne nqpe'], shapeGrads: Float[Array, 'ne nqpe npe nd'], conns: Int[Array, 'ne nnpe'], quadratureRule: QuadratureRule, isAxisymmetric: bool) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+pancax.fem.function_space.construct_function_space(mesh, quadratureRule, mode2D='cartesian')[source]
+

Construct a discrete function space.

+

:param : +:type : param mesh: The mesh of the domain. +:param : +:type : param quadratureRule: The quadrature rule to be used for integrating on the +:param domain.: +:param : +:type : param mode2D: A string indicating how the 2D domain is interpreted for +:param integration. Valid values are cartesian and axisymmetric.: +:param Axisymetric mode will include the factor of 2*pi*r in the vols: +:param attribute.:

+
+
Return type:
+

The FunctionSpace object.

+
+
+
+ +
+
+pancax.fem.function_space.construct_function_space_from_parent_element(mesh, shapeOnRef, quadratureRule, mode2D='cartesian')[source]
+

Construct a function space with precomputed shape function data on the parent element.

+

This version of the function space constructor is Jax-transformable, +and in particular can be jitted. The computation of the shape function +values and derivatives on the parent element is not transformable in +general. However, the mapping of the shape function data to the elements in +the mesh is transformable. One can precompute the parent element shape +functions once and for all, and then use this special factory function to +construct the function space and avoid the non-transformable part of the +operation. The primary use case is for shape sensitivities: the coordinates +of the mesh change, and we want Jax to pick up the sensitivities of the +shape function derivatives in space to the coordinate changes +(which occurs through the mapping from the parent element to the spatial +domain).

+

:param : +:type : param mesh: The mesh of the domain. +:param : +:type : param shapeOnRef: A tuple of the shape function values and gradients on the +:param parent element: +:param evaluated at the quadrature points. The caller must: +:param take care to ensure the shape functions are evaluated at the same: +:param points as contained in the quadratureRule parameter.: +:param : domain. +:type : param quadratureRule: The quadrature rule to be used for integrating on the +:param : +:type : param mode2D: A string indicating how the 2D domain is interpreted for +:param integration. See the default factory function for details.:

+
+
Return type:
+

The FunctionSpace object.

+
+
+
+ +
+
+pancax.fem.function_space.map_element_shape_grads(coordField, nodeOrdinals, parentElement, shapeGradients)[source]
+
+ +
+
+pancax.fem.function_space.compute_element_volumes(coordField, nodeOrdinals, parentElement, shapes, shapeGradients, weights)[source]
+
+ +
+
+pancax.fem.function_space.compute_element_volumes_axisymmetric(coordField, nodeOrdinals, parentElement, shapes, shapeGradients, weights)[source]
+
+ +
+
+pancax.fem.function_space.default_modify_element_gradient(elemGrads, elemShapes, elemVols, elemNodalDisps, elemNodalCoords)[source]
+
+ +
+
+pancax.fem.function_space.compute_field_gradient(functionSpace, nodalField, nodalCoords, modify_element_gradient=<function default_modify_element_gradient>)[source]
+
+ +
+
+pancax.fem.function_space.interpolate_to_points(functionSpace, nodalField)[source]
+
+ +
+
+pancax.fem.function_space.integrate_over_block(functionSpace, U, X, stateVars, props, dt, func, block, *params, modify_element_gradient=<function default_modify_element_gradient>)[source]
+

Integrates a density function over a block of the mesh.

+
+
Parameters:
+
    +
  • functionSpace – Function space object to do the integration with.

  • +
  • U – The vector of dofs for the primal field in the functional.

  • +
  • X – Nodal coordinates

  • +
  • stateVars – Internal state variable array.

  • +
  • dt – Current time increment

  • +
  • func – Lagrangian density function to integrate, Must have the signature +func(u, dudx, q, x, *params) -> scalar, where u is the primal field, q is the +value of the internal variables, x is the current point coordinates, and *params is +a variadic set of additional parameters, which correspond to the *params argument. +block: Group of elements to integrate over. This is an array of element indices. For +performance, the elements within the block should be numbered consecutively.

  • +
  • modify_element_gradient – Optional function that modifies the gradient at the element level. +This can be to set the particular 2D mode, and additionally to enforce volume averaging +on the gradient operator. This is a keyword-only argument.

  • +
+
+
+

Returns +A scalar value for the integral of the density functional func integrated over the +block of elements.

+
+ +
+
+pancax.fem.function_space.evaluate_on_block(functionSpace, U, X, stateVars, dt, props, func, block, *params, modify_element_gradient=<function default_modify_element_gradient>)[source]
+

Evaluates a density function at every quadrature point in a block of the mesh.

+
+
Parameters:
+
    +
  • functionSpace – Function space object to do the evaluation with.

  • +
  • U – The vector of dofs for the primal field in the functional.

  • +
  • X – Nodal coordinates

  • +
  • stateVars – Internal state variable array.

  • +
  • dt – Current time increment

  • +
  • func – Lagrangian density function to evaluate, Must have the signature +`func(u, dudx, q, x, *params) -> scalar`, where `u` is the primal field, `q` is the +value of the internal variables, `x` is the current point coordinates, and `*params` is +a variadic set of additional parameters, which correspond to the `*params` argument.

  • +
  • block – Group of elements to evaluate over. This is an array of element indices. For +performance, the elements within the block should be numbered consecutively.

  • +
  • modify_element_gradient – Optional function that modifies the gradient at the element level. +This can be to set the particular 2D mode, and additionally to enforce volume averaging +on the gradient operator. This is a keyword-only argument.

  • +
+
+
+

Returns +An array of shape (numElements, numQuadPtsPerElement) that contains the scalar values of the +density functional `func` at every quadrature point in the block.

+
+ +
+
+pancax.fem.function_space.integrate_element_from_local_field(elemNodalField, elemNodalCoords, elemStates, dt, elemShapes, elemShapeGrads, elemVols, func, modify_element_gradient=<function default_modify_element_gradient>)[source]
+

Integrate over element with element nodal field as input. +This allows element residuals and element stiffness matrices to computed.

+
+ +
+
+pancax.fem.function_space.compute_element_field_gradient(U, coords, elemShapes, elemShapeGrads, elemVols, elemConnectivity, modify_element_gradient)[source]
+
+ +
+
+pancax.fem.function_space.compute_quadrature_point_field_gradient(u, shapeGrad)[source]
+
+ +
+
+pancax.fem.function_space.interpolate_to_point(elementNodalValues, shape)[source]
+
+ +
+
+pancax.fem.function_space.interpolate_to_element_points(U, elemShapes, elemConnectivity)[source]
+
+ +
+
+pancax.fem.function_space.integrate_element(U, coords, elemStates, elemShapes, elemShapeGrads, elemVols, elemConn, func, modify_element_gradient)[source]
+
+ +
+
+pancax.fem.function_space.evaluate_on_element(U, coords, elemStates, props, dt, elemShapes, elemShapeGrads, elemVols, elemConn, kernelFunc, modify_element_gradient, *params)[source]
+
+ +
+
+pancax.fem.function_space.project_quadrature_field_to_element_field(functionSpace, quadField)[source]
+
+ +
+
+pancax.fem.function_space.average_quadrature_field_over_element(elemQPData, vols)[source]
+
+ +
+
+pancax.fem.function_space.get_nodal_values_on_edge(functionSpace, nodalField, edge)[source]
+

Get nodal values of a field on an element edge.

+
+
Parameters:
+
    +
  • functionSpace – a FunctionSpace object

  • +
  • nodalField – The nodal vector defined over the mesh (shape is number of +nodes by number of field components)

  • +
  • edge – tuple containing the element number containing the edge and the +permutation (0, 1, or 2) of the edge within the triangle

  • +
+
+
+
+ +
+
+pancax.fem.function_space.interpolate_nodal_field_on_edge(functionSpace, U, interpolationPoints, edge)[source]
+

Interpolate a nodal field to specified points on an element edge.

+
+
Parameters:
+
    +
  • functionSpace – a FunctionSpace object

  • +
  • U – the nodal values array

  • +
  • interpolationPoints – coordinates of points (in the 1D parametric space) to +interpolate to

  • +
  • edge – tuple containing the element number containing the edge and the +permutation (0, 1, or 2) of the edge within the triangle

  • +
+
+
+
+ +
+
+pancax.fem.function_space.integrate_function_on_edge(functionSpace, func, U, quadRule, edge)[source]
+
+ +
+
+pancax.fem.function_space.integrate_function_on_edges(functionSpace, func, U, quadRule, edges)[source]
+
+ +
+
+

pancax.fem.mesh module

+
+
+class pancax.fem.mesh.Mesh(coords: Float[Array, 'nn nd'], conns: Float[Array, 'ne nnpe'], simplexNodesOrdinals: Float[Array, 'ne 3'], parentElement: any, parentElement1d: any, blocks: Dict[str, Float] | None = None, nodeSets: Dict[str, Float] | None = None, sideSets: Dict[str, Float] | None = None)[source]
+

Bases: Module

+

Triangle mesh representing a domain.

+
+
Parameters:
+
    +
  • coords – Coordinates of the nodes, shape (nNodes, nDim).

  • +
  • conns – Nodal connectivity table of the elements.

  • +
  • simplexNodesOrdinals – Indices of the nodes that are vertices.

  • +
  • parentElement – A ParentElement that is the element type in +parametric space. A mesh can contain only 1 element type.

  • +
  • parentElement1d

  • +
  • blocks – A dictionary mapping element block names to the indices of the +elements in the block.

  • +
  • nodeSets – A dictionary mapping node set names to the indices of the +nodes.

  • +
  • sideSets – A dictionary mapping side set names to the edges. The +edge data structure is a tuple of the element index and the local +number of the edge within that element. For example, triangle +elements will have edge 0, 1, or 2 for this entry.

  • +
+
+
+
+
+coords: Float[Array, 'nn nd']
+
+ +
+
+conns: Float[Array, 'ne nnpe']
+
+ +
+
+simplexNodesOrdinals: Float[Array, 'ne 3']
+
+ +
+
+parentElement: any
+
+ +
+
+parentElement1d: any
+
+ +
+
+blocks: Dict[str, Float] | None = None
+
+ +
+
+nodeSets: Dict[str, Float] | None = None
+
+ +
+
+sideSets: Dict[str, Float] | None = None
+
+ +
+
+get_blocks(blockNames: List[str])[source]
+
+ +
+
+property num_dimensions: int
+

dimension number of mesh

+
+
Type:
+

return

+
+
+
+ +
+
+property num_elements: int
+

number of elements in mesh

+
+
Type:
+

return

+
+
+
+ +
+
+property num_nodes: int
+

number of nodes in mesh

+
+ +
+
+__init__(coords: Float[Array, 'nn nd'], conns: Float[Array, 'ne nnpe'], simplexNodesOrdinals: Float[Array, 'ne 3'], parentElement: any, parentElement1d: any, blocks: Dict[str, Float] | None = None, nodeSets: Dict[str, Float] | None = None, sideSets: Dict[str, Float] | None = None) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+pancax.fem.mesh.create_structured_mesh_data(Nx, Ny, xExtent, yExtent)[source]
+
+ +
+
+pancax.fem.mesh.construct_mesh_from_basic_data(coords, conns, blocks, nodeSets=None, sideSets=None)[source]
+
+ +
+
+pancax.fem.mesh.construct_structured_mesh(Nx, Ny, xExtent, yExtent, elementOrder=1, useBubbleElement=False)[source]
+
+ +
+
+pancax.fem.mesh.combine_nodesets(set1, set2, nodeOffset)[source]
+
+ +
+
+pancax.fem.mesh.combine_sidesets(set1, set2, elemOffset)[source]
+
+ +
+
+pancax.fem.mesh.combine_blocks(set1, set2, elemOffset)[source]
+
+ +
+
+pancax.fem.mesh.combine_mesh(m1, m2)[source]
+
+ +
+
+pancax.fem.mesh.mesh_with_coords(mesh, coords)[source]
+
+ +
+
+pancax.fem.mesh.mesh_with_nodesets(mesh, nodeSets)[source]
+
+ +
+
+pancax.fem.mesh.mesh_with_blocks(mesh, blocks)[source]
+
+ +
+
+pancax.fem.mesh.create_edges(conns)[source]
+

Generate topological information about edges in a triangulation.

+
+
Parameters:
+

conns ((nTriangles, 3) array) – Connectivity table of the triangulation.

+
+
Returns:
+

    +
  • edgeConns ((nEdges, 2) array) – Vertices of each edge. Boundary edges are always in the +counter-clockwise sense, so that the interior of the body is on the left +side when walking from the first vertex to the second.

  • +
  • edges ((nEdges, 4) array) – Edge-to-triangle topological information. Each row provides the +follwing information for each edge: [leftT, leftP, rightT, rightP], +where leftT is the ID of the triangle to the left, leftP is the +permutation of the edge in the left triangle (edge 0, 1, or 2), rightT +is the ID of the triangle to the right, and rightP is the permutation +of the edge in the right triangle. If the edge is a boundary edge, the +values of rightT and rightP are -1.

  • +
+

+
+
+
+ +
+
+pancax.fem.mesh.create_higher_order_mesh_from_simplex_mesh(mesh, order, useBubbleElement=False, copyNodeSets=False, createNodeSetsFromSideSets=False)[source]
+
+ +
+
+pancax.fem.mesh.create_nodesets_from_sidesets(mesh)[source]
+
+ +
+
+pancax.fem.mesh.num_nodes(mesh)[source]
+
+ +
+
+pancax.fem.mesh.get_edge_node_indices(mesh: Mesh, edge)[source]
+
+ +
+
+pancax.fem.mesh.get_edge_field(mesh: Mesh, edge, field)[source]
+

Evaluate field on nodes of an element edge. +Arguments:

+
+
Parameters:
+
    +
  • mesh – a Mesh object

  • +
  • edge – tuple containing the element number containing the edge and the +permutation (0, 1, or 2) of the edge within the triangle

  • +
+
+
+
+ +
+
+pancax.fem.mesh.get_edge_coords(mesh: Mesh, edge)[source]
+
+ +
+
+pancax.fem.mesh.compute_edge_vectors(mesh: Mesh, edgeCoords)[source]
+

Get geometric vectors for an element edge.

+

Assumes that the edgs has a constant shape jacobian, that is, the +transformation from the parent element is affine.

+

Arguments +:param mesh: a Mesh object +:param edgeCoords: coordinates of all nodes on the edge, in the order +defined by the 1D parent element convention

+

Returns +tuple (t, n, j) with +:return t: the unit tangent vector +:return n: the outward unit normal vector +:return j: jacobian of the transformation from parent to physical space

+
+ +
+
+

pancax.fem.quadrature_rules module

+
+
+class pancax.fem.quadrature_rules.QuadratureRule(parentElement: BaseElement, degree: int)[source]
+

Bases: Module

+

Quadrature rule points and weights. +A namedtuple containing xigauss, a numpy array of the +coordinates of the sample points in the reference domain, and +wgauss, a numpy array with the weights.

+
+
Parameters:
+
    +
  • xigauss – coordinates of gauss points in reference element

  • +
  • wgauss – weights of gauss points in reference element

  • +
+
+
+
+
+__init__(parentElement: BaseElement, degree: int) None[source]
+
+ +
+
+xigauss: Float[Array, 'nq nd']
+
+ +
+
+wgauss: Float[Array, 'nq']
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+pancax.fem.quadrature_rules.create_quadrature_rule_1D(degree: int) QuadratureRule[source]
+

Creates a Gauss-Legendre quadrature on the unit interval.

+

The rule can exactly integrate polynomials of degree up to +degree.

+
+
Parameters:
+

degree (Highest degree polynomial to be exactly integrated by the quadrature rule)

+
+
Returns:
+

    +
  • A QuadratureRule named tuple containing the quadrature point coordinates

  • +
  • and the weights.

  • +
+

+
+
+
+ +
+
+pancax.fem.quadrature_rules.eval_at_iso_points(xigauss, field)[source]
+
+ +
+
+pancax.fem.quadrature_rules.create_quadrature_rule_on_hex(quad_degree: int) QuadratureRule[source]
+
+ +
+
+pancax.fem.quadrature_rules.create_quadrature_rule_on_quad(quad_degree: int) QuadratureRule[source]
+
+
Parameters:
+

quad_degree – degree of quadrature rule to create

+
+
+
+ +
+
+pancax.fem.quadrature_rules.create_quadrature_rule_on_tet(degree: int) QuadratureRule[source]
+
+ +
+
+pancax.fem.quadrature_rules.create_quadrature_rule_on_triangle(degree: int) QuadratureRule[source]
+

Creates a Gauss-Legendre quadrature on the unit triangle.

+

The rule can exactly integrate 2D polynomials up to the value of +degree. The domain is the triangle between the vertices +(0, 0)-(1, 0)-(0, 1). The rules here are guaranteed to be +cyclically symmetric in triangular coordinates and to have strictly +positive weights.

+
+
Parameters:
+

degree (Highest degree polynomial to be exactly integrated by the quadrature rule)

+
+
Returns:
+

    +
  • A QuadratureRule named tuple containing the quadrature point coordinates

  • +
  • and the weights.

  • +
+

+
+
+
+ +
+
+pancax.fem.quadrature_rules.create_padded_quadrature_rule_1D(degree)[source]
+

Creates 1D Gauss quadrature rule data that are padded to maintain a +uniform size, which makes this function jit-able.

+

This function is inteded to be used only when jit compilation of calls to the +quadrature rules are needed. Otherwise, prefer to use the standard quadrature +rules. The standard rules do not contain extra 0s for padding, which makes +them more efficient when used repeatedly (such as in the global energy).

+
+
Parameters:
+

degree – degree of highest polynomial to be integrated exactly

+
+
+
+ +
+
+pancax.fem.quadrature_rules._gauss_quad_1D_1pt(_)[source]
+
+ +
+
+pancax.fem.quadrature_rules._gauss_quad_1D_2pt(_)[source]
+
+ +
+
+pancax.fem.quadrature_rules._gauss_quad_1D_3pt(_)[source]
+
+ +
+
+pancax.fem.quadrature_rules._gauss_quad_1D_4pt(_)[source]
+
+ +
+
+pancax.fem.quadrature_rules._gauss_quad_1D_5pt(_)[source]
+
+ +
+
+

pancax.fem.read_exodus_mesh module

+
+
+pancax.fem.read_exodus_mesh.read_exodus_mesh(fileName: str)[source]
+
+
Parameters:
+

fileName – file name of exodus mesh to read

+
+
Returns:
+

A mesh object

+
+
+
+ +
+
+pancax.fem.read_exodus_mesh._read_coordinates(exodusDataset)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._read_block_conns(exodusDataset, blockOrdinal)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._read_blocks(exodusDataset)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._read_node_sets(exodusDataset)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._read_side_sets(exodusDataset)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._read_element_type(exodusDataset)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._read_names_list(exodusDataset, recordName)[source]
+
+ +
+
+pancax.fem.read_exodus_mesh._get_vertex_nodes_from_exodus_tri6_mesh(conns)[source]
+
+ +
+
+

pancax.fem.sparse_matrix_assembler module

+
+
+pancax.fem.sparse_matrix_assembler.assemble_sparse_stiffness_matrix(kValues, conns, dofManager)[source]
+
+ +
+
+

pancax.fem.surface module

+
+
+pancax.fem.surface.create_edges(coords, conns, edge_is_potentially_in_contact)[source]
+
+ +
+
+pancax.fem.surface.get_coords(coords, conns, side)[source]
+
+ +
+
+pancax.fem.surface.interpolate_nodal_field_on_edge(mesh, U, interpolationPoints, edge)[source]
+
+ +
+
+pancax.fem.surface.integrate_values(quadratureRule, coords, gaussField)[source]
+
+ +
+
+pancax.fem.surface.integrate_function(quadratureRule, coords, field_func)[source]
+
+ +
+
+pancax.fem.surface.integrate_function_on_surface(quadratureRule, edges, mesh, func)[source]
+
+ +
+
+pancax.fem.surface.integrate_function_on_edge(quadratureRule, edge, mesh, func)[source]
+
+ +
+
+pancax.fem.surface.compute_normal(edgeCoords)[source]
+
+ +
+
+pancax.fem.surface.get_field_index(edge, conns)[source]
+
+ +
+
+pancax.fem.surface.eval_field(field, fieldIndex)[source]
+
+ +
+
+pancax.fem.surface.compute_edge_vectors(edgeCoords)[source]
+
+ +
+
+

pancax.fem.traction_bc module

+
+
+pancax.fem.traction_bc.interpolate_nodal_field_on_edge(conns, U, quadRule, edge)[source]
+
+ +
+
+pancax.fem.traction_bc.compute_traction_potential_energy_on_edge(coords, conns, U, quadRule, edge, load, time)[source]
+
+ +
+
+pancax.fem.traction_bc.compute_traction_potential_energy(coords, conns, U, quadRule, edges, load, time=0.0)[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.html b/html/pancax.html new file mode 100644 index 0000000..4504f40 --- /dev/null +++ b/html/pancax.html @@ -0,0 +1,1828 @@ + + + + + + + + + pancax package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax package

+
+

Subpackages

+
+ +
+
+
+

Submodules

+
+
+

pancax.__main__ module

+
+
+

pancax.history_writer module

+
+
+class pancax.history_writer.BaseHistoryWriter(log_every: int, write_every: int)[source]
+

Bases: Module

+
+
+log_every: int
+
+ +
+
+write_every: int
+
+ +
+
+abstract to_csv()[source]
+
+ +
+
+write_data(key: str, val: float) None[source]
+
+ +
+
+abstract write_aux_values(loss)[source]
+
+ +
+
+abstract write_epoch(epoch)[source]
+
+ +
+
+write_history(loss, epoch: int)[source]
+
+ +
+
+abstract write_loss(loss)[source]
+
+ +
+
+__init__(log_every: int, write_every: int) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.history_writer.HistoryWriter(history_file: str, log_every: int, write_every: int)[source]
+

Bases: BaseHistoryWriter

+
+
+log_every: int
+
+ +
+
+write_every: int
+
+ +
+
+__init__(history_file: str, log_every: int, write_every: int) None[source]
+
+ +
+
+history_file: Path
+
+ +
+
+data_dict: dict
+
+ +
+
+to_csv() None[source]
+
+ +
+
+write_aux_values(loss)[source]
+
+ +
+
+write_epoch(epoch)[source]
+
+ +
+
+write_loss(loss)[source]
+
+ +
+
+_write_loss(loss, epoch: int, log_every=1, save_every=1000)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.history_writer.EnsembleHistoryWriter(base_name: str, n_pinns: int, log_every: int, write_every: int)[source]
+

Bases: BaseHistoryWriter

+
+
+log_every: int
+
+ +
+
+write_every: int
+
+ +
+
+__init__(base_name: str, n_pinns: int, log_every: int, write_every: int) None[source]
+
+ +
+
+history_writers: List[HistoryWriter]
+
+ +
+
+to_csv()[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+write_aux_values(loss)[source]
+
+ +
+
+write_epoch(epoch)[source]
+
+ +
+
+write_loss(loss)[source]
+
+ +
+ +
+
+

pancax.kinematics module

+
+
+pancax.kinematics.create_field_methods(domain, bc_func)[source]
+
+ +
+
+pancax.kinematics.deformation_gradients(grad_us, formulation)[source]
+
+ +
+
+pancax.kinematics.invariants_old(grad_us, formulation)[source]
+
+ +
+
+pancax.kinematics.invariants(grad_u)[source]
+
+ +
+
+pancax.kinematics.plane_strain(F)[source]
+
+ +
+
+pancax.kinematics.incompressible_plane_stress(F)[source]
+
+ +
+
+

pancax.logging module

+
+
+pancax.logging.log_loss(loss, n, log_every)[source]
+
+ +
+
+class pancax.logging.BaseLogger(log_every: int)[source]
+

Bases: Module

+
+
+log_every: int
+
+ +
+
+abstract flush()[source]
+
+ +
+
+log_loss(loss, epoch)[source]
+
+ +
+
+abstract write_aux_values(loss)[source]
+
+ +
+
+abstract write_epoch_value(epoch)[source]
+
+ +
+
+abstract write_loss_value(loss)[source]
+
+ +
+
+__init__(log_every: int) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.logging.Logger(log_file_in: str, log_every: int)[source]
+

Bases: BaseLogger

+
+
+__init__(log_file_in: str, log_every: int) None[source]
+
+ +
+
+log_file: any
+
+ +
+
+flush()[source]
+
+ +
+
+write_aux_values(loss)[source]
+
+ +
+
+write_epoch_value(epoch)[source]
+
+ +
+
+write_loss_value(loss)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.logging.EnsembleLogger(base_name: str, n_pinns: int, log_every: int)[source]
+

Bases: BaseLogger

+
+
+__init__(base_name: str, n_pinns: int, log_every: int) None[source]
+
+ +
+
+loggers: List[Logger]
+
+ +
+
+flush()[source]
+
+ +
+
+write_aux_values(loss)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+write_epoch_value(epoch)[source]
+
+ +
+
+write_loss_value(loss)[source]
+
+ +
+ +
+
+

pancax.physics module

+
+
+pancax.physics.element_quantity(f, x, u, conn, N, grad_N, JxW, props)[source]
+
+ +
+
+pancax.physics.element_quantity_new(f, fspace, x_el, u_el, props)[source]
+
+ +
+
+pancax.physics.element_quantity_grad(f, fspace, x_el, u_el, props)
+

Jacobian of element_quantity_new with respect to positional argument(s) 3. Takes the same arguments as element_quantity_new but returns the jacobian of the output with respect to the arguments at positions 3.

+
+ +
+
+pancax.physics.element_quantity_hessian(f, fspace, x_el, u_el, props)
+

Jacobian of element_quantity_new with respect to positional argument(s) 3. Takes the same arguments as element_quantity_new but returns the jacobian of the output with respect to the arguments at positions 3.

+
+ +
+
+pancax.physics.potential_energy(domain, us, props)[source]
+
+ +
+
+pancax.physics.residual_mse(domain, us, props)[source]
+
+ +
+
+pancax.physics.mass_matrix(domain, us, props)[source]
+
+ +
+
+pancax.physics.stiffness_matrix(domain, us, props)[source]
+
+ +
+
+pancax.physics.traction_energy()[source]
+
+ +
+
+pancax.physics.internal_force(domain, us, props)
+

Gradient of potential_energy with respect to positional argument(s) 1. Takes the same arguments as potential_energy but returns the gradient, which has the same shape as the arguments at positions 1.

+
+ +
+
+pancax.physics.residual(x, y, z)
+
+ +
+
+pancax.physics.potential_energy_and_internal_force(domain, us, props)
+

Value and gradient of potential_energy with respect to positional argument(s) 1. Takes the same arguments as potential_energy but returns a two-element tuple where the first element is the value of potential_energy and the second element is the gradient, which has the same shape as the arguments at positions 1.

+
+ +
+
+pancax.physics.potential_energy_and_residual(domain, us, props)[source]
+
+ +
+
+pancax.physics.potential_energy_residual_and_reaction_force(domain, us, props)[source]
+
+ +
+
+pancax.physics.strong_form_residual(params, domain, t)[source]
+
+ +
+
+pancax.physics.nodal_incompressibility_constraint(params, domain, t)[source]
+
+ +
+
+pancax.physics.quadrature_incompressibility_constraint(domain, us, props)[source]
+
+ +
+
+pancax.physics.incompressible_energy(domain, us, props)[source]
+
+ +
+
+pancax.physics.incompressible_internal_force(domain, us, props)
+

Gradient of incompressible_energy with respect to positional argument(s) 1. Takes the same arguments as incompressible_energy but returns the gradient, which has the same shape as the arguments at positions 1.

+
+ +
+
+pancax.physics.incompressible_energy_and_internal_force(domain, us, props)
+

Value and gradient of incompressible_energy with respect to positional argument(s) 1. Takes the same arguments as incompressible_energy but returns a two-element tuple where the first element is the value of incompressible_energy and the second element is the gradient, which has the same shape as the arguments at positions 1.

+
+ +
+
+pancax.physics.incompressible_energy_and_residual(domain, us, props)[source]
+
+ +
+
+

pancax.post_processor module

+
+
+class pancax.post_processor.PostProcessor(mesh_file: str)[source]
+

Bases: object

+
+
+__init__(mesh_file: str) None[source]
+
+ +
+
+check_variable_names(domain, variables) None[source]
+
+ +
+
+close() None[source]
+
+ +
+
+copy_mesh(output_file: str) None[source]
+
+ +
+
+get_node_variable_number(domain, variables) int[source]
+
+ +
+
+get_element_variable_number(domain, variables) int[source]
+
+ +
+
+init(domain, output_file: str, node_variables: List[str], element_variables: List[str] | None = []) None[source]
+
+ +
+
+index_to_component(index)[source]
+
+ +
+
+write_outputs(params, domain) None[source]
+
+ +
+ +
+
+

pancax.timer module

+
+
+exception pancax.timer.TimerError[source]
+

Bases: Exception

+

A custom exception used to report errors in use of Timer class

+
+ +
+
+class pancax.timer.Timer(name: str | None = None, text: str = 'Time in {name}: {:0.8f} seconds', logger: ~typing.Callable[[str], None] | None = <built-in function print>)[source]
+

Bases: ContextDecorator

+

Time your code using a class, context manager, or decorator

+
+
+timers: ClassVar[Dict[str, float]] = {}
+
+ +
+
+name: str | None = None
+
+ +
+
+text: str = 'Time in {name}: {:0.8f} seconds'
+
+ +
+
+logger(*, sep=' ', end='\n', file=None, flush=False)
+

Prints the values to a stream, or to sys.stdout by default.

+
+
sep

string inserted between values, default a space.

+
+
end

string appended after the last value, default a newline.

+
+
file

a file-like object (stream); defaults to the current sys.stdout.

+
+
flush

whether to forcibly flush the stream.

+
+
+
+ +
+
+_start_time: float | None = None
+
+ +
+
+start() None[source]
+

Start a new timer

+
+ +
+
+stop() float[source]
+

Stop the timer, and report the elapsed time

+
+ +
+
+__init__(name: str | None = None, text: str = 'Time in {name}: {:0.8f} seconds', logger: ~typing.Callable[[str], None] | None = <built-in function print>) None
+
+ +
+ +
+
+

pancax.trainer module

+
+
+class pancax.trainer.Trainer(domain, opt, checkpoint_base='checkpoint', history_file='history.csv', log_file='pinn.log', output_file_base='output', output_node_variables=[], output_element_variables=[], log_every=1000, output_every=10000, serialise_every=10000, workdir='/__w/pancax/pancax/docs')[source]
+

Bases: object

+
+
+__init__(domain, opt, checkpoint_base='checkpoint', history_file='history.csv', log_file='pinn.log', output_file_base='output', output_node_variables=[], output_element_variables=[], log_every=1000, output_every=10000, serialise_every=10000, workdir='/__w/pancax/pancax/docs') None[source]
+
+ +
+
+init(params)[source]
+
+ +
+
+serialise(params)[source]
+
+ +
+
+step(params, opt_st)[source]
+
+ +
+
+train(params, n_epochs)[source]
+
+ +
+
+write_outputs(params)[source]
+
+ +
+ +
+
+

pancax.utils module

+
+
+exception pancax.utils.DataFileNotFoundException[source]
+

Bases: Exception

+
+ +
+
+exception pancax.utils.MeshFileNotFoundException[source]
+

Bases: Exception

+
+ +
+
+pancax.utils.find_data_file(data_file_in: str)[source]
+
+ +
+
+pancax.utils.find_mesh_file(mesh_file_in: str)[source]
+
+ +
+
+pancax.utils.set_checkpoint_file(checkpoint_file_base: str)[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.kernels.html b/html/pancax.kernels.html new file mode 100644 index 0000000..4c2dcb5 --- /dev/null +++ b/html/pancax.kernels.html @@ -0,0 +1,879 @@ + + + + + + + + + pancax.kernels package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.kernels package

+
+

Submodules

+
+
+

pancax.kernels.base_kernel module

+
+
+pancax.kernels.base_kernel.vector_names(base_name: str, dim: int)[source]
+
+ +
+
+pancax.kernels.base_kernel.full_tensor_names(base_name: str)[source]
+

Provides a full list of tensorial variable component names +:param base_name: base name for a tensor variable e.g. base_name_xx

+
+ +
+
+pancax.kernels.base_kernel.full_tensor_names_2D(base_name: str)[source]
+

Provides a full list of tensorial variable component names +:param base_name: base name for a tensor variable e.g. base_name_xx

+
+ +
+
+pancax.kernels.base_kernel.element_pp(func, has_props=False, jit=True)[source]
+
+
Parameters:
+
    +
  • func – Function to use for an element property output variable

  • +
  • has_props – Whether or not this function need properties

  • +
  • jit – Whether or not to jit this function

  • +
+
+
+
+ +
+
+pancax.kernels.base_kernel.nodal_pp(func, has_props=False, jit=True)[source]
+
+
Parameters:
+
    +
  • func – Function to use for a nodal property output variable

  • +
  • has_props – Whether or not this function need properties

  • +
  • jit – Whether or not to jit this function

  • +
+
+
+
+ +
+
+pancax.kernels.base_kernel.standard_pp(physics)[source]
+
+ +
+
+class pancax.kernels.base_kernel.PhysicsKernel(mesh_file, bc_func, use_delta_pinn)[source]
+

Bases: ABC

+
+
+n_dofs: int
+
+ +
+
+field_value_names: List[str]
+
+ +
+
+var_name_to_method: Dict[str, Dict[str, Callable | List[str]]] = {}
+
+ +
+
+__init__(mesh_file, bc_func, use_delta_pinn) None[source]
+
+ +
+
+bc_func: Callable
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.kernels.base_kernel.StrongFormPhysicsKernel(mesh_file, bc_func, use_delta_pinn)[source]
+

Bases: PhysicsKernel

+
+
+n_dofs: int
+
+ +
+
+field_value_names: List[str]
+
+ +
+
+bc_func: Callable
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+__init__(mesh_file, bc_func, use_delta_pinn) None[source]
+
+ +
+
+field_gradients(field_network, x, t)[source]
+
+ +
+
+field_hessians(field_network, x, t)[source]
+
+ +
+
+field_laplacians(field_network, x, t)[source]
+
+ +
+
+field_time_derivatives(field_network, x, t)[source]
+
+ +
+
+field_second_time_derivatives(field_network, x, t)[source]
+
+ +
+
+abstract strong_form_neumann_bc(params, x, t, n)[source]
+
+ +
+
+abstract strong_form_residual(params, x, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.kernels.base_kernel.WeakFormPhysicsKernel(mesh_file, bc_func, use_delta_pinn)[source]
+

Bases: PhysicsKernel

+
+
+n_dofs: int
+
+ +
+
+field_value_names: List[str]
+
+ +
+
+bc_func: Callable
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+__init__(mesh_file, bc_func, use_delta_pinn) None[source]
+
+ +
+
+element_field_gradient(params, domain, t)[source]
+
+ +
+
+element_quantity(f, fspace, x_el, u_el, props)[source]
+
+ +
+
+element_quantity_grad(f, fspace, x_el, u_el, props)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+element_quantity_hessian(f, fspace, x_el, u_el, props)[source]
+
+ +
+
+abstract energy(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+ +
+
+

pancax.kernels.laplace_beltrami module

+
+
+class pancax.kernels.laplace_beltrami.LaplaceBeltrami(mesh_file, bc_func, n_eigs: int, use_delta_pinn: bool | None = False)[source]
+

Bases: WeakFormPhysicsKernel

+
+
+n_dofs: int = 1
+
+ +
+
+field_names = ['eigenvector']
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+__init__(mesh_file, bc_func, n_eigs: int, use_delta_pinn: bool | None = False)[source]
+
+ +
+
+energy(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+kinetic_energy(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.kernels.linear_elasticity module

+
+
+class pancax.kernels.linear_elasticity.LinearElasticity2D(mesh_file: str, bc_func: ~typing.Callable, body_force: ~typing.Callable = <function LinearElasticity2D.<lambda>>, use_delta_pinn: bool | None = False)[source]
+

Bases: StrongFormPhysicsKernel, WeakFormPhysicsKernel

+
+
+n_dofs: int = 2
+
+ +
+
+field_value_names: List[str] = ['displ_x', 'displ_y']
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+__init__(mesh_file: str, bc_func: ~typing.Callable, body_force: ~typing.Callable = <function LinearElasticity2D.<lambda>>, use_delta_pinn: bool | None = False) None[source]
+
+ +
+
+energy(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+strong_form_residual(params, x, t)[source]
+
+ +
+
+strong_form_neumann_bc(params, x, t, n)[source]
+
+ +
+
+linear_strain(field_network, x, t)[source]
+
+ +
+
+cauchy_stress(params, x, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.kernels.poisson module

+
+
+class pancax.kernels.poisson.Poisson(mesh_file, bc_func: Callable, f: Callable, use_delta_pinn: bool | None = False)[source]
+

Bases: StrongFormPhysicsKernel, WeakFormPhysicsKernel

+
+
+n_dofs: int = 1
+
+ +
+
+field_value_names: List[str] = ['u']
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+__init__(mesh_file, bc_func: Callable, f: Callable, use_delta_pinn: bool | None = False)[source]
+
+ +
+
+energy(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+strong_form_residual(params, x, t)[source]
+
+ +
+
+strong_form_neumann_bc(params, x, t, n)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.kernels.solid_mechanics module

+
+
+class pancax.kernels.solid_mechanics.BaseMechanicsFormulation[source]
+

Bases: ABC

+
+
+n_dimensions: int
+
+ +
+
+abstract modify_field_gradient(grad_u)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.kernels.solid_mechanics.IncompressiblePlaneStress[source]
+

Bases: BaseMechanicsFormulation

+
+
+n_dimensions: int = 2
+
+ +
+
+__init__() None[source]
+
+ +
+
+deformation_gradient(grad_u)[source]
+
+ +
+
+modify_field_gradient(grad_u)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.kernels.solid_mechanics.PlaneStrain[source]
+

Bases: BaseMechanicsFormulation

+
+
+n_dimensions: int = 2
+
+ +
+
+extract_stress(P)[source]
+
+ +
+
+modify_field_gradient(grad_u)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.kernels.solid_mechanics.ThreeDimensional[source]
+

Bases: BaseMechanicsFormulation

+
+
+n_dimensions: int = 3
+
+ +
+
+modify_field_gradient(grad_u)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.kernels.solid_mechanics.SolidMechanics(mesh, bc_func, constitutive_model, formulation, use_delta_pinn: bool | None = False)[source]
+

Bases: StrongFormPhysicsKernel, WeakFormPhysicsKernel

+
+
+field_values_names: List[str]
+
+ +
+
+bc_func: Callable
+
+ +
+
+use_delta_pinn: bool
+
+ +
+
+__init__(mesh, bc_func, constitutive_model, formulation, use_delta_pinn: bool | None = False)[source]
+
+ +
+
+n_dofs: int
+
+ +
+
+constitutive_model: ConstitutiveModel
+
+ +
+
+formulation: BaseMechanicsFormulation
+
+ +
+
+element_field_gradient(params, domain, t)[source]
+
+ +
+
+element_quantity_from_func(func: Callable, with_props: bool | None = False)[source]
+
+ +
+
+energy(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+nodal_incompressibility_constraint(field_network, x, t)[source]
+
+ +
+
+quadrature_incompressibility_constraint(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+pk1_stress_weak_form(x_el, u_el, N, grad_N, JxW, props)[source]
+
+ +
+
+strong_form_residual(params, x, t)[source]
+
+ +
+
+strong_form_neumann_bc(params, x, t, n)[source]
+
+ +
+
+pk1_stress(params, x, t)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.loss_functions.html b/html/pancax.loss_functions.html new file mode 100644 index 0000000..597dd10 --- /dev/null +++ b/html/pancax.loss_functions.html @@ -0,0 +1,773 @@ + + + + + + + + + pancax.loss_functions package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.loss_functions package

+
+

Submodules

+
+
+

pancax.loss_functions.base_loss_function module

+
+
+class pancax.loss_functions.base_loss_function.BaseLossFunction[source]
+

Bases: Module

+

Base class for loss functions. +Currently does nothing but helps build a +type hierarchy.

+
+
+filtered_loss(diff_params, static_params, domain)[source]
+
+ +
+
+__init__() None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.base_loss_function.BCLossFunction[source]
+

Bases: BaseLossFunction

+

Base class for boundary condition loss functions.

+

A load_step method is expect with the following +type signature +load_step(self, params, domain, t)

+
+
+abstract load_step(params, domain, t)[source]
+
+ +
+
+__init__() None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.base_loss_function.PhysicsLossFunction[source]
+

Bases: BaseLossFunction

+

Base class for physics loss functions.

+

A load_step method is expect with the following +type signature +load_step(self, params, domain, t)

+
+
+abstract load_step(params, domain, t)[source]
+
+ +
+
+__init__() None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.loss_functions.bc_loss_functions module

+
+
+class pancax.loss_functions.bc_loss_functions.DirichletBCLoss(weight: float | None = 1.0)[source]
+

Bases: BCLossFunction

+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.bc_loss_functions.NeumannBCLoss(weight: float | None = 1.0)[source]
+

Bases: BCLossFunction

+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+ +
+
+

pancax.loss_functions.data_loss_functions module

+
+
+class pancax.loss_functions.data_loss_functions.FullFieldDataLoss(weight: float | None = 1.0)[source]
+

Bases: BaseLossFunction

+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.loss_functions.physics_loss_functions_strong_form module

+
+
+pancax.loss_functions.physics_loss_functions_strong_form.StrongFormResidualLoss(weight: float | None = 1.0)[source]
+
+ +
+
+pancax.loss_functions.physics_loss_functions_strong_form.StrongFormNeumannBCLoss(weight: float | None = 1.0)[source]
+
+ +
+
+pancax.loss_functions.physics_loss_functions_strong_form.StrongFormIncompressibilityConstraint(weight: bool | None = 1.0)[source]
+
+ +
+
+

pancax.loss_functions.strong_form_loss_functions module

+
+
+class pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss(weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+ +
+
+

pancax.loss_functions.utils module

+
+
+class pancax.loss_functions.utils.CombineLossFunctions(*funcs, with_props=False)[source]
+

Bases: BaseLossFunction

+
+
+__init__(*funcs, with_props=False)[source]
+
+ +
+
+funcs: any
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+with_props: bool
+
+ +
+ +
+
+

pancax.loss_functions.weak_form_loss_functions module

+
+
+class pancax.loss_functions.weak_form_loss_functions.EnergyLoss(weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+

Energy loss function akin to the deep energy method.

+

Calculates the following quantity

+
+\[\mathcal{L} = w\Pi\left[u\right] = w\int_\Omega\psi\left(\mathbf{F}\right)\]
+
+
Parameters:
+

weight – weight for this loss function

+
+
+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss(energy_weight: float | None = 1.0, residual_weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+

Energy and residual loss function used in Hamel et. al

+

Calculates the following quantity

+
+\[\mathcal{L} = w_1\Pi\left[u\right] + w_2\delta\Pi\left[u\right]_{free}\]
+
+
Parameters:
+
    +
  • energy_weight – Weight for the energy w_1

  • +
  • residual_weight – Weight for the residual w_2

  • +
+
+
+
+
+__init__(energy_weight: float | None = 1.0, residual_weight: float | None = 1.0)[source]
+
+ +
+
+energy_weight: float
+
+ +
+
+residual_weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss(energy_weight: float | None = 1.0, residual_weight: float | None = 1.0, reaction_weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+
+
+__init__(energy_weight: float | None = 1.0, residual_weight: float | None = 1.0, reaction_weight: float | None = 1.0)[source]
+
+ +
+
+energy_weight: float
+
+ +
+
+residual_weight: float
+
+ +
+
+reaction_weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint(weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss(weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss(weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+

Energy loss function akin to the deep energy method.

+

Calculates the following quantity

+
+\[\mathcal{L} = w\Pi\left[u\right] = w\int_\Omega\psi\left(\mathbf{F}\right)\]
+
+
Parameters:
+

weight – weight for this loss function

+
+
+
+
+__init__(weight: float | None = 1.0)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+ +
+
+class pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss(energy_weight: float | None = 1.0, residual_weight: float | None = 1.0)[source]
+

Bases: PhysicsLossFunction

+

Energy and residual loss function used in Hamel et. al

+

Calculates the following quantity

+
+\[\mathcal{L} = w_1\Pi\left[u\right] + w_2\delta\Pi\left[u\right]_{free}\]
+
+
Parameters:
+
    +
  • energy_weight – Weight for the energy w_1

  • +
  • residual_weight – Weight for the residual w_2

  • +
+
+
+
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+__init__(energy_weight: float | None = 1.0, residual_weight: float | None = 1.0)[source]
+
+ +
+
+energy_weight: float
+
+ +
+
+residual_weight: float
+
+ +
+
+load_step(params, domain, t)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.math.html b/html/pancax.math.html new file mode 100644 index 0000000..69c7df0 --- /dev/null +++ b/html/pancax.math.html @@ -0,0 +1,424 @@ + + + + + + + + + pancax.math package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.math package

+
+

Submodules

+
+
+

pancax.math.math module

+
+
+pancax.math.math.safe_sqrt_jvp(xt, vt)[source]
+
+ +
+
+pancax.math.math.sum2(a)[source]
+

Sum a vector to much higher accuracy than numpy.sum.

+
+
Parameters:
+

a (ndarray, with only one axis (shape [n,]))

+
+
Returns:
+

sum – The sum of the numbers in the array

+
+
Return type:
+

real

+
+
+

This special sum method computes the result as accurate as if +computed in quadruple precision.

+

Reference: +T. Ogita, S. M. Rump, and S. Oishi. Accurate sum and dot product. +SIAM J. Sci. Comput., Vol 26, No 6, pp. 1955-1988. +doi: 10.1137/030601818

+
+ +
+
+pancax.math.math._two_sum(a, b)[source]
+
+ +
+
+pancax.math.math.dot2(x, y)[source]
+

Compute inner product of 2 vectors to much higher accuracy than numpy.dot.

+

:param : +:type : param x: ndarray, with only one axis (shape [n,]) +:param : +:type : param y: ndarray, with only one axis (shape [n,])

+
+
Returns:
+

The inner product of the input vectors.

+
+
Return type:
+

return dotprod: real

+
+
+

This special inner product method computes the result as accurate +as if computed in quadruple precision. This algorithm is useful to +computing objective functions from numerical integration. It avoids +accumulation of floating point cancellation error that can obscure +whether an objective function has truly decreased.

+

The environment variable setting +‘XLA_FLAGS = “–xla_cpu_enable_fast_math=false”’ +is critical for this function to work on the CPU. Otherwise, xla +apparently sets a flag for LLVM that allows unsafe floating point +optimizations that can change associativity.

+

Reference +T. Ogita, S. M. Rump, and S. Oishi. Accurate sum and dot product. +SIAM J. Sci. Comput., Vol 26, No 6, pp. 1955-1988. +doi 10.1137/030601818

+
+ +
+
+pancax.math.math._two_product(a, b)[source]
+
+ +
+
+pancax.math.math._float_split(a)[source]
+
+ +
+
+

pancax.math.tensor_math module

+
+
+pancax.math.tensor_math.if_then_else(cond, val1, val2)[source]
+
+ +
+
+pancax.math.tensor_math.compute_deviatoric_tensor(strain)[source]
+
+ +
+
+pancax.math.tensor_math.dev(strain)[source]
+
+ +
+
+pancax.math.tensor_math.tensor_norm(tensor)[source]
+
+ +
+
+pancax.math.tensor_math.norm_of_deviator_squared(tensor)[source]
+
+ +
+
+pancax.math.tensor_math.norm_of_deviator(tensor)[source]
+
+ +
+
+pancax.math.tensor_math.mises_equivalent_stress(stress)[source]
+
+ +
+
+pancax.math.tensor_math.triaxiality(A)[source]
+
+ +
+
+pancax.math.tensor_math.sym(A)[source]
+
+ +
+
+pancax.math.tensor_math.logh(A)[source]
+
+ +
+
+pancax.math.tensor_math.logh_from_eigen(eVals, eVecs)[source]
+
+ +
+
+pancax.math.tensor_math.tensor_2D_to_3D(H)[source]
+
+ +
+
+pancax.math.tensor_math.eigen_sym33_non_unit(tensor)[source]
+
+ +
+
+pancax.math.tensor_math.eigen_sym33_unit(tensor)[source]
+
+ +
+
+pancax.math.tensor_math.cos_of_acos_divided_by_3(x)[source]
+
+ +
+
+pancax.math.tensor_math.mtk_log_sqrt_jvp(Cpack, Hpack)[source]
+
+ +
+
+pancax.math.tensor_math.mtk_pow_jvp(m, Cpack, Hpack)[source]
+
+ +
+
+pancax.math.tensor_math.relative_log_difference_taylor(lam1, lam2)[source]
+
+ +
+
+pancax.math.tensor_math.relative_log_difference_no_tolerance_check(lam1, lam2)[source]
+
+ +
+
+pancax.math.tensor_math.relative_log_difference(lam1, lam2)[source]
+
+ +
+
+pancax.math.tensor_math.log_jvp(Cpack, Hpack)[source]
+
+ +
+
+pancax.math.tensor_math.jvp_sqrtm(primals, tangents)[source]
+
+ +
+
+pancax.math.tensor_math.sqrtm_dbp(A)[source]
+

Matrix square root by product form of Denman-Beavers iteration.

+

Translated from the Matrix Function Toolbox +http://www.ma.man.ac.uk/~higham/mftoolbox +Nicholas J. Higham, Functions of Matrices: Theory and Computation, +SIAM, Philadelphia, PA, USA, 2008. ISBN 978-0-898716-46-7,

+
+ +
+
+pancax.math.tensor_math.logm_jvp(primals, tangents)[source]
+
+ +
+
+pancax.math.tensor_math._logm_iss(A)[source]
+

Logarithmic map by inverse scaling and squaring and Padé approximants

+

Translated from the Matrix Function Toolbox +http://www.ma.man.ac.uk/~higham/mftoolbox +Nicholas J. Higham, Functions of Matrices: Theory and Computation, +SIAM, Philadelphia, PA, USA, 2008. ISBN 978-0-898716-46-7,

+
+ +
+
+pancax.math.tensor_math.log_pade_pf(A, n)[source]
+

Logarithmic map by Padé approximant and partial fractions

+
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.networks.html b/html/pancax.networks.html new file mode 100644 index 0000000..60855d3 --- /dev/null +++ b/html/pancax.networks.html @@ -0,0 +1,627 @@ + + + + + + + + + pancax.networks package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.networks package

+
+

Submodules

+
+
+

pancax.networks.elm module

+
+
+pancax.networks.elm.activation(x)[source]
+
+ +
+
+class pancax.networks.elm.ELM(n_inputs, n_outputs, n_neurons, key)[source]
+

Bases: Module

+
+
+__init__(n_inputs, n_outputs, n_neurons, key)[source]
+
+ +
+
+layer: any
+
+ +
+
+beta: any
+
+ +
+
+n_outputs: int
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.networks.elm.ELM2(layer: <built-in function any>, beta: <built-in function any>, n_outputs: int)[source]
+

Bases: Module

+
+
+layer: any
+
+ +
+
+__init__(layer: any, beta: any, n_outputs: int) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+beta: any
+
+ +
+
+n_outputs: int
+
+ +
+ +
+
+

pancax.networks.field_property_pair module

+
+
+class pancax.networks.field_property_pair.BasePancaxModel[source]
+

Bases: Module

+

Base class for pancax model parameters.

+

This includes a few helper methods

+
+
+serialise(base_name, epoch)[source]
+
+ +
+
+__init__() None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+class pancax.networks.field_property_pair.FieldPropertyPair(fields: Module, properties: Module)[source]
+

Bases: BasePancaxModel

+

Data structure for storing a set of field network +parameters and a set of material properties

+
+
Parameters:
+
    +
  • fields – field network parameters object

  • +
  • properties – property parameters object

  • +
+
+
+
+
+fields: Module
+
+ +
+
+properties: Module
+
+ +
+
+freeze_fields_filter()[source]
+
+ +
+
+freeze_props_filter()[source]
+
+ +
+
+__init__(fields: Module, properties: Module) None
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.networks.initialization module

+
+
+pancax.networks.initialization.zero_init(key: PRNGKey, shape) Float[Array, 'no ni'][source]
+
+
Parameters:
+
    +
  • weight – current weight array for sizing

  • +
  • key – rng key

  • +
+
+
Returns:
+

A new set of weights

+
+
+
+ +
+
+pancax.networks.initialization.trunc_init(key: PRNGKey, shape) Float[Array, 'no ni'][source]
+
+
Parameters:
+
    +
  • weight – current weight array for sizing

  • +
  • key – rng key

  • +
+
+
Returns:
+

A new set of weights

+
+
+
+ +
+
+pancax.networks.initialization.init_linear_weight(model: Module, init_fn: Callable, key: PRNGKey) Module[source]
+
+
Parameters:
+
    +
  • model – equinox model

  • +
  • init_fn – function to initialize weigth with

  • +
  • key – rng key

  • +
+
+
Returns:
+

a new equinox model

+
+
+
+ +
+
+pancax.networks.initialization.init_linear(model: Module, init_fn: Callable, key: PRNGKey)[source]
+
+
Parameters:
+
    +
  • model – equinox model

  • +
  • init_fn – function to initialize weigth with

  • +
  • key – rng key

  • +
+
+
Returns:
+

a new equinox model

+
+
+
+ +
+
+pancax.networks.initialization.box_init(layer: Linear, key: PRNGKey)[source]
+
+ +
+
+

pancax.networks.mlp module

+
+
+pancax.networks.mlp.Linear(n_inputs: int, n_outputs: int, key: PRNGKey)[source]
+
+
Parameters:
+
    +
  • n_inputs – Number of inputs to linear layer

  • +
  • n_outputs – Number of outputs of the linear layer

  • +
  • key – rng key

  • +
+
+
Returns:
+

Equinox Linear layer

+
+
+
+ +
+
+pancax.networks.mlp.MLP(n_inputs: int, n_outputs: int, n_neurons: int, n_layers: int, activation: ~typing.Callable, key: ~jax._src.random.PRNGKey, use_final_bias: bool | None = False, init_func: ~typing.Callable | None = <function trunc_init>)[source]
+
+
Parameters:
+
    +
  • n_inputs – Number of inputs to the MLP

  • +
  • n_outputs – Number of outputs of the MLP

  • +
  • n_neurons – Number of neurons in each hidden layer of the MLP

  • +
  • n_layers – Number of hidden layers in the MLP

  • +
  • activation – Activation function, e.g. tanh or relu

  • +
  • key – rng key

  • +
  • use_final_bias – Boolean for whether or not to use a bias +vector in the final layer

  • +
+
+
Returns:
+

Equinox MLP layer

+
+
+
+ +
+
+pancax.networks.mlp.MLPBasis(n_inputs: int, n_neurons: int, n_layers: int, activation: ~typing.Callable, key: ~jax._src.random.PRNGKey, init_func: ~typing.Callable | None = <function trunc_init>)[source]
+
+ +
+
+

pancax.networks.properties module

+
+
+class pancax.networks.properties.Properties(prop_mins: ~jax.Array, prop_maxs: ~jax.Array, key: ~jax._src.random.PRNGKey, activation_func: ~typing.Callable | None = <PjitFunction of <function sigmoid>>)[source]
+

Bases: Module

+
+
Parameters:
+
    +
  • prop_mins – Minimum allowable properties

  • +
  • prop_maxs – Maximum allowable properties

  • +
  • prop_params – Actual tunable parameters

  • +
+
+
+
+
+__init__(prop_mins: ~jax.Array, prop_maxs: ~jax.Array, key: ~jax._src.random.PRNGKey, activation_func: ~typing.Callable | None = <PjitFunction of <function sigmoid>>) None[source]
+
+
Parameters:
+
    +
  • prop_mins – Minimum allowable properties

  • +
  • prop_maxs – Maximum allowable properties

  • +
  • key – rng key

  • +
+
+
+
+ +
+
+prop_mins: Array
+
+ +
+
+prop_maxs: Array
+
+ +
+
+prop_params: Array
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+activation_func: Callable
+
+ +
+ +
+
+class pancax.networks.properties.FixedProperties(props: jax.Array)[source]
+

Bases: Properties

+
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+__init__(props: Array) None[source]
+
+
Parameters:
+

props – Property values to be fixed

+
+
+
+ +
+ +
+
+

pancax.networks.rbf module

+
+
+class pancax.networks.rbf.RBFBasis(n_inputs: int, n_neurons: int, key: <function PRNGKey at 0x7f19afe23880>)[source]
+

Bases: Module

+
+
+__init__(n_inputs: int, n_neurons: int, key: PRNGKey) None[source]
+
+ +
+
+center: Array
+
+ +
+
+sigma: Array
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+pancax.networks.rbf.rbf_normalization(hidden)[source]
+
+ +
+
+

Module contents

+
+
+pancax.networks.Network(network_type, *args, **kwargs)[source]
+
+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/pancax.optimizers.html b/html/pancax.optimizers.html new file mode 100644 index 0000000..901b077 --- /dev/null +++ b/html/pancax.optimizers.html @@ -0,0 +1,303 @@ + + + + + + + + + pancax.optimizers package — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

pancax.optimizers package

+
+

Submodules

+
+
+

pancax.optimizers.adam module

+
+
+class pancax.optimizers.adam.Adam(loss_function: Callable, has_aux: bool | None = False, jit: bool | None = True, learning_rate: float | None = 0.001, transition_steps: int | None = 500, decay_rate: float | None = 0.99, clip_gradients: bool | None = False, filter_spec: Callable | None = None)[source]
+

Bases: Optimizer

+
+
+__init__(loss_function: Callable, has_aux: bool | None = False, jit: bool | None = True, learning_rate: float | None = 0.001, transition_steps: int | None = 500, decay_rate: float | None = 0.99, clip_gradients: bool | None = False, filter_spec: Callable | None = None) None[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+
+make_step_method()[source]
+
+ +
+ +
+
+

pancax.optimizers.base module

+
+
+class pancax.optimizers.base.Optimizer(loss_function: Callable, has_aux: bool | None = False, jit: bool | None = True)[source]
+

Bases: ABC

+
+
+__init__(loss_function: Callable, has_aux: bool | None = False, jit: bool | None = True) None[source]
+
+ +
+
+abstract make_step_method(params)[source]
+
+ +
+
+ensemble_init(params)[source]
+
+ +
+
+ensemble_step_old(params, domain, opt_st)[source]
+
+ +
+
+init(params)[source]
+
+ +
+
+train(params, domain, times, opt, logger, history, pp, n_epochs, log_every: int | None = 100, serialise_every: int | None = 10000, postprocess_every: int | None = 10000)[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.optimizers.lbfgs module

+
+
+pancax.optimizers.lbfgs.value_and_grad_from_state(value_fn)[source]
+
+ +
+
+class pancax.optimizers.lbfgs.LBFGS(loss_function: Callable, has_aux: bool | None = False, jit: bool | None = False, learning_rate: float | None = 0.1)[source]
+

Bases: Optimizer

+
+
+__init__(loss_function: Callable, has_aux: bool | None = False, jit: bool | None = False, learning_rate: float | None = 0.1) None[source]
+
+ +
+
+make_step_method()[source]
+
+ +
+
+_abc_impl = <_abc._abc_data object>
+
+ +
+ +
+
+

pancax.optimizers.utils module

+
+
+pancax.optimizers.utils.trainable_filter(params: any, freeze_properties: bool | None = True, freeze_basis: bool | None = False)[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/html/py-modindex.html b/html/py-modindex.html new file mode 100644 index 0000000..7b12197 --- /dev/null +++ b/html/py-modindex.html @@ -0,0 +1,528 @@ + + + + + + + + Python Module Index — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Python Module Index

+ +
+ p +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ p
+ pancax +
    + pancax.bcs +
    + pancax.bcs.distance_functions +
    + pancax.bcs.essential_bc +
    + pancax.bcs.natural_bc +
    + pancax.bvps +
    + pancax.bvps.biaxial_tension +
    + pancax.bvps.simple_shear +
    + pancax.bvps.uniaxial_tension +
    + pancax.constitutive_models +
    + pancax.constitutive_models.base_constitutive_model +
    + pancax.constitutive_models.blatz_ko +
    + pancax.constitutive_models.gent +
    + pancax.constitutive_models.neohookean +
    + pancax.constitutive_models.swanson +
    + pancax.data +
    + pancax.data.full_field_data +
    + pancax.data.global_data +
    + pancax.domains +
    + pancax.domains.base_domain +
    + pancax.domains.collocation_domain +
    + pancax.domains.delta_pinn_domain +
    + pancax.domains.inverse_domain +
    + pancax.domains.utils +
    + pancax.domains.variational_domain +
    + pancax.fem +
    + pancax.fem.dof_manager +
    + pancax.fem.elements +
    + pancax.fem.elements.base_element +
    + pancax.fem.elements.hex8_element +
    + pancax.fem.elements.line_element +
    + pancax.fem.elements.quad4_element +
    + pancax.fem.elements.quad9_element +
    + pancax.fem.elements.simplex_tri_element +
    + pancax.fem.elements.tet10_element +
    + pancax.fem.elements.tet4_element +
    + pancax.fem.function_space +
    + pancax.fem.mesh +
    + pancax.fem.quadrature_rules +
    + pancax.fem.read_exodus_mesh +
    + pancax.fem.sparse_matrix_assembler +
    + pancax.fem.surface +
    + pancax.fem.traction_bc +
    + pancax.history_writer +
    + pancax.kernels +
    + pancax.kernels.base_kernel +
    + pancax.kernels.laplace_beltrami +
    + pancax.kernels.linear_elasticity +
    + pancax.kernels.poisson +
    + pancax.kernels.solid_mechanics +
    + pancax.kinematics +
    + pancax.logging +
    + pancax.loss_functions +
    + pancax.loss_functions.base_loss_function +
    + pancax.loss_functions.bc_loss_functions +
    + pancax.loss_functions.data_loss_functions +
    + pancax.loss_functions.physics_loss_functions_strong_form +
    + pancax.loss_functions.strong_form_loss_functions +
    + pancax.loss_functions.utils +
    + pancax.loss_functions.weak_form_loss_functions +
    + pancax.math +
    + pancax.math.math +
    + pancax.math.tensor_math +
    + pancax.networks +
    + pancax.networks.elm +
    + pancax.networks.field_property_pair +
    + pancax.networks.initialization +
    + pancax.networks.mlp +
    + pancax.networks.properties +
    + pancax.networks.rbf +
    + pancax.optimizers +
    + pancax.optimizers.adam +
    + pancax.optimizers.base +
    + pancax.optimizers.lbfgs +
    + pancax.optimizers.utils +
    + pancax.physics +
    + pancax.post_processor +
    + pancax.timer +
    + pancax.trainer +
    + pancax.utils +
+ + +
+
+
+ +
+ +
+

© Copyright 2024, Craig M. Hamel.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/html/search.html b/html/search.html new file mode 100644 index 0000000..44afde0 --- /dev/null +++ b/html/search.html @@ -0,0 +1,133 @@ + + + + + + + + Search — pancax 0.0.2 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2024, Craig M. Hamel.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/html/searchindex.js b/html/searchindex.js new file mode 100644 index 0000000..5760784 --- /dev/null +++ b/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Indices and tables": [[0, "indices-and-tables"]], "Module contents": [[2, "module-pancax"], [3, "module-pancax.bcs"], [4, "module-pancax.bvps"], [5, "module-pancax.constitutive_models"], [6, "module-pancax.data"], [7, "module-pancax.domains"], [8, "module-pancax.fem"], [9, "module-pancax.fem.elements"], [10, "module-pancax.kernels"], [11, "module-pancax.loss_functions"], [12, "module-pancax.math"], [13, "module-pancax.networks"], [14, "module-pancax.optimizers"]], "Pancax": [[0, null]], "Submodules": [[2, "submodules"], [3, "submodules"], [4, "submodules"], [5, "submodules"], [6, "submodules"], [7, "submodules"], [8, "submodules"], [9, "submodules"], [10, "submodules"], [11, "submodules"], [12, "submodules"], [13, "submodules"], [14, "submodules"]], "Subpackages": [[2, "subpackages"], [8, "subpackages"]], "pancax": [[1, null]], "pancax package": [[2, null]], "pancax.__main__ module": [[2, "pancax-main-module"]], "pancax.bcs package": [[3, null]], "pancax.bcs.distance_functions module": [[3, "module-pancax.bcs.distance_functions"]], "pancax.bcs.essential_bc module": [[3, "module-pancax.bcs.essential_bc"]], "pancax.bcs.natural_bc module": [[3, "module-pancax.bcs.natural_bc"]], "pancax.bvps package": [[4, null]], "pancax.bvps.biaxial_tension module": [[4, "module-pancax.bvps.biaxial_tension"]], "pancax.bvps.simple_shear module": [[4, "module-pancax.bvps.simple_shear"]], "pancax.bvps.uniaxial_tension module": [[4, "module-pancax.bvps.uniaxial_tension"]], "pancax.constitutive_models package": [[5, null]], "pancax.constitutive_models.base_constitutive_model module": [[5, "module-pancax.constitutive_models.base_constitutive_model"]], "pancax.constitutive_models.blatz_ko module": [[5, "module-pancax.constitutive_models.blatz_ko"]], "pancax.constitutive_models.gent module": [[5, "module-pancax.constitutive_models.gent"]], "pancax.constitutive_models.neohookean module": [[5, "module-pancax.constitutive_models.neohookean"]], "pancax.constitutive_models.swanson module": [[5, "module-pancax.constitutive_models.swanson"]], "pancax.data package": [[6, null]], "pancax.data.full_field_data module": [[6, "module-pancax.data.full_field_data"]], "pancax.data.global_data module": [[6, "module-pancax.data.global_data"]], "pancax.domains package": [[7, null]], "pancax.domains.base_domain module": [[7, "module-pancax.domains.base_domain"]], "pancax.domains.collocation_domain module": [[7, "module-pancax.domains.collocation_domain"]], "pancax.domains.delta_pinn_domain module": [[7, "module-pancax.domains.delta_pinn_domain"]], "pancax.domains.inverse_domain module": [[7, "module-pancax.domains.inverse_domain"]], "pancax.domains.utils module": [[7, "module-pancax.domains.utils"]], "pancax.domains.variational_domain module": [[7, "module-pancax.domains.variational_domain"]], "pancax.fem package": [[8, null]], "pancax.fem.dof_manager module": [[8, "module-pancax.fem.dof_manager"]], "pancax.fem.elements package": [[9, null]], "pancax.fem.elements.base_element module": [[9, "module-pancax.fem.elements.base_element"]], "pancax.fem.elements.hex8_element module": [[9, "module-pancax.fem.elements.hex8_element"]], "pancax.fem.elements.line_element module": [[9, "module-pancax.fem.elements.line_element"]], "pancax.fem.elements.quad4_element module": [[9, "module-pancax.fem.elements.quad4_element"]], "pancax.fem.elements.quad9_element module": [[9, "module-pancax.fem.elements.quad9_element"]], "pancax.fem.elements.simplex_tri_element module": [[9, "module-pancax.fem.elements.simplex_tri_element"]], "pancax.fem.elements.tet10_element module": [[9, "module-pancax.fem.elements.tet10_element"]], "pancax.fem.elements.tet4_element module": [[9, "module-pancax.fem.elements.tet4_element"]], "pancax.fem.function_space module": [[8, "module-pancax.fem.function_space"]], "pancax.fem.mesh module": [[8, "module-pancax.fem.mesh"]], "pancax.fem.quadrature_rules module": [[8, "module-pancax.fem.quadrature_rules"]], "pancax.fem.read_exodus_mesh module": [[8, "module-pancax.fem.read_exodus_mesh"]], "pancax.fem.sparse_matrix_assembler module": [[8, "module-pancax.fem.sparse_matrix_assembler"]], "pancax.fem.surface module": [[8, "module-pancax.fem.surface"]], "pancax.fem.traction_bc module": [[8, "module-pancax.fem.traction_bc"]], "pancax.history_writer module": [[2, "module-pancax.history_writer"]], "pancax.kernels package": [[10, null]], "pancax.kernels.base_kernel module": [[10, "module-pancax.kernels.base_kernel"]], "pancax.kernels.laplace_beltrami module": [[10, "module-pancax.kernels.laplace_beltrami"]], "pancax.kernels.linear_elasticity module": [[10, "module-pancax.kernels.linear_elasticity"]], "pancax.kernels.poisson module": [[10, "module-pancax.kernels.poisson"]], "pancax.kernels.solid_mechanics module": [[10, "module-pancax.kernels.solid_mechanics"]], "pancax.kinematics module": [[2, "module-pancax.kinematics"]], "pancax.logging module": [[2, "module-pancax.logging"]], "pancax.loss_functions package": [[11, null]], "pancax.loss_functions.base_loss_function module": [[11, "module-pancax.loss_functions.base_loss_function"]], "pancax.loss_functions.bc_loss_functions module": [[11, "module-pancax.loss_functions.bc_loss_functions"]], "pancax.loss_functions.data_loss_functions module": [[11, "module-pancax.loss_functions.data_loss_functions"]], "pancax.loss_functions.physics_loss_functions_strong_form module": [[11, "module-pancax.loss_functions.physics_loss_functions_strong_form"]], "pancax.loss_functions.strong_form_loss_functions module": [[11, "module-pancax.loss_functions.strong_form_loss_functions"]], "pancax.loss_functions.utils module": [[11, "module-pancax.loss_functions.utils"]], "pancax.loss_functions.weak_form_loss_functions module": [[11, "module-pancax.loss_functions.weak_form_loss_functions"]], "pancax.math package": [[12, null]], "pancax.math.math module": [[12, "module-pancax.math.math"]], "pancax.math.tensor_math module": [[12, "module-pancax.math.tensor_math"]], "pancax.networks package": [[13, null]], "pancax.networks.elm module": [[13, "module-pancax.networks.elm"]], "pancax.networks.field_property_pair module": [[13, "module-pancax.networks.field_property_pair"]], "pancax.networks.initialization module": [[13, "module-pancax.networks.initialization"]], "pancax.networks.mlp module": [[13, "module-pancax.networks.mlp"]], "pancax.networks.properties module": [[13, "module-pancax.networks.properties"]], "pancax.networks.rbf module": [[13, "module-pancax.networks.rbf"]], "pancax.optimizers package": [[14, null]], "pancax.optimizers.adam module": [[14, "module-pancax.optimizers.adam"]], "pancax.optimizers.base module": [[14, "module-pancax.optimizers.base"]], "pancax.optimizers.lbfgs module": [[14, "module-pancax.optimizers.lbfgs"]], "pancax.optimizers.utils module": [[14, "module-pancax.optimizers.utils"]], "pancax.physics module": [[2, "module-pancax.physics"]], "pancax.post_processor module": [[2, "module-pancax.post_processor"]], "pancax.timer module": [[2, "module-pancax.timer"]], "pancax.trainer module": [[2, "module-pancax.trainer"]], "pancax.utils module": [[2, "module-pancax.utils"]]}, "docnames": ["index", "modules", "pancax", "pancax.bcs", "pancax.bvps", "pancax.constitutive_models", "pancax.data", "pancax.domains", "pancax.fem", "pancax.fem.elements", "pancax.kernels", "pancax.loss_functions", "pancax.math", "pancax.networks", "pancax.optimizers"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1}, "filenames": ["index.rst", "modules.rst", "pancax.rst", "pancax.bcs.rst", "pancax.bvps.rst", "pancax.constitutive_models.rst", "pancax.data.rst", "pancax.domains.rst", "pancax.fem.rst", "pancax.fem.elements.rst", "pancax.kernels.rst", "pancax.loss_functions.rst", "pancax.math.rst", "pancax.networks.rst", "pancax.optimizers.rst"], "indexentries": {"__init__() (pancax.bcs.essential_bc.essentialbc method)": [[3, "pancax.bcs.essential_bc.EssentialBC.__init__", false]], "__init__() (pancax.bcs.essential_bc.essentialbcset method)": [[3, "pancax.bcs.essential_bc.EssentialBCSet.__init__", false]], "__init__() (pancax.bcs.natural_bc.naturalbc method)": [[3, "pancax.bcs.natural_bc.NaturalBC.__init__", false]], "__init__() (pancax.constitutive_models.base_constitutive_model.constitutivemodelfixedbulkmodulus method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus.__init__", false]], "__init__() (pancax.constitutive_models.swanson.swanson4 method)": [[5, "pancax.constitutive_models.swanson.Swanson4.__init__", false]], "__init__() (pancax.constitutive_models.swanson.swanson4fixedbulkmodulus method)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus.__init__", false]], "__init__() (pancax.constitutive_models.swanson.swanson6 method)": [[5, "pancax.constitutive_models.swanson.Swanson6.__init__", false]], "__init__() (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus method)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus.__init__", false]], "__init__() (pancax.data.full_field_data.fullfielddata method)": [[6, "pancax.data.full_field_data.FullFieldData.__init__", false]], "__init__() (pancax.data.global_data.globaldata method)": [[6, "pancax.data.global_data.GlobalData.__init__", false]], "__init__() (pancax.domains.base_domain.basedomain method)": [[7, "pancax.domains.base_domain.BaseDomain.__init__", false]], "__init__() (pancax.domains.collocation_domain.collocationdomain method)": [[7, "pancax.domains.collocation_domain.CollocationDomain.__init__", false]], "__init__() (pancax.domains.delta_pinn_domain.deltapinndomain method)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.__init__", false]], "__init__() (pancax.domains.inverse_domain.inversedomain method)": [[7, "pancax.domains.inverse_domain.InverseDomain.__init__", false]], "__init__() (pancax.domains.variational_domain.variationaldomain method)": [[7, "pancax.domains.variational_domain.VariationalDomain.__init__", false]], "__init__() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.__init__", false]], "__init__() (pancax.fem.elements.base_element.baseelement method)": [[9, "pancax.fem.elements.base_element.BaseElement.__init__", false]], "__init__() (pancax.fem.elements.hex8_element.hex8element method)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.__init__", false]], "__init__() (pancax.fem.elements.line_element.lineelement method)": [[9, "pancax.fem.elements.line_element.LineElement.__init__", false]], "__init__() (pancax.fem.elements.quad4_element.quad4element method)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.__init__", false]], "__init__() (pancax.fem.elements.quad9_element.quad9element method)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.__init__", false]], "__init__() (pancax.fem.elements.simplex_tri_element.simplextrielement method)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.__init__", false]], "__init__() (pancax.fem.elements.tet10_element.tet10element method)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.__init__", false]], "__init__() (pancax.fem.elements.tet4_element.tet4element method)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.__init__", false]], "__init__() (pancax.fem.function_space.functionspace method)": [[8, "pancax.fem.function_space.FunctionSpace.__init__", false]], "__init__() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.__init__", false]], "__init__() (pancax.fem.mesh.mesh method)": [[8, "pancax.fem.mesh.Mesh.__init__", false]], "__init__() (pancax.fem.quadrature_rules.quadraturerule method)": [[8, "pancax.fem.quadrature_rules.QuadratureRule.__init__", false]], "__init__() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.__init__", false]], "__init__() (pancax.history_writer.ensemblehistorywriter method)": [[2, "pancax.history_writer.EnsembleHistoryWriter.__init__", false]], "__init__() (pancax.history_writer.historywriter method)": [[2, "pancax.history_writer.HistoryWriter.__init__", false]], "__init__() (pancax.kernels.base_kernel.physicskernel method)": [[10, "pancax.kernels.base_kernel.PhysicsKernel.__init__", false]], "__init__() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.__init__", false]], "__init__() (pancax.kernels.base_kernel.weakformphysicskernel method)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.__init__", false]], "__init__() (pancax.kernels.laplace_beltrami.laplacebeltrami method)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami.__init__", false]], "__init__() (pancax.kernels.linear_elasticity.linearelasticity2d method)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.__init__", false]], "__init__() (pancax.kernels.poisson.poisson method)": [[10, "pancax.kernels.poisson.Poisson.__init__", false]], "__init__() (pancax.kernels.solid_mechanics.incompressibleplanestress method)": [[10, "pancax.kernels.solid_mechanics.IncompressiblePlaneStress.__init__", false]], "__init__() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.__init__", false]], "__init__() (pancax.logging.baselogger method)": [[2, "pancax.logging.BaseLogger.__init__", false]], "__init__() (pancax.logging.ensemblelogger method)": [[2, "pancax.logging.EnsembleLogger.__init__", false]], "__init__() (pancax.logging.logger method)": [[2, "pancax.logging.Logger.__init__", false]], "__init__() (pancax.loss_functions.base_loss_function.baselossfunction method)": [[11, "pancax.loss_functions.base_loss_function.BaseLossFunction.__init__", false]], "__init__() (pancax.loss_functions.base_loss_function.bclossfunction method)": [[11, "pancax.loss_functions.base_loss_function.BCLossFunction.__init__", false]], "__init__() (pancax.loss_functions.base_loss_function.physicslossfunction method)": [[11, "pancax.loss_functions.base_loss_function.PhysicsLossFunction.__init__", false]], "__init__() (pancax.loss_functions.bc_loss_functions.dirichletbcloss method)": [[11, "pancax.loss_functions.bc_loss_functions.DirichletBCLoss.__init__", false]], "__init__() (pancax.loss_functions.bc_loss_functions.neumannbcloss method)": [[11, "pancax.loss_functions.bc_loss_functions.NeumannBCLoss.__init__", false]], "__init__() (pancax.loss_functions.data_loss_functions.fullfielddataloss method)": [[11, "pancax.loss_functions.data_loss_functions.FullFieldDataLoss.__init__", false]], "__init__() (pancax.loss_functions.strong_form_loss_functions.strongformresidualloss method)": [[11, "pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss.__init__", false]], "__init__() (pancax.loss_functions.utils.combinelossfunctions method)": [[11, "pancax.loss_functions.utils.CombineLossFunctions.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.energyandresidualloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.energyloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyLoss.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.energyresidualandreactionloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyandresidualloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.quadratureincompressibilityconstraint method)": [[11, "pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint.__init__", false]], "__init__() (pancax.loss_functions.weak_form_loss_functions.residualmseloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss.__init__", false]], "__init__() (pancax.networks.elm.elm method)": [[13, "pancax.networks.elm.ELM.__init__", false]], "__init__() (pancax.networks.elm.elm2 method)": [[13, "pancax.networks.elm.ELM2.__init__", false]], "__init__() (pancax.networks.field_property_pair.basepancaxmodel method)": [[13, "pancax.networks.field_property_pair.BasePancaxModel.__init__", false]], "__init__() (pancax.networks.field_property_pair.fieldpropertypair method)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair.__init__", false]], "__init__() (pancax.networks.properties.fixedproperties method)": [[13, "pancax.networks.properties.FixedProperties.__init__", false]], "__init__() (pancax.networks.properties.properties method)": [[13, "pancax.networks.properties.Properties.__init__", false]], "__init__() (pancax.networks.rbf.rbfbasis method)": [[13, "pancax.networks.rbf.RBFBasis.__init__", false]], "__init__() (pancax.optimizers.adam.adam method)": [[14, "pancax.optimizers.adam.Adam.__init__", false]], "__init__() (pancax.optimizers.base.optimizer method)": [[14, "pancax.optimizers.base.Optimizer.__init__", false]], "__init__() (pancax.optimizers.lbfgs.lbfgs method)": [[14, "pancax.optimizers.lbfgs.LBFGS.__init__", false]], "__init__() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.__init__", false]], "__init__() (pancax.timer.timer method)": [[2, "pancax.timer.Timer.__init__", false]], "__init__() (pancax.trainer.trainer method)": [[2, "pancax.trainer.Trainer.__init__", false]], "_abc_impl (pancax.bcs.essential_bc.essentialbc attribute)": [[3, "pancax.bcs.essential_bc.EssentialBC._abc_impl", false]], "_abc_impl (pancax.bcs.essential_bc.essentialbcset attribute)": [[3, "pancax.bcs.essential_bc.EssentialBCSet._abc_impl", false]], "_abc_impl (pancax.bcs.natural_bc.naturalbc attribute)": [[3, "pancax.bcs.natural_bc.NaturalBC._abc_impl", false]], "_abc_impl (pancax.constitutive_models.base_constitutive_model.constitutivemodel attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel._abc_impl", false]], "_abc_impl (pancax.constitutive_models.base_constitutive_model.constitutivemodelfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus._abc_impl", false]], "_abc_impl (pancax.constitutive_models.blatz_ko.blatzko attribute)": [[5, "pancax.constitutive_models.blatz_ko.BlatzKo._abc_impl", false]], "_abc_impl (pancax.constitutive_models.gent.gent attribute)": [[5, "pancax.constitutive_models.gent.Gent._abc_impl", false]], "_abc_impl (pancax.constitutive_models.gent.gentfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.gent.GentFixedBulkModulus._abc_impl", false]], "_abc_impl (pancax.constitutive_models.neohookean.neohookean attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookean._abc_impl", false]], "_abc_impl (pancax.constitutive_models.neohookean.neohookeanfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus._abc_impl", false]], "_abc_impl (pancax.constitutive_models.swanson.swanson4 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4._abc_impl", false]], "_abc_impl (pancax.constitutive_models.swanson.swanson4fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus._abc_impl", false]], "_abc_impl (pancax.constitutive_models.swanson.swanson6 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6._abc_impl", false]], "_abc_impl (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus._abc_impl", false]], "_abc_impl (pancax.data.full_field_data.fullfielddata attribute)": [[6, "pancax.data.full_field_data.FullFieldData._abc_impl", false]], "_abc_impl (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData._abc_impl", false]], "_abc_impl (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain._abc_impl", false]], "_abc_impl (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain._abc_impl", false]], "_abc_impl (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain._abc_impl", false]], "_abc_impl (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain._abc_impl", false]], "_abc_impl (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain._abc_impl", false]], "_abc_impl (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement._abc_impl", false]], "_abc_impl (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element._abc_impl", false]], "_abc_impl (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement._abc_impl", false]], "_abc_impl (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element._abc_impl", false]], "_abc_impl (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element._abc_impl", false]], "_abc_impl (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement._abc_impl", false]], "_abc_impl (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element._abc_impl", false]], "_abc_impl (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element._abc_impl", false]], "_abc_impl (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace._abc_impl", false]], "_abc_impl (pancax.fem.function_space.nonallocatedfunctionspace attribute)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace._abc_impl", false]], "_abc_impl (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh._abc_impl", false]], "_abc_impl (pancax.fem.quadrature_rules.quadraturerule attribute)": [[8, "pancax.fem.quadrature_rules.QuadratureRule._abc_impl", false]], "_abc_impl (pancax.history_writer.basehistorywriter attribute)": [[2, "pancax.history_writer.BaseHistoryWriter._abc_impl", false]], "_abc_impl (pancax.history_writer.ensemblehistorywriter attribute)": [[2, "pancax.history_writer.EnsembleHistoryWriter._abc_impl", false]], "_abc_impl (pancax.history_writer.historywriter attribute)": [[2, "pancax.history_writer.HistoryWriter._abc_impl", false]], "_abc_impl (pancax.kernels.base_kernel.physicskernel attribute)": [[10, "pancax.kernels.base_kernel.PhysicsKernel._abc_impl", false]], "_abc_impl (pancax.kernels.base_kernel.strongformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel._abc_impl", false]], "_abc_impl (pancax.kernels.base_kernel.weakformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel._abc_impl", false]], "_abc_impl (pancax.kernels.laplace_beltrami.laplacebeltrami attribute)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami._abc_impl", false]], "_abc_impl (pancax.kernels.linear_elasticity.linearelasticity2d attribute)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D._abc_impl", false]], "_abc_impl (pancax.kernels.poisson.poisson attribute)": [[10, "pancax.kernels.poisson.Poisson._abc_impl", false]], "_abc_impl (pancax.kernels.solid_mechanics.basemechanicsformulation attribute)": [[10, "pancax.kernels.solid_mechanics.BaseMechanicsFormulation._abc_impl", false]], "_abc_impl (pancax.kernels.solid_mechanics.incompressibleplanestress attribute)": [[10, "pancax.kernels.solid_mechanics.IncompressiblePlaneStress._abc_impl", false]], "_abc_impl (pancax.kernels.solid_mechanics.planestrain attribute)": [[10, "pancax.kernels.solid_mechanics.PlaneStrain._abc_impl", false]], "_abc_impl (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics._abc_impl", false]], "_abc_impl (pancax.kernels.solid_mechanics.threedimensional attribute)": [[10, "pancax.kernels.solid_mechanics.ThreeDimensional._abc_impl", false]], "_abc_impl (pancax.logging.baselogger attribute)": [[2, "pancax.logging.BaseLogger._abc_impl", false]], "_abc_impl (pancax.logging.ensemblelogger attribute)": [[2, "pancax.logging.EnsembleLogger._abc_impl", false]], "_abc_impl (pancax.logging.logger attribute)": [[2, "pancax.logging.Logger._abc_impl", false]], "_abc_impl (pancax.loss_functions.base_loss_function.baselossfunction attribute)": [[11, "pancax.loss_functions.base_loss_function.BaseLossFunction._abc_impl", false]], "_abc_impl (pancax.loss_functions.base_loss_function.bclossfunction attribute)": [[11, "pancax.loss_functions.base_loss_function.BCLossFunction._abc_impl", false]], "_abc_impl (pancax.loss_functions.base_loss_function.physicslossfunction attribute)": [[11, "pancax.loss_functions.base_loss_function.PhysicsLossFunction._abc_impl", false]], "_abc_impl (pancax.loss_functions.bc_loss_functions.dirichletbcloss attribute)": [[11, "pancax.loss_functions.bc_loss_functions.DirichletBCLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.bc_loss_functions.neumannbcloss attribute)": [[11, "pancax.loss_functions.bc_loss_functions.NeumannBCLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.data_loss_functions.fullfielddataloss attribute)": [[11, "pancax.loss_functions.data_loss_functions.FullFieldDataLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.strong_form_loss_functions.strongformresidualloss attribute)": [[11, "pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.utils.combinelossfunctions attribute)": [[11, "pancax.loss_functions.utils.CombineLossFunctions._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.energyandresidualloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.energyloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.energyresidualandreactionloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyandresidualloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.quadratureincompressibilityconstraint attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint._abc_impl", false]], "_abc_impl (pancax.loss_functions.weak_form_loss_functions.residualmseloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss._abc_impl", false]], "_abc_impl (pancax.networks.elm.elm attribute)": [[13, "pancax.networks.elm.ELM._abc_impl", false]], "_abc_impl (pancax.networks.elm.elm2 attribute)": [[13, "pancax.networks.elm.ELM2._abc_impl", false]], "_abc_impl (pancax.networks.field_property_pair.basepancaxmodel attribute)": [[13, "pancax.networks.field_property_pair.BasePancaxModel._abc_impl", false]], "_abc_impl (pancax.networks.field_property_pair.fieldpropertypair attribute)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair._abc_impl", false]], "_abc_impl (pancax.networks.properties.fixedproperties attribute)": [[13, "pancax.networks.properties.FixedProperties._abc_impl", false]], "_abc_impl (pancax.networks.properties.properties attribute)": [[13, "pancax.networks.properties.Properties._abc_impl", false]], "_abc_impl (pancax.networks.rbf.rbfbasis attribute)": [[13, "pancax.networks.rbf.RBFBasis._abc_impl", false]], "_abc_impl (pancax.optimizers.adam.adam attribute)": [[14, "pancax.optimizers.adam.Adam._abc_impl", false]], "_abc_impl (pancax.optimizers.base.optimizer attribute)": [[14, "pancax.optimizers.base.Optimizer._abc_impl", false]], "_abc_impl (pancax.optimizers.lbfgs.lbfgs attribute)": [[14, "pancax.optimizers.lbfgs.LBFGS._abc_impl", false]], "_asdict() (pancax.fem.elements.base_element.shapefunctions method)": [[9, "pancax.fem.elements.base_element.ShapeFunctions._asdict", false]], "_field_defaults (pancax.fem.elements.base_element.shapefunctions attribute)": [[9, "pancax.fem.elements.base_element.ShapeFunctions._field_defaults", false]], "_fields (pancax.fem.elements.base_element.shapefunctions attribute)": [[9, "pancax.fem.elements.base_element.ShapeFunctions._fields", false]], "_float_split() (in module pancax.math.math)": [[12, "pancax.math.math._float_split", false]], "_gauss_quad_1d_1pt() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules._gauss_quad_1D_1pt", false]], "_gauss_quad_1d_2pt() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules._gauss_quad_1D_2pt", false]], "_gauss_quad_1d_3pt() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules._gauss_quad_1D_3pt", false]], "_gauss_quad_1d_4pt() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules._gauss_quad_1D_4pt", false]], "_gauss_quad_1d_5pt() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules._gauss_quad_1D_5pt", false]], "_get_vertex_nodes_from_exodus_tri6_mesh() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._get_vertex_nodes_from_exodus_tri6_mesh", false]], "_logm_iss() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math._logm_iss", false]], "_make() (pancax.fem.elements.base_element.shapefunctions class method)": [[9, "pancax.fem.elements.base_element.ShapeFunctions._make", false]], "_make_hessian_bc_mask() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager._make_hessian_bc_mask", false]], "_make_hessian_coordinates() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager._make_hessian_coordinates", false]], "_read_block_conns() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_block_conns", false]], "_read_blocks() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_blocks", false]], "_read_coordinates() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_coordinates", false]], "_read_element_type() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_element_type", false]], "_read_names_list() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_names_list", false]], "_read_node_sets() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_node_sets", false]], "_read_side_sets() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh._read_side_sets", false]], "_replace() (pancax.fem.elements.base_element.shapefunctions method)": [[9, "pancax.fem.elements.base_element.ShapeFunctions._replace", false]], "_start_time (pancax.timer.timer attribute)": [[2, "pancax.timer.Timer._start_time", false]], "_two_product() (in module pancax.math.math)": [[12, "pancax.math.math._two_product", false]], "_two_sum() (in module pancax.math.math)": [[12, "pancax.math.math._two_sum", false]], "_write_loss() (pancax.history_writer.historywriter method)": [[2, "pancax.history_writer.HistoryWriter._write_loss", false]], "activation() (in module pancax.networks.elm)": [[13, "pancax.networks.elm.activation", false]], "activation_func (pancax.networks.properties.properties attribute)": [[13, "pancax.networks.properties.Properties.activation_func", false]], "adam (class in pancax.optimizers.adam)": [[14, "pancax.optimizers.adam.Adam", false]], "assemble_sparse_stiffness_matrix() (in module pancax.fem.sparse_matrix_assembler)": [[8, "pancax.fem.sparse_matrix_assembler.assemble_sparse_stiffness_matrix", false]], "average_quadrature_field_over_element() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.average_quadrature_field_over_element", false]], "basedomain (class in pancax.domains.base_domain)": [[7, "pancax.domains.base_domain.BaseDomain", false]], "baseelement (class in pancax.fem.elements.base_element)": [[9, "pancax.fem.elements.base_element.BaseElement", false]], "basehistorywriter (class in pancax.history_writer)": [[2, "pancax.history_writer.BaseHistoryWriter", false]], "baselogger (class in pancax.logging)": [[2, "pancax.logging.BaseLogger", false]], "baselossfunction (class in pancax.loss_functions.base_loss_function)": [[11, "pancax.loss_functions.base_loss_function.BaseLossFunction", false]], "basemechanicsformulation (class in pancax.kernels.solid_mechanics)": [[10, "pancax.kernels.solid_mechanics.BaseMechanicsFormulation", false]], "basepancaxmodel (class in pancax.networks.field_property_pair)": [[13, "pancax.networks.field_property_pair.BasePancaxModel", false]], "bc_func (pancax.kernels.base_kernel.physicskernel attribute)": [[10, "pancax.kernels.base_kernel.PhysicsKernel.bc_func", false]], "bc_func (pancax.kernels.base_kernel.strongformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.bc_func", false]], "bc_func (pancax.kernels.base_kernel.weakformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.bc_func", false]], "bc_func (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.bc_func", false]], "bclossfunction (class in pancax.loss_functions.base_loss_function)": [[11, "pancax.loss_functions.base_loss_function.BCLossFunction", false]], "bcs (pancax.bcs.essential_bc.essentialbcset attribute)": [[3, "pancax.bcs.essential_bc.EssentialBCSet.bcs", false]], "beta (pancax.networks.elm.elm attribute)": [[13, "pancax.networks.elm.ELM.beta", false]], "beta (pancax.networks.elm.elm2 attribute)": [[13, "pancax.networks.elm.ELM2.beta", false]], "biaxiallinearramp() (in module pancax.bvps.biaxial_tension)": [[4, "pancax.bvps.biaxial_tension.BiaxialLinearRamp", false]], "blatzko (class in pancax.constitutive_models.blatz_ko)": [[5, "pancax.constitutive_models.blatz_ko.BlatzKo", false]], "blocks (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.blocks", false]], "box_init() (in module pancax.networks.initialization)": [[13, "pancax.networks.initialization.box_init", false]], "bulk_modulus (pancax.constitutive_models.base_constitutive_model.constitutivemodelfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus.bulk_modulus", false]], "bulk_modulus (pancax.constitutive_models.gent.gentfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.gent.GentFixedBulkModulus.bulk_modulus", false]], "bulk_modulus (pancax.constitutive_models.neohookean.neohookeanfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus.bulk_modulus", false]], "bulk_modulus (pancax.constitutive_models.swanson.swanson4fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus.bulk_modulus", false]], "bulk_modulus (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus.bulk_modulus", false]], "cauchy_stress() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.cauchy_stress", false]], "cauchy_stress() (pancax.kernels.linear_elasticity.linearelasticity2d method)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.cauchy_stress", false]], "center (pancax.networks.rbf.rbfbasis attribute)": [[13, "pancax.networks.rbf.RBFBasis.center", false]], "check_variable_names() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.check_variable_names", false]], "close() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.close", false]], "collocationdomain (class in pancax.domains.collocation_domain)": [[7, "pancax.domains.collocation_domain.CollocationDomain", false]], "combine_blocks() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.combine_blocks", false]], "combine_mesh() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.combine_mesh", false]], "combine_nodesets() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.combine_nodesets", false]], "combine_sidesets() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.combine_sidesets", false]], "combinelossfunctions (class in pancax.loss_functions.utils)": [[11, "pancax.loss_functions.utils.CombineLossFunctions", false]], "component (pancax.bcs.essential_bc.essentialbc attribute)": [[3, "pancax.bcs.essential_bc.EssentialBC.component", false]], "compute_deviatoric_tensor() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.compute_deviatoric_tensor", false]], "compute_edge_vectors() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.compute_edge_vectors", false]], "compute_edge_vectors() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.compute_edge_vectors", false]], "compute_element_field_gradient() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.compute_element_field_gradient", false]], "compute_element_volumes() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.compute_element_volumes", false]], "compute_element_volumes_axisymmetric() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.compute_element_volumes_axisymmetric", false]], "compute_field_gradient() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.compute_field_gradient", false]], "compute_field_gradient() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.compute_field_gradient", false]], "compute_normal() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.compute_normal", false]], "compute_quadrature_point_field_gradient() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.compute_quadrature_point_field_gradient", false]], "compute_shapes() (pancax.fem.elements.base_element.baseelement method)": [[9, "pancax.fem.elements.base_element.BaseElement.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.hex8_element.hex8element method)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.line_element.lineelement method)": [[9, "pancax.fem.elements.line_element.LineElement.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.quad4_element.quad4element method)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.quad9_element.quad9element method)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.simplex_tri_element.simplextrielement method)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.tet10_element.tet10element method)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.compute_shapes", false]], "compute_shapes() (pancax.fem.elements.tet4_element.tet4element method)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.compute_shapes", false]], "compute_traction_potential_energy() (in module pancax.fem.traction_bc)": [[8, "pancax.fem.traction_bc.compute_traction_potential_energy", false]], "compute_traction_potential_energy_on_edge() (in module pancax.fem.traction_bc)": [[8, "pancax.fem.traction_bc.compute_traction_potential_energy_on_edge", false]], "conns (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.conns", false]], "conns (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.conns", false]], "conns (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.conns", false]], "conns (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace.conns", false]], "conns (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.conns", false]], "constitutive_model (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.constitutive_model", false]], "constitutivemodel (class in pancax.constitutive_models.base_constitutive_model)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel", false]], "constitutivemodelfixedbulkmodulus (class in pancax.constitutive_models.base_constitutive_model)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus", false]], "construct_function_space() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.construct_function_space", false]], "construct_function_space_from_parent_element() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.construct_function_space_from_parent_element", false]], "construct_mesh_from_basic_data() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.construct_mesh_from_basic_data", false]], "construct_structured_mesh() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.construct_structured_mesh", false]], "coordinates (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement.coordinates", false]], "coordinates (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.coordinates", false]], "coordinates (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement.coordinates", false]], "coordinates (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.coordinates", false]], "coordinates (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.coordinates", false]], "coordinates (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.coordinates", false]], "coordinates (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.coordinates", false]], "coordinates (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.coordinates", false]], "coordinates() (pancax.bcs.essential_bc.essentialbc method)": [[3, "pancax.bcs.essential_bc.EssentialBC.coordinates", false]], "coordinates() (pancax.bcs.natural_bc.naturalbc method)": [[3, "pancax.bcs.natural_bc.NaturalBC.coordinates", false]], "coords (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.coords", false]], "coords (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.coords", false]], "coords (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.coords", false]], "coords (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.coords", false]], "coords (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.coords", false]], "coords (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.coords", false]], "copy_mesh() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.copy_mesh", false]], "cos_of_acos_divided_by_3() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.cos_of_acos_divided_by_3", false]], "create_edges() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.create_edges", false]], "create_edges() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.create_edges", false]], "create_field() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.create_field", false]], "create_field_methods() (in module pancax.kinematics)": [[2, "pancax.kinematics.create_field_methods", false]], "create_higher_order_mesh_from_simplex_mesh() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.create_higher_order_mesh_from_simplex_mesh", false]], "create_nodesets_from_sidesets() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.create_nodesets_from_sidesets", false]], "create_padded_quadrature_rule_1d() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.create_padded_quadrature_rule_1D", false]], "create_quadrature_rule_1d() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.create_quadrature_rule_1D", false]], "create_quadrature_rule_on_hex() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.create_quadrature_rule_on_hex", false]], "create_quadrature_rule_on_quad() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.create_quadrature_rule_on_quad", false]], "create_quadrature_rule_on_tet() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.create_quadrature_rule_on_tet", false]], "create_quadrature_rule_on_triangle() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.create_quadrature_rule_on_triangle", false]], "create_structured_mesh_data() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.create_structured_mesh_data", false]], "cutoff_strain (pancax.constitutive_models.swanson.swanson4 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4.cutoff_strain", false]], "cutoff_strain (pancax.constitutive_models.swanson.swanson6 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6.cutoff_strain", false]], "cutoff_strain (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus.cutoff_strain", false]], "data_dict (pancax.history_writer.historywriter attribute)": [[2, "pancax.history_writer.HistoryWriter.data_dict", false]], "datafilenotfoundexception": [[2, "pancax.utils.DataFileNotFoundException", false]], "default_modify_element_gradient() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.default_modify_element_gradient", false]], "deformation_gradient() (pancax.kernels.solid_mechanics.incompressibleplanestress method)": [[10, "pancax.kernels.solid_mechanics.IncompressiblePlaneStress.deformation_gradient", false]], "deformation_gradients() (in module pancax.kinematics)": [[2, "pancax.kinematics.deformation_gradients", false]], "degree (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement.degree", false]], "degree (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.degree", false]], "degree (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement.degree", false]], "degree (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.degree", false]], "degree (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.degree", false]], "degree (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.degree", false]], "degree (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.degree", false]], "degree (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.degree", false]], "deltapinndomain (class in pancax.domains.delta_pinn_domain)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain", false]], "dev() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.dev", false]], "dirichletbcloss (class in pancax.loss_functions.bc_loss_functions)": [[11, "pancax.loss_functions.bc_loss_functions.DirichletBCLoss", false]], "displacements (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.displacements", false]], "distance() (in module pancax.bcs.distance_functions)": [[3, "pancax.bcs.distance_functions.distance", false]], "distance_function() (in module pancax.bcs.distance_functions)": [[3, "pancax.bcs.distance_functions.distance_function", false]], "dof_manager (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.dof_manager", false]], "dof_manager (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.dof_manager", false]], "dof_manager (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.dof_manager", false]], "dof_manager (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.dof_manager", false]], "dof_manager (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.dof_manager", false]], "dofmanager (class in pancax.fem.dof_manager)": [[8, "pancax.fem.dof_manager.DofManager", false]], "dot2() (in module pancax.math.math)": [[12, "pancax.math.math.dot2", false]], "eigen_modes (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.eigen_modes", false]], "eigen_sym33_non_unit() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.eigen_sym33_non_unit", false]], "eigen_sym33_unit() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.eigen_sym33_unit", false]], "element_field_gradient() (pancax.kernels.base_kernel.weakformphysicskernel method)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.element_field_gradient", false]], "element_field_gradient() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.element_field_gradient", false]], "element_pp() (in module pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.element_pp", false]], "element_quantity() (in module pancax.physics)": [[2, "pancax.physics.element_quantity", false]], "element_quantity() (pancax.kernels.base_kernel.weakformphysicskernel method)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.element_quantity", false]], "element_quantity_from_func() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.element_quantity_from_func", false]], "element_quantity_grad() (in module pancax.physics)": [[2, "pancax.physics.element_quantity_grad", false]], "element_quantity_grad() (pancax.kernels.base_kernel.weakformphysicskernel method)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.element_quantity_grad", false]], "element_quantity_hessian() (in module pancax.physics)": [[2, "pancax.physics.element_quantity_hessian", false]], "element_quantity_hessian() (pancax.kernels.base_kernel.weakformphysicskernel method)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.element_quantity_hessian", false]], "element_quantity_new() (in module pancax.physics)": [[2, "pancax.physics.element_quantity_new", false]], "elementtype (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement.elementType", false]], "elementtype (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.elementType", false]], "elementtype (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement.elementType", false]], "elementtype (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.elementType", false]], "elementtype (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.elementType", false]], "elementtype (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.elementType", false]], "elementtype (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.elementType", false]], "elementtype (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.elementType", false]], "elm (class in pancax.networks.elm)": [[13, "pancax.networks.elm.ELM", false]], "elm2 (class in pancax.networks.elm)": [[13, "pancax.networks.elm.ELM2", false]], "energy() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.energy", false]], "energy() (pancax.constitutive_models.blatz_ko.blatzko method)": [[5, "pancax.constitutive_models.blatz_ko.BlatzKo.energy", false]], "energy() (pancax.constitutive_models.gent.gent method)": [[5, "pancax.constitutive_models.gent.Gent.energy", false]], "energy() (pancax.constitutive_models.neohookean.neohookean method)": [[5, "pancax.constitutive_models.neohookean.NeoHookean.energy", false]], "energy() (pancax.constitutive_models.swanson.swanson4 method)": [[5, "pancax.constitutive_models.swanson.Swanson4.energy", false]], "energy() (pancax.constitutive_models.swanson.swanson6 method)": [[5, "pancax.constitutive_models.swanson.Swanson6.energy", false]], "energy() (pancax.kernels.base_kernel.weakformphysicskernel method)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.energy", false]], "energy() (pancax.kernels.laplace_beltrami.laplacebeltrami method)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami.energy", false]], "energy() (pancax.kernels.linear_elasticity.linearelasticity2d method)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.energy", false]], "energy() (pancax.kernels.poisson.poisson method)": [[10, "pancax.kernels.poisson.Poisson.energy", false]], "energy() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.energy", false]], "energy_weight (pancax.loss_functions.weak_form_loss_functions.energyandresidualloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss.energy_weight", false]], "energy_weight (pancax.loss_functions.weak_form_loss_functions.energyresidualandreactionloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss.energy_weight", false]], "energy_weight (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyandresidualloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss.energy_weight", false]], "energyandresidualloss (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss", false]], "energyloss (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyLoss", false]], "energyresidualandreactionloss (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss", false]], "ensemble_init() (pancax.optimizers.base.optimizer method)": [[14, "pancax.optimizers.base.Optimizer.ensemble_init", false]], "ensemble_step_old() (pancax.optimizers.base.optimizer method)": [[14, "pancax.optimizers.base.Optimizer.ensemble_step_old", false]], "ensemblehistorywriter (class in pancax.history_writer)": [[2, "pancax.history_writer.EnsembleHistoryWriter", false]], "ensemblelogger (class in pancax.logging)": [[2, "pancax.logging.EnsembleLogger", false]], "essential_bcs (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.essential_bcs", false]], "essential_bcs (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.essential_bcs", false]], "essential_bcs (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.essential_bcs", false]], "essential_bcs (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.essential_bcs", false]], "essentialbc (class in pancax.bcs.essential_bc)": [[3, "pancax.bcs.essential_bc.EssentialBC", false]], "essentialbcset (class in pancax.bcs.essential_bc)": [[3, "pancax.bcs.essential_bc.EssentialBCSet", false]], "eval_at_iso_points() (in module pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.eval_at_iso_points", false]], "eval_field() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.eval_field", false]], "evaluate_on_block() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.evaluate_on_block", false]], "evaluate_on_element() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.evaluate_on_element", false]], "evaluate_on_element() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.evaluate_on_element", false]], "extract_stress() (pancax.kernels.solid_mechanics.planestrain method)": [[10, "pancax.kernels.solid_mechanics.PlaneStrain.extract_stress", false]], "facenodes (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement.faceNodes", false]], "facenodes (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.faceNodes", false]], "facenodes (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement.faceNodes", false]], "facenodes (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.faceNodes", false]], "facenodes (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.faceNodes", false]], "facenodes (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.faceNodes", false]], "facenodes (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.faceNodes", false]], "facenodes (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.faceNodes", false]], "field_data (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.field_data", false]], "field_gradients() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.field_gradients", false]], "field_hessians() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.field_hessians", false]], "field_laplacians() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.field_laplacians", false]], "field_names (pancax.kernels.laplace_beltrami.laplacebeltrami attribute)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami.field_names", false]], "field_second_time_derivatives() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.field_second_time_derivatives", false]], "field_time_derivatives() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.field_time_derivatives", false]], "field_value_names (pancax.kernels.base_kernel.physicskernel attribute)": [[10, "pancax.kernels.base_kernel.PhysicsKernel.field_value_names", false]], "field_value_names (pancax.kernels.base_kernel.strongformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.field_value_names", false]], "field_value_names (pancax.kernels.base_kernel.weakformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.field_value_names", false]], "field_value_names (pancax.kernels.linear_elasticity.linearelasticity2d attribute)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.field_value_names", false]], "field_value_names (pancax.kernels.poisson.poisson attribute)": [[10, "pancax.kernels.poisson.Poisson.field_value_names", false]], "field_values() (pancax.domains.base_domain.basedomain method)": [[7, "pancax.domains.base_domain.BaseDomain.field_values", false]], "field_values() (pancax.domains.delta_pinn_domain.deltapinndomain method)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.field_values", false]], "field_values_names (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.field_values_names", false]], "fieldpropertypair (class in pancax.networks.field_property_pair)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair", false]], "fields (pancax.networks.field_property_pair.fieldpropertypair attribute)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair.fields", false]], "filtered_loss() (pancax.loss_functions.base_loss_function.baselossfunction method)": [[11, "pancax.loss_functions.base_loss_function.BaseLossFunction.filtered_loss", false]], "find_data_file() (in module pancax.utils)": [[2, "pancax.utils.find_data_file", false]], "find_mesh_file() (in module pancax.utils)": [[2, "pancax.utils.find_mesh_file", false]], "fixedproperties (class in pancax.networks.properties)": [[13, "pancax.networks.properties.FixedProperties", false]], "flush() (pancax.logging.baselogger method)": [[2, "pancax.logging.BaseLogger.flush", false]], "flush() (pancax.logging.ensemblelogger method)": [[2, "pancax.logging.EnsembleLogger.flush", false]], "flush() (pancax.logging.logger method)": [[2, "pancax.logging.Logger.flush", false]], "formulation (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.formulation", false]], "freeze_fields_filter() (pancax.networks.field_property_pair.fieldpropertypair method)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair.freeze_fields_filter", false]], "freeze_props_filter() (pancax.networks.field_property_pair.fieldpropertypair method)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair.freeze_props_filter", false]], "fspace (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.fspace", false]], "fspace (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.fspace", false]], "fspace (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.fspace", false]], "fspace_centroid (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.fspace_centroid", false]], "fspace_centroid (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.fspace_centroid", false]], "fspace_centroid (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.fspace_centroid", false]], "full_tensor_names() (in module pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.full_tensor_names", false]], "full_tensor_names_2d() (in module pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.full_tensor_names_2D", false]], "fullfielddata (class in pancax.data.full_field_data)": [[6, "pancax.data.full_field_data.FullFieldData", false]], "fullfielddataloss (class in pancax.loss_functions.data_loss_functions)": [[11, "pancax.loss_functions.data_loss_functions.FullFieldDataLoss", false]], "funcs (pancax.loss_functions.utils.combinelossfunctions attribute)": [[11, "pancax.loss_functions.utils.CombineLossFunctions.funcs", false]], "function() (pancax.bcs.essential_bc.essentialbc method)": [[3, "pancax.bcs.essential_bc.EssentialBC.function", false]], "function() (pancax.bcs.natural_bc.naturalbc method)": [[3, "pancax.bcs.natural_bc.NaturalBC.function", false]], "functionspace (class in pancax.fem.function_space)": [[8, "pancax.fem.function_space.FunctionSpace", false]], "gent (class in pancax.constitutive_models.gent)": [[5, "pancax.constitutive_models.gent.Gent", false]], "gentfixedbulkmodulus (class in pancax.constitutive_models.gent)": [[5, "pancax.constitutive_models.gent.GentFixedBulkModulus", false]], "get_bc_size() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.get_bc_size", false]], "get_bc_values() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.get_bc_values", false]], "get_blocks() (pancax.fem.mesh.mesh method)": [[8, "pancax.fem.mesh.Mesh.get_blocks", false]], "get_coords() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.get_coords", false]], "get_edge_coords() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.get_edge_coords", false]], "get_edge_field() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.get_edge_field", false]], "get_edge_node_indices() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.get_edge_node_indices", false]], "get_edges() (in module pancax.bcs.distance_functions)": [[3, "pancax.bcs.distance_functions.get_edges", false]], "get_element_variable_number() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.get_element_variable_number", false]], "get_field_index() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.get_field_index", false]], "get_lobatto_nodes_1d() (in module pancax.fem.elements.base_element)": [[9, "pancax.fem.elements.base_element.get_lobatto_nodes_1d", false]], "get_nodal_values_on_edge() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.get_nodal_values_on_edge", false]], "get_node_variable_number() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.get_node_variable_number", false]], "get_unknown_size() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.get_unknown_size", false]], "get_unknown_values() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.get_unknown_values", false]], "global_data (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.global_data", false]], "globaldata (class in pancax.data.global_data)": [[6, "pancax.data.global_data.GlobalData", false]], "gradients (pancax.fem.elements.base_element.shapefunctions attribute)": [[9, "pancax.fem.elements.base_element.ShapeFunctions.gradients", false]], "hex8element (class in pancax.fem.elements.hex8_element)": [[9, "pancax.fem.elements.hex8_element.Hex8Element", false]], "history_file (pancax.history_writer.historywriter attribute)": [[2, "pancax.history_writer.HistoryWriter.history_file", false]], "history_writers (pancax.history_writer.ensemblehistorywriter attribute)": [[2, "pancax.history_writer.EnsembleHistoryWriter.history_writers", false]], "historywriter (class in pancax.history_writer)": [[2, "pancax.history_writer.HistoryWriter", false]], "i1() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.I1", false]], "i1_bar() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.I1_bar", false]], "i2() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.I2", false]], "i2_bar() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.I2_bar", false]], "if_then_else() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.if_then_else", false]], "incompressible_energy() (in module pancax.physics)": [[2, "pancax.physics.incompressible_energy", false]], "incompressible_energy_and_internal_force() (in module pancax.physics)": [[2, "pancax.physics.incompressible_energy_and_internal_force", false]], "incompressible_energy_and_residual() (in module pancax.physics)": [[2, "pancax.physics.incompressible_energy_and_residual", false]], "incompressible_internal_force() (in module pancax.physics)": [[2, "pancax.physics.incompressible_internal_force", false]], "incompressible_plane_stress() (in module pancax.kinematics)": [[2, "pancax.kinematics.incompressible_plane_stress", false]], "incompressibleenergyandresidualloss (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss", false]], "incompressibleenergyloss (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss", false]], "incompressibleplanestress (class in pancax.kernels.solid_mechanics)": [[10, "pancax.kernels.solid_mechanics.IncompressiblePlaneStress", false]], "index_to_component() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.index_to_component", false]], "init() (pancax.optimizers.base.optimizer method)": [[14, "pancax.optimizers.base.Optimizer.init", false]], "init() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.init", false]], "init() (pancax.trainer.trainer method)": [[2, "pancax.trainer.Trainer.init", false]], "init_linear() (in module pancax.networks.initialization)": [[13, "pancax.networks.initialization.init_linear", false]], "init_linear_weight() (in module pancax.networks.initialization)": [[13, "pancax.networks.initialization.init_linear_weight", false]], "inputs (pancax.data.full_field_data.fullfielddata attribute)": [[6, "pancax.data.full_field_data.FullFieldData.inputs", false]], "integrate_element() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.integrate_element", false]], "integrate_element_from_local_field() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.integrate_element_from_local_field", false]], "integrate_function() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.integrate_function", false]], "integrate_function_on_edge() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.integrate_function_on_edge", false]], "integrate_function_on_edge() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.integrate_function_on_edge", false]], "integrate_function_on_edges() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.integrate_function_on_edges", false]], "integrate_function_on_surface() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.integrate_function_on_surface", false]], "integrate_on_element() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.integrate_on_element", false]], "integrate_on_elements() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.integrate_on_elements", false]], "integrate_over_block() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.integrate_over_block", false]], "integrate_values() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.integrate_values", false]], "interiornodes (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement.interiorNodes", false]], "interiornodes (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.interiorNodes", false]], "interiornodes (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement.interiorNodes", false]], "interiornodes (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.interiorNodes", false]], "interiornodes (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.interiorNodes", false]], "interiornodes (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.interiorNodes", false]], "interiornodes (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.interiorNodes", false]], "interiornodes (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.interiorNodes", false]], "internal_force() (in module pancax.physics)": [[2, "pancax.physics.internal_force", false]], "interpolate_nodal_field_on_edge() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.interpolate_nodal_field_on_edge", false]], "interpolate_nodal_field_on_edge() (in module pancax.fem.surface)": [[8, "pancax.fem.surface.interpolate_nodal_field_on_edge", false]], "interpolate_nodal_field_on_edge() (in module pancax.fem.traction_bc)": [[8, "pancax.fem.traction_bc.interpolate_nodal_field_on_edge", false]], "interpolate_to_element_points() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.interpolate_to_element_points", false]], "interpolate_to_point() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.interpolate_to_point", false]], "interpolate_to_points() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.interpolate_to_points", false]], "invariants() (in module pancax.kinematics)": [[2, "pancax.kinematics.invariants", false]], "invariants() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.invariants", false]], "invariants_old() (in module pancax.kinematics)": [[2, "pancax.kinematics.invariants_old", false]], "inversedomain (class in pancax.domains.inverse_domain)": [[7, "pancax.domains.inverse_domain.InverseDomain", false]], "isaxisymmetric (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace.isAxisymmetric", false]], "jacobian() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.jacobian", false]], "jvp_sqrtm() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.jvp_sqrtm", false]], "jxws() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.JxWs", false]], "kinetic_energy() (pancax.kernels.laplace_beltrami.laplacebeltrami method)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami.kinetic_energy", false]], "laplacebeltrami (class in pancax.kernels.laplace_beltrami)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami", false]], "layer (pancax.networks.elm.elm attribute)": [[13, "pancax.networks.elm.ELM.layer", false]], "layer (pancax.networks.elm.elm2 attribute)": [[13, "pancax.networks.elm.ELM2.layer", false]], "lbfgs (class in pancax.optimizers.lbfgs)": [[14, "pancax.optimizers.lbfgs.LBFGS", false]], "line_segment() (in module pancax.bcs.distance_functions)": [[3, "pancax.bcs.distance_functions.line_segment", false]], "linear() (in module pancax.networks.mlp)": [[13, "pancax.networks.mlp.Linear", false]], "linear_strain() (pancax.kernels.linear_elasticity.linearelasticity2d method)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.linear_strain", false]], "linearelasticity2d (class in pancax.kernels.linear_elasticity)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D", false]], "lineelement (class in pancax.fem.elements.line_element)": [[9, "pancax.fem.elements.line_element.LineElement", false]], "load_step() (pancax.loss_functions.base_loss_function.bclossfunction method)": [[11, "pancax.loss_functions.base_loss_function.BCLossFunction.load_step", false]], "load_step() (pancax.loss_functions.base_loss_function.physicslossfunction method)": [[11, "pancax.loss_functions.base_loss_function.PhysicsLossFunction.load_step", false]], "load_step() (pancax.loss_functions.bc_loss_functions.dirichletbcloss method)": [[11, "pancax.loss_functions.bc_loss_functions.DirichletBCLoss.load_step", false]], "load_step() (pancax.loss_functions.bc_loss_functions.neumannbcloss method)": [[11, "pancax.loss_functions.bc_loss_functions.NeumannBCLoss.load_step", false]], "load_step() (pancax.loss_functions.strong_form_loss_functions.strongformresidualloss method)": [[11, "pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.energyandresidualloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.energyloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyLoss.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.energyresidualandreactionloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyandresidualloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.quadratureincompressibilityconstraint method)": [[11, "pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint.load_step", false]], "load_step() (pancax.loss_functions.weak_form_loss_functions.residualmseloss method)": [[11, "pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss.load_step", false]], "log_every (pancax.history_writer.basehistorywriter attribute)": [[2, "pancax.history_writer.BaseHistoryWriter.log_every", false]], "log_every (pancax.history_writer.ensemblehistorywriter attribute)": [[2, "pancax.history_writer.EnsembleHistoryWriter.log_every", false]], "log_every (pancax.history_writer.historywriter attribute)": [[2, "pancax.history_writer.HistoryWriter.log_every", false]], "log_every (pancax.logging.baselogger attribute)": [[2, "pancax.logging.BaseLogger.log_every", false]], "log_file (pancax.logging.logger attribute)": [[2, "pancax.logging.Logger.log_file", false]], "log_jvp() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.log_jvp", false]], "log_loss() (in module pancax.logging)": [[2, "pancax.logging.log_loss", false]], "log_loss() (pancax.logging.baselogger method)": [[2, "pancax.logging.BaseLogger.log_loss", false]], "log_pade_pf() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.log_pade_pf", false]], "logger (class in pancax.logging)": [[2, "pancax.logging.Logger", false]], "logger() (pancax.timer.timer method)": [[2, "pancax.timer.Timer.logger", false]], "loggers (pancax.logging.ensemblelogger attribute)": [[2, "pancax.logging.EnsembleLogger.loggers", false]], "logh() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.logh", false]], "logh_from_eigen() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.logh_from_eigen", false]], "logm_jvp() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.logm_jvp", false]], "make_mesh_time_dependent() (in module pancax.domains.utils)": [[7, "pancax.domains.utils.make_mesh_time_dependent", false]], "make_step_method() (pancax.optimizers.adam.adam method)": [[14, "pancax.optimizers.adam.Adam.make_step_method", false]], "make_step_method() (pancax.optimizers.base.optimizer method)": [[14, "pancax.optimizers.base.Optimizer.make_step_method", false]], "make_step_method() (pancax.optimizers.lbfgs.lbfgs method)": [[14, "pancax.optimizers.lbfgs.LBFGS.make_step_method", false]], "make_times_column() (in module pancax.domains.utils)": [[7, "pancax.domains.utils.make_times_column", false]], "map_element_shape_grads() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.map_element_shape_grads", false]], "mass_matrix() (in module pancax.physics)": [[2, "pancax.physics.mass_matrix", false]], "mesh (class in pancax.fem.mesh)": [[8, "pancax.fem.mesh.Mesh", false]], "mesh (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.mesh", false]], "mesh (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.mesh", false]], "mesh (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.mesh", false]], "mesh (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.mesh", false]], "mesh_file (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.mesh_file", false]], "mesh_with_blocks() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.mesh_with_blocks", false]], "mesh_with_coords() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.mesh_with_coords", false]], "mesh_with_nodesets() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.mesh_with_nodesets", false]], "meshfilenotfoundexception": [[2, "pancax.utils.MeshFileNotFoundException", false]], "mises_equivalent_stress() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.mises_equivalent_stress", false]], "mlp() (in module pancax.networks.mlp)": [[13, "pancax.networks.mlp.MLP", false]], "mlpbasis() (in module pancax.networks.mlp)": [[13, "pancax.networks.mlp.MLPBasis", false]], "modify_field_gradient() (pancax.kernels.solid_mechanics.basemechanicsformulation method)": [[10, "pancax.kernels.solid_mechanics.BaseMechanicsFormulation.modify_field_gradient", false]], "modify_field_gradient() (pancax.kernels.solid_mechanics.incompressibleplanestress method)": [[10, "pancax.kernels.solid_mechanics.IncompressiblePlaneStress.modify_field_gradient", false]], "modify_field_gradient() (pancax.kernels.solid_mechanics.planestrain method)": [[10, "pancax.kernels.solid_mechanics.PlaneStrain.modify_field_gradient", false]], "modify_field_gradient() (pancax.kernels.solid_mechanics.threedimensional method)": [[10, "pancax.kernels.solid_mechanics.ThreeDimensional.modify_field_gradient", false]], "module": [[2, "module-pancax", false], [2, "module-pancax.history_writer", false], [2, "module-pancax.kinematics", false], [2, "module-pancax.logging", false], [2, "module-pancax.physics", false], [2, "module-pancax.post_processor", false], [2, "module-pancax.timer", false], [2, "module-pancax.trainer", false], [2, "module-pancax.utils", false], [3, "module-pancax.bcs", false], [3, "module-pancax.bcs.distance_functions", false], [3, "module-pancax.bcs.essential_bc", false], [3, "module-pancax.bcs.natural_bc", false], [4, "module-pancax.bvps", false], [4, "module-pancax.bvps.biaxial_tension", false], [4, "module-pancax.bvps.simple_shear", false], [4, "module-pancax.bvps.uniaxial_tension", false], [5, "module-pancax.constitutive_models", false], [5, "module-pancax.constitutive_models.base_constitutive_model", false], [5, "module-pancax.constitutive_models.blatz_ko", false], [5, "module-pancax.constitutive_models.gent", false], [5, "module-pancax.constitutive_models.neohookean", false], [5, "module-pancax.constitutive_models.swanson", false], [6, "module-pancax.data", false], [6, "module-pancax.data.full_field_data", false], [6, "module-pancax.data.global_data", false], [7, "module-pancax.domains", false], [7, "module-pancax.domains.base_domain", false], [7, "module-pancax.domains.collocation_domain", false], [7, "module-pancax.domains.delta_pinn_domain", false], [7, "module-pancax.domains.inverse_domain", false], [7, "module-pancax.domains.utils", false], [7, "module-pancax.domains.variational_domain", false], [8, "module-pancax.fem", false], [8, "module-pancax.fem.dof_manager", false], [8, "module-pancax.fem.function_space", false], [8, "module-pancax.fem.mesh", false], [8, "module-pancax.fem.quadrature_rules", false], [8, "module-pancax.fem.read_exodus_mesh", false], [8, "module-pancax.fem.sparse_matrix_assembler", false], [8, "module-pancax.fem.surface", false], [8, "module-pancax.fem.traction_bc", false], [9, "module-pancax.fem.elements", false], [9, "module-pancax.fem.elements.base_element", false], [9, "module-pancax.fem.elements.hex8_element", false], [9, "module-pancax.fem.elements.line_element", false], [9, "module-pancax.fem.elements.quad4_element", false], [9, "module-pancax.fem.elements.quad9_element", false], [9, "module-pancax.fem.elements.simplex_tri_element", false], [9, "module-pancax.fem.elements.tet10_element", false], [9, "module-pancax.fem.elements.tet4_element", false], [10, "module-pancax.kernels", false], [10, "module-pancax.kernels.base_kernel", false], [10, "module-pancax.kernels.laplace_beltrami", false], [10, "module-pancax.kernels.linear_elasticity", false], [10, "module-pancax.kernels.poisson", false], [10, "module-pancax.kernels.solid_mechanics", false], [11, "module-pancax.loss_functions", false], [11, "module-pancax.loss_functions.base_loss_function", false], [11, "module-pancax.loss_functions.bc_loss_functions", false], [11, "module-pancax.loss_functions.data_loss_functions", false], [11, "module-pancax.loss_functions.physics_loss_functions_strong_form", false], [11, "module-pancax.loss_functions.strong_form_loss_functions", false], [11, "module-pancax.loss_functions.utils", false], [11, "module-pancax.loss_functions.weak_form_loss_functions", false], [12, "module-pancax.math", false], [12, "module-pancax.math.math", false], [12, "module-pancax.math.tensor_math", false], [13, "module-pancax.networks", false], [13, "module-pancax.networks.elm", false], [13, "module-pancax.networks.field_property_pair", false], [13, "module-pancax.networks.initialization", false], [13, "module-pancax.networks.mlp", false], [13, "module-pancax.networks.properties", false], [13, "module-pancax.networks.rbf", false], [14, "module-pancax.optimizers", false], [14, "module-pancax.optimizers.adam", false], [14, "module-pancax.optimizers.base", false], [14, "module-pancax.optimizers.lbfgs", false], [14, "module-pancax.optimizers.utils", false]], "mtk_log_sqrt_jvp() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.mtk_log_sqrt_jvp", false]], "mtk_pow_jvp() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.mtk_pow_jvp", false]], "n_dimensions (pancax.kernels.solid_mechanics.basemechanicsformulation attribute)": [[10, "pancax.kernels.solid_mechanics.BaseMechanicsFormulation.n_dimensions", false]], "n_dimensions (pancax.kernels.solid_mechanics.incompressibleplanestress attribute)": [[10, "pancax.kernels.solid_mechanics.IncompressiblePlaneStress.n_dimensions", false]], "n_dimensions (pancax.kernels.solid_mechanics.planestrain attribute)": [[10, "pancax.kernels.solid_mechanics.PlaneStrain.n_dimensions", false]], "n_dimensions (pancax.kernels.solid_mechanics.threedimensional attribute)": [[10, "pancax.kernels.solid_mechanics.ThreeDimensional.n_dimensions", false]], "n_dofs (pancax.kernels.base_kernel.physicskernel attribute)": [[10, "pancax.kernels.base_kernel.PhysicsKernel.n_dofs", false]], "n_dofs (pancax.kernels.base_kernel.strongformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.n_dofs", false]], "n_dofs (pancax.kernels.base_kernel.weakformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.n_dofs", false]], "n_dofs (pancax.kernels.laplace_beltrami.laplacebeltrami attribute)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami.n_dofs", false]], "n_dofs (pancax.kernels.linear_elasticity.linearelasticity2d attribute)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.n_dofs", false]], "n_dofs (pancax.kernels.poisson.poisson attribute)": [[10, "pancax.kernels.poisson.Poisson.n_dofs", false]], "n_dofs (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.n_dofs", false]], "n_eigen_values (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.n_eigen_values", false]], "n_nodes (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.n_nodes", false]], "n_outputs (pancax.networks.elm.elm attribute)": [[13, "pancax.networks.elm.ELM.n_outputs", false]], "n_outputs (pancax.networks.elm.elm2 attribute)": [[13, "pancax.networks.elm.ELM2.n_outputs", false]], "n_properties (pancax.constitutive_models.base_constitutive_model.constitutivemodel attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.n_properties", false]], "n_properties (pancax.constitutive_models.base_constitutive_model.constitutivemodelfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus.n_properties", false]], "n_properties (pancax.constitutive_models.blatz_ko.blatzko attribute)": [[5, "pancax.constitutive_models.blatz_ko.BlatzKo.n_properties", false]], "n_properties (pancax.constitutive_models.gent.gent attribute)": [[5, "pancax.constitutive_models.gent.Gent.n_properties", false]], "n_properties (pancax.constitutive_models.gent.gentfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.gent.GentFixedBulkModulus.n_properties", false]], "n_properties (pancax.constitutive_models.neohookean.neohookean attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookean.n_properties", false]], "n_properties (pancax.constitutive_models.neohookean.neohookeanfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus.n_properties", false]], "n_properties (pancax.constitutive_models.swanson.swanson4 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4.n_properties", false]], "n_properties (pancax.constitutive_models.swanson.swanson4fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus.n_properties", false]], "n_properties (pancax.constitutive_models.swanson.swanson6 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6.n_properties", false]], "n_properties (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus.n_properties", false]], "n_time_steps (pancax.data.full_field_data.fullfielddata attribute)": [[6, "pancax.data.full_field_data.FullFieldData.n_time_steps", false]], "n_time_steps (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.n_time_steps", false]], "name (pancax.timer.timer attribute)": [[2, "pancax.timer.Timer.name", false]], "natural_bcs (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.natural_bcs", false]], "natural_bcs (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.natural_bcs", false]], "natural_bcs (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.natural_bcs", false]], "natural_bcs (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.natural_bcs", false]], "naturalbc (class in pancax.bcs.natural_bc)": [[3, "pancax.bcs.natural_bc.NaturalBC", false]], "neohookean (class in pancax.constitutive_models.neohookean)": [[5, "pancax.constitutive_models.neohookean.NeoHookean", false]], "neohookeanfixedbulkmodulus (class in pancax.constitutive_models.neohookean)": [[5, "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus", false]], "network() (in module pancax.networks)": [[13, "pancax.networks.Network", false]], "neumann_ns (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.neumann_ns", false]], "neumann_xs (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.neumann_xs", false]], "neumannbcloss (class in pancax.loss_functions.bc_loss_functions)": [[11, "pancax.loss_functions.bc_loss_functions.NeumannBCLoss", false]], "nodal_incompressibility_constraint() (in module pancax.physics)": [[2, "pancax.physics.nodal_incompressibility_constraint", false]], "nodal_incompressibility_constraint() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.nodal_incompressibility_constraint", false]], "nodal_pp() (in module pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.nodal_pp", false]], "nodeset (pancax.bcs.essential_bc.essentialbc attribute)": [[3, "pancax.bcs.essential_bc.EssentialBC.nodeSet", false]], "nodesets (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.nodeSets", false]], "nonallocatedfunctionspace (class in pancax.fem.function_space)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace", false]], "norm_of_deviator() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.norm_of_deviator", false]], "norm_of_deviator_squared() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.norm_of_deviator_squared", false]], "normals() (pancax.bcs.natural_bc.naturalbc method)": [[3, "pancax.bcs.natural_bc.NaturalBC.normals", false]], "num_dimensions (pancax.fem.mesh.mesh property)": [[8, "pancax.fem.mesh.Mesh.num_dimensions", false]], "num_elements (pancax.fem.mesh.mesh property)": [[8, "pancax.fem.mesh.Mesh.num_elements", false]], "num_nodes (pancax.fem.mesh.mesh property)": [[8, "pancax.fem.mesh.Mesh.num_nodes", false]], "num_nodes() (in module pancax.fem.mesh)": [[8, "pancax.fem.mesh.num_nodes", false]], "optimizer (class in pancax.optimizers.base)": [[14, "pancax.optimizers.base.Optimizer", false]], "outputs (pancax.data.full_field_data.fullfielddata attribute)": [[6, "pancax.data.full_field_data.FullFieldData.outputs", false]], "outputs (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.outputs", false]], "pancax": [[2, "module-pancax", false]], "pancax.bcs": [[3, "module-pancax.bcs", false]], "pancax.bcs.distance_functions": [[3, "module-pancax.bcs.distance_functions", false]], "pancax.bcs.essential_bc": [[3, "module-pancax.bcs.essential_bc", false]], "pancax.bcs.natural_bc": [[3, "module-pancax.bcs.natural_bc", false]], "pancax.bvps": [[4, "module-pancax.bvps", false]], "pancax.bvps.biaxial_tension": [[4, "module-pancax.bvps.biaxial_tension", false]], "pancax.bvps.simple_shear": [[4, "module-pancax.bvps.simple_shear", false]], "pancax.bvps.uniaxial_tension": [[4, "module-pancax.bvps.uniaxial_tension", false]], "pancax.constitutive_models": [[5, "module-pancax.constitutive_models", false]], "pancax.constitutive_models.base_constitutive_model": [[5, "module-pancax.constitutive_models.base_constitutive_model", false]], "pancax.constitutive_models.blatz_ko": [[5, "module-pancax.constitutive_models.blatz_ko", false]], "pancax.constitutive_models.gent": [[5, "module-pancax.constitutive_models.gent", false]], "pancax.constitutive_models.neohookean": [[5, "module-pancax.constitutive_models.neohookean", false]], "pancax.constitutive_models.swanson": [[5, "module-pancax.constitutive_models.swanson", false]], "pancax.data": [[6, "module-pancax.data", false]], "pancax.data.full_field_data": [[6, "module-pancax.data.full_field_data", false]], "pancax.data.global_data": [[6, "module-pancax.data.global_data", false]], "pancax.domains": [[7, "module-pancax.domains", false]], "pancax.domains.base_domain": [[7, "module-pancax.domains.base_domain", false]], "pancax.domains.collocation_domain": [[7, "module-pancax.domains.collocation_domain", false]], "pancax.domains.delta_pinn_domain": [[7, "module-pancax.domains.delta_pinn_domain", false]], "pancax.domains.inverse_domain": [[7, "module-pancax.domains.inverse_domain", false]], "pancax.domains.utils": [[7, "module-pancax.domains.utils", false]], "pancax.domains.variational_domain": [[7, "module-pancax.domains.variational_domain", false]], "pancax.fem": [[8, "module-pancax.fem", false]], "pancax.fem.dof_manager": [[8, "module-pancax.fem.dof_manager", false]], "pancax.fem.elements": [[9, "module-pancax.fem.elements", false]], "pancax.fem.elements.base_element": [[9, "module-pancax.fem.elements.base_element", false]], "pancax.fem.elements.hex8_element": [[9, "module-pancax.fem.elements.hex8_element", false]], "pancax.fem.elements.line_element": [[9, "module-pancax.fem.elements.line_element", false]], "pancax.fem.elements.quad4_element": [[9, "module-pancax.fem.elements.quad4_element", false]], "pancax.fem.elements.quad9_element": [[9, "module-pancax.fem.elements.quad9_element", false]], "pancax.fem.elements.simplex_tri_element": [[9, "module-pancax.fem.elements.simplex_tri_element", false]], "pancax.fem.elements.tet10_element": [[9, "module-pancax.fem.elements.tet10_element", false]], "pancax.fem.elements.tet4_element": [[9, "module-pancax.fem.elements.tet4_element", false]], "pancax.fem.function_space": [[8, "module-pancax.fem.function_space", false]], "pancax.fem.mesh": [[8, "module-pancax.fem.mesh", false]], "pancax.fem.quadrature_rules": [[8, "module-pancax.fem.quadrature_rules", false]], "pancax.fem.read_exodus_mesh": [[8, "module-pancax.fem.read_exodus_mesh", false]], "pancax.fem.sparse_matrix_assembler": [[8, "module-pancax.fem.sparse_matrix_assembler", false]], "pancax.fem.surface": [[8, "module-pancax.fem.surface", false]], "pancax.fem.traction_bc": [[8, "module-pancax.fem.traction_bc", false]], "pancax.history_writer": [[2, "module-pancax.history_writer", false]], "pancax.kernels": [[10, "module-pancax.kernels", false]], "pancax.kernels.base_kernel": [[10, "module-pancax.kernels.base_kernel", false]], "pancax.kernels.laplace_beltrami": [[10, "module-pancax.kernels.laplace_beltrami", false]], "pancax.kernels.linear_elasticity": [[10, "module-pancax.kernels.linear_elasticity", false]], "pancax.kernels.poisson": [[10, "module-pancax.kernels.poisson", false]], "pancax.kernels.solid_mechanics": [[10, "module-pancax.kernels.solid_mechanics", false]], "pancax.kinematics": [[2, "module-pancax.kinematics", false]], "pancax.logging": [[2, "module-pancax.logging", false]], "pancax.loss_functions": [[11, "module-pancax.loss_functions", false]], "pancax.loss_functions.base_loss_function": [[11, "module-pancax.loss_functions.base_loss_function", false]], "pancax.loss_functions.bc_loss_functions": [[11, "module-pancax.loss_functions.bc_loss_functions", false]], "pancax.loss_functions.data_loss_functions": [[11, "module-pancax.loss_functions.data_loss_functions", false]], "pancax.loss_functions.physics_loss_functions_strong_form": [[11, "module-pancax.loss_functions.physics_loss_functions_strong_form", false]], "pancax.loss_functions.strong_form_loss_functions": [[11, "module-pancax.loss_functions.strong_form_loss_functions", false]], "pancax.loss_functions.utils": [[11, "module-pancax.loss_functions.utils", false]], "pancax.loss_functions.weak_form_loss_functions": [[11, "module-pancax.loss_functions.weak_form_loss_functions", false]], "pancax.math": [[12, "module-pancax.math", false]], "pancax.math.math": [[12, "module-pancax.math.math", false]], "pancax.math.tensor_math": [[12, "module-pancax.math.tensor_math", false]], "pancax.networks": [[13, "module-pancax.networks", false]], "pancax.networks.elm": [[13, "module-pancax.networks.elm", false]], "pancax.networks.field_property_pair": [[13, "module-pancax.networks.field_property_pair", false]], "pancax.networks.initialization": [[13, "module-pancax.networks.initialization", false]], "pancax.networks.mlp": [[13, "module-pancax.networks.mlp", false]], "pancax.networks.properties": [[13, "module-pancax.networks.properties", false]], "pancax.networks.rbf": [[13, "module-pancax.networks.rbf", false]], "pancax.optimizers": [[14, "module-pancax.optimizers", false]], "pancax.optimizers.adam": [[14, "module-pancax.optimizers.adam", false]], "pancax.optimizers.base": [[14, "module-pancax.optimizers.base", false]], "pancax.optimizers.lbfgs": [[14, "module-pancax.optimizers.lbfgs", false]], "pancax.optimizers.utils": [[14, "module-pancax.optimizers.utils", false]], "pancax.physics": [[2, "module-pancax.physics", false]], "pancax.post_processor": [[2, "module-pancax.post_processor", false]], "pancax.timer": [[2, "module-pancax.timer", false]], "pancax.trainer": [[2, "module-pancax.trainer", false]], "pancax.utils": [[2, "module-pancax.utils", false]], "parentelement (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.parentElement", false]], "parentelement1d (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.parentElement1d", false]], "pascal_triangle_monomials() (in module pancax.fem.elements.base_element)": [[9, "pancax.fem.elements.base_element.pascal_triangle_monomials", false]], "physics (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.physics", false]], "physics (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.physics", false]], "physics (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.physics", false]], "physics (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.physics", false]], "physics (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.physics", false]], "physicskernel (class in pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.PhysicsKernel", false]], "physicslossfunction (class in pancax.loss_functions.base_loss_function)": [[11, "pancax.loss_functions.base_loss_function.PhysicsLossFunction", false]], "pk1_stress() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.pk1_stress", false]], "pk1_stress() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.pk1_stress", false]], "pk1_stress_weak_form() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.pk1_stress_weak_form", false]], "plane_strain() (in module pancax.kinematics)": [[2, "pancax.kinematics.plane_strain", false]], "planestrain (class in pancax.kernels.solid_mechanics)": [[10, "pancax.kernels.solid_mechanics.PlaneStrain", false]], "plot_data() (pancax.data.full_field_data.fullfielddata method)": [[6, "pancax.data.full_field_data.FullFieldData.plot_data", false]], "plot_registration() (pancax.data.full_field_data.fullfielddata method)": [[6, "pancax.data.full_field_data.FullFieldData.plot_registration", false]], "poisson (class in pancax.kernels.poisson)": [[10, "pancax.kernels.poisson.Poisson", false]], "postprocessor (class in pancax.post_processor)": [[2, "pancax.post_processor.PostProcessor", false]], "potential_energy() (in module pancax.physics)": [[2, "pancax.physics.potential_energy", false]], "potential_energy_and_internal_force() (in module pancax.physics)": [[2, "pancax.physics.potential_energy_and_internal_force", false]], "potential_energy_and_residual() (in module pancax.physics)": [[2, "pancax.physics.potential_energy_and_residual", false]], "potential_energy_residual_and_reaction_force() (in module pancax.physics)": [[2, "pancax.physics.potential_energy_residual_and_reaction_force", false]], "project_quadrature_field_to_element_field() (in module pancax.fem.function_space)": [[8, "pancax.fem.function_space.project_quadrature_field_to_element_field", false]], "prop_maxs (pancax.networks.properties.properties attribute)": [[13, "pancax.networks.properties.Properties.prop_maxs", false]], "prop_mins (pancax.networks.properties.properties attribute)": [[13, "pancax.networks.properties.Properties.prop_mins", false]], "prop_params (pancax.networks.properties.properties attribute)": [[13, "pancax.networks.properties.Properties.prop_params", false]], "properties (class in pancax.networks.properties)": [[13, "pancax.networks.properties.Properties", false]], "properties (pancax.networks.field_property_pair.fieldpropertypair attribute)": [[13, "pancax.networks.field_property_pair.FieldPropertyPair.properties", false]], "property_names (pancax.constitutive_models.base_constitutive_model.constitutivemodel attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.property_names", false]], "property_names (pancax.constitutive_models.base_constitutive_model.constitutivemodelfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus.property_names", false]], "property_names (pancax.constitutive_models.blatz_ko.blatzko attribute)": [[5, "pancax.constitutive_models.blatz_ko.BlatzKo.property_names", false]], "property_names (pancax.constitutive_models.gent.gent attribute)": [[5, "pancax.constitutive_models.gent.Gent.property_names", false]], "property_names (pancax.constitutive_models.gent.gentfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.gent.GentFixedBulkModulus.property_names", false]], "property_names (pancax.constitutive_models.neohookean.neohookean attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookean.property_names", false]], "property_names (pancax.constitutive_models.neohookean.neohookeanfixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus.property_names", false]], "property_names (pancax.constitutive_models.swanson.swanson4 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4.property_names", false]], "property_names (pancax.constitutive_models.swanson.swanson4fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus.property_names", false]], "property_names (pancax.constitutive_models.swanson.swanson6 attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6.property_names", false]], "property_names (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus attribute)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus.property_names", false]], "quad4element (class in pancax.fem.elements.quad4_element)": [[9, "pancax.fem.elements.quad4_element.Quad4Element", false]], "quad9element (class in pancax.fem.elements.quad9_element)": [[9, "pancax.fem.elements.quad9_element.Quad9Element", false]], "quadrature_incompressibility_constraint() (in module pancax.physics)": [[2, "pancax.physics.quadrature_incompressibility_constraint", false]], "quadrature_incompressibility_constraint() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.quadrature_incompressibility_constraint", false]], "quadrature_rule (pancax.fem.function_space.nonallocatedfunctionspace attribute)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.quadrature_rule", false]], "quadratureincompressibilityconstraint (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint", false]], "quadraturerule (class in pancax.fem.quadrature_rules)": [[8, "pancax.fem.quadrature_rules.QuadratureRule", false]], "quadraturerule (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace.quadratureRule", false]], "rbf_normalization() (in module pancax.networks.rbf)": [[13, "pancax.networks.rbf.rbf_normalization", false]], "rbfbasis (class in pancax.networks.rbf)": [[13, "pancax.networks.rbf.RBFBasis", false]], "reaction_dof (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.reaction_dof", false]], "reaction_nodes (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.reaction_nodes", false]], "reaction_weight (pancax.loss_functions.weak_form_loss_functions.energyresidualandreactionloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss.reaction_weight", false]], "read_exodus_mesh() (in module pancax.fem.read_exodus_mesh)": [[8, "pancax.fem.read_exodus_mesh.read_exodus_mesh", false]], "relative_log_difference() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.relative_log_difference", false]], "relative_log_difference_no_tolerance_check() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.relative_log_difference_no_tolerance_check", false]], "relative_log_difference_taylor() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.relative_log_difference_taylor", false]], "residual() (in module pancax.physics)": [[2, "pancax.physics.residual", false]], "residual_mse() (in module pancax.physics)": [[2, "pancax.physics.residual_mse", false]], "residual_weight (pancax.loss_functions.weak_form_loss_functions.energyandresidualloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss.residual_weight", false]], "residual_weight (pancax.loss_functions.weak_form_loss_functions.energyresidualandreactionloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss.residual_weight", false]], "residual_weight (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyandresidualloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss.residual_weight", false]], "residualmseloss (class in pancax.loss_functions.weak_form_loss_functions)": [[11, "pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss", false]], "safe_sqrt_jvp() (in module pancax.math.math)": [[12, "pancax.math.math.safe_sqrt_jvp", false]], "serialise() (pancax.networks.field_property_pair.basepancaxmodel method)": [[13, "pancax.networks.field_property_pair.BasePancaxModel.serialise", false]], "serialise() (pancax.trainer.trainer method)": [[2, "pancax.trainer.Trainer.serialise", false]], "set_checkpoint_file() (in module pancax.utils)": [[2, "pancax.utils.set_checkpoint_file", false]], "shape_function_gradients() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.shape_function_gradients", false]], "shape_function_values() (pancax.fem.function_space.nonallocatedfunctionspace method)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.shape_function_values", false]], "shape_functions (pancax.fem.function_space.nonallocatedfunctionspace attribute)": [[8, "pancax.fem.function_space.NonAllocatedFunctionSpace.shape_functions", false]], "shapefunctions (class in pancax.fem.elements.base_element)": [[9, "pancax.fem.elements.base_element.ShapeFunctions", false]], "shapegrads (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace.shapeGrads", false]], "shapes (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace.shapes", false]], "sideset (pancax.bcs.natural_bc.naturalbc attribute)": [[3, "pancax.bcs.natural_bc.NaturalBC.sideset", false]], "sidesets (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.sideSets", false]], "sigma (pancax.networks.rbf.rbfbasis attribute)": [[13, "pancax.networks.rbf.RBFBasis.sigma", false]], "simpleshearlinearramp() (in module pancax.bvps.simple_shear)": [[4, "pancax.bvps.simple_shear.SimpleShearLinearRamp", false]], "simplexnodesordinals (pancax.fem.mesh.mesh attribute)": [[8, "pancax.fem.mesh.Mesh.simplexNodesOrdinals", false]], "simplextrielement (class in pancax.fem.elements.simplex_tri_element)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement", false]], "slice_unknowns_with_dof_indices() (pancax.fem.dof_manager.dofmanager method)": [[8, "pancax.fem.dof_manager.DofManager.slice_unknowns_with_dof_indices", false]], "solidmechanics (class in pancax.kernels.solid_mechanics)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics", false]], "solve_eigen_problem() (pancax.domains.delta_pinn_domain.deltapinndomain method)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.solve_eigen_problem", false]], "sqrtm_dbp() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.sqrtm_dbp", false]], "standard_pp() (in module pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.standard_pp", false]], "start() (pancax.timer.timer method)": [[2, "pancax.timer.Timer.start", false]], "step() (pancax.trainer.trainer method)": [[2, "pancax.trainer.Trainer.step", false]], "stiffness_matrix() (in module pancax.physics)": [[2, "pancax.physics.stiffness_matrix", false]], "stop() (pancax.timer.timer method)": [[2, "pancax.timer.Timer.stop", false]], "strong_form_neumann_bc() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.strong_form_neumann_bc", false]], "strong_form_neumann_bc() (pancax.kernels.linear_elasticity.linearelasticity2d method)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.strong_form_neumann_bc", false]], "strong_form_neumann_bc() (pancax.kernels.poisson.poisson method)": [[10, "pancax.kernels.poisson.Poisson.strong_form_neumann_bc", false]], "strong_form_neumann_bc() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.strong_form_neumann_bc", false]], "strong_form_residual() (in module pancax.physics)": [[2, "pancax.physics.strong_form_residual", false]], "strong_form_residual() (pancax.kernels.base_kernel.strongformphysicskernel method)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.strong_form_residual", false]], "strong_form_residual() (pancax.kernels.linear_elasticity.linearelasticity2d method)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.strong_form_residual", false]], "strong_form_residual() (pancax.kernels.poisson.poisson method)": [[10, "pancax.kernels.poisson.Poisson.strong_form_residual", false]], "strong_form_residual() (pancax.kernels.solid_mechanics.solidmechanics method)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.strong_form_residual", false]], "strongformincompressibilityconstraint() (in module pancax.loss_functions.physics_loss_functions_strong_form)": [[11, "pancax.loss_functions.physics_loss_functions_strong_form.StrongFormIncompressibilityConstraint", false]], "strongformneumannbcloss() (in module pancax.loss_functions.physics_loss_functions_strong_form)": [[11, "pancax.loss_functions.physics_loss_functions_strong_form.StrongFormNeumannBCLoss", false]], "strongformphysicskernel (class in pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel", false]], "strongformresidualloss (class in pancax.loss_functions.strong_form_loss_functions)": [[11, "pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss", false]], "strongformresidualloss() (in module pancax.loss_functions.physics_loss_functions_strong_form)": [[11, "pancax.loss_functions.physics_loss_functions_strong_form.StrongFormResidualLoss", false]], "sum2() (in module pancax.math.math)": [[12, "pancax.math.math.sum2", false]], "swanson4 (class in pancax.constitutive_models.swanson)": [[5, "pancax.constitutive_models.swanson.Swanson4", false]], "swanson4fixedbulkmodulus (class in pancax.constitutive_models.swanson)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus", false]], "swanson6 (class in pancax.constitutive_models.swanson)": [[5, "pancax.constitutive_models.swanson.Swanson6", false]], "swanson6fixedbulkmodulus (class in pancax.constitutive_models.swanson)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus", false]], "sym() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.sym", false]], "tensor_2d_to_3d() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.tensor_2D_to_3D", false]], "tensor_norm() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.tensor_norm", false]], "tet10element (class in pancax.fem.elements.tet10_element)": [[9, "pancax.fem.elements.tet10_element.Tet10Element", false]], "tet4element (class in pancax.fem.elements.tet4_element)": [[9, "pancax.fem.elements.tet4_element.Tet4Element", false]], "text (pancax.timer.timer attribute)": [[2, "pancax.timer.Timer.text", false]], "threedimensional (class in pancax.kernels.solid_mechanics)": [[10, "pancax.kernels.solid_mechanics.ThreeDimensional", false]], "timer (class in pancax.timer)": [[2, "pancax.timer.Timer", false]], "timererror": [[2, "pancax.timer.TimerError", false]], "timers (pancax.timer.timer attribute)": [[2, "pancax.timer.Timer.timers", false]], "times (pancax.data.global_data.globaldata attribute)": [[6, "pancax.data.global_data.GlobalData.times", false]], "times (pancax.domains.base_domain.basedomain attribute)": [[7, "pancax.domains.base_domain.BaseDomain.times", false]], "times (pancax.domains.collocation_domain.collocationdomain attribute)": [[7, "pancax.domains.collocation_domain.CollocationDomain.times", false]], "times (pancax.domains.delta_pinn_domain.deltapinndomain attribute)": [[7, "pancax.domains.delta_pinn_domain.DeltaPINNDomain.times", false]], "times (pancax.domains.inverse_domain.inversedomain attribute)": [[7, "pancax.domains.inverse_domain.InverseDomain.times", false]], "times (pancax.domains.variational_domain.variationaldomain attribute)": [[7, "pancax.domains.variational_domain.VariationalDomain.times", false]], "to_csv() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.to_csv", false]], "to_csv() (pancax.history_writer.ensemblehistorywriter method)": [[2, "pancax.history_writer.EnsembleHistoryWriter.to_csv", false]], "to_csv() (pancax.history_writer.historywriter method)": [[2, "pancax.history_writer.HistoryWriter.to_csv", false]], "traction_energy() (in module pancax.physics)": [[2, "pancax.physics.traction_energy", false]], "train() (pancax.optimizers.base.optimizer method)": [[14, "pancax.optimizers.base.Optimizer.train", false]], "train() (pancax.trainer.trainer method)": [[2, "pancax.trainer.Trainer.train", false]], "trainable_filter() (in module pancax.optimizers.utils)": [[14, "pancax.optimizers.utils.trainable_filter", false]], "trainer (class in pancax.trainer)": [[2, "pancax.trainer.Trainer", false]], "triaxiality() (in module pancax.math.tensor_math)": [[12, "pancax.math.tensor_math.triaxiality", false]], "trunc_init() (in module pancax.networks.initialization)": [[13, "pancax.networks.initialization.trunc_init", false]], "uniaxialtensionlinearramp() (in module pancax.bvps.uniaxial_tension)": [[4, "pancax.bvps.uniaxial_tension.UniaxialTensionLinearRamp", false]], "unpack_properties() (pancax.constitutive_models.base_constitutive_model.constitutivemodel method)": [[5, "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.blatz_ko.blatzko method)": [[5, "pancax.constitutive_models.blatz_ko.BlatzKo.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.gent.gent method)": [[5, "pancax.constitutive_models.gent.Gent.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.gent.gentfixedbulkmodulus method)": [[5, "pancax.constitutive_models.gent.GentFixedBulkModulus.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.neohookean.neohookean method)": [[5, "pancax.constitutive_models.neohookean.NeoHookean.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.neohookean.neohookeanfixedbulkmodulus method)": [[5, "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.swanson.swanson4 method)": [[5, "pancax.constitutive_models.swanson.Swanson4.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.swanson.swanson4fixedbulkmodulus method)": [[5, "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.swanson.swanson6 method)": [[5, "pancax.constitutive_models.swanson.Swanson6.unpack_properties", false]], "unpack_properties() (pancax.constitutive_models.swanson.swanson6fixedbulkmodulus method)": [[5, "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus.unpack_properties", false]], "use_delta_pinn (pancax.kernels.base_kernel.physicskernel attribute)": [[10, "pancax.kernels.base_kernel.PhysicsKernel.use_delta_pinn", false]], "use_delta_pinn (pancax.kernels.base_kernel.strongformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.StrongFormPhysicsKernel.use_delta_pinn", false]], "use_delta_pinn (pancax.kernels.base_kernel.weakformphysicskernel attribute)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel.use_delta_pinn", false]], "use_delta_pinn (pancax.kernels.laplace_beltrami.laplacebeltrami attribute)": [[10, "pancax.kernels.laplace_beltrami.LaplaceBeltrami.use_delta_pinn", false]], "use_delta_pinn (pancax.kernels.linear_elasticity.linearelasticity2d attribute)": [[10, "pancax.kernels.linear_elasticity.LinearElasticity2D.use_delta_pinn", false]], "use_delta_pinn (pancax.kernels.poisson.poisson attribute)": [[10, "pancax.kernels.poisson.Poisson.use_delta_pinn", false]], "use_delta_pinn (pancax.kernels.solid_mechanics.solidmechanics attribute)": [[10, "pancax.kernels.solid_mechanics.SolidMechanics.use_delta_pinn", false]], "value_and_grad_from_state() (in module pancax.optimizers.lbfgs)": [[14, "pancax.optimizers.lbfgs.value_and_grad_from_state", false]], "values (pancax.fem.elements.base_element.shapefunctions attribute)": [[9, "pancax.fem.elements.base_element.ShapeFunctions.values", false]], "vander1d() (in module pancax.fem.elements.base_element)": [[9, "pancax.fem.elements.base_element.vander1d", false]], "vander2d() (in module pancax.fem.elements.base_element)": [[9, "pancax.fem.elements.base_element.vander2d", false]], "var_name_to_method (pancax.kernels.base_kernel.physicskernel attribute)": [[10, "pancax.kernels.base_kernel.PhysicsKernel.var_name_to_method", false]], "variationaldomain (class in pancax.domains.variational_domain)": [[7, "pancax.domains.variational_domain.VariationalDomain", false]], "vector_names() (in module pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.vector_names", false]], "vertexnodes (pancax.fem.elements.base_element.baseelement attribute)": [[9, "pancax.fem.elements.base_element.BaseElement.vertexNodes", false]], "vertexnodes (pancax.fem.elements.hex8_element.hex8element attribute)": [[9, "pancax.fem.elements.hex8_element.Hex8Element.vertexNodes", false]], "vertexnodes (pancax.fem.elements.line_element.lineelement attribute)": [[9, "pancax.fem.elements.line_element.LineElement.vertexNodes", false]], "vertexnodes (pancax.fem.elements.quad4_element.quad4element attribute)": [[9, "pancax.fem.elements.quad4_element.Quad4Element.vertexNodes", false]], "vertexnodes (pancax.fem.elements.quad9_element.quad9element attribute)": [[9, "pancax.fem.elements.quad9_element.Quad9Element.vertexNodes", false]], "vertexnodes (pancax.fem.elements.simplex_tri_element.simplextrielement attribute)": [[9, "pancax.fem.elements.simplex_tri_element.SimplexTriElement.vertexNodes", false]], "vertexnodes (pancax.fem.elements.tet10_element.tet10element attribute)": [[9, "pancax.fem.elements.tet10_element.Tet10Element.vertexNodes", false]], "vertexnodes (pancax.fem.elements.tet4_element.tet4element attribute)": [[9, "pancax.fem.elements.tet4_element.Tet4Element.vertexNodes", false]], "vols (pancax.fem.function_space.functionspace attribute)": [[8, "pancax.fem.function_space.FunctionSpace.vols", false]], "weakformphysicskernel (class in pancax.kernels.base_kernel)": [[10, "pancax.kernels.base_kernel.WeakFormPhysicsKernel", false]], "weight (pancax.loss_functions.bc_loss_functions.dirichletbcloss attribute)": [[11, "pancax.loss_functions.bc_loss_functions.DirichletBCLoss.weight", false]], "weight (pancax.loss_functions.bc_loss_functions.neumannbcloss attribute)": [[11, "pancax.loss_functions.bc_loss_functions.NeumannBCLoss.weight", false]], "weight (pancax.loss_functions.data_loss_functions.fullfielddataloss attribute)": [[11, "pancax.loss_functions.data_loss_functions.FullFieldDataLoss.weight", false]], "weight (pancax.loss_functions.strong_form_loss_functions.strongformresidualloss attribute)": [[11, "pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss.weight", false]], "weight (pancax.loss_functions.weak_form_loss_functions.energyloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.EnergyLoss.weight", false]], "weight (pancax.loss_functions.weak_form_loss_functions.incompressibleenergyloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss.weight", false]], "weight (pancax.loss_functions.weak_form_loss_functions.quadratureincompressibilityconstraint attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint.weight", false]], "weight (pancax.loss_functions.weak_form_loss_functions.residualmseloss attribute)": [[11, "pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss.weight", false]], "wgauss (pancax.fem.quadrature_rules.quadraturerule attribute)": [[8, "pancax.fem.quadrature_rules.QuadratureRule.wgauss", false]], "with_props (pancax.loss_functions.utils.combinelossfunctions attribute)": [[11, "pancax.loss_functions.utils.CombineLossFunctions.with_props", false]], "write_aux_values() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.write_aux_values", false]], "write_aux_values() (pancax.history_writer.ensemblehistorywriter method)": [[2, "pancax.history_writer.EnsembleHistoryWriter.write_aux_values", false]], "write_aux_values() (pancax.history_writer.historywriter method)": [[2, "pancax.history_writer.HistoryWriter.write_aux_values", false]], "write_aux_values() (pancax.logging.baselogger method)": [[2, "pancax.logging.BaseLogger.write_aux_values", false]], "write_aux_values() (pancax.logging.ensemblelogger method)": [[2, "pancax.logging.EnsembleLogger.write_aux_values", false]], "write_aux_values() (pancax.logging.logger method)": [[2, "pancax.logging.Logger.write_aux_values", false]], "write_data() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.write_data", false]], "write_epoch() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.write_epoch", false]], "write_epoch() (pancax.history_writer.ensemblehistorywriter method)": [[2, "pancax.history_writer.EnsembleHistoryWriter.write_epoch", false]], "write_epoch() (pancax.history_writer.historywriter method)": [[2, "pancax.history_writer.HistoryWriter.write_epoch", false]], "write_epoch_value() (pancax.logging.baselogger method)": [[2, "pancax.logging.BaseLogger.write_epoch_value", false]], "write_epoch_value() (pancax.logging.ensemblelogger method)": [[2, "pancax.logging.EnsembleLogger.write_epoch_value", false]], "write_epoch_value() (pancax.logging.logger method)": [[2, "pancax.logging.Logger.write_epoch_value", false]], "write_every (pancax.history_writer.basehistorywriter attribute)": [[2, "pancax.history_writer.BaseHistoryWriter.write_every", false]], "write_every (pancax.history_writer.ensemblehistorywriter attribute)": [[2, "pancax.history_writer.EnsembleHistoryWriter.write_every", false]], "write_every (pancax.history_writer.historywriter attribute)": [[2, "pancax.history_writer.HistoryWriter.write_every", false]], "write_history() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.write_history", false]], "write_loss() (pancax.history_writer.basehistorywriter method)": [[2, "pancax.history_writer.BaseHistoryWriter.write_loss", false]], "write_loss() (pancax.history_writer.ensemblehistorywriter method)": [[2, "pancax.history_writer.EnsembleHistoryWriter.write_loss", false]], "write_loss() (pancax.history_writer.historywriter method)": [[2, "pancax.history_writer.HistoryWriter.write_loss", false]], "write_loss_value() (pancax.logging.baselogger method)": [[2, "pancax.logging.BaseLogger.write_loss_value", false]], "write_loss_value() (pancax.logging.ensemblelogger method)": [[2, "pancax.logging.EnsembleLogger.write_loss_value", false]], "write_loss_value() (pancax.logging.logger method)": [[2, "pancax.logging.Logger.write_loss_value", false]], "write_outputs() (pancax.post_processor.postprocessor method)": [[2, "pancax.post_processor.PostProcessor.write_outputs", false]], "write_outputs() (pancax.trainer.trainer method)": [[2, "pancax.trainer.Trainer.write_outputs", false]], "xigauss (pancax.fem.quadrature_rules.quadraturerule attribute)": [[8, "pancax.fem.quadrature_rules.QuadratureRule.xigauss", false]], "zero_init() (in module pancax.networks.initialization)": [[13, "pancax.networks.initialization.zero_init", false]]}, "objects": {"": [[2, 0, 0, "-", "pancax"]], "pancax": [[3, 0, 0, "-", "bcs"], [4, 0, 0, "-", "bvps"], [5, 0, 0, "-", "constitutive_models"], [6, 0, 0, "-", "data"], [7, 0, 0, "-", "domains"], [8, 0, 0, "-", "fem"], [2, 0, 0, "-", "history_writer"], [10, 0, 0, "-", "kernels"], [2, 0, 0, "-", "kinematics"], [2, 0, 0, "-", "logging"], [11, 0, 0, "-", "loss_functions"], [12, 0, 0, "-", "math"], [13, 0, 0, "-", "networks"], [14, 0, 0, "-", "optimizers"], [2, 0, 0, "-", "physics"], [2, 0, 0, "-", "post_processor"], [2, 0, 0, "-", "timer"], [2, 0, 0, "-", "trainer"], [2, 0, 0, "-", "utils"]], "pancax.bcs": [[3, 0, 0, "-", "distance_functions"], [3, 0, 0, "-", "essential_bc"], [3, 0, 0, "-", "natural_bc"]], "pancax.bcs.distance_functions": [[3, 1, 1, "", "distance"], [3, 1, 1, "", "distance_function"], [3, 1, 1, "", "get_edges"], [3, 1, 1, "", "line_segment"]], "pancax.bcs.essential_bc": [[3, 2, 1, "", "EssentialBC"], [3, 2, 1, "", "EssentialBCSet"]], "pancax.bcs.essential_bc.EssentialBC": [[3, 3, 1, "", "__init__"], [3, 4, 1, "", "_abc_impl"], [3, 4, 1, "", "component"], [3, 3, 1, "", "coordinates"], [3, 3, 1, "", "function"], [3, 4, 1, "", "nodeSet"]], "pancax.bcs.essential_bc.EssentialBCSet": [[3, 3, 1, "", "__init__"], [3, 4, 1, "", "_abc_impl"], [3, 4, 1, "", "bcs"]], "pancax.bcs.natural_bc": [[3, 2, 1, "", "NaturalBC"]], "pancax.bcs.natural_bc.NaturalBC": [[3, 3, 1, "", "__init__"], [3, 4, 1, "", "_abc_impl"], [3, 3, 1, "", "coordinates"], [3, 3, 1, "", "function"], [3, 3, 1, "", "normals"], [3, 4, 1, "", "sideset"]], "pancax.bvps": [[4, 0, 0, "-", "biaxial_tension"], [4, 0, 0, "-", "simple_shear"], [4, 0, 0, "-", "uniaxial_tension"]], "pancax.bvps.biaxial_tension": [[4, 1, 1, "", "BiaxialLinearRamp"]], "pancax.bvps.simple_shear": [[4, 1, 1, "", "SimpleShearLinearRamp"]], "pancax.bvps.uniaxial_tension": [[4, 1, 1, "", "UniaxialTensionLinearRamp"]], "pancax.constitutive_models": [[5, 0, 0, "-", "base_constitutive_model"], [5, 0, 0, "-", "blatz_ko"], [5, 0, 0, "-", "gent"], [5, 0, 0, "-", "neohookean"], [5, 0, 0, "-", "swanson"]], "pancax.constitutive_models.base_constitutive_model": [[5, 2, 1, "", "ConstitutiveModel"], [5, 2, 1, "", "ConstitutiveModelFixedBulkModulus"]], "pancax.constitutive_models.base_constitutive_model.ConstitutiveModel": [[5, 3, 1, "", "I1"], [5, 3, 1, "", "I1_bar"], [5, 3, 1, "", "I2"], [5, 3, 1, "", "I2_bar"], [5, 4, 1, "", "_abc_impl"], [5, 3, 1, "", "cauchy_stress"], [5, 3, 1, "", "energy"], [5, 3, 1, "", "invariants"], [5, 3, 1, "", "jacobian"], [5, 4, 1, "", "n_properties"], [5, 3, 1, "", "pk1_stress"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.base_constitutive_model.ConstitutiveModelFixedBulkModulus": [[5, 3, 1, "", "__init__"], [5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "bulk_modulus"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"]], "pancax.constitutive_models.blatz_ko": [[5, 2, 1, "", "BlatzKo"]], "pancax.constitutive_models.blatz_ko.BlatzKo": [[5, 4, 1, "", "_abc_impl"], [5, 3, 1, "", "energy"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.gent": [[5, 2, 1, "", "Gent"], [5, 2, 1, "", "GentFixedBulkModulus"]], "pancax.constitutive_models.gent.Gent": [[5, 4, 1, "", "_abc_impl"], [5, 3, 1, "", "energy"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.gent.GentFixedBulkModulus": [[5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "bulk_modulus"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.neohookean": [[5, 2, 1, "", "NeoHookean"], [5, 2, 1, "", "NeoHookeanFixedBulkModulus"]], "pancax.constitutive_models.neohookean.NeoHookean": [[5, 4, 1, "", "_abc_impl"], [5, 3, 1, "", "energy"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.neohookean.NeoHookeanFixedBulkModulus": [[5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "bulk_modulus"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.swanson": [[5, 2, 1, "", "Swanson4"], [5, 2, 1, "", "Swanson4FixedBulkModulus"], [5, 2, 1, "", "Swanson6"], [5, 2, 1, "", "Swanson6FixedBulkModulus"]], "pancax.constitutive_models.swanson.Swanson4": [[5, 3, 1, "", "__init__"], [5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "cutoff_strain"], [5, 3, 1, "", "energy"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.swanson.Swanson4FixedBulkModulus": [[5, 3, 1, "", "__init__"], [5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "bulk_modulus"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.swanson.Swanson6": [[5, 3, 1, "", "__init__"], [5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "cutoff_strain"], [5, 3, 1, "", "energy"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.constitutive_models.swanson.Swanson6FixedBulkModulus": [[5, 3, 1, "", "__init__"], [5, 4, 1, "", "_abc_impl"], [5, 4, 1, "", "bulk_modulus"], [5, 4, 1, "", "cutoff_strain"], [5, 4, 1, "", "n_properties"], [5, 4, 1, "", "property_names"], [5, 3, 1, "", "unpack_properties"]], "pancax.data": [[6, 0, 0, "-", "full_field_data"], [6, 0, 0, "-", "global_data"]], "pancax.data.full_field_data": [[6, 2, 1, "", "FullFieldData"]], "pancax.data.full_field_data.FullFieldData": [[6, 3, 1, "", "__init__"], [6, 4, 1, "", "_abc_impl"], [6, 4, 1, "", "inputs"], [6, 4, 1, "", "n_time_steps"], [6, 4, 1, "", "outputs"], [6, 3, 1, "", "plot_data"], [6, 3, 1, "", "plot_registration"]], "pancax.data.global_data": [[6, 2, 1, "", "GlobalData"]], "pancax.data.global_data.GlobalData": [[6, 3, 1, "", "__init__"], [6, 4, 1, "", "_abc_impl"], [6, 4, 1, "", "displacements"], [6, 4, 1, "", "n_nodes"], [6, 4, 1, "", "n_time_steps"], [6, 4, 1, "", "outputs"], [6, 4, 1, "", "reaction_dof"], [6, 4, 1, "", "reaction_nodes"], [6, 4, 1, "", "times"]], "pancax.domains": [[7, 0, 0, "-", "base_domain"], [7, 0, 0, "-", "collocation_domain"], [7, 0, 0, "-", "delta_pinn_domain"], [7, 0, 0, "-", "inverse_domain"], [7, 0, 0, "-", "utils"], [7, 0, 0, "-", "variational_domain"]], "pancax.domains.base_domain": [[7, 2, 1, "", "BaseDomain"]], "pancax.domains.base_domain.BaseDomain": [[7, 3, 1, "", "__init__"], [7, 4, 1, "", "_abc_impl"], [7, 4, 1, "", "coords"], [7, 4, 1, "", "dof_manager"], [7, 4, 1, "", "essential_bcs"], [7, 3, 1, "", "field_values"], [7, 4, 1, "", "mesh"], [7, 4, 1, "", "mesh_file"], [7, 4, 1, "", "natural_bcs"], [7, 4, 1, "", "physics"], [7, 4, 1, "", "times"]], "pancax.domains.collocation_domain": [[7, 2, 1, "", "CollocationDomain"]], "pancax.domains.collocation_domain.CollocationDomain": [[7, 3, 1, "", "__init__"], [7, 4, 1, "", "_abc_impl"], [7, 4, 1, "", "coords"], [7, 4, 1, "", "dof_manager"], [7, 4, 1, "", "essential_bcs"], [7, 4, 1, "", "mesh"], [7, 4, 1, "", "natural_bcs"], [7, 4, 1, "", "neumann_ns"], [7, 4, 1, "", "neumann_xs"], [7, 4, 1, "", "physics"], [7, 4, 1, "", "times"]], "pancax.domains.delta_pinn_domain": [[7, 2, 1, "", "DeltaPINNDomain"]], "pancax.domains.delta_pinn_domain.DeltaPINNDomain": [[7, 3, 1, "", "__init__"], [7, 4, 1, "", "_abc_impl"], [7, 4, 1, "", "conns"], [7, 4, 1, "", "coords"], [7, 4, 1, "", "dof_manager"], [7, 4, 1, "", "eigen_modes"], [7, 4, 1, "", "essential_bcs"], [7, 3, 1, "", "field_values"], [7, 4, 1, "", "fspace"], [7, 4, 1, "", "fspace_centroid"], [7, 4, 1, "", "mesh"], [7, 4, 1, "", "n_eigen_values"], [7, 4, 1, "", "natural_bcs"], [7, 4, 1, "", "physics"], [7, 3, 1, "", "solve_eigen_problem"], [7, 4, 1, "", "times"]], "pancax.domains.inverse_domain": [[7, 2, 1, "", "InverseDomain"]], "pancax.domains.inverse_domain.InverseDomain": [[7, 3, 1, "", "__init__"], [7, 4, 1, "", "_abc_impl"], [7, 4, 1, "", "conns"], [7, 4, 1, "", "coords"], [7, 4, 1, "", "dof_manager"], [7, 4, 1, "", "field_data"], [7, 4, 1, "", "fspace"], [7, 4, 1, "", "fspace_centroid"], [7, 4, 1, "", "global_data"], [7, 4, 1, "", "physics"], [7, 4, 1, "", "times"]], "pancax.domains.utils": [[7, 1, 1, "", "make_mesh_time_dependent"], [7, 1, 1, "", "make_times_column"]], "pancax.domains.variational_domain": [[7, 2, 1, "", "VariationalDomain"]], "pancax.domains.variational_domain.VariationalDomain": [[7, 3, 1, "", "__init__"], [7, 4, 1, "", "_abc_impl"], [7, 4, 1, "", "conns"], [7, 4, 1, "", "coords"], [7, 4, 1, "", "dof_manager"], [7, 4, 1, "", "essential_bcs"], [7, 4, 1, "", "fspace"], [7, 4, 1, "", "fspace_centroid"], [7, 4, 1, "", "mesh"], [7, 4, 1, "", "natural_bcs"], [7, 4, 1, "", "physics"], [7, 4, 1, "", "times"]], "pancax.fem": [[8, 0, 0, "-", "dof_manager"], [9, 0, 0, "-", "elements"], [8, 0, 0, "-", "function_space"], [8, 0, 0, "-", "mesh"], [8, 0, 0, "-", "quadrature_rules"], [8, 0, 0, "-", "read_exodus_mesh"], [8, 0, 0, "-", "sparse_matrix_assembler"], [8, 0, 0, "-", "surface"], [8, 0, 0, "-", "traction_bc"]], "pancax.fem.dof_manager": [[8, 2, 1, "", "DofManager"]], "pancax.fem.dof_manager.DofManager": [[8, 3, 1, "", "__init__"], [8, 3, 1, "", "_make_hessian_bc_mask"], [8, 3, 1, "", "_make_hessian_coordinates"], [8, 3, 1, "", "create_field"], [8, 3, 1, "", "get_bc_size"], [8, 3, 1, "", "get_bc_values"], [8, 3, 1, "", "get_unknown_size"], [8, 3, 1, "", "get_unknown_values"], [8, 3, 1, "", "slice_unknowns_with_dof_indices"]], "pancax.fem.elements": [[9, 0, 0, "-", "base_element"], [9, 0, 0, "-", "hex8_element"], [9, 0, 0, "-", "line_element"], [9, 0, 0, "-", "quad4_element"], [9, 0, 0, "-", "quad9_element"], [9, 0, 0, "-", "simplex_tri_element"], [9, 0, 0, "-", "tet10_element"], [9, 0, 0, "-", "tet4_element"]], "pancax.fem.elements.base_element": [[9, 2, 1, "", "BaseElement"], [9, 2, 1, "", "ShapeFunctions"], [9, 1, 1, "", "get_lobatto_nodes_1d"], [9, 1, 1, "", "pascal_triangle_monomials"], [9, 1, 1, "", "vander1d"], [9, 1, 1, "", "vander2d"]], "pancax.fem.elements.base_element.BaseElement": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.base_element.ShapeFunctions": [[9, 3, 1, "", "_asdict"], [9, 4, 1, "", "_field_defaults"], [9, 4, 1, "", "_fields"], [9, 3, 1, "", "_make"], [9, 3, 1, "", "_replace"], [9, 4, 1, "", "gradients"], [9, 4, 1, "", "values"]], "pancax.fem.elements.hex8_element": [[9, 2, 1, "", "Hex8Element"]], "pancax.fem.elements.hex8_element.Hex8Element": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.line_element": [[9, 2, 1, "", "LineElement"]], "pancax.fem.elements.line_element.LineElement": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.quad4_element": [[9, 2, 1, "", "Quad4Element"]], "pancax.fem.elements.quad4_element.Quad4Element": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.quad9_element": [[9, 2, 1, "", "Quad9Element"]], "pancax.fem.elements.quad9_element.Quad9Element": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.simplex_tri_element": [[9, 2, 1, "", "SimplexTriElement"]], "pancax.fem.elements.simplex_tri_element.SimplexTriElement": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.tet10_element": [[9, 2, 1, "", "Tet10Element"]], "pancax.fem.elements.tet10_element.Tet10Element": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.elements.tet4_element": [[9, 2, 1, "", "Tet4Element"]], "pancax.fem.elements.tet4_element.Tet4Element": [[9, 3, 1, "", "__init__"], [9, 4, 1, "", "_abc_impl"], [9, 3, 1, "", "compute_shapes"], [9, 4, 1, "", "coordinates"], [9, 4, 1, "", "degree"], [9, 4, 1, "", "elementType"], [9, 4, 1, "", "faceNodes"], [9, 4, 1, "", "interiorNodes"], [9, 4, 1, "", "vertexNodes"]], "pancax.fem.function_space": [[8, 2, 1, "", "FunctionSpace"], [8, 2, 1, "", "NonAllocatedFunctionSpace"], [8, 1, 1, "", "average_quadrature_field_over_element"], [8, 1, 1, "", "compute_element_field_gradient"], [8, 1, 1, "", "compute_element_volumes"], [8, 1, 1, "", "compute_element_volumes_axisymmetric"], [8, 1, 1, "", "compute_field_gradient"], [8, 1, 1, "", "compute_quadrature_point_field_gradient"], [8, 1, 1, "", "construct_function_space"], [8, 1, 1, "", "construct_function_space_from_parent_element"], [8, 1, 1, "", "default_modify_element_gradient"], [8, 1, 1, "", "evaluate_on_block"], [8, 1, 1, "", "evaluate_on_element"], [8, 1, 1, "", "get_nodal_values_on_edge"], [8, 1, 1, "", "integrate_element"], [8, 1, 1, "", "integrate_element_from_local_field"], [8, 1, 1, "", "integrate_function_on_edge"], [8, 1, 1, "", "integrate_function_on_edges"], [8, 1, 1, "", "integrate_over_block"], [8, 1, 1, "", "interpolate_nodal_field_on_edge"], [8, 1, 1, "", "interpolate_to_element_points"], [8, 1, 1, "", "interpolate_to_point"], [8, 1, 1, "", "interpolate_to_points"], [8, 1, 1, "", "map_element_shape_grads"], [8, 1, 1, "", "project_quadrature_field_to_element_field"]], "pancax.fem.function_space.FunctionSpace": [[8, 3, 1, "", "__init__"], [8, 4, 1, "", "_abc_impl"], [8, 4, 1, "", "conns"], [8, 4, 1, "", "isAxisymmetric"], [8, 4, 1, "", "quadratureRule"], [8, 4, 1, "", "shapeGrads"], [8, 4, 1, "", "shapes"], [8, 4, 1, "", "vols"]], "pancax.fem.function_space.NonAllocatedFunctionSpace": [[8, 3, 1, "", "JxWs"], [8, 3, 1, "", "__init__"], [8, 4, 1, "", "_abc_impl"], [8, 3, 1, "", "compute_field_gradient"], [8, 3, 1, "", "evaluate_on_element"], [8, 3, 1, "", "integrate_on_element"], [8, 3, 1, "", "integrate_on_elements"], [8, 4, 1, "", "quadrature_rule"], [8, 3, 1, "", "shape_function_gradients"], [8, 3, 1, "", "shape_function_values"], [8, 4, 1, "", "shape_functions"]], "pancax.fem.mesh": [[8, 2, 1, "", "Mesh"], [8, 1, 1, "", "combine_blocks"], [8, 1, 1, "", "combine_mesh"], [8, 1, 1, "", "combine_nodesets"], [8, 1, 1, "", "combine_sidesets"], [8, 1, 1, "", "compute_edge_vectors"], [8, 1, 1, "", "construct_mesh_from_basic_data"], [8, 1, 1, "", "construct_structured_mesh"], [8, 1, 1, "", "create_edges"], [8, 1, 1, "", "create_higher_order_mesh_from_simplex_mesh"], [8, 1, 1, "", "create_nodesets_from_sidesets"], [8, 1, 1, "", "create_structured_mesh_data"], [8, 1, 1, "", "get_edge_coords"], [8, 1, 1, "", "get_edge_field"], [8, 1, 1, "", "get_edge_node_indices"], [8, 1, 1, "", "mesh_with_blocks"], [8, 1, 1, "", "mesh_with_coords"], [8, 1, 1, "", "mesh_with_nodesets"], [8, 1, 1, "", "num_nodes"]], "pancax.fem.mesh.Mesh": [[8, 3, 1, "", "__init__"], [8, 4, 1, "", "_abc_impl"], [8, 4, 1, "", "blocks"], [8, 4, 1, "", "conns"], [8, 4, 1, "", "coords"], [8, 3, 1, "", "get_blocks"], [8, 4, 1, "", "nodeSets"], [8, 5, 1, "", "num_dimensions"], [8, 5, 1, "", "num_elements"], [8, 5, 1, "", "num_nodes"], [8, 4, 1, "", "parentElement"], [8, 4, 1, "", "parentElement1d"], [8, 4, 1, "", "sideSets"], [8, 4, 1, "", "simplexNodesOrdinals"]], "pancax.fem.quadrature_rules": [[8, 2, 1, "", "QuadratureRule"], [8, 1, 1, "", "_gauss_quad_1D_1pt"], [8, 1, 1, "", "_gauss_quad_1D_2pt"], [8, 1, 1, "", "_gauss_quad_1D_3pt"], [8, 1, 1, "", "_gauss_quad_1D_4pt"], [8, 1, 1, "", "_gauss_quad_1D_5pt"], [8, 1, 1, "", "create_padded_quadrature_rule_1D"], [8, 1, 1, "", "create_quadrature_rule_1D"], [8, 1, 1, "", "create_quadrature_rule_on_hex"], [8, 1, 1, "", "create_quadrature_rule_on_quad"], [8, 1, 1, "", "create_quadrature_rule_on_tet"], [8, 1, 1, "", "create_quadrature_rule_on_triangle"], [8, 1, 1, "", "eval_at_iso_points"]], "pancax.fem.quadrature_rules.QuadratureRule": [[8, 3, 1, "", "__init__"], [8, 4, 1, "", "_abc_impl"], [8, 4, 1, "", "wgauss"], [8, 4, 1, "", "xigauss"]], "pancax.fem.read_exodus_mesh": [[8, 1, 1, "", "_get_vertex_nodes_from_exodus_tri6_mesh"], [8, 1, 1, "", "_read_block_conns"], [8, 1, 1, "", "_read_blocks"], [8, 1, 1, "", "_read_coordinates"], [8, 1, 1, "", "_read_element_type"], [8, 1, 1, "", "_read_names_list"], [8, 1, 1, "", "_read_node_sets"], [8, 1, 1, "", "_read_side_sets"], [8, 1, 1, "", "read_exodus_mesh"]], "pancax.fem.sparse_matrix_assembler": [[8, 1, 1, "", "assemble_sparse_stiffness_matrix"]], "pancax.fem.surface": [[8, 1, 1, "", "compute_edge_vectors"], [8, 1, 1, "", "compute_normal"], [8, 1, 1, "", "create_edges"], [8, 1, 1, "", "eval_field"], [8, 1, 1, "", "get_coords"], [8, 1, 1, "", "get_field_index"], [8, 1, 1, "", "integrate_function"], [8, 1, 1, "", "integrate_function_on_edge"], [8, 1, 1, "", "integrate_function_on_surface"], [8, 1, 1, "", "integrate_values"], [8, 1, 1, "", "interpolate_nodal_field_on_edge"]], "pancax.fem.traction_bc": [[8, 1, 1, "", "compute_traction_potential_energy"], [8, 1, 1, "", "compute_traction_potential_energy_on_edge"], [8, 1, 1, "", "interpolate_nodal_field_on_edge"]], "pancax.history_writer": [[2, 2, 1, "", "BaseHistoryWriter"], [2, 2, 1, "", "EnsembleHistoryWriter"], [2, 2, 1, "", "HistoryWriter"]], "pancax.history_writer.BaseHistoryWriter": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_abc_impl"], [2, 4, 1, "", "log_every"], [2, 3, 1, "", "to_csv"], [2, 3, 1, "", "write_aux_values"], [2, 3, 1, "", "write_data"], [2, 3, 1, "", "write_epoch"], [2, 4, 1, "", "write_every"], [2, 3, 1, "", "write_history"], [2, 3, 1, "", "write_loss"]], "pancax.history_writer.EnsembleHistoryWriter": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_abc_impl"], [2, 4, 1, "", "history_writers"], [2, 4, 1, "", "log_every"], [2, 3, 1, "", "to_csv"], [2, 3, 1, "", "write_aux_values"], [2, 3, 1, "", "write_epoch"], [2, 4, 1, "", "write_every"], [2, 3, 1, "", "write_loss"]], "pancax.history_writer.HistoryWriter": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_abc_impl"], [2, 3, 1, "", "_write_loss"], [2, 4, 1, "", "data_dict"], [2, 4, 1, "", "history_file"], [2, 4, 1, "", "log_every"], [2, 3, 1, "", "to_csv"], [2, 3, 1, "", "write_aux_values"], [2, 3, 1, "", "write_epoch"], [2, 4, 1, "", "write_every"], [2, 3, 1, "", "write_loss"]], "pancax.kernels": [[10, 0, 0, "-", "base_kernel"], [10, 0, 0, "-", "laplace_beltrami"], [10, 0, 0, "-", "linear_elasticity"], [10, 0, 0, "-", "poisson"], [10, 0, 0, "-", "solid_mechanics"]], "pancax.kernels.base_kernel": [[10, 2, 1, "", "PhysicsKernel"], [10, 2, 1, "", "StrongFormPhysicsKernel"], [10, 2, 1, "", "WeakFormPhysicsKernel"], [10, 1, 1, "", "element_pp"], [10, 1, 1, "", "full_tensor_names"], [10, 1, 1, "", "full_tensor_names_2D"], [10, 1, 1, "", "nodal_pp"], [10, 1, 1, "", "standard_pp"], [10, 1, 1, "", "vector_names"]], "pancax.kernels.base_kernel.PhysicsKernel": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 4, 1, "", "bc_func"], [10, 4, 1, "", "field_value_names"], [10, 4, 1, "", "n_dofs"], [10, 4, 1, "", "use_delta_pinn"], [10, 4, 1, "", "var_name_to_method"]], "pancax.kernels.base_kernel.StrongFormPhysicsKernel": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 4, 1, "", "bc_func"], [10, 3, 1, "", "field_gradients"], [10, 3, 1, "", "field_hessians"], [10, 3, 1, "", "field_laplacians"], [10, 3, 1, "", "field_second_time_derivatives"], [10, 3, 1, "", "field_time_derivatives"], [10, 4, 1, "", "field_value_names"], [10, 4, 1, "", "n_dofs"], [10, 3, 1, "", "strong_form_neumann_bc"], [10, 3, 1, "", "strong_form_residual"], [10, 4, 1, "", "use_delta_pinn"]], "pancax.kernels.base_kernel.WeakFormPhysicsKernel": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 4, 1, "", "bc_func"], [10, 3, 1, "", "element_field_gradient"], [10, 3, 1, "", "element_quantity"], [10, 3, 1, "", "element_quantity_grad"], [10, 3, 1, "", "element_quantity_hessian"], [10, 3, 1, "", "energy"], [10, 4, 1, "", "field_value_names"], [10, 4, 1, "", "n_dofs"], [10, 4, 1, "", "use_delta_pinn"]], "pancax.kernels.laplace_beltrami": [[10, 2, 1, "", "LaplaceBeltrami"]], "pancax.kernels.laplace_beltrami.LaplaceBeltrami": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "energy"], [10, 4, 1, "", "field_names"], [10, 3, 1, "", "kinetic_energy"], [10, 4, 1, "", "n_dofs"], [10, 4, 1, "", "use_delta_pinn"]], "pancax.kernels.linear_elasticity": [[10, 2, 1, "", "LinearElasticity2D"]], "pancax.kernels.linear_elasticity.LinearElasticity2D": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "cauchy_stress"], [10, 3, 1, "", "energy"], [10, 4, 1, "", "field_value_names"], [10, 3, 1, "", "linear_strain"], [10, 4, 1, "", "n_dofs"], [10, 3, 1, "", "strong_form_neumann_bc"], [10, 3, 1, "", "strong_form_residual"], [10, 4, 1, "", "use_delta_pinn"]], "pancax.kernels.poisson": [[10, 2, 1, "", "Poisson"]], "pancax.kernels.poisson.Poisson": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "energy"], [10, 4, 1, "", "field_value_names"], [10, 4, 1, "", "n_dofs"], [10, 3, 1, "", "strong_form_neumann_bc"], [10, 3, 1, "", "strong_form_residual"], [10, 4, 1, "", "use_delta_pinn"]], "pancax.kernels.solid_mechanics": [[10, 2, 1, "", "BaseMechanicsFormulation"], [10, 2, 1, "", "IncompressiblePlaneStress"], [10, 2, 1, "", "PlaneStrain"], [10, 2, 1, "", "SolidMechanics"], [10, 2, 1, "", "ThreeDimensional"]], "pancax.kernels.solid_mechanics.BaseMechanicsFormulation": [[10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "modify_field_gradient"], [10, 4, 1, "", "n_dimensions"]], "pancax.kernels.solid_mechanics.IncompressiblePlaneStress": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "deformation_gradient"], [10, 3, 1, "", "modify_field_gradient"], [10, 4, 1, "", "n_dimensions"]], "pancax.kernels.solid_mechanics.PlaneStrain": [[10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "extract_stress"], [10, 3, 1, "", "modify_field_gradient"], [10, 4, 1, "", "n_dimensions"]], "pancax.kernels.solid_mechanics.SolidMechanics": [[10, 3, 1, "", "__init__"], [10, 4, 1, "", "_abc_impl"], [10, 4, 1, "", "bc_func"], [10, 4, 1, "", "constitutive_model"], [10, 3, 1, "", "element_field_gradient"], [10, 3, 1, "", "element_quantity_from_func"], [10, 3, 1, "", "energy"], [10, 4, 1, "", "field_values_names"], [10, 4, 1, "", "formulation"], [10, 4, 1, "", "n_dofs"], [10, 3, 1, "", "nodal_incompressibility_constraint"], [10, 3, 1, "", "pk1_stress"], [10, 3, 1, "", "pk1_stress_weak_form"], [10, 3, 1, "", "quadrature_incompressibility_constraint"], [10, 3, 1, "", "strong_form_neumann_bc"], [10, 3, 1, "", "strong_form_residual"], [10, 4, 1, "", "use_delta_pinn"]], "pancax.kernels.solid_mechanics.ThreeDimensional": [[10, 4, 1, "", "_abc_impl"], [10, 3, 1, "", "modify_field_gradient"], [10, 4, 1, "", "n_dimensions"]], "pancax.kinematics": [[2, 1, 1, "", "create_field_methods"], [2, 1, 1, "", "deformation_gradients"], [2, 1, 1, "", "incompressible_plane_stress"], [2, 1, 1, "", "invariants"], [2, 1, 1, "", "invariants_old"], [2, 1, 1, "", "plane_strain"]], "pancax.logging": [[2, 2, 1, "", "BaseLogger"], [2, 2, 1, "", "EnsembleLogger"], [2, 2, 1, "", "Logger"], [2, 1, 1, "", "log_loss"]], "pancax.logging.BaseLogger": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_abc_impl"], [2, 3, 1, "", "flush"], [2, 4, 1, "", "log_every"], [2, 3, 1, "", "log_loss"], [2, 3, 1, "", "write_aux_values"], [2, 3, 1, "", "write_epoch_value"], [2, 3, 1, "", "write_loss_value"]], "pancax.logging.EnsembleLogger": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_abc_impl"], [2, 3, 1, "", "flush"], [2, 4, 1, "", "loggers"], [2, 3, 1, "", "write_aux_values"], [2, 3, 1, "", "write_epoch_value"], [2, 3, 1, "", "write_loss_value"]], "pancax.logging.Logger": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_abc_impl"], [2, 3, 1, "", "flush"], [2, 4, 1, "", "log_file"], [2, 3, 1, "", "write_aux_values"], [2, 3, 1, "", "write_epoch_value"], [2, 3, 1, "", "write_loss_value"]], "pancax.loss_functions": [[11, 0, 0, "-", "base_loss_function"], [11, 0, 0, "-", "bc_loss_functions"], [11, 0, 0, "-", "data_loss_functions"], [11, 0, 0, "-", "physics_loss_functions_strong_form"], [11, 0, 0, "-", "strong_form_loss_functions"], [11, 0, 0, "-", "utils"], [11, 0, 0, "-", "weak_form_loss_functions"]], "pancax.loss_functions.base_loss_function": [[11, 2, 1, "", "BCLossFunction"], [11, 2, 1, "", "BaseLossFunction"], [11, 2, 1, "", "PhysicsLossFunction"]], "pancax.loss_functions.base_loss_function.BCLossFunction": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"]], "pancax.loss_functions.base_loss_function.BaseLossFunction": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "filtered_loss"]], "pancax.loss_functions.base_loss_function.PhysicsLossFunction": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"]], "pancax.loss_functions.bc_loss_functions": [[11, 2, 1, "", "DirichletBCLoss"], [11, 2, 1, "", "NeumannBCLoss"]], "pancax.loss_functions.bc_loss_functions.DirichletBCLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.bc_loss_functions.NeumannBCLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.data_loss_functions": [[11, 2, 1, "", "FullFieldDataLoss"]], "pancax.loss_functions.data_loss_functions.FullFieldDataLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.physics_loss_functions_strong_form": [[11, 1, 1, "", "StrongFormIncompressibilityConstraint"], [11, 1, 1, "", "StrongFormNeumannBCLoss"], [11, 1, 1, "", "StrongFormResidualLoss"]], "pancax.loss_functions.strong_form_loss_functions": [[11, 2, 1, "", "StrongFormResidualLoss"]], "pancax.loss_functions.strong_form_loss_functions.StrongFormResidualLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.utils": [[11, 2, 1, "", "CombineLossFunctions"]], "pancax.loss_functions.utils.CombineLossFunctions": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 4, 1, "", "funcs"], [11, 4, 1, "", "with_props"]], "pancax.loss_functions.weak_form_loss_functions": [[11, 2, 1, "", "EnergyAndResidualLoss"], [11, 2, 1, "", "EnergyLoss"], [11, 2, 1, "", "EnergyResidualAndReactionLoss"], [11, 2, 1, "", "IncompressibleEnergyAndResidualLoss"], [11, 2, 1, "", "IncompressibleEnergyLoss"], [11, 2, 1, "", "QuadratureIncompressibilityConstraint"], [11, 2, 1, "", "ResidualMSELoss"]], "pancax.loss_functions.weak_form_loss_functions.EnergyAndResidualLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 4, 1, "", "energy_weight"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "residual_weight"]], "pancax.loss_functions.weak_form_loss_functions.EnergyLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.weak_form_loss_functions.EnergyResidualAndReactionLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 4, 1, "", "energy_weight"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "reaction_weight"], [11, 4, 1, "", "residual_weight"]], "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyAndResidualLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 4, 1, "", "energy_weight"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "residual_weight"]], "pancax.loss_functions.weak_form_loss_functions.IncompressibleEnergyLoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.weak_form_loss_functions.QuadratureIncompressibilityConstraint": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.loss_functions.weak_form_loss_functions.ResidualMSELoss": [[11, 3, 1, "", "__init__"], [11, 4, 1, "", "_abc_impl"], [11, 3, 1, "", "load_step"], [11, 4, 1, "", "weight"]], "pancax.math": [[12, 0, 0, "-", "math"], [12, 0, 0, "-", "tensor_math"]], "pancax.math.math": [[12, 1, 1, "", "_float_split"], [12, 1, 1, "", "_two_product"], [12, 1, 1, "", "_two_sum"], [12, 1, 1, "", "dot2"], [12, 1, 1, "", "safe_sqrt_jvp"], [12, 1, 1, "", "sum2"]], "pancax.math.tensor_math": [[12, 1, 1, "", "_logm_iss"], [12, 1, 1, "", "compute_deviatoric_tensor"], [12, 1, 1, "", "cos_of_acos_divided_by_3"], [12, 1, 1, "", "dev"], [12, 1, 1, "", "eigen_sym33_non_unit"], [12, 1, 1, "", "eigen_sym33_unit"], [12, 1, 1, "", "if_then_else"], [12, 1, 1, "", "jvp_sqrtm"], [12, 1, 1, "", "log_jvp"], [12, 1, 1, "", "log_pade_pf"], [12, 1, 1, "", "logh"], [12, 1, 1, "", "logh_from_eigen"], [12, 1, 1, "", "logm_jvp"], [12, 1, 1, "", "mises_equivalent_stress"], [12, 1, 1, "", "mtk_log_sqrt_jvp"], [12, 1, 1, "", "mtk_pow_jvp"], [12, 1, 1, "", "norm_of_deviator"], [12, 1, 1, "", "norm_of_deviator_squared"], [12, 1, 1, "", "relative_log_difference"], [12, 1, 1, "", "relative_log_difference_no_tolerance_check"], [12, 1, 1, "", "relative_log_difference_taylor"], [12, 1, 1, "", "sqrtm_dbp"], [12, 1, 1, "", "sym"], [12, 1, 1, "", "tensor_2D_to_3D"], [12, 1, 1, "", "tensor_norm"], [12, 1, 1, "", "triaxiality"]], "pancax.networks": [[13, 1, 1, "", "Network"], [13, 0, 0, "-", "elm"], [13, 0, 0, "-", "field_property_pair"], [13, 0, 0, "-", "initialization"], [13, 0, 0, "-", "mlp"], [13, 0, 0, "-", "properties"], [13, 0, 0, "-", "rbf"]], "pancax.networks.elm": [[13, 2, 1, "", "ELM"], [13, 2, 1, "", "ELM2"], [13, 1, 1, "", "activation"]], "pancax.networks.elm.ELM": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"], [13, 4, 1, "", "beta"], [13, 4, 1, "", "layer"], [13, 4, 1, "", "n_outputs"]], "pancax.networks.elm.ELM2": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"], [13, 4, 1, "", "beta"], [13, 4, 1, "", "layer"], [13, 4, 1, "", "n_outputs"]], "pancax.networks.field_property_pair": [[13, 2, 1, "", "BasePancaxModel"], [13, 2, 1, "", "FieldPropertyPair"]], "pancax.networks.field_property_pair.BasePancaxModel": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"], [13, 3, 1, "", "serialise"]], "pancax.networks.field_property_pair.FieldPropertyPair": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"], [13, 4, 1, "", "fields"], [13, 3, 1, "", "freeze_fields_filter"], [13, 3, 1, "", "freeze_props_filter"], [13, 4, 1, "", "properties"]], "pancax.networks.initialization": [[13, 1, 1, "", "box_init"], [13, 1, 1, "", "init_linear"], [13, 1, 1, "", "init_linear_weight"], [13, 1, 1, "", "trunc_init"], [13, 1, 1, "", "zero_init"]], "pancax.networks.mlp": [[13, 1, 1, "", "Linear"], [13, 1, 1, "", "MLP"], [13, 1, 1, "", "MLPBasis"]], "pancax.networks.properties": [[13, 2, 1, "", "FixedProperties"], [13, 2, 1, "", "Properties"]], "pancax.networks.properties.FixedProperties": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"]], "pancax.networks.properties.Properties": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"], [13, 4, 1, "", "activation_func"], [13, 4, 1, "", "prop_maxs"], [13, 4, 1, "", "prop_mins"], [13, 4, 1, "", "prop_params"]], "pancax.networks.rbf": [[13, 2, 1, "", "RBFBasis"], [13, 1, 1, "", "rbf_normalization"]], "pancax.networks.rbf.RBFBasis": [[13, 3, 1, "", "__init__"], [13, 4, 1, "", "_abc_impl"], [13, 4, 1, "", "center"], [13, 4, 1, "", "sigma"]], "pancax.optimizers": [[14, 0, 0, "-", "adam"], [14, 0, 0, "-", "base"], [14, 0, 0, "-", "lbfgs"], [14, 0, 0, "-", "utils"]], "pancax.optimizers.adam": [[14, 2, 1, "", "Adam"]], "pancax.optimizers.adam.Adam": [[14, 3, 1, "", "__init__"], [14, 4, 1, "", "_abc_impl"], [14, 3, 1, "", "make_step_method"]], "pancax.optimizers.base": [[14, 2, 1, "", "Optimizer"]], "pancax.optimizers.base.Optimizer": [[14, 3, 1, "", "__init__"], [14, 4, 1, "", "_abc_impl"], [14, 3, 1, "", "ensemble_init"], [14, 3, 1, "", "ensemble_step_old"], [14, 3, 1, "", "init"], [14, 3, 1, "", "make_step_method"], [14, 3, 1, "", "train"]], "pancax.optimizers.lbfgs": [[14, 2, 1, "", "LBFGS"], [14, 1, 1, "", "value_and_grad_from_state"]], "pancax.optimizers.lbfgs.LBFGS": [[14, 3, 1, "", "__init__"], [14, 4, 1, "", "_abc_impl"], [14, 3, 1, "", "make_step_method"]], "pancax.optimizers.utils": [[14, 1, 1, "", "trainable_filter"]], "pancax.physics": [[2, 1, 1, "", "element_quantity"], [2, 1, 1, "", "element_quantity_grad"], [2, 1, 1, "", "element_quantity_hessian"], [2, 1, 1, "", "element_quantity_new"], [2, 1, 1, "", "incompressible_energy"], [2, 1, 1, "", "incompressible_energy_and_internal_force"], [2, 1, 1, "", "incompressible_energy_and_residual"], [2, 1, 1, "", "incompressible_internal_force"], [2, 1, 1, "", "internal_force"], [2, 1, 1, "", "mass_matrix"], [2, 1, 1, "", "nodal_incompressibility_constraint"], [2, 1, 1, "", "potential_energy"], [2, 1, 1, "", "potential_energy_and_internal_force"], [2, 1, 1, "", "potential_energy_and_residual"], [2, 1, 1, "", "potential_energy_residual_and_reaction_force"], [2, 1, 1, "", "quadrature_incompressibility_constraint"], [2, 1, 1, "", "residual"], [2, 1, 1, "", "residual_mse"], [2, 1, 1, "", "stiffness_matrix"], [2, 1, 1, "", "strong_form_residual"], [2, 1, 1, "", "traction_energy"]], "pancax.post_processor": [[2, 2, 1, "", "PostProcessor"]], "pancax.post_processor.PostProcessor": [[2, 3, 1, "", "__init__"], [2, 3, 1, "", "check_variable_names"], [2, 3, 1, "", "close"], [2, 3, 1, "", "copy_mesh"], [2, 3, 1, "", "get_element_variable_number"], [2, 3, 1, "", "get_node_variable_number"], [2, 3, 1, "", "index_to_component"], [2, 3, 1, "", "init"], [2, 3, 1, "", "write_outputs"]], "pancax.timer": [[2, 2, 1, "", "Timer"], [2, 6, 1, "", "TimerError"]], "pancax.timer.Timer": [[2, 3, 1, "", "__init__"], [2, 4, 1, "", "_start_time"], [2, 3, 1, "", "logger"], [2, 4, 1, "", "name"], [2, 3, 1, "", "start"], [2, 3, 1, "", "stop"], [2, 4, 1, "", "text"], [2, 4, 1, "", "timers"]], "pancax.trainer": [[2, 2, 1, "", "Trainer"]], "pancax.trainer.Trainer": [[2, 3, 1, "", "__init__"], [2, 3, 1, "", "init"], [2, 3, 1, "", "serialise"], [2, 3, 1, "", "step"], [2, 3, 1, "", "train"], [2, 3, 1, "", "write_outputs"]], "pancax.utils": [[2, 6, 1, "", "DataFileNotFoundException"], [2, 6, 1, "", "MeshFileNotFoundException"], [2, 1, 1, "", "find_data_file"], [2, 1, 1, "", "find_mesh_file"], [2, 1, 1, "", "set_checkpoint_file"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"], "2": ["py", "class", "Python class"], "3": ["py", "method", "Python method"], "4": ["py", "attribute", "Python attribute"], "5": ["py", "property", "Python property"], "6": ["py", "exception", "Python exception"]}, "objtypes": {"0": "py:module", "1": "py:function", "2": "py:class", "3": "py:method", "4": "py:attribute", "5": "py:property", "6": "py:exception"}, "terms": {"": [2, 12], "0": [2, 3, 8, 9, 11, 12, 14], "001": 14, "030601818": 12, "0x7f199ccec900": 3, "0x7f19afe23880": 13, "1": [2, 3, 5, 7, 8, 9, 10, 11, 14], "10": 12, "100": 14, "1000": 2, "10000": [2, 14], "1137": 12, "1955": 12, "1988": 12, "1d": 8, "2": [5, 7, 8, 9, 10, 12], "2008": 12, "26": 12, "2d": 8, "3": [2, 5, 8, 9, 10], "4": [5, 8, 9], "46": 12, "5": [5, 9], "500": 14, "6": [5, 9, 12], "7": [5, 9, 12], "8": 9, "898716": 12, "8f": 2, "9": 9, "978": 12, "99": 14, "A": [2, 3, 6, 7, 8, 11, 12, 13], "For": 8, "If": 8, "In": 8, "It": 12, "No": 12, "One": 8, "That": 8, "The": [3, 5, 8, 12], "_": [8, 11], "_1": 5, "_2": 5, "__init__": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14], "__main__": 1, "__w": 2, "_abc": [2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14], "_abc_data": [2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14], "_abc_impl": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14], "_asdict": [8, 9], "_field": [8, 9], "_field_default": [8, 9], "_float_split": [2, 12], "_gauss_quad_1d_1pt": [2, 8], "_gauss_quad_1d_2pt": [2, 8], "_gauss_quad_1d_3pt": [2, 8], "_gauss_quad_1d_4pt": [2, 8], "_gauss_quad_1d_5pt": [2, 8], "_get_vertex_nodes_from_exodus_tri6_mesh": [2, 8], "_logm_iss": [2, 12], "_make": [8, 9], "_make_hessian_bc_mask": [2, 8], "_make_hessian_coordin": [2, 8], "_read_block": [2, 8], "_read_block_conn": [2, 8], "_read_coordin": [2, 8], "_read_element_typ": [2, 8], "_read_names_list": [2, 8], "_read_node_set": [2, 8], "_read_side_set": [2, 8], "_replac": [8, 9], "_src": 13, "_start_tim": [1, 2], "_two_product": [2, 12], "_two_sum": [2, 12], "_write_loss": [1, 2], "a1": 5, "a_1": 5, "abc": [5, 10, 14], "abl": 8, "about": 8, "abstract": [2, 5, 9, 10, 11, 14], "ac": 12, "accumul": 12, "accur": 12, "accuraci": 12, "activ": [2, 8, 13], "activation_func": [2, 13], "actual": 13, "adam": [0, 1, 2], "addit": 8, "addition": 8, "affin": 8, "after": 2, "akin": 11, "al": 11, "algorithm": [5, 12], "alia": 9, "all": [7, 8], "allow": [8, 12, 13], "alwai": 8, "an": [7, 8, 9, 10, 12], "ani": [2, 7, 8, 9, 11, 13, 14], "appar": 12, "append": 2, "appli": [3, 8], "approxim": 12, "ar": [7, 8, 9], "arg": 13, "argument": [2, 8], "arrai": [3, 5, 6, 7, 8, 9, 12, 13], "assemble_sparse_stiffness_matrix": [2, 8], "associ": [9, 12], "assum": 8, "attribut": 8, "averag": 8, "average_quadrature_field_over_el": [2, 8], "avoid": [8, 12], "axi": 12, "axisymetr": 8, "axisymmetr": 8, "b": 12, "b1": 5, "b_1": 5, "bar": 5, "base": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13], "base_constitutive_model": [0, 1, 2], "base_domain": [0, 1, 2], "base_el": [2, 8], "base_kernel": [0, 1, 2], "base_loss_funct": [0, 1, 2], "base_nam": [2, 10, 13], "base_name_xx": 10, "basedomain": [2, 7], "baseel": [8, 9], "basehistorywrit": [1, 2], "baselogg": [1, 2], "baselossfunct": [2, 11], "basemechanicsformul": [2, 10], "basepancaxmodel": [2, 13], "bc": [0, 1, 2, 7, 8], "bc_func": [2, 10], "bc_loss_funct": [0, 1, 2], "bclossfunct": [2, 11], "beaver": 12, "beta": [2, 13], "better": 8, "between": [2, 8], "bia": 13, "biaxial_tens": [0, 1, 2], "biaxiallinearramp": [2, 4], "blatz": 5, "blatz_ko": [0, 1, 2], "blatzko": [2, 5], "block": [2, 7, 8], "blocknam": 8, "blockordin": 8, "bodi": 8, "body_forc": 10, "book": 6, "bool": [6, 7, 8, 10, 11, 13, 14], "boolean": [8, 13], "bound": 5, "boundari": [8, 11], "box_init": [2, 13], "build": 11, "built": [2, 13], "bulk": 5, "bulk_modulu": [2, 5], "bvp": [0, 1, 2], "c1": 5, "c_1": 5, "calcul": [5, 6, 7, 8, 9, 11], "calculu": 8, "call": 8, "callabl": [2, 3, 10, 13, 14], "caller": 8, "can": [8, 12], "cancel": 12, "care": 8, "cartesian": 8, "case": 8, "cauchy_stress": [2, 5, 10], "cell": 7, "center": [2, 13], "chang": [8, 12], "check_variable_nam": [1, 2], "checkpoint": 2, "checkpoint_bas": 2, "checkpoint_file_bas": 2, "class": [2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14], "classmethod": 9, "classvar": 2, "clip_gradi": 14, "clockwis": 8, "close": [1, 2], "code": 2, "collect": 8, "collocation_domain": [0, 1, 2], "collocationdomain": [2, 7], "combin": 8, "combine_block": [2, 8], "combine_mesh": [2, 8], "combine_nodeset": [2, 8], "combine_sideset": [2, 8], "combinelossfunct": [2, 11], "compar": 6, "compil": 8, "compon": [2, 3, 8, 10], "comput": [8, 12], "compute_deviatoric_tensor": [2, 12], "compute_edge_vector": [2, 8], "compute_element_field_gradi": [2, 8], "compute_element_volum": [2, 8], "compute_element_volumes_axisymmetr": [2, 8], "compute_field_gradi": [2, 8], "compute_norm": [2, 8], "compute_quadrature_point_field_gradi": [2, 8], "compute_shap": [8, 9], "compute_traction_potential_energi": [2, 8], "compute_traction_potential_energy_on_edg": [2, 8], "cond": 12, "condit": 11, "configur": [7, 9], "conn": [2, 7, 8], "connect": [7, 8], "consecut": 8, "consistut": 5, "constant": 8, "constitutive_model": [0, 1, 2, 10], "constitutivemodel": [2, 5, 10], "constitutivemodelfixedbulkmodulu": [2, 5], "construct": 8, "construct_function_spac": [2, 8], "construct_function_space_from_parent_el": [2, 8], "construct_mesh_from_basic_data": [2, 8], "construct_structured_mesh": [2, 8], "constructor": 8, "contain": 8, "content": [0, 1], "context": 2, "contextdecor": 2, "convent": 8, "coord": [2, 7, 8], "coordfield": 8, "coordin": [2, 3, 7, 8, 9], "copy_mesh": [1, 2], "copynodeset": 8, "correspond": 8, "cos_of_acos_divided_by_3": [2, 12], "counter": 8, "cpack": 12, "cpu": 12, "creat": 8, "create_edg": [2, 8], "create_field": [2, 8], "create_field_method": [1, 2], "create_higher_order_mesh_from_simplex_mesh": [2, 8], "create_nodesets_from_sideset": [2, 8], "create_padded_quadrature_rule_1d": [2, 8], "create_quadrature_rule_1d": [2, 8], "create_quadrature_rule_on_hex": [2, 8], "create_quadrature_rule_on_quad": [2, 8], "create_quadrature_rule_on_tet": [2, 8], "create_quadrature_rule_on_triangl": [2, 8], "create_structured_mesh_data": [2, 8], "createnodesetsfromsideset": 8, "critic": 12, "csv": 2, "current": [2, 6, 7, 8, 11, 13], "curv": 6, "custom": 2, "cutoff_strain": [2, 5], "cyclic": 8, "data": [0, 1, 2, 7, 8, 13], "data_dict": [1, 2], "data_fil": 6, "data_file_in": 2, "data_loss_funct": [0, 1, 2], "datafilenotfoundexcept": [1, 2], "decay_r": 14, "decor": 2, "decreas": 12, "deep": 11, "default": [2, 3, 8], "default_modify_element_gradi": [2, 8], "defin": [5, 8, 9], "deform": 5, "deformation_gradi": [1, 2, 10], "degre": [6, 8, 9], "delta": 11, "delta_pinn_domain": [0, 1, 2], "deltapinndomain": [2, 7], "denman": 12, "densiti": [5, 8], "deriv": [5, 7, 8], "describ": 8, "det": 5, "detail": 8, "determin": 8, "dev": [2, 12], "dict": [2, 8, 9, 10], "dictionari": 8, "diff_param": 11, "differ": 9, "differenti": 8, "dim": [8, 10], "dimens": [8, 9], "direct": 4, "dirichletbcloss": [2, 11], "discret": [8, 9], "disp_kei": 6, "displ_i": 10, "displ_x": 10, "displac": [2, 6], "distanc": [2, 3], "distance_funct": [0, 1, 2], "distort": 5, "do": 8, "doc": 2, "document": 8, "doe": 11, "dof": [3, 7, 8], "dof_manag": [0, 1, 2, 7], "dofindexslic": 8, "dofmanag": [2, 7, 8], "doi": 12, "domain": [0, 1, 2, 3, 6, 8, 10, 11, 14], "dot": 12, "dot2": [2, 12], "dotprod": 12, "dt": 8, "dtype": 9, "dudx": 8, "dure": 5, "e": [10, 13], "each": [8, 9, 13], "edg": 8, "edge_is_potentially_in_contact": 8, "edgeconn": 8, "edgecoord": 8, "effici": 8, "eigen_mod": [2, 7], "eigen_sym33_non_unit": [2, 12], "eigen_sym33_unit": [2, 12], "eigenvalu": 7, "eigenvector": 10, "elaps": 2, "elemconn": 8, "elemconnect": 8, "element": [2, 7, 8, 10], "element_field_gradi": [2, 10], "element_pp": [2, 10], "element_quant": [1, 2, 10], "element_quantity_from_func": [2, 10], "element_quantity_grad": [1, 2, 10], "element_quantity_hessian": [1, 2, 10], "element_quantity_new": [1, 2], "element_vari": 2, "elementnodalvalu": 8, "elementord": 8, "elementtyp": [8, 9], "elemgrad": 8, "elemnodalcoord": 8, "elemnodaldisp": 8, "elemnodalfield": 8, "elemoffset": 8, "elemqpdata": 8, "elemshap": 8, "elemshapegrad": 8, "elemst": 8, "elemvol": 8, "elm": [0, 1, 2], "elm2": [2, 13], "empti": 9, "enabl": 7, "encount": 5, "end": 2, "energi": [2, 5, 8, 10, 11], "energy_weight": [2, 11], "energyandresidualloss": [2, 11], "energyloss": [2, 11], "energyresidualandreactionloss": [2, 11], "enforc": [3, 8], "ensemble_init": [2, 14], "ensemble_step_old": [2, 14], "ensemblehistorywrit": [1, 2], "ensemblelogg": [1, 2], "ensur": 8, "entri": 8, "environ": 12, "epoch": [2, 13], "equal": 9, "equinox": 13, "error": [2, 12], "essenti": [3, 6, 7], "essentiablbc": 7, "essential_bc": [0, 1, 2, 7], "essentialbc": [2, 3, 7, 8], "essentialbcset": [2, 3], "et": 11, "etc": [7, 8], "eval": 12, "eval_at_iso_point": [2, 8], "eval_field": [2, 8], "evalu": [8, 9], "evaluate_on_block": [2, 8], "evaluate_on_el": [2, 8], "evaluationpoint": 9, "evec": 12, "everi": 8, "exactli": 8, "exampl": 8, "except": [2, 9], "exodu": [7, 8], "exodusdataset": 8, "expect": 11, "extra": 8, "extract_stress": [2, 10], "f": [2, 3, 5, 10, 11], "face": 9, "facenod": [8, 9], "factor": 8, "factori": 8, "fals": [2, 6, 7, 8, 10, 11, 12, 13, 14], "fem": [0, 1, 2], "few": 13, "field": [2, 3, 6, 7, 8, 9, 13], "field_data": [2, 7], "field_func": 8, "field_gradi": [2, 10], "field_hessian": [2, 10], "field_laplacian": [2, 10], "field_nam": [2, 10], "field_network": [7, 10], "field_property_pair": [0, 1, 2], "field_second_time_deriv": [2, 10], "field_time_deriv": [2, 10], "field_valu": [2, 7], "field_value_nam": [2, 10], "field_values_nam": [2, 10], "fielddata": 7, "fieldindex": 8, "fieldpropertypair": [2, 13], "file": [2, 7, 8], "filenam": 8, "filter_spec": 14, "filtered_loss": [2, 11], "final": 13, "final_displac": 4, "final_displacement_i": 4, "final_displacement_x": 4, "find_data_fil": [1, 2], "find_mesh_fil": [1, 2], "first": [2, 5, 8], "fix": [7, 8, 13], "fixedproperti": [2, 13], "flag": [7, 12], "float": [2, 3, 4, 5, 7, 8, 9, 11, 12, 13, 14], "float32": 9, "flush": [1, 2], "follow": [5, 11], "follw": 8, "forc": 6, "force_kei": 6, "forcibli": 2, "form": [5, 12], "formul": [2, 10], "forwarddomain": 7, "frac": 5, "fraction": 12, "free": [7, 8, 11], "freedom": 6, "freeze_basi": 14, "freeze_fields_filt": [2, 13], "freeze_properti": 14, "freeze_props_filt": [2, 13], "from": [5, 6, 7, 8, 9, 12], "fspace": [2, 7, 10], "fspace_centroid": [2, 7], "full": [6, 7, 10], "full_field_data": [0, 1, 2], "full_tensor_nam": [2, 10], "full_tensor_names_2d": [2, 10], "fullfielddata": [2, 6, 7], "fullfielddataloss": [2, 11], "func": [2, 8, 10, 11], "functino": 9, "function": [2, 3, 8, 9, 10, 11, 12, 13], "function_spac": [0, 1, 2], "functionspac": [2, 7, 8], "g": [5, 10, 13], "gauss": 8, "gaussfield": 8, "gener": 8, "gent": [0, 1, 2], "gentfixedbulkmodulu": [2, 5], "geometr": 8, "geometri": 7, "get": 8, "get_bc_siz": [2, 8], "get_bc_valu": [2, 8], "get_block": [2, 8], "get_coord": [2, 8], "get_edg": [2, 3], "get_edge_coord": [2, 8], "get_edge_field": [2, 8], "get_edge_node_indic": [2, 8], "get_element_variable_numb": [1, 2], "get_field_index": [2, 8], "get_lobatto_nodes_1d": [8, 9], "get_nodal_values_on_edg": [2, 8], "get_node_variable_numb": [1, 2], "get_unknown_s": [2, 8], "get_unknown_valu": [2, 8], "give": 3, "given": 9, "gj_m": 5, "global": [6, 7, 8], "global_data": [0, 1, 2, 7], "globaldata": [2, 6, 7], "grad_n": [2, 10], "grad_u": [2, 10], "gradient": [2, 5, 8, 9], "ground": 6, "group": 8, "guarante": 8, "guard": 5, "gui": 8, "h": 12, "ha": [2, 8, 12], "hamel": 11, "hardcod": 6, "has_aux": 14, "has_prop": 10, "have": [8, 9], "help": [7, 11], "helper": 13, "here": 8, "hex8": 9, "hex8_el": [2, 8], "hex8el": [8, 9], "hidden": 13, "hierarchi": 11, "higham": 12, "higher": 12, "highest": 8, "histori": [2, 14], "history_fil": [1, 2], "history_writ": 1, "historywrit": [1, 2], "hold": [6, 7], "hook": 7, "how": 8, "howev": 8, "hpack": 12, "http": 12, "i": [2, 5, 8, 9, 11, 12], "i1": [2, 5], "i1_bar": [2, 5], "i2": [2, 5], "i2_bar": [2, 5], "i_1": 5, "i_2": 5, "i_3": 5, "id": 8, "if_then_els": [2, 12], "includ": [5, 8, 13], "incompressible_energi": [1, 2], "incompressible_energy_and_internal_forc": [1, 2], "incompressible_energy_and_residu": [1, 2], "incompressible_internal_forc": [1, 2], "incompressible_plane_stress": [1, 2], "incompressibleenergyandresidualloss": [2, 11], "incompressibleenergyloss": [2, 11], "incompressibleplanestress": [2, 10], "increment": 8, "independ": 7, "index": [0, 2, 8], "index_to_compon": [1, 2], "indic": 8, "inform": 8, "init": [1, 2, 14], "init_fn": 13, "init_func": 13, "init_linear": [2, 13], "init_linear_weight": [2, 13], "initi": [0, 1, 2, 7], "inner": 12, "input": [2, 6, 8, 12, 13], "input_kei": 6, "insert": 2, "int": [2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 14], "int32": 9, "int_": 11, "inted": 8, "integr": [7, 8, 12], "integrate_el": [2, 8], "integrate_element_from_local_field": [2, 8], "integrate_funct": [2, 8], "integrate_function_on_edg": [2, 8], "integrate_function_on_surfac": [2, 8], "integrate_on_el": [2, 8], "integrate_over_block": [2, 8], "integrate_valu": [2, 8], "interfac": 5, "interior": [8, 9], "interiornod": [8, 9], "intern": 8, "internal_forc": [1, 2], "interpol": 8, "interpolate_nodal_field_on_edg": [2, 8], "interpolate_to_element_point": [2, 8], "interpolate_to_point": [2, 8], "interpolationpoint": 8, "interpret": 8, "interv": 8, "invari": [1, 2, 5], "invariants_old": [1, 2], "invers": [6, 7, 12], "inverse_domain": [0, 1, 2], "inversedomain": [2, 7], "isaxisymmetr": [2, 8], "isbn": 12, "iter": [9, 12], "j": [5, 8, 12], "j_m": 5, "jacobian": [2, 5, 8], "jax": [8, 13], "jaxtyp": 3, "jit": [8, 10, 14], "jm": 5, "jvp_sqrtm": [2, 12], "jxw": [2, 8, 10], "k": 5, "keep": [6, 7], "kei": [2, 13], "kernel": [0, 1, 2, 7], "kernelfunc": 8, "keyword": 8, "kinemat": 1, "kinetic_energi": [2, 10], "ko": 5, "kvalu": 8, "kwarg": 13, "kwd": 9, "l": 11, "lagrangian": 8, "lam1": 12, "lam2": 12, "lambda": [3, 10], "laplace_beltrami": [0, 1, 2], "laplacebeltrami": [2, 10], "last": 2, "layer": [2, 13], "lbfg": [0, 1, 2], "learning_r": 14, "left": [5, 8, 11], "leftp": 8, "leftt": 8, "legendr": 8, "length": 4, "length_i": 4, "length_x": 4, "level": 8, "like": [2, 7, 8], "line": [7, 9], "line_el": [2, 8], "line_seg": [2, 3], "linear": [2, 13], "linear_elast": [0, 1, 2], "linear_strain": [2, 10], "linearelasticity2d": [2, 10], "lineel": [8, 9], "list": [2, 3, 5, 6, 7, 8, 9, 10], "llvm": 12, "ln": 5, "load": [7, 8], "load_step": [2, 11], "local": 8, "log": 1, "log_everi": [1, 2, 14], "log_fil": [1, 2], "log_file_in": 2, "log_jvp": [2, 12], "log_loss": [1, 2], "log_pade_pf": [2, 12], "logarithm": 12, "logger": [1, 2, 14], "logh": [2, 12], "logh_from_eigen": [2, 12], "logm_jvp": [2, 12], "loss": [2, 11], "loss_funct": [0, 1, 2, 14], "m": [3, 12], "m1": 8, "m2": 8, "ma": 12, "maintain": 8, "make": [7, 8, 9], "make_mesh_time_depend": [2, 7], "make_step_method": [2, 14], "make_times_column": [2, 7], "man": 12, "manag": 2, "map": [8, 9, 12], "map_element_shape_grad": [2, 8], "mass_matrix": [1, 2], "materi": 13, "math": [0, 1, 2], "mathbf": [5, 11], "mathcal": 11, "matric": [8, 12], "matrix": [7, 12], "maximum": 13, "measur": 6, "mesh": [0, 1, 2, 3, 7, 10], "mesh_fil": [2, 6, 7, 10], "mesh_file_in": 2, "mesh_with_block": [2, 8], "mesh_with_coord": [2, 8], "mesh_with_nodeset": [2, 8], "meshfilenotfoundexcept": [1, 2], "method": [5, 9, 11, 12, 13], "mftoolbox": 12, "minimum": 13, "mises_equivalent_stress": [2, 12], "mlp": [0, 1, 2], "mlpbasi": [2, 13], "mode": 8, "mode2d": 8, "model": [5, 6, 13], "modifi": 8, "modify_element_gradi": 8, "modify_field_gradi": [2, 10], "modul": [0, 1], "modulu": 5, "more": 8, "most": 7, "mtk_log_sqrt_jvp": [2, 12], "mtk_pow_jvp": [2, 12], "mu": 5, "much": 12, "multipli": 8, "must": 8, "n": [2, 8, 10, 12], "n_dimens": [2, 4, 10], "n_dof": [2, 10], "n_eig": 10, "n_eigen_valu": [2, 7], "n_epoch": [2, 14], "n_input": 13, "n_layer": 13, "n_neuron": 13, "n_node": [2, 6, 7], "n_output": [2, 13], "n_pinn": 2, "n_properti": [2, 5], "n_time_step": [2, 6], "name": [1, 2, 3, 5, 7, 8, 9, 10], "namedtupl": [8, 9], "natural_bc": [0, 1, 2, 7], "naturalbc": [2, 3, 7], "nb": 8, "nd": [3, 7, 8, 9], "ndarrai": 12, "ndim": [8, 9], "ndpe": 8, "ne": [7, 8], "nedg": 8, "need": [8, 10], "neohookean": [0, 1, 2], "neohookeanfixedbulkmodulu": [2, 5], "network": [0, 1, 2], "network_typ": 13, "neumann_n": [2, 7], "neumann_x": [2, 7], "neumannbcloss": [2, 11], "neuron": 13, "nev": 7, "new": [2, 9, 13], "newlin": 2, "nf": [3, 9], "ni": 13, "nichola": 12, "nn": [7, 8, 9], "nndode": 9, "nni": 9, "nnode": [8, 9], "nnpe": [7, 8], "nnpf": 9, "nodal": [7, 8, 9, 10], "nodal_incompressibility_constraint": [1, 2, 10], "nodal_pp": [2, 10], "nodalcoord": 8, "nodalfield": 8, "nodalpoint": 9, "node": [6, 8, 9], "node_vari": 2, "nodeoffset": 8, "nodeordin": 8, "nodeset": [2, 3, 6, 8], "non": [5, 8], "nonallocatedfunctionspac": [2, 8], "none": [2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14], "nonsens": 5, "norm_of_devi": [2, 12], "norm_of_deviator_squar": [2, 12], "normal": [2, 3, 8], "note": 7, "noth": 11, "now": 6, "np": [5, 9], "npe": 8, "npt": 9, "nq": 8, "nqpe": 8, "nset_id": 6, "nt": 7, "ntriangl": 8, "nu": 8, "nu_new": 8, "num_dimens": [2, 8], "num_el": [2, 8], "num_nod": [2, 8], "number": [5, 6, 7, 8, 9, 12, 13], "numel": 8, "numer": 12, "numpi": [8, 12], "numquadptsperel": 8, "nx": 8, "ny": 8, "object": [2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "obscur": 12, "occur": 8, "ogita": 12, "oishi": 12, "omega": 11, "onc": 8, "one": 12, "onli": [7, 8, 12], "oper": 8, "opt": [2, 14], "opt_st": [2, 14], "optim": [0, 1, 2, 12], "option": [3, 8], "order": [7, 8], "otherwis": [8, 12], "output": [2, 6, 10, 13], "output_element_vari": 2, "output_everi": 2, "output_fil": 2, "output_file_bas": 2, "output_kei": 6, "output_node_vari": 2, "outward": 8, "over": [7, 8], "p": 10, "p1": 5, "p_1": 5, "p_order": 7, "pa": 12, "packag": [0, 1], "pad": 8, "pad\u00e9": 12, "page": 0, "param": [2, 8, 10, 11, 12, 14], "paramet": [3, 5, 6, 7, 8, 9, 10, 11, 12, 13], "parameter": 8, "parametr": [8, 9], "parent": 8, "parentel": [2, 8], "parentelement1d": [2, 8], "part": 8, "partial": 12, "particular": 8, "pascal_triangle_monomi": [8, 9], "path": [2, 7], "per": 8, "perform": 8, "permut": 8, "philadelphia": 12, "physic": [1, 6, 7, 8, 10, 11], "physics_loss_functions_strong_form": [0, 1, 2], "physicskernel": [2, 7, 10], "physicslossfunct": [2, 11], "pi": [8, 11], "pick": 8, "pinn": [2, 6], "pjitfunct": 13, "pk1_stress": [2, 5, 10], "pk1_stress_weak_form": [2, 10], "plane_strain": [1, 2], "planestrain": [2, 10], "plot": 6, "plot_data": [2, 6], "plot_registr": [2, 6], "point": [8, 9, 12], "poisson": [0, 1, 2], "polynomi": [7, 8, 9], "posit": [2, 5, 8], "post_processor": 1, "postprocess_everi": 14, "postprocessor": [1, 2], "potenti": 5, "potential_energi": [1, 2], "potential_energy_and_internal_forc": [1, 2], "potential_energy_and_residu": [1, 2], "potential_energy_residual_and_reaction_forc": [1, 2], "pp": [12, 14], "precis": 12, "precomput": 8, "prefer": 8, "primal": [8, 12], "primari": 8, "print": 2, "prngkei": 13, "problem": [6, 7], "product": 12, "project_quadrature_field_to_element_field": [2, 8], "prop": [2, 5, 8, 10, 13], "prop_max": [2, 13], "prop_min": [2, 13], "prop_param": [2, 13], "properti": [0, 1, 2, 5, 8, 10], "property_nam": [2, 5], "provid": [8, 10], "psi": [5, 11], "q": 8, "q1": 5, "q_1": 5, "q_order": 7, "q_rule": 8, "q_rule_1d": [3, 7], "q_rule_2d": 7, "quad4": 9, "quad4_el": [2, 8], "quad4el": [8, 9], "quad9": 9, "quad9_el": [2, 8], "quad9el": [8, 9], "quad_degre": 8, "quadfield": 8, "quadratur": [7, 8, 9], "quadrature_incompressibility_constraint": [1, 2, 10], "quadrature_rul": [0, 1, 2], "quadratureincompressibilityconstraint": [2, 11], "quadraturerul": [2, 8], "quadrul": 8, "quadrupl": 12, "quantiti": 11, "r": 8, "r1": 5, "r_1": 5, "rail": 5, "random": 13, "rbf": [0, 1, 2], "rbf_normal": [2, 13], "rbfbasi": [2, 13], "reaction": 6, "reaction_dof": [2, 6], "reaction_nod": [2, 6], "reaction_weight": [2, 11], "read": 8, "read_exodus_mesh": [0, 1, 2], "real": 12, "realli": 8, "recordnam": 8, "refer": [7, 8, 9, 12], "relative_log_differ": [2, 12], "relative_log_difference_no_tolerance_check": [2, 12], "relative_log_difference_taylor": [2, 12], "relu": 13, "renam": 7, "repeatedli": 8, "replac": 9, "report": 2, "repres": 8, "residu": [1, 2, 8, 11], "residual_ms": [1, 2], "residual_weight": [2, 11], "residualmseloss": [2, 11], "respect": [2, 8], "respons": 6, "result": 12, "return": [2, 5, 8, 9, 12, 13], "right": [5, 8, 11], "rightp": 8, "rightt": 8, "rng": 13, "root": 12, "row": 8, "rule": [7, 8], "rump": 12, "safe_sqrt_jvp": [2, 12], "same": [2, 8], "sampl": 8, "save_everi": 2, "scalar": 8, "scale": 12, "sci": 12, "search": 0, "second": [2, 8], "see": 8, "segment": 3, "self": 11, "sens": [7, 8], "sensit": 8, "sep": 2, "sequenc": 9, "serialis": [1, 2, 13], "serialise_everi": [2, 14], "serv": 6, "set": [6, 7, 8, 9, 12, 13], "set1": 8, "set2": 8, "set_checkpoint_fil": [1, 2], "shame": 9, "shape": [2, 8, 9, 12, 13], "shape_funct": [2, 8], "shape_function_gradi": [2, 8], "shape_function_valu": [2, 8], "shapefunct": [8, 9], "shapegrad": [2, 8], "shapegradi": 8, "shapeonref": 8, "shear": 5, "should": 8, "siam": 12, "side": 8, "sideset": [2, 3, 8], "sigma": [2, 13], "sigmoid": 13, "signatur": [8, 11], "simple_shear": [0, 1, 2], "simpleshearlinearramp": [2, 4], "simplex": 9, "simplex_tri_el": [2, 8], "simplexnodesordin": [2, 8], "simplextriel": [8, 9], "simpli": 5, "singl": 7, "size": [8, 13], "slice_unknowns_with_dof_indic": [2, 8], "so": 8, "solid_mechan": [0, 1, 2], "solidmechan": [2, 10], "solv": 6, "solve_eigen_problem": [2, 7], "some": 6, "sourc": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "space": [2, 8, 9], "sparse_matrix_assembl": [0, 1, 2], "spatial": [8, 9], "special": [8, 12], "specifi": [8, 9], "sqrt": 5, "sqrtm_dbp": [2, 12], "squar": 12, "sset": 3, "sset_nam": 3, "standard": 8, "standard_pp": [2, 10], "start": [1, 2], "state": 8, "statevar": 8, "static": 5, "static_param": 11, "stdout": 2, "step": [1, 2], "stiff": 8, "stiffness_matrix": [1, 2], "stop": [1, 2], "store": [6, 13], "str": [2, 3, 4, 5, 6, 7, 8, 9, 10], "strain": [5, 12], "stream": 2, "stress": 12, "strictli": 8, "string": [2, 7, 8], "strong_form_loss_funct": [0, 1, 2], "strong_form_neumann_bc": [2, 10], "strong_form_residu": [1, 2, 10], "strongformincompressibilityconstraint": [2, 11], "strongformneumannbcloss": [2, 11], "strongformphysicskernel": [2, 10], "strongformresidualloss": [2, 11], "structur": [6, 7, 8, 13], "submodul": [0, 1], "subpackag": [0, 1], "sum": 12, "sum2": [2, 12], "support": 7, "surfac": [0, 1, 2, 7], "swanson": [0, 1, 2], "swanson4": [2, 5], "swanson4fixedbulkmodulu": [2, 5], "swanson6": [2, 5], "swanson6fixedbulkmodulu": [2, 5], "sy": 2, "sym": [2, 12], "symmetr": 8, "t": [2, 3, 5, 7, 8, 10, 11, 12], "tabl": 8, "take": [2, 8], "tangent": [8, 12], "tanh": 13, "technologi": 9, "tensor": [10, 12], "tensor_2d_to_3d": [2, 12], "tensor_math": [0, 1, 2], "tensor_norm": [2, 12], "tensori": 10, "tet10": 9, "tet10_el": [2, 8], "tet10el": [8, 9], "tet4": 9, "tet4_el": [2, 8], "tet4el": [8, 9], "text": [1, 2], "than": 12, "them": [5, 8], "theori": 12, "thi": [3, 5, 7, 8, 10, 11, 12, 13], "thing": 7, "threedimension": [2, 10], "through": 8, "time": [2, 6, 7, 8, 14], "time_step": 6, "timer": 1, "timererror": [1, 2], "times_in": 7, "times_kei": 6, "to_csv": [1, 2], "todo": [6, 7, 8], "toolbox": 12, "topolog": 8, "tr": 5, "track": 7, "traction_bc": [0, 1, 2], "traction_energi": [1, 2], "train": [1, 2, 5, 6, 14], "trainable_filt": [2, 14], "trainer": 1, "transform": 8, "transition_step": 14, "translat": 12, "tri": [7, 9], "triangl": 8, "triangul": 8, "triangular": 8, "triaxial": [2, 12], "true": [10, 14], "truli": 12, "trunc_init": [2, 13], "truncat": 5, "truth": 6, "tunabl": 13, "tupl": [2, 8], "two": 2, "type": [2, 3, 7, 8, 9, 10, 11, 12, 13], "u": [2, 3, 8, 10, 11], "u_el": [2, 10], "ubc": 8, "uk": 12, "uniaxial_tens": [0, 1, 2], "uniaxialtensionlinearramp": [2, 4], "uniform": 8, "unit": 8, "unknown": 8, "unkown": 8, "unpack": 5, "unpack_properti": [2, 5], "unsaf": 12, "up": [7, 8], "us": [2, 6, 7, 8, 10, 11, 12, 13], "usa": 12, "use_delta_pinn": [2, 10], "use_final_bia": 13, "usebubbleel": 8, "usual": 9, "util": [0, 1], "uu": 8, "val": 2, "val1": 12, "val2": 12, "valid": 8, "valu": [2, 3, 7, 8, 9, 13], "value_and_grad_from_st": [2, 14], "value_fn": 14, "vander1d": [8, 9], "vander2d": [8, 9], "var_name_to_method": [2, 10], "variabl": [2, 6, 8, 10, 12], "variad": 8, "variational_domain": [0, 1, 2], "variationaldomain": [2, 7], "vector": [7, 8, 12, 13], "vector_nam": [2, 10], "vectorize_over_tim": 7, "version": 8, "vertex": [8, 9], "vertexnod": [8, 9], "vertic": 8, "vol": [2, 8, 12], "volum": 8, "vt": 12, "w": 11, "w_1": 11, "w_2": 11, "walk": 8, "want": 8, "we": 8, "weak_form_loss_funct": [0, 1, 2], "weakformphysicskernel": [2, 10], "weight": [2, 8, 11, 13], "weigth": 13, "wgauss": [2, 8], "what": 7, "when": [6, 8], "where": [2, 6, 8, 9], "whether": [2, 10, 12, 13], "which": [2, 8, 9], "with_prop": [2, 10, 11], "within": 8, "work": 12, "workdir": 2, "write_aux_valu": [1, 2], "write_data": [1, 2], "write_epoch": [1, 2], "write_epoch_valu": [1, 2], "write_everi": [1, 2], "write_histori": [1, 2], "write_loss": [1, 2], "write_loss_valu": [1, 2], "write_output": [1, 2], "www": 12, "x": [2, 3, 8, 9, 10, 12, 13], "x1": 3, "x2": 3, "x_el": [2, 10], "xextent": 8, "xigauss": [2, 8], "xla": 12, "xla_cpu_enable_fast_math": 12, "xla_flag": 12, "xt": 12, "y": [2, 12], "yextent": 8, "your": 2, "z": 2, "zero": 3, "zero_init": [2, 13]}, "titles": ["Pancax", "pancax", "pancax package", "pancax.bcs package", "pancax.bvps package", "pancax.constitutive_models package", "pancax.data package", "pancax.domains package", "pancax.fem package", "pancax.fem.elements package", "pancax.kernels package", "pancax.loss_functions package", "pancax.math package", "pancax.networks package", "pancax.optimizers package"], "titleterms": {"__main__": 2, "adam": 14, "base": 14, "base_constitutive_model": 5, "base_domain": 7, "base_el": 9, "base_kernel": 10, "base_loss_funct": 11, "bc": 3, "bc_loss_funct": 11, "biaxial_tens": 4, "blatz_ko": 5, "bvp": 4, "collocation_domain": 7, "constitutive_model": 5, "content": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "data": 6, "data_loss_funct": 11, "delta_pinn_domain": 7, "distance_funct": 3, "dof_manag": 8, "domain": 7, "element": 9, "elm": 13, "essential_bc": 3, "fem": [8, 9], "field_property_pair": 13, "full_field_data": 6, "function_spac": 8, "gent": 5, "global_data": 6, "hex8_el": 9, "history_writ": 2, "indic": 0, "initi": 13, "inverse_domain": 7, "kernel": 10, "kinemat": 2, "laplace_beltrami": 10, "lbfg": 14, "line_el": 9, "linear_elast": 10, "log": 2, "loss_funct": 11, "math": 12, "mesh": 8, "mlp": 13, "modul": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "natural_bc": 3, "neohookean": 5, "network": 13, "optim": 14, "packag": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "pancax": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "physic": 2, "physics_loss_functions_strong_form": 11, "poisson": 10, "post_processor": 2, "properti": 13, "quad4_el": 9, "quad9_el": 9, "quadrature_rul": 8, "rbf": 13, "read_exodus_mesh": 8, "simple_shear": 4, "simplex_tri_el": 9, "solid_mechan": 10, "sparse_matrix_assembl": 8, "strong_form_loss_funct": 11, "submodul": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "subpackag": [2, 8], "surfac": 8, "swanson": 5, "tabl": 0, "tensor_math": 12, "tet10_el": 9, "tet4_el": 9, "timer": 2, "traction_bc": 8, "trainer": 2, "uniaxial_tens": 4, "util": [2, 7, 11, 14], "variational_domain": 7, "weak_form_loss_funct": 11}}) \ No newline at end of file