API Reference
Core Data Structure
NNFEM.Domain — TypeDomainDate structure for the computatational domain.
nnodes: Int64, number of nodes (each quadratical quad element has 9 nodes)nodes: Float64[nnodes, ndims], coordinate array of all nodesneles: number of elementselements: a list ofneleselement arrays, each element is a structndims: Int64, dimension of the problem spacestate: a matrix of sizennodes×ndims. Current displacement of all nodal freedoms,state[1:nnodes]are for the first direction.Dstate:nnodes×ndims. Previous displacement of all nodal freedoms,Dstate[1:nnodes]are for the first direction.LM:Int64[neles][ndims], LM(e,d) is the global equation number (active freedom number) of element e's d th freedom,∘ -1 means fixed (time-independent) Dirichlet ∘ -2 means time-dependent Dirichlet ∘ >0 means the global equation numberDOF: a matrix of sizeneles×ndims, DOF(e,d) is the global freedom (including both active and inactive DOFs) number of element e's d th freedom.ID: a matrix of sizennodes×ndims.ID(n,d)is the equation number (active freedom number) of node n's $d$-th freedom,∘ -1 means fixed (time-independent) Dirichlet ∘ -2 means time-dependent Dirichlet ∘ >0 means the global equation numberneqs: Int64, number of equations, a.k.a., active freedomseq_to_dof: an integer vector of lengthneqs, map from to equation number (active freedom number) to the freedom number (Int64[1:nnodes] are for the first direction)dof_to_eq: a bolean array of sizennodes×ndims, map from freedom number(Int64[1:nnodes] are for the first direction) to booleans (active freedoms(equation number) are true)EBC: Int64[nnodes, ndims], EBC[n,d] is the displacement boundary condition of node n's dth freedom, -1 means fixed(time-independent) Dirichlet boundary nodes -2 means time-dependent Dirichlet boundary nodesg: Float64[nnodes, ndims], values for fixed(time-independent) Dirichlet boundary conditions of node n's dth freedom,FBC: Int64[nnodes, ndims],FBC[n,d]` is the force load boundary condition of node n's dth freedom, -1 means constant(time-independent) force load boundary nodes -2 means time-dependent force load boundary nodesfext: Float64[neqs], constant (time-independent) nodal forces on these freedomsEdge_Traction_Data:n × 3integer matrix for natural boundary conditions.
Edge_Traction_Data[i,1]is the element id,Edge_Traction_Data[i,2]is the local edge id in the element, where the force is exterted (should be on the boundary, but not required)Edge_Traction_Data[i,3]is the force id, which should be consistent with the last component of theEdge_funcin theGlobdat
time: Float64, current timenpoints: Int64, number of points (each quadratical quad element has 4 points, npoints==nnodes, when porder==1)node_to_point: Int64[nnodes]:map from node number to point point, -1 means the node is not a geometry point
NNFEM.Domain — TypeDomain(nodes::Array{Float64}, elements::Array, ndims::Int64 = 2,
EBC::Union{Missing, Array{Int64}} = missing, g::Union{Missing, Array{Float64}} = missing, FBC::Union{Missing, Array{Int64}} = missing,
f::Union{Missing, Array{Float64}} = missing, edge_traction_data::Array{Int64,2}=zeros(Int64,0,3))Creating a finite element domain.
nodes: coordinate array of all nodes, annodes × 2matrixelements: element array. Each element is a material struct, e.g.,PlaneStrain.ndims: dimension of the problem space. For 2D problems, ndims = 2.EBC:nnodes × ndimsinteger matrix for essential boundary conditionsEBC[n,d]is the displacement boundary condition of noden`'s $d$-th freedom,∘ -1: fixed (time-independent) Dirichlet boundary nodes
∘ -2: time-dependent Dirichlet boundary nodes
g:nnodes × ndimsdouble matrix, values for fixed (time-independent) Dirichlet boundary conditions of noden's $d$-th freedom,FBC:nnodes × ndimsinteger matrix for nodal force boundary conditions.
FBC[n,d] is the force load boundary condition of node n's dth freedom,
∘ -1 means constant(time-independent) force load boundary nodes
∘ -2 means time-dependent force load boundary nodes
f:nnodes × ndimsdouble matrix, values for constant (time-independent) force load boundary conditions of node n's $d$-th freedom,Edge_Traction_Data:n × 3integer matrix for natural boundary conditions.
Edge_Traction_Data[i,1] is the element id, Edge_Traction_Data[i,2] is the local edge id in the element, where the force is exterted (should be on the boundary, but not required) Edge_Traction_Data[i,3] is the force id, which should be consistent with the last component of the Edge_func in the Globdat
For time-dependent boundary conditions (EBC or FBC entries are -2), the corresponding f or g entries are not used.
NNFEM.GlobalData — TypeGlobalDataStore data for finite element updates. Assume the problem has n freedoms,
state: a vector of length $n$. Displacement array at the current time, only for active freedoms. The ordering is based on the equation number.Dstate: a vector of length $n$. Displacement array at the previous time.velo: a vector of length $n$. Velocity array at the current time.acce: a vector of length $n$. Acceleration array at the current time.time: float, current time.M: a matrix of size $n\times n$ spares mass matrixMlumped: a vector of length $n$ lumped mass arrayMID: Float64[n, nd1] off-diagonal part of the mass matrix, between the active freedoms and the time-dependent Dirichlet freedoms, assume there are nd time-dependent Dirichlet freedomsEBC_func: displacement $d$, velocity $v$, and acceleration $a$ from time-dependent Dirichlet boundary conditions
The length of each output is the same as number of "-2" in EBC array. The ordering is direction major, i.e., $u_1, u_3, \ldots, v_1, v_3, \ldots$
FBC_func: time-dependent load boundary condition.
Here $f$ is a vector. Its length is the same as number of "-2" in FBC array. The ordering is direction major, i.e., $u_1, u_3, \ldots, v_1, v_3, \ldots$
Body_func: time-dependent/independent body force function.
Here $f$ is a vector or a matrix (second dimension is 2) depending on the dimension of state variables. The output is a $N\times n_{\text{dim}}$ matrix, where $N$ is the length of $x_{\text{array}}$ or $y_{\text{array}}$, and $n_{\text{dim}}$ is the dimension of the problem (1 or 2).
Edge_func: time-dependent/independent traction load.
Here $f$ is a vector. Its length is the same as the length of $x_{\text{array}}$ or $y_{\text{array}}$.
NNFEM.GlobalData — TypeGlobalData(state::Union{Array{Float64,1},Missing},
Dstate::Union{Array{Float64,1},Missing},
velo::Union{Array{Float64,1},Missing},
acce::Union{Array{Float64,1},Missing},
neqs::Int64,
EBC_func::Union{Function, Nothing}=nothing, FBC_func::Union{Function, Nothing}=nothing,
Body_func::Union{Function,Nothing}=nothing, Edge_func::Union{Function,Nothing}=nothing)The size of state, Dstate, velo, acce must be neqs, i.e., the active DOFs. If they are missing, they are treated as zeros.
state, Dstate, velo, acce can be missing, in which case they are interpreted as zeros.
Domain
NNFEM.getEqns — FunctiongetEqns(domain::Domain, iele::Int64)Gets the equation numbers (active freedom numbers) of the element. This excludes both the time-dependent and time-independent Dirichlet boundary conditions.
NNFEM.getDofs — FunctiongetDofs(domain::Domain, iele::Int64)Get the global freedom numbers of the element
domain: Domainiele: Int64, element number
Return: Int64[], the global freedom numbers of the element (ordering in local element ordering)
NNFEM.getCoords — FunctiongetCoords(domain::Domain, el_nodes::Array{Int64})Get the coordinates of several nodes (possibly in one element)
domain: Domainel_nodes: Int64[n], node array
Return: Float64[n, ndims], the coordinates of these nodes
NNFEM.getNGauss — FunctiongetNGauss(domain::Domain)Gets the total number of Gauss quadrature points.
NNFEM.getGaussPoints — FunctiongetGaussPoints(elem::Continuum)Returns the Gauss quadrature nodes of the element in the undeformed domain
getGaussPoints(domain::Domain)Returns all Gauss points as a $n_g\times 2$ matrix, where $n_g$ is the total number of Gauss points.
NNFEM.getState — MethodgetState(domain::Domain, el_dofs::Array{Int64})Get the displacements of several nodes (possibly in one element)
domain: Domainel_nodes: Int64[n], node array
Return: Float64[n, ndims], the displacements of these nodes
NNFEM.getStrain — MethodgetStrain(domain::Domain)Computes the strain from the domain data. The output is $n_g\times 3$ matrix, where $n_g$ is the total number of Gauss points. Each row is the strain tensor $\begin{bmatrix} \epsilon_{xx} & \epsilon_{yy} & \gamma_{xy} \end{bmatrix}$
NNFEM.getDStrain — MethodgetDStrain(domain::Domain)Computes the strain at last time step from the domain data. The output is $n_g\times 3$ matrix, where $n_g$ is the total number of Gauss points. Each row is the strain tensor $\begin{bmatrix} \epsilon_{xx} & \epsilon_{yy} & \gamma_{xy} \end{bmatrix}$
NNFEM.getStress — FunctiongetStress(domain::Domain, Δt::Float64 = 0.0; save_trace::Bool = false)Returns the stress based on domain.state and domain.Dstate. If save_trace is true, the stress is also saved to domain.stress, which is useful for visualization.
The output is $n_g\times 3$ matrix, where $n_g$ is the total number of Gauss points. Each row is the strain tensor $\begin{bmatrix} \sigma_{xx} & \sigma_{yy} & \sigma_{xy} \end{bmatrix}$
NNFEM.getElems — FunctiongetElems(domain::Domain)Returns the element connectivity matrix $n_e \times 4$. This function implicitly assumes that all elements are quadrilateral.
NNFEM.getStressHistory — FunctiongetStressHistory(domain::Domain)Returns the stress history.
NNFEM.getStrainHistory — FunctiongetStrainHistory(domain::Domain)Returns the strain history.
NNFEM.getStateHistory — FunctiongetStateHistory(domain::Domain)Returns the state history.
Elements
NNFEM.getEdgeForce — FunctiongetEdgeForce(elem::Continuum, iedge::Float64, fvalue::Array{Float64,2})Returns the force imposed by boundary tractions.
fvalue is a $n_{edge_gauss}\times 2$ matrix, which is ordered the same as the Gaussian points in undeformed parent edge element.
The element nodes are ordered as
# 4 ---- 3 # 4 --7-- 3
# # 8 9 6
# 1 ---- 2 # 1 --5-- 2
for porder=1 or porder=2
iedge 1, 2, 3, 4 are (1,2), (2,3), (3,4), (4,1)
are (1,2,5), (2,3,6), (3,4,7), (4,1,8)Returns the nodal force due to the traction on the iedge-th edge of the element $\int_{s} \mathbf{f}(\mathbf{x})\cdot \delta \mathbf{u}(\mathbf{x}) d s = \int_{e} \mathbf{f}(\xi)\cdot \delta \mathbf{u}(\xi) |\frac{\partial \mathbf{x}}{\partial \xi}| d \xi$
This function imposes force in the undeformed domain. Add force in the deformed domain in the future.
getEdgeForce(domain::Domain, globdat::GlobalData, time::Float64)Computes the edge force vector $F_\mathrm{edge}$ defined in domain.edge_traction_data
globdat: GlobalDatadomain: Domain, finite element domain, for data structuretime: Float64, current time step size
NNFEM.getBodyForce — FunctiongetBodyForce(elem::Continuum, fvalue::Array{Float64,2})Returns the body force.
fvalueis a $n_{gauss}\times 2$ matrix, which is ordered the same as Gaussian points in the undeformed parent element.
Returns the nodal force due to the body force $\int_{e} \mathbf{f}(\mathbf{x})\cdot \delta \mathbf{u}(\mathbf{x}) d \mathbf{x} = \int_{e} \mathbf{f}(\mathbf{\xi})\cdot \delta \mathbf{u}(\mathbf{\xi}) |\frac{\partial \mathbf{x}}{\partial \mathbf{\xi}}| d \mathbf{\xi}$
Add force in the deformed domain.
getBodyForce(elem::Continuum, fvalue::Array{Float64, 1})Returns
on a specific element $A$ fvalue has the same length as number of Gauss points.
getBodyForce(domain::Domain, globdat::GlobalData, time::Float64)Computes the body force vector $F_\mathrm{body}$ of length neqs
globdat: GlobalDatadomain: Domain, finite element domain, for data structureΔt: Float64, current time step size
NNFEM.getMassMatrix — FunctiongetMassMatrix(elem::Continuum)Returns the mass matrix and lumped mass matrix of the element elem.
NNFEM.getNodes — FunctiongetNodes(elem::Continuum)Alias for elem.elnodes
Missing docstring for getGaussPoints. Check Documenter's build log for details.
NNFEM.commitHistory — FunctioncommitHistory(elem::Continuum)Updates the historic parameters in the material properties.
commitHistory(domain::Domain)Update current step strain and stress in the history map of the domain. This is essential for visualization and time dependent constitutive relations.
NNFEM.FiniteStrainContinuum — TypeFiniteStrainContinuum(coords::Array{Float64}, elnodes::Array{Int64}, props::Dict{String, Any}, ngp::Int64=2)NNFEM.FiniteStrainContinuum — TypeFiniteStrainContinuumConstructs a finite strain element.
eledim: spatial dimension of the element (default = 2).mat: constitutive law, a length#elemvector of materials such asPlaneStresselnodes: the node indices in this finite element, an integer arrayprops: property dictionarycoords: coordinates of the vertices of the elementdhdx,weights,hs: data for integralstress: stress at each quadrature points
Example
# Local degrees of freedom
# 4 ---- 3
#
# 1 ---- 2
nx = 10
ny = 5
h = 0.1
element = FiniteStrainContinuum[]
prop = Dict("name"=> "PlaneStrain", "rho"=> 0.0876584, "E"=>0.07180760098, "nu"=>0.4)
for j = 1:ny
for i = 1:nx
n = (nx+1)*(j-1) + (i-1)+1
elnodes = [n, n + 1, n + 1 + (nx + 1), n + (nx + 1)]
ngp = 3 # 3 x 3 Gauss points per element
coords = [(i-1)*h (j-1)*h
i*h (j-1)*h
i*h j*h
(i-1)*h j*h]
push!(element, FiniteStrainContinuum(coords,elnodes, prop, ngp))
end
endNNFEM.SmallStrainContinuum — TypeSmallStrainContinuum(coords::Array{Float64}, elnodes::Array{Int64}, props::Dict{String, Any}, ngp::Int64=2)NNFEM.SmallStrainContinuum — TypeSmallStrainContinuumConstructs a small strain element.
eledim: spatial dimension of the element (default = 2).mat: constitutive law, a length#elemvector of materials such asPlaneStresselnodes: the node indices in this finite element, an integer arrayprops: property dictionarycoords: coordinates of the vertices of the elementdhdx: list ofngpshape functions for first order derivatives $\nabla \phi(x)$ (ndof×2) on the Gaussian pointsweights: weight vector of lengthn_gauss_points, for numerical quadraturehs: list ofngpshape functions for function values $\phi(x)$ (lengthndofvectors) on the Gaussian pointsstress: stress at each quadrature points; this field is reserved for visualization.
Example
# Local degrees of freedom
# 4 ---- 3
#
# 1 ---- 2
nx = 10
ny = 5
h = 0.1
element = SmallStrainContinuum[]
prop = Dict("name"=> "PlaneStrain", "rho"=> 0.0876584, "E"=>0.07180760098, "nu"=>0.4)
for j = 1:ny
for i = 1:nx
n = (nx+1)*(j-1) + (i-1)+1
elnodes = [n, n + 1, n + 1 + (nx + 1), n + (nx + 1)]
ngp = 3 # 3 x 3 Gauss points per element
coords = [(i-1)*h (j-1)*h
i*h (j-1)*h
i*h j*h
(i-1)*h j*h]
push!(element, SmallStrainContinuum(coords,elnodes, prop, ngp))
end
endNNFEM.getInternalForce — MethodgetInternalForce(elem::SmallStrainContinuum, state::Array{Float64}, Dstate::Array{Float64}, Δt::Float64)Returns the internal force term. state and Dstate are restriction of full state variables to this element.
NNFEM.getStiffAndForce — MethodgetStiffAndForce(elem::SmallStrainContinuum, state::Array{Float64}, Dstate::Array{Float64}, Δt::Float64)Returns the internal force term and the stiffness matrix. state and Dstate are restriction of full state variables to this element.
NNFEM.getStiffAndForce1 — MethodgetStiffAndForce(elem::SmallStrainContinuum, state::Array{Float64}, Dstate::Array{Float64}, Δt::Float64)Returns the internal force term and the stiffness matrix. state and Dstate are restriction of full state variables to this element.
NNFEM.getStrain — MethodgetStrain(elem::SmallStrainContinuum, state::Array{Float64})Returns the strain of this element. state is restricted to this variable.
Materials
NNFEM.PlaneStress — TypePlaneStressCreates a plane stress element
H: Linear elasticity matrix, $3\times3$E: Young's modulusν: Poisson's ratioρ: densityσ0: stress at the last time stepσ0_: (for internal use), stress to be updated incommitHistoryε0: strain at the last time stepε0_: (for internal use), strain to be updated incommitHistory
Example
prop = Dict("name"=> "PlaneStress", "rho"=> 0.0876584, "E"=>0.07180760098, "nu"=>0.4)
mat = PlaneStress(prop)NNFEM.PlaneStress — MethodPlaneStress(prop::Dict{String, Any})prop should contain at least the following three fields: E, nu, rho
NNFEM.PlaneStrain — TypePlaneStrainCreates a plane strain element
H: Linear elasticity matrix, $3\times3$E: Young's modulusν: Poisson's ratioρ: densityσ0: stress at the last time stepσ0_: (for internal use), stress to be updated incommitHistoryε0: strain at the last time stepε0_: (for internal use), strain to be updated incommitHistory
Example
prop = Dict("name"=> "PlaneStrain", "rho"=> 0.0876584, "E"=>0.07180760098, "nu"=>0.4)
mat = PlaneStrain(prop)NNFEM.PlaneStrain — MethodPlaneStrain(prop::Dict{String, Any})prop should contain at least the following three fields: E, nu, rho
NNFEM.PlaneStressIncompressibleRivlinSaunders — TypePascon, João Paulo. "Large deformation analysis of plane-stress hyperelastic problems via triangular membrane finite elements." International Journal of Advanced Structural Engineering (2019): 1-20.
Matrix and Vector Assembly
NNFEM.assembleInternalForce — FunctionassembleInternalForce(domain::Domain, Δt::Float64 = 0.0)Computes the internal force vector $F_\mathrm{int}$ of length neqs
globdat: GlobalDatadomain: Domain, finite element domain, for data structureΔt: Float64, current time step size
Only the information in domain is used for computing internal force. Therefore, the boundary conditions in domain must be set appropriately.
assembleInternalForce(domain::Domain, nn::Function, E_all::PyObject, DE_all::PyObject, w∂E∂u_all::PyObject, σ0_all::PyObject)Computes local internal force fint and then assemble to Fint, which generates inverse problem automatically.
domain: finite element domainnn: constitutive relation for expressingstress = f(strain), assumingstressandstrainare defined on Gauss points ((neles*nGauss) × nstrains).E_all: strain data of size(neles*nGauss) × nstrainsat the current time step.DE_all: strain data of size(neles*nGauss) × nstrainsat the last time step.w∂E∂u_all: sensitivity matrix of size(neles*nGauss) x ndofs_per_element x nstrains;neles*nGaussis the number of Gaussian quadrature points,ndofs_per_elementis the number of freedoms per element, andnstrainis the number of strain components. The sensitivity matrix already considers the quadrature weights.
where $e$ is the element index, $g$ is the Gaussian index.
σ0_all: stress data of sizeneles*nGauss×nstrainsat the last time step.
Return:
- \[F_{\mathrm{int}}\]: internal force vector of length
neqns - \[\sigma_{\mathrm{all}}\]: predicted stress at current step, a matrix of size
(neles*nGauss) × nstrains
NNFEM.assembleStiffAndForce — FunctionassembleStiffAndForce(domain::Domain, Δt::Float64 = 0.0)Computes the internal force and stiffness matrix.
domain: Domain, finite element domain, for data structureΔt: Float64, current time step size
Returns a length neqs vector $F_{\mathrm{int}}$ and neqs×neqs sparse stiffness matrix.
NNFEM.assembleMassMatrix! — FunctionassembleMassMatrix!(globaldat::GlobalData, domain::Domain)Computes the constant sparse mass matrix $M_{\mathrm{mass}}$, the lumped mass matrix $M_{\mathrm{lump}}$ due to time-dependent Dirichlet boundary conditions, and store them in globaldat.
Here M is a neqns×neqns matrix, and $M_{ID}$ is a neqns×nd matrix. $M_{\mathrm{lump}}$ assumes that the local mass matrix is a diagonal matrix.
globdat:GlobalDatadomain:Domain, finite element domain, for data structure

Missing docstring for getBodyForce. Check Documenter's build log for details.
NNFEM.getExternalForce — FunctiongetExternalForce(self::Domain, globaldat::GlobalData, fext::Union{Missing,Array{Float64}}=missing)Computes external force vector at globaldat.time, This includes all the body force, external load, and internal force caused by acceleration.
State Updates
This set of functions include boundary condition updates, data transfer, and other bookkeeping utilities.
Missing docstring for commitHistory. Check Documenter's build log for details.
NNFEM.setConstantDirichletBoundary! — FunctionsetConstantDirichletBoundary!(self::Domain, EBC::Array{Int64}, g::Array{Float64})Bookkeepings for time-independent Dirichlet boundary conditions. Only called once in the constructor of domain. It updates the fixed (time-independent Dirichlet boundary) state entries and builds both LM and DOF arrays.
self: DomainEBC: Int64[nnodes, ndims], EBC[n,d] is the displacement boundary condition of node n's dth freedom,∘ -1 means fixed(time-independent) Dirichlet boundary nodes
∘ -2 means time-dependent Dirichlet boundary nodes
g: Float64[nnodes, ndims], values for fixed (time-independent) Dirichlet boundary conditions of node n's dth freedom,
NNFEM.setConstantNodalForces! — FunctionBookkeepings for time-independent Nodal force boundary conditions. Only called once in the constructor of domain. It updates the fixed (time-independent Nodal forces) state entries and builds both LM and DOF arrays.
self: DomainFBC: Int64[nnodes, ndims], FBC[n,d] is the displacement boundary condition of node n's dth freedom,∘ -1 means fixed (time-independent) Nodal force freedoms
∘ -2 means time-dependent Nodal force freedoms
f: Float64[nnodes, ndims], values for fixed (time-independent) Neumann boundary conditions of node n's dth freedom,
#The name is misleading
NNFEM.updateStates! — FunctionupdateStates!(domain::Domain, globaldat::GlobalData)
update time-dependent Dirichlet boundary condition to globaldat.timeUpdate state and Dstate in domain. This includes
Copy state variable values for active DOFs from
globaldatSet time-dependent essential boundary conditions using
globaldat.EBC
The time-independent boundary conditions are inherented from last time step.
NNFEM.updateTimeDependentEssentialBoundaryCondition! — FunctionupdateTimeDependentEssentialBoundaryCondition!(domain::Domain, globaldat::GlobalData)If there exists time-dependent Dirichlet boundary conditions, updateTimeDependentEssentialBoundaryCondition! must be called to update the boundaries in domain. This function is called by updateStates!
This function updates state data in domain.
Solvers
NNFEM.ExplicitSolverStep — FunctionExplicitSolverStep(globdat::GlobalData, domain::Domain, Δt::Float64)Central Difference explicit solver for M a + fint(u) = fext(u). a, v, u are acceleration, velocity and displacement.
You need to call SolverInitial! before the first time step, if $f^{ext}_0 \neq 0$. Otherwise we assume the initial acceleration globdat.acce[:] = 0.
NNFEM.GeneralizedAlphaSolverStep — FunctionGeneralizedAlphaSolverStep(globdat::GlobalData, domain::Domain, Δt::Float64,
ρ::Float64 = 0.0, ε::Float64 = 1e-8, ε0::Float64 = 1e-8, maxiterstep::Int64=100,
η::Float64 = 1.0, failsafe::Bool = false, verbose::Bool = false)Implicit solver for $Ma + f_{int}(u) = fext$ Here $a$, $v$, $u$ are acceleration, velocity and displacement respectively.
ρ: controls the damping effect of the α-scheme, ρ∈[0,1], ρ=1 corresponds to the maximum dampingε: Float64, absolute error for Newton convergenceε0: Float64, relative error for Newton convergencemax_iter: Int64, maximum iteration number for Newton convergenceη: Float64, Newton step size at the first iterationfailsafe: Bool, if failsafe is true, when the Newton fails to converge, revert back, and return false
The nonlinear $\alpha$
'a_{n+1}' is solved by
As for \alpha_m and $\alpha_f$
use the current states a, v, u, time in globdat, and update these stetes to next time step update domain history, when failsafe is true, and Newton's solver fails, nothing will be changed.
You need to call SolverInitial! before the first time step, if f^{ext}0 != 0. SolverInitial! updates a0 in the globdat.acce a0 = M^{-1}(- f^{int}(u0) + f^{ext}_0)
We assume globdat.acce[:] = a_0 and so far initialized to 0 We also assume the external force is conservative (it does not depend on the current deformation)
NNFEM.ImplicitStaticSolver — FunctionImplicitStaticSolver(globdat::GlobalData, domain::Domain;
N::Int64 = 10, ε::Float64 = 1.e-6, maxiterstep::Int64=100)Solves $K(u) = F$ using the incremental load method. Specifically, at step $i$, we solve
globdat, GlobalDatadomain, DomainN, an integer, load stepping stepsε, Float64, absolute error for Newton convergencemaxiterstep, Int64, maximum iteration number for Newton convergence
ImplicitStaticSolver(globdat::GlobalData, domain::Domain,
d0::Union{Array{Float64, 1}, PyObject},
nn::Function, θ::Union{Array{Float64, 1}, PyObject},
Fext::Union{Array{Float64, 1}, PyObject, Missing}=missing)Solves the static problem
using Newton's method. Users provide nn, which is a function that outputs stress and stress sensitivity given the strain tensor.
d0: a vector of length2domain.nnodes, the fixed Dirichlet DOF should be populated with boundary values.Fext: external force, a vector of lengthdomain.neqs
NNFEM.SolverInitial! — FunctionSolverInitial!(Δt::Float64, globdat::GlobalData, domain::Domain)You need to call SolverInitial! before the first time step, if $f^{ext}_0 \neq 0$
NNFEM.SolverInitial — FunctionSolverInitial(Δt::Float64, globdat::GlobalData, domain::Domain)Similar to SolverInitial!, but returns the (displacement, velocity, acceleartion) tuple.
Mesh Utilities
NNFEM.meshread — Functionmeshread(gmshfile::String)Reads a gmsh file gmshfile and return (nodes, elements) tuple.
NNFEM.psread — Functionpsread(gmshfile::String)Reads the physical group information from gmshfile. Returns a dictionary
PhysicalGroupName => IndexIndex is a $n\times 2$ coordinate matrix. We do not output indices because there may be postprocessing procedures after creating the mesh.
NNFEM.addCurveLoop — FunctionAdd a curve loop (a closed wire) formed by the curves curveTags.
NNFEM.addPhysicalGroup — FunctionForms a physical group of dimension dim and tag tag with name name
Visualization
NNFEM.visualize_boundary — Functionvisualize_boundary(domain::Domain, direction::String="x")Visualizes the boundary conditions. The boundary configuration is shown in the direction direction.

NNFEM.visualize_displacement — Methodvisualize_displacement(domain::Domain)
visualize_displacement(u::Array{Float64, 2}, domain::Domain)Animation of displacements using points.

NNFEM.visualize_mesh — Methodvisualize_displacement(domain::Domain)
visualize_displacement(nodes::Array{Float64,2}, elems::Array{Int64, 2})Visualizes the mesh. 
NNFEM.visualize_scalar_on_scoped_body — Methodvisualize_scalar_on_scoped_body(d::Array{Float64}, domain::Domain, kwargs...)
visualize_scalar_on_scoped_body(s::Array{Float64, 1}, d::Array{Float64,1}, domain::Domain;
scale_factor::Float64 = -1.0, kwargs...)Plot the scalar on scoped body. For example, s can be the von Mises stress tensor.
NNFEM.visualize_scalar_on_undeformed_body — Methodvisualize_scalar_on_undeformed_body(s::Array{Float64, 1}, domain::Domain; kwargs...)
visualize_scalar_on_undeformed_body(s::Array{Float64, 2}, domain::Domain; frames::Int64 = 20, kwargs...)Plots or animates scalar values s on the domain domain
NNFEM.visualize_total_deformation_on_scoped_body — Methodvisualize_total_deformation_on_scoped_body(d_all::Array{Float64,2}, domain::Domain;
scale_factor::Float64 = 1.0, frames::Int64 = 20)Visualizes the total deformation

NNFEM.visualize_von_mises_stress — Methodvisualize_von_mises_stress(domain::Domain, t_step::Int64; kwargs...)Plot of von Mises stress tensors at time step t_step.

NNFEM.visualize_von_mises_stress — Methodvisualize_von_mises_stress(domain::Domain; frames::Int64 = 20, kwargs...)Animation of von Mises stress tensors.

NNFEM.visualize_von_mises_stress_on_scoped_body — Methodvisualize_von_mises_stress_on_scoped_body(d_all::Array{Float64,2}, domain::Domain;
scale_factor::Real = -1.0, frames::Int64 = 20)Similar to visualize_von_mises_stress, but the domain can be a deformed body.

NNFEM.visualize_x_deformation_on_scoped_body — Methodvisualize_x_deformation_on_scoped_body(d_all::Array{Float64,2}, domain::Domain;
scale_factor::Real = 1.0, frames::Int64 = 20, kwargs...)Visualizes the $x$ directional displacement.
NNFEM.visualize_y_deformation_on_scoped_body — Methodvisualize_y_deformation_on_scoped_body(d_all::Array{Float64,2}, domain::Domain;
scale_factor::Real = 1.0, frames::Int64 = 20, kwargs...)Visualizes the $y$ directional displacement.
Automatic Differentiation
NNFEM.init_nnfem — Functioninit_nnfem(domain::Domain)
Prepares domain for use in custom operators.
NNFEM.s_eval_strain_on_gauss_points — Functions_eval_strain_on_gauss_points(state::Union{Array{Float64,1}, PyObject})Computes the strain on Gauss points in the small strain case. state is the full displacement vector.
NNFEM.s_compute_stiffness_matrix — Functions_compute_stiffness_matrix(k::Union{Array{Float64,3}, PyObject})Computes the small strain stiffness matrix. $k$ is a $n\times 3\times 3$ matrix, where $n$ is the total number of Gauss points. Returns a SparseTensor.
NNFEM.s_compute_internal_force_term — Functions_compute_internal_force_term(stress::Union{Array{Float64,2}, PyObject})Computes the internal force $\int_\Omega \sigma : \delta \epsilon dx$ Only active DOFs are considered.
NNFEM.f_eval_strain_on_gauss_points — Functionf_eval_strain_on_gauss_points(state::Union{Array{Float64,1}, PyObject})Computes the strain on Gauss points in the finite strain case. state is the full displacement vector.
NNFEM.f_compute_internal_force_term — Functionf_compute_internal_force_term(stress::Union{Array{Float64,2}, PyObject},
state::Union{Array{Float64,1}, PyObject},
domain::Domain)Computes the internal force for finite strain continuum
Only active DOFs are considered.
NNFEM.ExplicitSolver — FunctionExplicitSolver(globdat::GlobalData, domain::Domain,
d0::Union{Array{Float64, 1}, PyObject},
v0::Union{Array{Float64, 1}, PyObject},
a0::Union{Array{Float64, 1}, PyObject},
Δt::Float64, NT::Int64,
H::Union{Array{Float64, 3}, Array{Float64, 2}, PyObject},
Fext::Union{Array{Float64, 2}, PyObject, Missing}=missing,
ubd::Union{Array{Float64, 2}, PyObject, Missing}=missing,
abd::Union{Array{Float64, 2}, PyObject, Missing}=missing; strain::String = "small")Differentiable Explicit Solver.
d0,v0,a0: initial full displacement, velocity, and acceleration.Δt: time stepHs: linear elasticity matrix at each Gauss pointFext: external force, $\mathrm{NT}\times n$, where $n$ is the active dof. The external force includes all body forces, external load forces (also called edge forces in NNFEM) and boundary acceleration-induced forces.ubd,abd: boundary displacementt and acceleration, $\mathrm{NT}\times m$, where $m$ is time-dependent boundary DOF. Time-independent boundary conditions are extracted fromdomain.strain_type(default = "small"): small strain or finite strain
ExplicitSolver(globdat::GlobalData, domain::Domain,
d0::Union{Array{Float64, 1}, PyObject},
v0::Union{Array{Float64, 1}, PyObject},
a0::Union{Array{Float64, 1}, PyObject},
Δt::Float64, NT::Int64,
nn::Function,
Fext::Union{Array{Float64, 2}, PyObject, Missing}=missing,
ubd::Union{Array{Float64, 2}, PyObject, Missing}=missing,
abd::Union{Array{Float64, 2}, PyObject, Missing}=missing; strain_type::String = "small"))Similar to ExplicitSolver; however, the constituve relation from $\epsilon$ to $\sigma$ must be provided by the function nn.
ExplicitSolver(globdat::GlobalData, domain::Domain,
d0::Union{Array{Float64, 1}, PyObject},
v0::Union{Array{Float64, 1}, PyObject},
a0::Union{Array{Float64, 1}, PyObject},
σ0::Union{Array{Float64, 1}, PyObject},
ε0::Union{Array{Float64, 1}, PyObject},
Δt::Float64, NT::Int64,
nn::Function,
Fext::Union{Array{Float64, 2}, PyObject, Missing}=missing,
ubd::Union{Array{Float64, 2}, PyObject, Missing}=missing,
abd::Union{Array{Float64, 2}, PyObject, Missing}=missing; strain_type::String = "small")Similar to ExplicitSolver; however, the constitutive relation has the form
Here the strain and stress are $n \times 3$ tensors. $n$ is the total number of Gaussian points and can be obtained via getNGauss(domain).
NNFEM.ExplicitSolverTime — FunctionExplicitSolverTime(Δt::Float64, NT::Int64)Returns the times for explicit solver. Boundary conditions and external forces should be given at these times.
NNFEM.GeneralizedAlphaSolver — FunctionGeneralizedAlphaSolver(globdat::GlobalData, domain::Domain,
d0::Union{Array{Float64, 1}, PyObject},
v0::Union{Array{Float64, 1}, PyObject},
a0::Union{Array{Float64, 1}, PyObject},
Δt::Float64, NT::Int64,
Hs::Union{Array{Float64, 3}, Array{Float64, 2}, PyObject},
Fext::Union{Array{Float64, 2}, PyObject, Missing}=missing,
ubd::Union{Array{Float64, 2}, PyObject, Missing}=missing,
abd::Union{Array{Float64, 2}, PyObject, Missing}=missing; ρ::Float64 = 0.0)Differentiable Generalized $\alpha$ scheme. This is an extension of αscheme provided in ADCME. This function does not support damping and variable time step (for efficiency).
d0,v0,a0: initial full displacement, velocity, and acceleration.Δt: time stepHs: linear elasticity matrix at each Gauss pointFext: external force, $\mathrm{NT}\times n$, where $n$ is the active dof. The external force includes all body forces, external load forces (also called edge forces in NNFEM) and boundary acceleration-induced forces.ubd,abd: boundary displacementt and acceleration, $\mathrm{NT}\times m$, where $m$ is boundary DOF. Time-independent boundary conditions are extracted fromdomain.
GeneralizedAlphaSolver does not support finite-strain continuum yet.
GeneralizedAlphaSolver(globdat::GlobalData, domain::Domain,
d0::Union{Array{Float64, 1}, PyObject},
v0::Union{Array{Float64, 1}, PyObject},
a0::Union{Array{Float64, 1}, PyObject},
Δt::Float64, NT::Int64,
Cs::Union{Array{Float64, 3}, Array{Float64, 2}, PyObject},
Hs::Union{Array{Float64, 3}, Array{Float64, 2}, PyObject},
Fext::Union{Array{Float64, 2}, PyObject, Missing}=missing,
ubd::Union{Array{Float64, 2}, PyObject, Missing}=missing,
abd::Union{Array{Float64, 2}, PyObject, Missing}=missing; ρ::Float64 = 0.0)Solve linear dynamical structural problem using a generalized alpha solver. Cs and Hs are the corresponding linear viscosity and linear elasticity matrix.
NNFEM.GeneralizedAlphaSolverTime — FunctionGeneralizedAlphaSolverTime(Δt::Float64, NT::Int64;ρ::Float64 = 0.0)Returns the times for the generalized $\alpha$ solver. Boundary conditions and external forces should be given at these times.
NNFEM.compute_boundary_info — Functioncompute_boundary_info(domain::Domain, globdat::GlobalData, ts::Array{Float64})Computes the boundary information ubd and abd
NNFEM.compute_external_force — Functioncompute_external_force(domain::Domain, globdat::GlobalData, ts::Union{Array{Float64}, Missing} = missing)Computes the external force (body force, edge force and force due to boundary acceleration).
NNFEM.compute_stress_rivlin_saunders — Functioncompute_stress_rivlin_saunders(strain::Union{PyObject, Array{Float64,2}},c1::Union{PyObject, Float64},c2::Union{PyObject, Float64})Computes the stress using the plane stress incompressible Rivlin Saunders model.
NNFEM.s_compute_stiffness_matrix1 — Functions_compute_stiffness_matrix1(k::Union{PyObject, Array{Float64,3}}, domain::Domain)Computes the stiffness matrix
\int_\Omega (K\nabla u) \cdot \nabla \delta u dx