API Reference
Core Data Structure
NNFEM.Domain
— TypeDomain
Date 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 ofneles
element 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 number
DOF
: 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 number
neqs
: 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 × 3
integer 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_func
in 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 × 2
matrixelements
: element array. Each element is a material struct, e.g.,PlaneStrain
.ndims
: dimension of the problem space. For 2D problems, ndims = 2.EBC
:nnodes × ndims
integer matrix for essential boundary conditionsEBC[n,d]
is the displacement boundary condition of node
n`'s $d$-th freedom,∘ -1: fixed (time-independent) Dirichlet boundary nodes
∘ -2: time-dependent Dirichlet boundary nodes
g
:nnodes × ndims
double matrix, values for fixed (time-independent) Dirichlet boundary conditions of noden
's $d$-th freedom,FBC
:nnodes × ndims
integer 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 × ndims
double matrix, values for constant (time-independent) force load boundary conditions of node n's $d$-th freedom,Edge_Traction_Data
:n × 3
integer 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
— TypeGlobalData
Store 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.
fvalue
is 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
— TypeFiniteStrainContinuum
Constructs a finite strain element.
eledim
: spatial dimension of the element (default = 2).mat
: constitutive law, a length#elem
vector of materials such asPlaneStress
elnodes
: 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
end
NNFEM.SmallStrainContinuum
— TypeSmallStrainContinuum(coords::Array{Float64}, elnodes::Array{Int64}, props::Dict{String, Any}, ngp::Int64=2)
NNFEM.SmallStrainContinuum
— TypeSmallStrainContinuum
Constructs a small strain element.
eledim
: spatial dimension of the element (default = 2).mat
: constitutive law, a length#elem
vector of materials such asPlaneStress
elnodes
: the node indices in this finite element, an integer arrayprops
: property dictionarycoords
: coordinates of the vertices of the elementdhdx
: list ofngp
shape functions for first order derivatives $\nabla \phi(x)$ (ndof×2
) on the Gaussian pointsweights
: weight vector of lengthn_gauss_points
, for numerical quadraturehs
: list ofngp
shape functions for function values $\phi(x)$ (lengthndof
vectors) 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
end
NNFEM.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
— TypePlaneStress
Creates 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
— TypePlaneStrain
Creates 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)
, assumingstress
andstrain
are defined on Gauss points ((neles*nGauss) × nstrains
).E_all
: strain data of size(neles*nGauss) × nstrains
at the current time step.DE_all
: strain data of size(neles*nGauss) × nstrains
at the last time step.w∂E∂u_all
: sensitivity matrix of size(neles*nGauss) x ndofs_per_element x nstrains
;neles*nGauss
is the number of Gaussian quadrature points,ndofs_per_element
is the number of freedoms per element, andnstrain
is 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×nstrains
at 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
:GlobalData
domain
: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.time
Update state
and Dstate
in domain
. This includes
Copy state variable values for active DOFs from
globaldat
Set 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 => Index
Index
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