# Functions

## Physical units

FinEtools.PhysicalUnitModule.phunMethod
phun(str::String; system_of_units = :SI, base_time_units = :SEC)

Evaluate an expression in physical units.

Inputs: –system_of_units

if system_of_units  ==  :US
basic assumed units are American Engineering:
LENGTH = FT, TIME = SEC, MASS = SLUG TEMPERATURE = RAN FORCE = LB
elseif system_of_units  ==  :CGS
basic assumed units are Centimeter,Gram,Second:
LENGTH = CM, TIME = SEC, MASS = GM TEMPERATURE = K FORCE = DYNE
elseif system_of_units  ==  :IMPERIAL
basic assumed units are Imperial:
LENGTH = FT, TIME = SEC, MASS = SLUG TEMPERATURE = RAN FORCE = LB
otherwise,
basic assumed units are :SIM (equivalent to :SI, default):
LENGTH = M , TIME = SEC, MASS = KG   TEMPERATURE = K   FORCE = N

base_time_units defaults to :SEC

Example

pu = ustring -> phun(ustring; system_of_units = :SIMM)
E1s = 130.0*pu("GPa")

yields 1.3e+5 (in mega Pascal) whereas

130.0*phun("GPa"; system_of_units = :SI)

yields 1.3e+11 (in Pascal)

## Bounding box functions

FinEtools.BoxModule.boundingboxMethod
boundingbox(x::AbstractArray)

Compute the bounding box of the points in x.

x = holds points, one per row.

Returns box = bounding box for 1-D box=[minx,maxx], or for 2-D box=[minx,maxx,miny,maxy], or for 3-D box=[minx,maxx,miny,maxy,minz,maxz]

FinEtools.BoxModule.intersectboxesMethod
intersectboxes(box1::AbstractVector, box2::AbstractVector)

Compute the intersection of two boxes.

The function returns an empty box (length(b) == 0) if the intersection is empty; otherwise a box is returned.

FinEtools.BoxModule.updatebox!Method
updatebox!(box::AbstractVector, x::AbstractArray)

Update a box with another location, or create a new box.

If the box does not have the correct dimensions, it is correctly sized.

box = bounding box for 1-D box=[minx,maxx], or for 2-D box=[minx,maxx,miny,maxy], or for 3-D box=[minx,maxx,miny,maxy,minz,maxz] The box is expanded to include the supplied location x. The variable x can hold multiple points in rows.

## Coordinate systems

FinEtools.CSysModule.gen_iso_csmat!Method
gen_iso_csmat!(csmatout::Matrix{T}, XYZ::Matrix{T}, tangents::Matrix{T}, feid::IT, qpid::IT) where {T, IT}

Compute the coordinate system for an isotropic material using information available by looking at the coordinate curves of isoparametric finite elements.

• XYZ= location in physical coordinates,
• tangents= tangent vector matrix, tangents to the parametric coordinate curves in the element,
• feid= finite element identifier;
• qpid = quadrature point identifier.

The basic assumption here is that the material is isotropic, and therefore the choice of the material directions does not really matter as long as they correspond to the dimensionality of the element. For instance a one-dimensional element (L2 as an example) may be embedded in a three-dimensional space.

This function assumes that it is being called for an mdim-dimensional manifold element, which is embedded in a sdim-dimensional Euclidean space. If mdim == sdim, the coordinate system matrix is the identity; otherwise the local coordinate directions are aligned with the linear subspace defined by the tangent vectors.

Warning

This cannot be reliably used to produce consistent stresses because each quadrature point gets a local coordinate system which depends on the orientation of the element, in general different from the neighboring elements.

FinEtools.CSysModule.updatecsmat!Method
updatecsmat!(self::CSys,
XYZ::Matrix{T},
tangents::Matrix{T},
feid::IT1,
qpid::IT2) where {T, IT1, IT2}

Update the coordinate system orientation matrix.

The coordinate system matrix is updated based upon the location XYZ of the evaluation point, and possibly on the Jacobian matrix tangents within the element in which the coordinate system matrix is evaluated, or perhaps on the identifier feid of the finite element and/or the quadrature point identifier.

After this function returns, the coordinate system matrix can be read in the buffer as self.csmat.

## Matrix utilities

FinEtools.MatrixUtilityModule.add_b1tdb2!Method
add_b1tdb2!(
Ke::Matrix{T},
B1::Matrix{T},
B2::Matrix{T},
Jac_w::T,
D::Matrix{T},
DB2::Matrix{T},
) where {T}

Add the product (B1'*(D*(Jac_w))*B2), to the matrix Ke.

The matrix Ke is assumed to be suitably initialized: the results of this computation are added. The matrix Ke may be rectangular.

The matrix D may be rectangular.

The matrix Ke is modified. The matrices B1, B2, and D are not modified inside this function. The scratch buffer DB is overwritten during each call of this function.

FinEtools.MatrixUtilityModule.add_btdb_ut_only!Method
add_btdb_ut_only!(Ke::Matrix{T}, B::Matrix{T}, Jac_w::T, D::Matrix{T}, DB::Matrix{T}) where {T}

Add the product (B'*(D*(Jac*w[j]))*B), to the matrix Ke.

Only upper triangle is computed; the lower triangle is not touched. (Use complete_lt! to complete the lower triangle, if needed.)

The matrix Ke is assumed to be suitably initialized.

The matrix Ke is modified. The matrices B and D are not modified inside this function. The scratch buffer DB is overwritten during each call of this function.

FinEtools.MatrixUtilityModule.add_btsigma!Method
add_btsigma!(Fe::Vector{T}, B::Matrix{T}, coefficient::T, sigma::Vector{T}) where {T}

Add the product B'*(sigma*coefficient), to the elementwise vector Fe.

The vector Fe is assumed to be suitably initialized.

The vector Fe is modified. The vector sigma is not modified inside this function.

FinEtools.MatrixUtilityModule.add_gkgt_ut_only!Method
add_gkgt_ut_only!(
Ke::Matrix{T},
Jac_w::T,
kappa_bar::Matrix{T},
) where {T}

Add the product gradN*kappa_bar*gradNT*(Jac*w[j]) to the matrix Ke.

Only upper triangle is computed; the lower triangle is not touched. (Use complete_lt! to complete the lower triangle, if needed.)

The matrix Ke is assumed to be suitably initialized.

Upon return, the matrix Ke is updated. The scratch buffer kappa_bargradNT is overwritten during each call of this function. The matrices gradN and kappa_bar are not modified inside this function.

FinEtools.MatrixUtilityModule.add_mggt_ut_only!Method
add_mggt_ut_only!(Ke::Matrix{T}, gradN::Matrix{T}, mult) where {T}

Add the product gradN*mult*gradNT to the matrix Ke.

The argument mult is a scalar. Only upper triangle is computed; the lower triangle is not touched. (Use complete_lt! to complete the lower triangle, if needed.)

The matrix Ke is assumed to be suitably initialized.

The matrix Ke is modified. The matrix gradN is not modified inside this function.

FinEtools.MatrixUtilityModule.add_n1n2t!Method
add_n1n2t!(Ke::Matrix{T}, N1::Matrix{T}, N2::Matrix{T}, Jac_w_coeff::T) where {T<:Number}

Add the product N1*(N2'*(coeff*(Jac*w(j))), to the matrix Ke.

The matrix Ke is assumed to be suitably initialized. The matrices N1 and N2 have a single column each.

The matrix Ke is modified. The matrix N1 and N2 are not modified inside this function.

FinEtools.MatrixUtilityModule.add_nnt_ut_only!Method
add_nnt_ut_only!(Ke::Matrix{T}, N::Matrix{T}, Jac_w_coeff::T) where {T<:Number}

Add the product Nn*(Nn'*(coeff*(Jac*w(j))), to the matrix Ke.

Only the upper triangle is computed; the lower triangle is not touched.

The matrix Ke is assumed to be suitably initialized. The matrix Nn has a single column.

The matrix Ke is modified. The matrix Nn is not modified inside this function.

FinEtools.MatrixUtilityModule.complete_lt!Method
complete_lt!(Ke::Matrix{T}) where {T}

Complete the lower triangle of the elementwise matrix Ke.

The matrix Ke is modified inside this function. The upper-triangle entries are copied across the diagonal to the lower triangle.

FinEtools.MatrixUtilityModule.jac!Method
jac!(J::Matrix{T}, ecoords::Matrix{T}, gradNparams::Matrix{T}) where {T}

Compute the Jacobian matrix at the quadrature point.

Arguments: J = Jacobian matrix, overwritten inside the function ecoords = matrix of the node coordinates for the element. gradNparams = matrix of basis function gradients

FinEtools.MatrixUtilityModule.loc!Method
loc!(loc::Matrix{T}, ecoords::Matrix{T}, N::Matrix{T}) where {T}

Compute the location of the quadrature point.

Arguments: loc = matrix of coordinates, overwritten inside the function ecoords = matrix of the node coordinates for the element. N = matrix of basis function values

FinEtools.MatrixUtilityModule.locjac!Method
locjac!(
loc::Matrix{T},
J::Matrix{T},
ecoords::Matrix{T},
N::Matrix{T},
) where {T}

Compute location and Jacobian matrix at the quadrature point.

Arguments: loc = matrix of coordinates, overwritten inside the function J = Jacobian matrix, overwritten inside the function ecoords = matrix of the node coordinates for the element. N = matrix of basis function values gradNparams = matrix of basis function gradients

FinEtools.MatrixUtilityModule.matrix_blocked_ddFunction
matrix_blocked_dd(A, row_nfreedofs, col_nfreedofs = row_nfreedofs)

Extract the "data-data" partition of a matrix.

The matrix is assumed to be composed of four blocks

A = [A_ff A_fd
A_df A_dd]

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...). The size of the ff block is row_nfreedofs, col_nfreedofs. Neither one of the blocks is square, unless row_nfreedofs == col_nfreedofs.

When row_nfreedofs == col_nfreedofs, only the number of rows needs to be given.

FinEtools.MatrixUtilityModule.matrix_blocked_dfFunction
matrix_blocked_df(A, row_nfreedofs, col_nfreedofs = row_nfreedofs)

Extract the "data-free" partition of a matrix.

The matrix is assumed to be composed of four blocks

A = [A_ff A_fd
A_df A_dd]

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...). The size of the ff block is row_nfreedofs, col_nfreedofs. Neither one of the blocks is square, unless row_nfreedofs == col_nfreedofs.

When row_nfreedofs == col_nfreedofs, only the number of rows needs to be given.

FinEtools.MatrixUtilityModule.matrix_blocked_fdFunction
matrix_blocked_fd(A, row_nfreedofs, col_nfreedofs = row_nfreedofs)

Extract the "free-data" partition of a matrix.

The matrix is assumed to be composed of four blocks

A = [A_ff A_fd
A_df A_dd]

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...). The size of the ff block is row_nfreedofs, col_nfreedofs. Neither one of the blocks is square, unless row_nfreedofs == col_nfreedofs.

When row_nfreedofs == col_nfreedofs, only the number of rows needs to be given.

FinEtools.MatrixUtilityModule.matrix_blocked_ffFunction
matrix_blocked_ff(A, row_nfreedofs, col_nfreedofs = row_nfreedofs)

Extract the "free-free" partition of a matrix.

The matrix is assumed to be composed of four blocks

A = [A_ff A_fd
A_df A_dd]

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...). The size of the ff block is row_nfreedofs, col_nfreedofs. Neither one of the blocks is square, unless row_nfreedofs == col_nfreedofs.

When row_nfreedofs == col_nfreedofs, only the number of rows needs to be given.

FinEtools.MatrixUtilityModule.mulCAB!Method
mulCAB!(C, A, B)

Compute the matrix C = A * B

The use of BLAS is purposefully avoided in order to eliminate contentions of multi-threaded execution of the library code with the user-level threads.

FinEtools.MatrixUtilityModule.mulCAB!Method
mulCAB!(C::Vector{T}, A, B::Vector{T})  where {T}

Compute the product C = A * B, where C and B are "vectors".

The use of BLAS is purposefully avoided in order to eliminate contentions of multi-threaded execution of the library code with the user-level threads.

FinEtools.MatrixUtilityModule.mulCABt!Method
mulCABt!(C, A, B)

Compute the matrix C = A * B'

The use of BLAS is purposefully avoided in order to eliminate contentions of multi-threaded execution of the library code with the user-level threads.

FinEtools.MatrixUtilityModule.mulCAtB!Method
mulCAtB!(C, A, B)

Compute the matrix C = A' * B

The use of BLAS is purposefully avoided in order to eliminate contentions of multi-threaded execution of the library code with the user-level threads.

FinEtools.MatrixUtilityModule.vector_blocked_dMethod
vector_blocked_d(V, nfreedofs)

Extract the "data" part of a vector.

The vector is composed of two blocks

V = [V_f
V_d]

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...).

FinEtools.MatrixUtilityModule.vector_blocked_fMethod
vector_blocked_f(V, nfreedofs)

Extract the "free" part of a vector.

The vector is composed of two blocks

V = [V_f
V_d]

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...).

## Force intensity

FinEtools.ForceIntensityModule.updateforce!Method
updateforce!(self::ForceIntensity, XYZ::Matrix{T}, tangents::Matrix{T}, feid::IT, qpid::IT) where {T<:Number, IT<:Integer}

Update the force intensity vector.

Returns a vector (stored in the cache self.cache).

## Rotation utilities

FinEtools.RotationUtilModule.cross3!Method
cross3!(
result::AbstractVector{T1},
theta::AbstractVector{T2},
v::AbstractVector{T3},
) where {T1, T2, T3}

Compute the cross product of two vectors in three-space in place.

FinEtools.RotationUtilModule.cross3!Method
cross3!(
result::AbstractVector{T1},
theta::Union{AbstractVector{T2}, Tuple{T2, T2, T2}},
v::Union{AbstractVector{T3}, Tuple{T3, T3, T3}}
) where {T1, T2, T3}

Compute the cross product of two vectors in three-space in place.

## Finite element sets

Base.catMethod
cat(self::T,  other::T) where {T<:AbstractFESet}

Concatenate the connectivities of two FE sets.

Base.countMethod
count(self::T)::FInt where {T<:AbstractFESet}

Get the number of individual connectivities in the FE set.

FinEtools.FESetModule.JacobianMethod
Jacobian(self::ET, J::Matrix{FT}) where {ET<:AbstractFESet0Manifold, FT}

Evaluate the point Jacobian.

• J = Jacobian matrix, columns are tangent to parametric coordinates curves.
FinEtools.FESetModule.JacobianMethod
Jacobian(self::ET, J::Matrix{FT}) where {ET<:AbstractFESet1Manifold, FT}

Evaluate the curve Jacobian.

• J = Jacobian matrix, columns are tangent to parametric coordinates curves.
FinEtools.FESetModule.JacobianMethod
Jacobian(self::ET, J::Matrix{FT}) where {ET<:AbstractFESet2Manifold, FT}

Evaluate the curve Jacobian.

• J = Jacobian matrix, columns are tangent to parametric coordinates curves.
FinEtools.FESetModule.JacobianMethod
Jacobian(self::ET, J::Matrix{FT}) where {ET<:AbstractFESet3Manifold, FT}

Evaluate the volume Jacobian.

J = Jacobian matrix, columns are tangent to parametric coordinates curves.

FinEtools.FESetModule.bfunMethod
bfun(self::ET, param_coords::Vector{T}) where {ET<:AbstractFESet, T}

Compute the values of the basis functions.

Compute the values of the basis functions at a given parametric coordinate. One basis function per row.

FinEtools.FESetModule.bfundparMethod
bfundpar(self::ET, param_coords::Vector{T}) where {ET<:AbstractFESet, T}

Compute the values of the basis function gradients.

Compute the values of the basis function gradients with respect to the parametric coordinates at a given parametric coordinate. One basis function gradients per row.

FinEtools.FESetModule.connasarrayMethod
connasarray(self::AbstractFESet{NODESPERELEM}) where {NODESPERELEM}

Return the connectivity as an array.

Return the connectivity as an integer array (matrix), where the number of rows matches the number of connectivities in the set.

FinEtools.FESetModule.gradN!Method
gradN!(
self::AbstractFESet1Manifold,
redJ::Matrix{FT},
) where {FT}

Compute the gradient of the basis functions with the respect to the "reduced" spatial coordinates.

• gradN= output, matrix of gradients, one per row
• gradNparams= matrix of gradients with respect to parametric coordinates, one per row
• redJ= reduced Jacobian matrix redJ=transpose(Rm)*J
FinEtools.FESetModule.gradN!Method
gradN!(
self::AbstractFESet2Manifold,
redJ::Matrix{FT},
) where {FT}

Compute the gradient of the basis functions with the respect to the "reduced" spatial coordinates.

• gradN= output, matrix of gradients, one per row
• gradNparams= matrix of gradients with respect to parametric coordinates, one per row
• redJ= reduced Jacobian matrix redJ=transpose(Rm)*J
FinEtools.FESetModule.gradN!Method
gradN!(
self::AbstractFESet3Manifold,
redJ::Matrix{FT},
) where {FT}

Compute the gradient of the basis functions with the respect to the "reduced" spatial coordinates.

• gradN= output, matrix of gradients, one per row
• gradNparams= matrix of gradients with respect to parametric coordinates, one per row
• redJ= reduced Jacobian matrix redJ=transpose(Rm)*J
FinEtools.FESetModule.inparametricMethod
inparametric(self::AbstractFESet, param_coords)

Are given parametric coordinates inside the element parametric domain?

Return a Boolean: is the point inside, true or false?

FinEtools.FESetModule.map2parametricMethod
map2parametric(
self::ET,
x::Matrix{FT},
pt::Vector{FT};
tolerance = 0.001,
maxiter = 5,
) where {ET<:AbstractFESet, FT}

Map a spatial location to parametric coordinates.

• x=array of spatial coordinates of the nodes, size(x) = nbfuns x dim,
• c= spatial location
• tolerance = tolerance in parametric coordinates; default is 0.001.

Return

• success = Boolean flag, true if successful, false otherwise.
• pc = Returns a row array of parametric coordinates if the solution was successful, otherwise NaN are returned.
FinEtools.FESetModule.setlabel!Method
setlabel!(self::ET, val::IT) where {ET<:AbstractFESet, IT}

Set the label of the entire finite elements set.

All elements are labeled with this number.

FinEtools.FESetModule.subsetMethod
subset(self::T, L) where {T<:AbstractFESet}

Extract a subset of the finite elements from the given finite element set.

• L: an integer vector, tuple, or a range.
FinEtools.FESetModule.updateconn!Method
updateconn!(self::ET, newids::Vector{IT}) where {ET<:AbstractFESet, IT}

Update the connectivity after the IDs of nodes changed.

newids= new node IDs. Note that indexes in the conn array "point" into the newids array. After the connectivity was updated this will no longer be true!

## Finite element nodes

Base.countMethod
count(self::FENodeSet)

Get the number of finite element nodes in the node set.

FinEtools.FENodeSetModule.xyz3Method
xyz3(self::FENodeSet)

Get the 3-D coordinate that define the location of the node. Even if the nodes were specified in lower dimension (1-D, 2-D) this function returns a 3-D coordinate by padding with zeros.

## Selecting nodes and elements

FinEtools.MeshSelectionModule.connectednodesMethod
connectednodes(fes::AbstractFESet)

Extract the node numbers of the nodes connected by given finite elements.

Extract the list of unique node numbers for the nodes that are connected by the finite element set fes. Note that it is assumed that all the FEs are of the same type (the same number of connected nodes by each cell).

FinEtools.MeshSelectionModule.findunconnnodesMethod
findunconnnodes(fens::FENodeSet, fes::AbstractFESet)

Find nodes that are not connected to any finite element.

Returns

connected = array is returned which is for the node k either true (node k is connected), or false (node k is not connected).

FinEtools.MeshSelectionModule.selectelemMethod
selectelem(fens::FENodeSet, fes::T; kwargs...) where {T<:AbstractFESet}

Select finite elements.

Arguments

• fens = finite element node set
• fes = finite element set
• kwargs = keyword arguments to specify the selection criteria

Selection criteria

facing

Select all "boundary" elements that "face" a certain direction.

exteriorbfl = selectelem(fens, bdryfes, facing=true, direction=[1.0, 1.0, 0.0]);

or

exteriorbfl = selectelem(fens, bdryfes, facing=true, direction=dout, dotmin = 0.99);

where

function dout(xyz)
return xyz/norm(xyz)
end

and xyz is the location of the centroid of a boundary element. Here the finite element is considered "facing" in the given direction if the dot product of its normal and the direction vector is greater than dotmin. The default value for dotmin is 0.01 (this corresponds to almost 90 degrees between the normal to the finite element and the given direction).

This selection method makes sense only for elements that are surface-like (i. e. for boundary mmeshes).

label

Select elements based on their label.

rl1 = selectelem(fens, fes, label=1)

box, distance

Select elements based on some criteria that their nodes satisfy. See the function selectnode().

Example: Select all elements whose nodes are closer than R+inflate from the point from.

linner = selectelem(fens, bfes, distance = R, from = [0.0 0.0 0.0],
inflate = tolerance)

Example:

exteriorbfl = selectelem(fens, bdryfes,
box=[1.0, 1.0, 0.0, pi/2, 0.0, Thickness], inflate=tolerance);

withnodes

Select elements whose nodes are in a given list of node numbers.

Example:

l = selectelem(fens, fes, withnodes = [13, 14])

flood

Select all FEs connected together, starting from a given node. Connections through a vertex (node) are sufficient.

Example: Select all FEs connected together (Starting from node 13):

l = selectelem(fens, fes, flood = true, startnode = 13)

Optional keyword arguments

Should we consider the element only if all its nodes are in?

• allin = Boolean: if true, then all nodes of an element must satisfy

the criterion; otherwise one is enough.

Output

felist = list of finite elements from the set that satisfy the criteria

FinEtools.MeshSelectionModule.selectnodeMethod
selectnode(fens::FENodeSet; kwargs...)

Select nodes using some criterion.

Arguments

• v = array of locations, one location per row
• kwargs = pairs of keyword argument/value

Selection criteria

box

nLx = vselect(fens.xyz, box = [0.0 Lx  0.0 0.0 0.0 0.0], inflate = Lx/1.0e5)

The keyword 'inflate' may be used to increase or decrease the extent of the box (or the distance) to make sure some nodes which would be on the boundary are either excluded or included.

distance

list = selectnode(fens.xyz; distance=1.0+0.1/2^nref, from=[0. 0.],
inflate=tolerance);

Find all nodes within a certain distance from a given point.

plane

candidates = selectnode(fens; plane = [0.0 0.0 1.0 0.0], thickness = h/1000)

The keyword plane defines the plane by its normal (the first two or three numbers) and its distance from the origin (the last number). Nodes are selected they lie on the plane, or near the plane within the distance thickness from the plane. The normal is assumed to be of unit length, if it isn't apply as such, it will be normalized internally.

nearestto

nh = selectnode(fens; nearestto = [R+Ro/2, 0.0, 0.0] )

Find the node nearest to the location given.

farthestfrom

nh = selectnode(fens; farthestfrom = [R+Ro/2, 0.0, 0.0] )

Find the node farthest from the location given.

FinEtools.MeshSelectionModule.vselectMethod
vselect(v::Matrix{T}; kwargs...) where {T<:Number}

Select locations (vertices) from the array based on some criterion.

See the function selectnode() for examples of the criteria that can be used to search vertices.

## Fields

Base.copyto!Method
copyto!(DEST::F,  SRC::F) where {F<:AbstractField}

Copy data from one field to another.

FinEtools.FieldModule.applyebc!Method
applyebc!(self::F) where {F<:AbstractField}

Apply EBCs (essential boundary conditions).

DEPRECATED: This function is a no-op and will be removed in the future.

FinEtools.FieldModule.gatherdofnums!Method
gatherdofnums!(self::F, dest::A, conn::CC) where {F<:AbstractField, A, CC}

Gather dofnums from the field.

The order is: for each node in the connectivity, copy into the buffer all the degrees of freedom for that node, then the next node and so on.

FinEtools.FieldModule.gathersysvec!Method
gathersysvec!(self::F, vec::Vector{T}, kind::KIND_INT = DOF_KIND_FREE) where {F<:AbstractField,T}

Gather values from the field for the system vector.

Arguments

• self: field;
• vec: destination buffer;
• kind: integer, kind of degrees of freedom to gather: default is DOF_KIND_FREE.
FinEtools.FieldModule.gathersysvecMethod
gathersysvec(self::F, kind::KIND_INT = DOF_KIND_FREE) where {F<:AbstractField}

Gather values from the field for the system vector.

Arguments

• self: field;
• kind: kind of degrees of freedom to gather; default is DOF_KIND_FREE.
FinEtools.FieldModule.gathersysvecMethod
gathersysvec(self::F, kind::Symbol) where {F<:AbstractField}

Gather values from the field for the system vector.

This is a compatibility version, using a symbol.

Arguments

• self::F: The field object.
• kind::Symbol: The kind of system vector to gather.
FinEtools.FieldModule.gathervalues_asmat!Method
gathervalues_asmat!(
self::F,
dest::AbstractArray{T,2},
conn::CC,
) where {F<:AbstractField, T, CC}

Gather values from the field into a two-dimensional array.

The order is: for each node in the connectivity, copy into the corresponding row of the buffer all the degrees of freedom, then the next node into the next row and so on.

dest = destination buffer: overwritten inside, must be preallocated in the correct size

The order of the loops matters, outer loop goes through the connectivity, inner loop goes through the degrees of freedom for each entity.

FinEtools.FieldModule.gathervalues_asvec!Method
gathervalues_asvec!(
self::F,
dest::AbstractArray{T,1},
conn::CC,
) where {F<:AbstractField, T, CC}

Gather values from the field into a vector.

The order is: for each node in the connectivity, copy into the buffer all the degrees of freedom, then the next node and so on.

dest = destination buffer: overwritten inside, must be preallocated in the correct size

The order of the loops matters, outer loop goes through the connectivity, inner loop goes through the degrees of freedom for each entity.

FinEtools.FieldModule.incrscattersysvec!Method
incrscattersysvec!(self::F, vec::AbstractVector{T}) where {F<:AbstractField, T<:Number}

Increment values of the field by scattering a system vector.

The vector may be either for just the free degrees of freedom, or for all the degrees of freedom.

FinEtools.FieldModule.numberdofs!Method
numberdofs!(self::F) where {F<:AbstractField}

Number the degrees of freedom.

The free components in the field are numbered consecutively, then all the fixed components are numbered, again consecutively.

No effort is made to optimize the numbering in any way. If you'd like to optimize the numbering of the degrees of freedom, use a form that sets the permutation of the degrees of freedom, or the permutation of the nodes.

FinEtools.FieldModule.numberdofs!Method
numberdofs!(self::F, entperm, kinds) where {F<:AbstractField}

Number the degrees of freedom.

Arguments

• self::F: The field object.
• entperm: The permutation of entities.
• kinds: The kinds of degrees of freedom. The degrees of freedom are numbered in the order in which the kinds are given here.

Examples

FinEtools.FieldModule.numberdofs!Method
numberdofs!(self::F, entperm) where {F<:AbstractField}

Number the degrees of freedom.

The free components in the field are numbered consecutively, then all the fixed components are numbered, again consecutively.

The sequence of the entities is given by the entperm permutation (array or range).

FinEtools.FieldModule.prescribeddofsMethod
prescribeddofs(uebc::F1, u::F2) where {F1<:AbstractField,  F2<:AbstractField}

Find which degrees of freedom are prescribed. uebc = field which defines the constraints (is the dof fixed and to which value), u = field which does not have the constraints applied, and serves as the source of equation numbers; uebc and u may be one and the same field.

FinEtools.FieldModule.scattersysvec!Method
scattersysvec!(self::F, vec::AbstractVector{T}, kind::KIND_INT = DOF_KIND_FREE) where {F<:AbstractField,T<:Number}

Scatter values to the field from a system vector.

The vector may be for an arbitrary kind of degrees of freedom (default is the free degrees of freedom).

FinEtools.FieldModule.setebc!Method
setebc!(self::F)

Set the EBCs (essential boundary conditions).

All essential boundary conditions are CLEARED.

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(
self::F,
fenid::IT1,
is_fixed::Bool,
comp::IT2,
val::T,
) where {F<:AbstractField,T<:Number,IT1<:Integer,IT2<:Integer}

Set the EBCs (essential boundary conditions).

fenids - array of N node identifiers is_fixed = scaler Boolean: are the degrees of freedom being fixed (true) or released (false), comp = integer, which degree of freedom (component), val = array of N values of type T

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(self::F, fenids::AbstractVector{IT})  where {IT<:Integer}

Set the EBCs (essential boundary conditions).

Suppress all degrees of freedom at the given nodes.

fenids - array of N node identifiers

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(self::F, fenid::IT) where {IT<:Integer}

Set the EBCs (essential boundary conditions).

Suppress all degrees of freedom at the given node.

fenid - One integer as a node identifier

All degrees of freedom at the node are set to zero.

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(
self::F,
fenids::AbstractVector{IT},
is_fixed::Bool,
comp::AbstractVector{IT},
val::T = 0.0,
) where {T<:Number, IT<:Integer}

Set the EBCs (essential boundary conditions).

fenids = array of N node identifiers comp = integer vector, which degree of freedom (component), val = scalar of type T, default is 0.0

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(
self::F,
fenids::AbstractVector{IT},
is_fixed::Bool,
comp::IT,
val::AbstractVector{T},
) where {T<:Number, IT<:Integer}

Set the EBCs (essential boundary conditions).

fenids - array of N node identifiers is_fixed = scaler Boolean: are the degrees of freedom being fixed (true) or released (false), comp = integer, which degree of freedom (component), val = array of N values of type T

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(
self::F,
fenids::AbstractVector{IT},
is_fixed::Bool,
comp::IT,
val::T = 0.0,
) where {T<:Number, IT<:Integer}

Set the EBCs (essential boundary conditions).

fenids - array of N node identifiers is_fixed = scaler Boolean: are the degrees of freedom being fixed (true) or released (false), comp = integer, which degree of freedom (component), val = scalar of type T

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(
self::F,
fenids::AbstractVector{IT},
comp::IT,
val::AbstractVector{T},
) where {T<:Number, IT<:Integer}

Set the EBCs (essential boundary conditions).

fenids = array of N node identifiers comp = integer, which degree of freedom (component), val = array of N values of type T

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.setebc!Method
setebc!(
self::F,
fenids::AbstractVector{IT},
comp::IT,
val::T = 0.0,
) where {T<:Number, IT<:Integer}

Set the EBCs (essential boundary conditions).

fenids = array of N node identifiers comp = integer, which degree of freedom (component), val = scalar of type T

Note: Any call to setebc!() potentially changes the current assignment which degrees of freedom are free and which are fixed and therefore is presumed to invalidate the current degree-of-freedom numbering.

FinEtools.FieldModule.wipe!Method
wipe!(self::F) where {F<:AbstractField}

Wipe all the data from the field.

This includes values, prescribed values, degree of freedom numbers, and "is fixed" flags. The number of free degrees of freedom is set to zero.

## Integration domain

FinEtools.IntegDomainModule.JacobiancurveMethod
Jacobiancurve(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet0Manifold, CC, T<:Number}

Evaluate the curve Jacobian.

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobiancurveMethod
Jacobiancurve(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet1Manifold, CC, T<:Number}

Evaluate the curve Jacobian.

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobianmdimMethod
Jacobianmdim(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
m::IT,
) where {MT<:AbstractFESet0Manifold, CC, T<:Number, IT}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 0-dimensional finite element, the manifold Jacobian is for

• m=0: +1
• m=1: Jacobiancurve
• m=2: Jacobiansurface
• m=3: Jacobianvolume
FinEtools.IntegDomainModule.JacobianmdimMethod
Jacobianmdim(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
m::IT,
) where {MT<:AbstractFESet1Manifold, CC, T<:Number, IT}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 1-dimensional finite element, the manifold Jacobian is for

• m=1: Jacobiancurve
• m=2: Jacobiansurface
• m=3: Jacobianvolume
FinEtools.IntegDomainModule.JacobianmdimMethod
Jacobianmdim(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
m::IT,
) where {MT<:AbstractFESet2Manifold, CC, T<:Number, IT}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 2-dimensional finite element, the manifold Jacobian is for

• m=2: Jacobiansurface
• m=3: Jacobianvolume
FinEtools.IntegDomainModule.JacobianmdimMethod
Jacobianmdim(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
m::IT,
) where {MT<:AbstractFESet3Manifold, CC, T<:Number, IT}

Evaluate the manifold Jacobian for an m-dimensional manifold.

For an 3-dimensional cell, the manifold Jacobian is

• m=3: Jacobianvolume
FinEtools.IntegDomainModule.JacobianpointMethod
Jacobianpoint(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet0Manifold, CC, T<:Number}

Evaluate the point Jacobian.

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobiansurfaceMethod
Jacobiansurface(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet0Manifold, CC, T<:Number}

Evaluate the surface Jacobian.

For the zero-dimensional cell, the surface Jacobian is (i) the product of the point Jacobian and the other dimension (units of length squared); or, when used as axially symmetric (ii) the product of the point Jacobian and the circumference of the circle through the point loc times the other dimension (units of length).

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobiansurfaceMethod
Jacobiansurface(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet1Manifold, CC, T<:Number}

Evaluate the surface Jacobian.

For the one-dimensional cell, the surface Jacobian is (i) the product of the curve Jacobian and the other dimension (units of length); or, when used as axially symmetric (ii) the product of the curve Jacobian and the circumference of the circle through the point loc.

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobiansurfaceMethod
Jacobiansurface(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet2Manifold, CC, T<:Number}

Evaluate the surface Jacobian.

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobianvolumeMethod
Jacobianvolume(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet0Manifold, CC, T<:Number}

Evaluate the volume Jacobian.

For the zero-dimensional cell, the volume Jacobian is (i) the product of the point Jacobian and the other dimension (units of length cubed); or, when used as axially symmetric (ii) the product of the point Jacobian and the circumference of the circle through the point loc and the other dimension (units of length squared).

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobianvolumeMethod
Jacobianvolume(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet1Manifold, CC, T<:Number}

Evaluate the volume Jacobian.

For the one-dimensional cell, the volume Jacobian is (i) the product of the curve Jacobian and the other dimension (units of length squared); or, when used as axially symmetric (ii) the product of the curve Jacobian and the circumference of the circle through the point loc and the other dimension (units of length).

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobianvolumeMethod
Jacobianvolume(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet2Manifold, CC, T<:Number}

Evaluate the volume Jacobian.

For the two-dimensional cell, the volume Jacobian is (i) the product of the surface Jacobian and the other dimension (units of length); or, when used as axially symmetric (ii) the product of the surface Jacobian and the circumference of the circle through the point loc (units of length).

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.JacobianvolumeMethod
Jacobianvolume(
self::IntegDomain{MT},
J::Matrix{T},
loc::Matrix{T},
conn::CC,
N::Matrix{T},
) where {MT<:AbstractFESet3Manifold, CC, T<:Number}

Evaluate the volume Jacobian.

• J = Jacobian matrix
• loc = location of the quadrature point in physical coordinates,
• conn = connectivity of the element,
• N = matrix of basis function values at the quadrature point.
FinEtools.IntegDomainModule.integrationdataMethod
integrationdata(
self::IntegDomain,
integration_rule::IR,
) where {IR<:AbstractIntegRule}

Calculate the data needed for a given numerical quadrature rule.

For given integration domain, compute the quantities needed for numerical integration. The integration rule does not necessarily have to be the one associated originally with the integration domain.

Return

npts, Ns, gradNparams, w, pc = number of quadrature points, arrays of basis function values at the quadrature points, arrays of gradients of basis functions with respect to the parametric coordinates, array of weights and array of locations of the quadrature points.

## Assembly of matrices and vectors

Base.eltypeMethod
eltype(a::A) where {A <: AbstractSysmatAssembler}

What is the type of the matrix buffer entries?

FinEtools.AssemblyModule.assemble!Method
assemble!(
self::SysmatAssemblerSparseDiag,
mat::MT,
dofnums_row::IV,
dofnums_col::IV,
) where {MT, IV}

Assemble a square symmetric diagonal matrix.

• dofnums = the row degree of freedom numbers, the column degree of freedom

number input is ignored (the row and column numbers are assumed to be the same).

• mat = diagonal square matrix
FinEtools.AssemblyModule.assemble!Method
assemble!(
self::SysmatAssemblerSparseHRZLumpingSymm,
mat::MT,
dofnums::IV,
ignore::IV,
) where {MT, IV}

Assemble a HRZ-lumped square symmetric matrix.

Assembly of a HRZ-lumped square symmetric matrix. The method assembles the scaled diagonal of the square symmetric matrix using the two vectors of equation numbers for the rows and columns.

FinEtools.AssemblyModule.assemble!Method
assemble!(
self::SysmatAssemblerSparseSymm,
mat::MT,
dofnums::IT,
ignore
) where {MT, IT}

Assemble a square symmetric matrix.

dofnums are the row degree of freedom numbers, the column degree of freedom number input is ignored (the row and column numbers are assumed to be the same).

FinEtools.AssemblyModule.assemble!Method
assemble!(self::SysvecAssembler{T}, vec::MV,
dofnums::D) where {T<:Number, MV<:AbstractArray{T}, D<:AbstractArray{FInt}}

Assemble an elementwise vector.

The method assembles a column element vector using the vector of degree of freedom numbers for the rows.

FinEtools.AssemblyModule.assemble!Method
assemble!(self::SysvecAssembler{T}, vec::MV,
dofnums::D) where {T<:Number, MV<:AbstractArray{T}, D<:AbstractArray{FInt}}

Assemble an elementwise vector.

The method assembles a column element vector using the vector of degree of freedom numbers for the rows.

FinEtools.AssemblyModule.expectedntriplesMethod
expectedntriples(
a::A,
elem_mat_nrows::IT,
elem_mat_ncols::IT,
n_elem_mats::IT,
) where {A<:AbstractSysmatAssembler, IT}

How many triples (I, J, V) does the assembler expect to store?

Default is: the product of the size of the element matrices times the number of matrices.

FinEtools.AssemblyModule.makematrix!Method
makematrix!(self::SysmatAssemblerFFBlock)

Make an assembled matrix. Delegate the construction of the matrix to the wrapped assembler. Then extract the left upper corner block of the matrix(the free-free matrix).

FinEtools.AssemblyModule.makematrix!Method
makematrix!(self::SysmatAssemblerSparseDiag)

Make a sparse symmetric square diagonal matrix.

Note

If nomatrixresult is set to true, dummy (zero) sparse matrix is returned. The entire result of the assembly is preserved in the assembler buffers. The ends of the buffers are filled with illegal (ignorable) values.

Note

When the matrix is constructed (nomatrixresult is false), the buffers are not deallocated, and the buffer_pointer is set to 1. It is then possible to immediately start assembling another matrix.

FinEtools.AssemblyModule.makematrix!Method
makematrix!(self::SysmatAssemblerSparseHRZLumpingSymm)

Make a sparse HRZ-lumped symmetric square matrix.

Note

If nomatrixresult is set to true, dummy (zero) sparse matrix is returned. The entire result of the assembly is preserved in the assembler buffers. The ends of the buffers are filled with illegal (ignorable) values.

Note

When the matrix is constructed (nomatrixresult is false), the buffers are not deallocated, and the buffer_pointer is set to 1. It is then possible to immediately start assembling another matrix.

FinEtools.AssemblyModule.makematrix!Method
makematrix!(self::SysmatAssemblerSparseSymm)

Make a sparse symmetric square matrix.

Note

If nomatrixresult is set to true, dummy (zero) sparse matrix is returned. The entire result of the assembly is preserved in the assembler buffers. The ends of the buffers are filled with illegal (ignorable) values.

Note

When the matrix is constructed (nomatrixresult is false), the buffers are not deallocated, and the buffer_pointer is set to 1. It is then possible to immediately start assembling another matrix.

FinEtools.AssemblyModule.makematrix!Method
makematrix!(self::SysmatAssemblerSparse)

Make a sparse matrix.

The sparse matrix is returned.

Note

If nomatrixresult is set to true, dummy (zero) sparse matrices are returned. The entire result of the assembly is preserved in the assembler buffers. The ends of the buffers are filled with illegal (ignorable) values.

Note

When the matrix is constructed (nomatrixresult is false), the buffers are not deallocated, and the buffer_pointer is set to 1. It is then possible to immediately start assembling another matrix.

FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysvecAssembler{T}, ndofs_row::FInt) where {T<:Number}

Start assembly.

The method makes the buffer for the vector assembly. It must be called before the first call to the method assemble.

• elem_mat_nmatrices = number of element matrices expected to be processed during the assembly.
• ndofs_row= Total number of degrees of freedom.

Returns

• self: the modified assembler.
FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysmatAssemblerFFBlock,
elem_mat_nrows::IT,
elem_mat_ncols::IT,
n_elem_mats::IT,
row_nalldofs::IT,
col_nalldofs::IT;
force_init = false) where {IT <: Integer}

Start assembly, delegate to the wrapped assembler.

FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysvecAssembler, ndofs_row)

Start assembly.

The method makes the buffer for the vector assembly. It must be called before the first call to the method assemble.

ndofs_row= Total number of degrees of freedom.

Returns

• self: the modified assembler.
FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysmatAssemblerSparseDiag{T},
elem_mat_nrows::IT,
elem_mat_ncols::IT,
n_elem_mats::IT,
row_nalldofs::IT,
col_nalldofs::IT;
force_init = false
) where {T, IT<:Integer}

Start the assembly of a symmetric square diagonal matrix.

The method makes buffers for matrix assembly. It must be called before the first call to the method assemble!.

Arguments

• elem_mat_nrows = row dimension of the element matrix;
• elem_mat_ncols = column dimension of the element matrix;
• n_elem_mats = number of element matrices;
• row_nalldofs= The total number of rows as a tuple;
• col_nalldofs= The total number of columns as a tuple.

The values stored in the buffers are initially undefined!

Returns

• self: the modified assembler.
FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysmatAssemblerSparseHRZLumpingSymm{T},
elem_mat_nrows::IT,
elem_mat_ncols::IT,
n_elem_mats::IT,
row_nalldofs::IT,
col_nalldofs::IT;
force_init = false
) where {T, IT<:Integer}

Start the assembly of a symmetric lumped diagonal square global matrix.

The method makes buffers for matrix assembly. It must be called before the first call to the method assemble!.

Arguments

• elem_mat_nrows = row dimension of the element matrix;
• elem_mat_ncols = column dimension of the element matrix;
• n_elem_mats = number of element matrices;
• row_nalldofs= The total number of rows as a tuple;
• col_nalldofs= The total number of columns as a tuple.

The values stored in the buffers are initially undefined!

Returns

• self: the modified assembler.
FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysmatAssemblerSparseSymm{T},
elem_mat_nrows::IT,
elem_mat_ncols::IT,
n_elem_mats::IT,
row_nalldofs::IT,
col_nalldofs::IT;
force_init = false
) where {T, IT<:Integer}

Start the assembly of a global matrix.

The method makes buffers for matrix assembly. It must be called before the first call to the method assemble!.

Arguments

• elem_mat_nrows = row dimension of the element matrix;
• elem_mat_ncols = column dimension of the element matrix;
• n_elem_mats = number of element matrices;
• row_nalldofs= The total number of rows as a tuple;
• col_nalldofs= The total number of columns as a tuple.

If the buffer_pointer field of the assembler is 0, which is the case after that assembler was created, the buffers are resized appropriately given the dimensions on input. Otherwise, the buffers are left completely untouched. The buffer_pointer is set to the beginning of the buffer, namely 1.

Returns

• self: the modified assembler.
Note

The buffers may be automatically resized if more numbers are assembled then initially intended. However, this operation will not necessarily be efficient and fast.

Note

The buffers are initially not filled with anything meaningful. After the assembly, only the (self._buffer_pointer - 1) entries are meaningful numbers. Beware!

FinEtools.AssemblyModule.startassembly!Method
startassembly!(self::SysmatAssemblerSparse{T},
elem_mat_nrows::IT,
elem_mat_ncols::IT,
n_elem_mats::IT,
row_nalldofs::IT,
col_nalldofs::IT;
force_init = false
) where {T, IT<:Integer}

Start the assembly of a global matrix.

The method makes buffers for matrix assembly. It must be called before the first call to the method assemble!.

Arguments

• elem_mat_nrows = row dimension of the element matrix;
• elem_mat_ncols = column dimension of the element matrix;
• n_elem_mats = number of element matrices;
• row_nalldofs= The total number of rows as a tuple;
• col_nalldofs= The total number of columns as a tuple.

If the buffer_pointer field of the assembler is 0, which is the case after that assembler was created, the buffers are resized appropriately given the dimensions on input. Otherwise, the buffers are left completely untouched. The buffer_pointer is set to the beginning of the buffer, namely 1.

Returns

• self: the modified assembler.
Note

The buffers are initially not filled with anything meaningful. After the assembly, only the (self._buffer_pointer - 1) entries are meaningful numbers. Beware!

Note

The buffers may be automatically resized if more numbers are assembled then initially intended. However, this operation will not necessarily be efficient and fast.

## Meshing

### Meshing with triangles

FinEtools.MeshTriangleModule.T3annulusMethod
T3annulus(rin::T, rex::T, nr::IT, nc::IT, angl::T, orientation::Symbol=:a)

Mesh of an annulus segment.

Mesh of an annulus segment, centered at the origin, with internal radius rin, and external radius rex, and development angle angl (in radians). Divided into elements: nr, nc in the radial and circumferential direction respectively.

FinEtools.MeshTriangleModule.T3circlenMethod
T3circlen(radius::T, nperradius::IT) where {T<:Number, IT<:Integer}

Mesh of a quarter circle with a given number of elements per radius.

The parameter nperradius should be an even number; if that isn't so is adjusted to by adding one.

FinEtools.MeshTriangleModule.T3circlesegMethod
T3circleseg(
angle::T,
ncircumferentially::IT,
orientation::Symbol = :a,
) where {T<:Number, IT<:Integer}

Mesh of a segment of a circle.

The subtended angle is angle in radians. The orientation: refer to T3block.

FinEtools.MeshTriangleModule.T6annulusMethod
T6annulus(
rin::T,
rex::T,
nr::IT,
nc::IT,
angl::T,
orientation::Symbol = :a,
) where {T<:Number, IT<:Integer}

Mesh of an annulus segment.

Mesh of an annulus segment, centered at the origin, with internal radius rin, and external radius rex, and development angle angl (in radians). Divided into elements: nr, nc in the radial and circumferential direction respectively.

FinEtools.MeshQuadrilateralModule.Q4annulusMethod
Q4annulus(rin::T, rex::T, nr::IT, nc::IT, Angl::T) where {T<:Number, IT<:Integer}

Mesh of an annulus segment.

Mesh of an annulus segment, centered at the origin, with internal radius rin, and external radius rex, and development angle Angl (in radians). Divided into elements: nr, nc in the radial and circumferential direction respectively.

FinEtools.MeshQuadrilateralModule.Q4blockxMethod
Q4blockx(xs::Vector{T}, ys::Vector{T})

Graded mesh of a rectangle, Q4 finite elements.

Mesh of a 2-D block, Q4 finite elements. The nodes are located at the Cartesian product of the two intervals on the input. This allows for construction of graded meshes.

xs,ys - Locations of the individual planes of nodes.

FinEtools.MeshQuadrilateralModule.Q4circlenMethod
Q4circlen(radius::T, nperradius::IT) where {T<:Number, IT<:Integer}

Mesh of a quarter circle with a given number of elements per radius.

The parameter nperradius should be an even number; if that isn't so is adjusted to by adding one.

FinEtools.MeshQuadrilateralModule.Q4ellipholeMethod
Q4elliphole(
L::T,
H::T,
nL::IT,
nH::IT,
nW::IT,
) where {T<:Number, IT<:Integer}

Mesh of one quarter of a rectangular plate with an elliptical hole.

xradius,yradius = radius of the ellipse, L,H= and dimensions of the plate, nL,nH= numbers of edges along the side of the plate; this also happens to be the number of edges along the circumference of the elliptical hole nW= number of edges along the remaining straight edge (from the hole in the direction of the length),

FinEtools.MeshQuadrilateralModule.Q8annulusMethod
Q8annulus(rin::T, rex::T, nr::IT, nc::IT, Angl::T) where {T<:Number, IT<:Integer}

Mesh of an annulus segment.

Mesh of an annulus segment, centered at the origin, with internal radius rin, and external radiusrex, and development angle Angl. Divided into elements:nr,nc in the radial and circumferential direction respectively.

### Meshing with tetrahedra

FinEtools.MeshTetrahedronModule.T10blockMethod
T10block(
Length::T,
Width::T,
Height::T,
nL::IT,
nW::IT,
nH::IT;
orientation::Symbol = :a,
) where {T<:Number, IT<:Integer}

Generate a tetrahedral mesh of T10 elements of a rectangular block.

FinEtools.MeshTetrahedronModule.T10blockxMethod
T10blockx(xs::VecOrMat{T}, ys::VecOrMat{T}, zs::VecOrMat{T}, orientation::Symbol = :a) where {T<:Number}

Generate a graded 10-node tetrahedral mesh of a 3D block.

10-node tetrahedra in a regular arrangement, with non-uniform given spacing between the nodes, with a given orientation of the diagonals.

The mesh is produced by splitting each logical rectangular cell into six tetrahedra.

FinEtools.MeshTetrahedronModule.T10cylindernMethod
T10cylindern(R::T, L::T, nR::IT, nL::IT; orientation = :b) where {T<:Number, IT<:Integer}

Ten-node tetrahedron mesh of solid cylinder with given number of edges per radius.

The axis of the cylinder is along the Z axis.

Even though the orientation is controllable, for some orientations the mesh is highly distorted (:a, :ca, :cb). So a decent mesh can only be expected for the orientation :b (default).

FinEtools.MeshTetrahedronModule.T10layeredplatexMethod
T10layeredplatex(
xs::VecOrMat{T},
ys::VecOrMat{T},
ts::VecOrMat{T},
nts::VecOrMat{IT},
orientation::Symbol = :a,
) where {T<:Number, IT<:Integer}

T10 mesh for a layered block (composite plate) with specified in plane coordinates.

xs,ys =Locations of the individual planes of nodes. ts= Array of layer thicknesses, nts= array of numbers of elements per layer

The finite elements of each layer are labeled with the layer number, starting from 1 at the bottom.

FinEtools.MeshTetrahedronModule.T10quartercylnMethod
T10quartercyln(R::T, L::T, nR::IT, nL::IT; orientation = :b) where {T<:Number, IT<:Integer}

Ten-node tetrahedron mesh of one quarter of solid cylinder with given number of edges per radius.

See: T4quartercyln

FinEtools.MeshTetrahedronModule.T10toT4Method
T10toT4(fens::FENodeSet,  fes::FESetT4)

Convert a mesh of tetrahedra of type T10 (quadratic 10-node) to tetrahedra T4.

If desired, the array of nodes may be compacted so that unconnected nodes are deleted.

FinEtools.MeshTetrahedronModule.T4blockMethod
T4block(
Length::T,
Width::T,
Height::T,
nL::IT,
nW::IT,
nH::IT,
orientation::Symbol = :a,
) where {T<:Number, IT<:Integer}

Generate a tetrahedral mesh of the 3D block.

Four-node tetrahedra in a regular arrangement, with uniform spacing between the nodes, with a given orientation of the diagonals.

The mesh is produced by splitting each logical rectangular cell into five or six tetrahedra, depending on the orientation: orientation = :a, :b generates 6 tetrahedra per cell. :ca, :cb generates 5 tetrahedra per cell.

Range =<0, Length> x <0, Width> x <0, Height>. Divided into elements: nL x nW x nH.

FinEtools.MeshTetrahedronModule.T4blockxMethod
T4blockx(xs::VecOrMat{T}, ys::VecOrMat{T}, zs::VecOrMat{T}, orientation::Symbol = :a) where {T<:Number}

Generate a graded tetrahedral mesh of a 3D block.

Four-node tetrahedra in a regular arrangement, with non-uniform given spacing between the nodes, with a given orientation of the diagonals.

The mesh is produced by splitting each logical rectangular cell into five or six tetrahedra: refer to T4block.

FinEtools.MeshTetrahedronModule.T4cylindernMethod
T4cylindern(R::T, L::T, nR::IT, nL::IT; orientation = :b) where {T<:Number, IT<:Integer}

Four-node tetrahedron mesh of solid cylinder with given number of edges per radius.

The axis of the cylinder is along the Z axis.

Even though the orientation is controllable, for some orientations the mesh is highly distorted (:a, :ca, :cb). So a decent mesh can only be expected for the orientation :b (default).

FinEtools.MeshTetrahedronModule.T4quartercylnMethod
T4quartercyln(R::T, L::T, nR::IT, nL::IT; orientation = :b) where {T<:Number, IT<:Integer}

Four-node tetrahedron mesh of one quarter of solid cylinder with given number of edges per radius.

The axis of the cylinder is along the Z axis. The mesh may be mirrored to create half a cylinder or a full cylinder.

Even though the orientation is controllable, for some orientations the mesh is highly distorted (:a, :ca, :cb). So a decent mesh can only be expected for the orientation :b (default).

FinEtools.MeshTetrahedronModule.T4refine20Method
T4refine20(fens::FENodeSet, fes::FESetT4)

Refine a tetrahedral four-node mesh into another four-node tetrahedral mesh, with each original tetrahedron being subdivided into 20 new tetrahedra.

Each vertex is given one hexahedron. The scheme generates 15 nodes per tetrahedron when creating the hexahedra, one for each edge, one for each face, and one for the interior.

FinEtools.MeshTetrahedronModule.tetvMethod
tetv(X)

Compute the volume of a tetrahedron.

X = Float64[0  4  3
9  2  4
6  1  7
0  1  5] # for these points the volume is 10.0
tetv(X, 1, 2, 3, 4)

### Meshing with hexahedra

FinEtools.MeshHexahedronModule.H8blockMethod
H8block(Length::T, Width::T, Height::T, nL::IT, nW::IT, nH::IT) where {T<:Number, IT<:Integer}

Make a mesh of a 3D block consisting of eight node hexahedra.

Length, Width, Height= dimensions of the mesh in Cartesian coordinate axes, smallest coordinate in all three directions is 0 (origin) nL, nW, nH=number of elements in the three directions

FinEtools.MeshHexahedronModule.H8cylindernMethod
H8cylindern(Radius::T, Length::T, nperradius::IT, nL::IT) where {T<:Number, IT<:Integer}

H8 mesh of a solid cylinder with given number of edges per radius (nperradius) and per length (nL).

FinEtools.MeshHexahedronModule.H8ellipholeMethod
H8elliphole(
L::T,
H::T,
T::T,
nL::IT,
nH::IT,
nW::IT,
nT::IT,
) where {T<:Number, IT<:Integer}

Mesh of one quarter of a rectangular plate with an elliptical hole.

xradius,yradius = radii of the ellipse, L,H = dimensions of the plate, Th = thickness of the plate nL,nH= numbers of edges along the side of the plate; this is also the number of edges along the circumference of the elliptical hole nW = number of edges along the remaining straight edge (from the hole in the radial direction),

FinEtools.MeshHexahedronModule.H8hexahedronMethod
H8hexahedron(xyz::Matrix{T}, nL::IT, nW::IT, nH::IT; blockfun = nothing) where {T<:Number, IT<:Integer}

Mesh of a general hexahedron given by the location of the vertices.

xyz = One vertex location per row; Either two rows (for a rectangular block given by the its corners), or eight rows (general hexahedron). nL, nW, nH = number of elements in each direction blockfun = Optional argument: function of the block-generating mesh function (having the signature of the function H8block()).

FinEtools.MeshHexahedronModule.H8layeredplatexMethod
H8layeredplatex(xs::Vector{T}, ys::Vector{T}, ts::Vector{T}, nts::Vector{IT}) where {T<:Number, IT<:Integer}

H8 mesh for a layered block (composite plate) with specified in plane coordinates.

xs,ys =Locations of the individual planes of nodes. ts= Array of layer thicknesses, nts= array of numbers of elements per layer

The finite elements of each layer are labeled with the layer number, starting from 1.

FinEtools.MeshHexahedronModule.H8sphereMethod
H8sphere(radius::T, nrefine::IT) where {T<:Number, IT<:Integer}

Create a mesh of 1/8 of the sphere of "radius". The  mesh will consist of
four hexahedral elements if "nrefine==0",  or more if "nrefine>0".
"nrefine" is the number of bisections applied  to refine the mesh.
FinEtools.MeshHexahedronModule.H8spherenMethod
H8spheren(radius::T, nperradius::IT) where {T<:Number, IT<:Integer}

Create a solid mesh of 1/8 of sphere.

Create a solid mesh of 1/8 of the sphere of radius, with nperradius elements per radius.

FinEtools.MeshHexahedronModule.T4toH8Method
T4toH8(fens::FENodeSet, fes::FESetT4)

Convert a tetrahedral four-node mesh into eight-node hexahedra.

Each vertex is given one hexahedron. The scheme generates 15 nodes per tetrahedron when creating the hexahedra, one for each edge, one for each face, and one for the interior.

### Mesh selection

See above as "Selecting nodes and elements".

### Mesh modification

FinEtools.MeshModificationModule.compactnodesMethod
compactnodes(fens::FENodeSet, connected::Vector{Bool})

Compact the finite element node set by deleting unconnected nodes.

fens = array of finite element nodes connected = The array element connected[j] is either 0 (when j is an unconnected node), or a positive number (when node j is connected to other nodes by at least one finite element)

Output

fens = new set of finite element nodes new_numbering= array which tells where in the new fens array the connected nodes are (or 0 when the node was unconnected). For instance, node 5 was connected, and in the new array it is the third node: then new_numbering[5] is 3.

Examples

Let us say there are nodes not connected to any finite element that you would like to remove from the mesh: here is how that would be accomplished.

connected = findunconnnodes(fens, fes);
fens, new_numbering = compactnodes(fens, connected);
fes = renumberconn!(fes, new_numbering);

Finally, check that the mesh is valid:

validate_mesh(fens, fes);
FinEtools.MeshModificationModule.distortblockMethod
distortblock(
B::F,
Length::T,
Width::T,
nL::IT,
nW::IT,
xdispmul::T,
ydispmul::T,
) where {F<:Function, T<:Number, IT<:Integer}

Distort a block mesh by shifting around the nodes. The goal is to distort the horizontal and vertical mesh lines into slanted lines. This is useful when testing finite elements where special directions must be avoided.

FinEtools.MeshModificationModule.distortblockMethod
distortblock(ofens::FENodeSet{T}, xdispmul::T, ydispmul::T) where {T<:Number}

Distort a block mesh by shifting around the nodes. The goal is to distort the horizontal and vertical mesh lines into slanted lines.

FinEtools.MeshModificationModule.element_coloring!Method
element_coloring!(element_colors, unique_colors, color_counts, fes, n2e, ellist)

Find coloring of the elements such that no two elements of the same color share a node.

Compute element coloring, supplying the current element colors and the list of elements to be assigned colors.

FinEtools.MeshModificationModule.element_coloringMethod
element_coloring(fes, n2e, ellist::Vector{IT} = IT[]) where {IT<:Integer}

Find coloring of the elements such that no two elements of the same color share a node.

Returns the colors of the elements (color here means an integer), and a list of the unique colors (numbers).

ellist = list of elements to be assigned colors; other element colors may be looked at

FinEtools.MeshModificationModule.fusenodesMethod
fusenodes(fens1::FENodeSet{T}, fens2::FENodeSet{T}, tolerance::T) where {T<:Number}

Fuse together nodes from two node sets.

Fuse two node sets. If necessary, by gluing together nodes located within tolerance of each other. The two node sets, fens1 and fens2, are fused together by merging the nodes that fall within a box of size tolerance. The merged node set, fens, and the new indexes of the nodes in the set fens1 are returned.

The set fens2 will be included unchanged, in the same order, in the node set fens. The indexes of the node set fens1 will have changed.

Example

After the call to this function we have k=new_indexes_of_fens1_nodes[j] is the node in the node set fens which used to be node j in node set fens1. The finite element set connectivity that used to refer to fens1 needs to be updated to refer to the same nodes in the set fens as updateconn!(fes, new_indexes_of_fens1_nodes);

FinEtools.MeshModificationModule.interior2boundaryMethod
interior2boundary(interiorconn::Array{IT,2}, extractb::Array{IT,2}) where {IT<:Integer}

Extract the boundary connectivity from the connectivity of the interior.

extractb = array that defines in which order the bounding faces are traversed. For example, for tetrahedra this array is extractb = [1 3 2; 1 2 4; 2 3 4; 1 4 3]

FinEtools.MeshModificationModule.mergemeshesMethod
mergemeshes(
fens1::FENodeSet{T},
fes1::T1,
fens2::FENodeSet{T},
fes2::T2,
tolerance::T,
) where {T, T1<:AbstractFESet, T2<:AbstractFESet}

Merge together two meshes.

Merge two meshes together by gluing together nodes within tolerance. The two meshes, fens1, fes1, and fens2, fes2, are glued together by merging the nodes that fall within a box of size tolerance. If tolerance is set to zero, no merging of nodes is performed; the two meshes are simply concatenated together.

The merged node set, fens, and the two finite element sets with renumbered connectivities are returned.

Important notes: On entry into this function the connectivity of fes1 point into fens1 and the connectivity of fes2 point into fens2. After this function returns the connectivity of both fes1 and fes2 point into fens. The order of the nodes of the node set fens1 in the resulting set fens will have changed, whereas the order of the nodes of the node set fens2 is are guaranteed to be the same. Therefore, the connectivity of fes2 will in fact remain the same.

FinEtools.MeshModificationModule.mergenmeshesMethod
mergenmeshes(meshes::Array{Tuple{FENodeSet{T},AbstractFESet}}, tolerance::T) where {T<:Number}

Merge several meshes together.

The meshes are glued together by merging the nodes that fall within a box of size tolerance. If tolerance is set to zero, no merging of nodes is performed; the nodes from the meshes are simply concatenated together.

Output

The merged node set, fens, and an array of finite element sets with renumbered connectivities are returned.

FinEtools.MeshModificationModule.mergenodesMethod
mergenodes(
fens::FENodeSet{T},
fes::AbstractFESet,
tolerance::T,
candidates::AbstractVector{IT},
) where {T<:Number, IT<:Integer}

Merge together nodes of a single node set.

Similar to mergenodes(fens, fes, tolerance), but only the candidate nodes are considered for merging. This can potentially speed up the operation by orders of magnitude.

FinEtools.MeshModificationModule.mergenodesMethod
mergenodes(fens::FENodeSet{T}, fes::AbstractFESet, tolerance::T) where {T<:Number}

Merge together nodes of a single node set.

Merge by gluing together nodes from a single node set located within tolerance of each other. The nodes are glued together by merging the nodes that fall within a box of size tolerance. The merged node set, fens, and the finite element set, fes, with renumbered connectivities are returned.

Warning: This tends to be an expensive operation!

FinEtools.MeshModificationModule.meshboundaryMethod
meshboundary(fes::T) where {T<:AbstractFESet}

Compute the boundary of a mesh defined by the given finite element set.

Arguments

• fes::T: The finite element set representing the mesh.

Returns

The boundary of the mesh.

Extract the finite elements of manifold dimension (n-1) from the supplied finite element set of manifold dimension (n).

FinEtools.MeshModificationModule.meshsmoothingMethod
meshsmoothing(fens::FENodeSet, fes::T; options...) where {T<:AbstractFESet}

General smoothing of meshes.

Keyword options

method = :taubin (default) or :laplace fixedv = Boolean array, one entry per vertex: is the vertex immovable (true) or movable (false) npass = number of passes (default 2)

Return

The modified node set.

FinEtools.MeshModificationModule.mirrormeshMethod
mirrormesh(
fens::FENodeSet,
fes::ET,
Normal::Vector{T},
Point::Vector{T};
kwargs...,
) where {ET<:AbstractFESet, T<:Number}

Mirror a mesh in a plane given by its normal and one point.

Keyword arguments

• renumb = node renumbering function for the mirrored element

Warning: The code to relies on the numbering of the finite elements: to reverse the orientation of the mirrored finite elements, the connectivity is listed in reverse order. If the mirrored finite elements do not follow this rule (for instance hexahedra or quadrilaterals), their areas/volumes will come out negative. In such a case the renumbering function of the connectivity needs to be supplied.

For instance: H8 elements require the renumbering function to be supplied as

renumb = (c) -> c[[1, 4, 3, 2, 5, 8, 7, 6]]
FinEtools.MeshModificationModule.nodepartitioningFunction
nodepartitioning(fens::FENodeSet, nincluded::Vector{Bool}, npartitions)

Compute the inertial-cut partitioning of the nodes.

nincluded = Boolean array: is the node to be included in the partitioning or not? npartitions = number of partitions, but note that the actual number of partitions is going to be a power of two.

The partitioning can be visualized for instance as:

partitioning = nodepartitioning(fens, npartitions)
partitionnumbers = unique(partitioning)
for gp = partitionnumbers
groupnodes = findall(k -> k == gp, partitioning)
File =  "partition-nodes-$(gp).vtk" vtkexportmesh(File, fens, FESetP1(reshape(groupnodes, length(groupnodes), 1))) end File = "partition-mesh.vtk" vtkexportmesh(File, fens, fes) @async run("paraview.exe"$File)
FinEtools.MeshModificationModule.nodepartitioningFunction
nodepartitioning(fens::FENodeSet, npartitions)

Compute the inertial-cut partitioning of the nodes.

npartitions = number of partitions, but note that the actual number of partitions will be a power of two.

In this variant all the nodes are to be included in the partitioning.

The partitioning can be visualized for instance as:

partitioning = nodepartitioning(fens, npartitions)
partitionnumbers = unique(partitioning)
for gp = partitionnumbers
groupnodes = findall(k -> k == gp, partitioning)
File =  "partition-nodes-Dollar(gp).vtk"
vtkexportmesh(File, fens, FESetP1(reshape(groupnodes, length(groupnodes), 1)))
end
File =  "partition-mesh.vtk"
vtkexportmesh(File, fens, fes)
@async run("paraview.exe" DollarFile)
FinEtools.MeshModificationModule.nodepartitioningMethod
nodepartitioning(fens::FENodeSet, fesarr, npartitions::Vector{Int})

Compute the inertial-cut partitioning of the nodes.

fesarr = array of finite element sets that represent regions npartitions = array of the number of partitions in each region. However note that the actual number of partitions will be a power of two.

The partitioning itself is carried out by nodepartitioning() with a list of nodes to be included in the partitioning. For each region I the nodes included in the partitioning are those connected to the elements of that region, but not to elements that belong to any of the previous regions, 1…I-1.

FinEtools.MeshModificationModule.outer_surface_of_solidMethod
outer_surface_of_solid(fens, bdry_fes)

Find the finite elements that form the outer boundary surface.

!!! note:

The code will currently not work correctly for 2D axially symmetric geometries.

Return

Set of boundary finite elements that enclose the solid. Now cavities are included.

FinEtools.MeshModificationModule.renumberconn!Method
renumberconn!(fes::AbstractFESet, new_numbering::AbstractVector{IT}) where {IT<:Integer}

Renumber the nodes in the connectivity of the finite elements based on a new numbering for the nodes.

fes =finite element set new_numbering = new serial numbers for the nodes. The connectivity should be changed as conn[j] –> new_numbering[conn[j]]

Let us say there are nodes not connected to any finite element that we would like to remove from the mesh: here is how that would be accomplished.

connected = findunconnnodes(fens, fes);
fens, new_numbering = compactnodes(fens, connected);
fes = renumberconn!(fes, new_numbering);

Finally, check that the mesh is valid:

validate_mesh(fens, fes);
FinEtools.MeshModificationModule.reordermeshMethod
reordermesh(fens, fes, ordering)

Reorder mesh (reshuffle nodes, renumber connectivities correspondingly).

Arguments

• fens: The set of mesh nodes.
• fes: The set of elements.
• ordering: The desired ordering of the nodes and elements.

Returns

The reordered mesh nodes and elements.

The ordering may come from Reverse Cuthill-McKey (package SymRCM).

FinEtools.MeshModificationModule.validate_meshMethod
validate_mesh(fens, fes)

Validate the given mesh by checking if it satisfies certain sanity criteria.

Arguments

• fens: The finite element nodes of the mesh.
• fes: The finite elements of the mesh.

Validate finite element mesh.

A finite element mesh given by the node set and the finite element set is validated by checking the sanity of the numbering:

• the node numbers need to be positive and in serial order
• the fe connectivity needs to refer to valid nodes
• the finite element nodes need to be connected to at least one finite element

An error is reported as soon as it is detected.

Returns

A boolean indicating whether the mesh is valid or not.

FinEtools.MeshModificationModule.vertexneighborsMethod
vertexneighbors(conn::Matrix{IT}, nvertices::IT) where {IT<:Integer}

Find the node neighbors in the mesh.

Return an array of integer vectors, element I holds an array of numbers of nodes which are connected to node I (including node I).

FinEtools.MeshModificationModule.vsmoothingMethod
vsmoothing(v::Matrix{T}, t::Matrix{IT}; kwargs...) where {T<:Number, IT<:Integer}

Internal routine for mesh smoothing.

Keyword options: method = :taubin (default) or :laplace fixedv = Boolean array, one entry per vertex: is the vertex immovable (true) or movable (false) npass = number of passes (default 2)

### Meshing utilities

FinEtools.MeshUtilModule.findhyperface!Method
findhyperface!(container,hyperface)

Find a hyper face in the container.

If the container holds the indicated hyper face, it is returned together with the stored new node number.

FinEtools.MeshUtilModule.gradedspaceMethod
gradedspace(start::T, stop::T, N::Int)  where {T<:Number}

Generate a quadratic sequence of N numbers between start and stop. This sequence corresponds to separation of adjacent numbers that increases linearly from start to finish.

Example

julia> gradedspace(2.0, 3.0, 5)
5-element Array{Float64,1}:
2.0
2.0625
2.25
2.5625
3.0
FinEtools.MeshUtilModule.linearspaceMethod
linearspace(start::T, stop::T, N::Int)  where {T<:Number}

Generate linear space.

Generate a linear sequence of N numbers between start and stop (i. e. sequence of number with uniform intervals inbetween).

Example

julia> linearspace(2.0, 3.0, 5)
2.0:0.25:3.0
FinEtools.MeshUtilModule.logspaceMethod
logspace(start::T, stop::T, N::Int)  where {T<:Number}

Generate logarithmic space.

Generate a logarithmic sequence of N numbers between start and stop (i. e. sequence of number with uniform intervals inbetween in the log space).

Example

julia> logspace(2.0, 3.0, 5)
5-element Array{Float64,1}:
100.0
177.82794100389228
316.2277660168379
562.341325190349
1000.0    
FinEtools.MeshUtilModule.makecontainerFunction
makecontainer()

Make hyper face container.

This is a dictionary of hyper faces, indexed with an anchor node. The anchor node is the smallest node number within the connectivity of the hyper face.

FinEtools.MeshUtilModule.ontosphereMethod
ontosphere(xyz::Matrix{T}, radius::T) where {T}

Project nodes onto a sphere of given radius.

Arguments

• xyz::Matrix{T}: A matrix of shape (3, N) representing the coordinates of N points.
• radius::T: The radius of the sphere.

Returns

A matrix of shape (3, N) representing the coordinates of points on the sphere.

### Mesh import

FinEtools.MeshImportModule.import_ABAQUSMethod
import_ABAQUS(filename)

Import Abaqus mesh (.inp file).

Limitations:

1. Only the *NODE and *ELEMENT sections are read
2. Only 4-node and 10-node tetrahedra, 8-node or 20-node hexahedra, 4-node quadrilaterals, 3-node triangles are handled.

Output

Data dictionary, with keys

• "fens" = finite element nodes.
• "fesets" = array of finite element sets.
• "nsets" = dictionary of "node sets", the keys are the names of the sets.
FinEtools.MeshImportModule.import_H5MESHMethod
import_H5MESH(meshfile)

Import mesh in the H5MESH format (.h5mesh file).

Output

Data dictionary, with keys

• "fens" = finite element nodes.
• "fesets" = array of finite element sets.
FinEtools.MeshImportModule.import_MESHMethod
import_MESH(filename)

Import mesh in the MESH format (.mesh, .xyz, .conn triplet of files).

Output

Data dictionary, with keys

• "fens" = finite element nodes.
• "fesets" = array of finite element sets.
FinEtools.MeshImportModule.import_NASTRANMethod
import_NASTRAN(filename)

Import tetrahedral (4- and 10-node) NASTRAN mesh (.nas file).

Limitations:

1. only the GRID, CTETRA, and PSOLID sections are read.
2. Only 4-node and 10-node tetrahedra are handled.
3. The file should be free-form (data separated by commas).

Some fixed-format files can also be processed (large-field, but not small-field).

Output

Data dictionary, with keys

• "fens": set of finite element nodes,
• "fesets": array of finite element sets,
• "property_ids": array of property ids (integers) associated with the finite element sets.

### Mesh export

#### VTK

FinEtools.MeshExportModule.VTK.vtkexportmeshMethod
vtkexportmesh(theFile::String, Connectivity, Points, Cell_type;
vectors=nothing, scalars=nothing)

Export mesh to a VTK 1.0 file as an unstructured grid.

Arguments:

• theFile = file name,
• Connectivity = array of connectivities, one row per element,
• Points = array of node coordinates, one row per node,
• Cell_type = type of the cell, refer to the predefined constants P1, L2, ..., H20, ...
• scalars = array of tuples, (name, data)
• vectors = array of tuples, (name, data)

For the scalars: If data is a vector, that data is exported as a single field. On the other hand, if it is an 2d array, each column is exported as a separate field.

FinEtools.MeshExportModule.VTK.vtkexportmeshMethod
vtkexportmesh(theFile::String, fens::FENodeSet, fes::T; opts...) where {T<:AbstractFESet}

Export mesh to a VTK 1.0 file as an unstructured grid.

Arguments:

• theFile = file name,
• fens = finite element node set,
• fes = finite element set,
• opts = keyword argument list, where
• scalars = array of tuples, (name, data)
• vectors = array of tuples, (name, data)

For the scalars: If data is a vector, that data is exported as a single field. On the other hand, if it is an 2d array, each column is exported as a separate field.

FinEtools.MeshExportModule.VTK.vtkexportvectorsMethod
vtkexportvectors(theFile::String, Points, vectors)

Export vector data to a VTK 1.0 file.

Arguments:

• theFile = file name,
• Points = array of collection of coordinates (tuples or vectors),
• vectors = array of tuples, (name, data), where name is a string, and data is array of collection of coordinates (tuples or vectors).

Example

Points = [(1.0, 3.0), (0.0, -1.0)]
vectors = [("v", [(-1.0, -2.0), (1.0, 1.0)])]
vtkexportvectors("theFile.VTK", Points, vectors)

will produce file with

# vtk DataFile Version 1.0
FinEtools Export
ASCII

DATASET UNSTRUCTURED_GRID
POINTS 2 double
1.0 3.0 0.0
0.0 -1.0 0.0

POINT_DATA 2
VECTORS v double
-1.0 -2.0 0.0
1.0 1.0 0.0
Note

The filter "Glyph" must be used within Paraview. Also in the drop-down menu "Glyph mode" select "all points".

#### Abaqus

Base.closeMethod
close(self::AbaqusExporter)

Close the stream opened by the exporter.

FinEtools.MeshExportModule.Abaqus.BOUNDARYMethod
BOUNDARY(self::AbaqusExporter, NSET::AbstractString, dof::Integer,  fixed_value)

Write out the *BOUNDARY option.

• NSET = name of a node set,
• is_fixed= array of Boolean flags (true means fixed, or prescribed), one row per node,
• fixed_value=array of displacements to which the corresponding displacement components is fixed
FinEtools.MeshExportModule.Abaqus.BOUNDARYMethod
BOUNDARY(self::AbaqusExporter, NSET::AbstractString, dof::Integer)

Write out the *BOUNDARY option to fix displacements at zero for a node set.

Invoke at Level: Model, Step

• NSET= node set,
• dof=Degree of freedom, 1, 2, 3
FinEtools.MeshExportModule.Abaqus.BOUNDARYMethod
BOUNDARY(self::AbaqusExporter, NSET::AbstractString, dof::Integer,
value::F) where {F}

Write out the *BOUNDARY option to fix displacements at nonzero value for a node set.

• NSET= node set,
• dof=Degree of freedom, 1, 2, 3
• typ = DISPLACEMENT
FinEtools.MeshExportModule.Abaqus.BOUNDARYMethod
BOUNDARY(self::AbaqusExporter, meshornset, is_fixed::AbstractArray{B,2}, fixed_value::AbstractArray{F,2}) where {B, F}

Write out the *BOUNDARY option.

• meshornset = name of a mesh or a node set,
• is_fixed= array of Boolean flags (true means fixed, or prescribed), one row per node, as many columns as there are degrees of freedom per node,
• fixed_value=array of displacements to which the corresponding displacement components is fixed, as many columns as there are degrees of freedom per node
FinEtools.MeshExportModule.Abaqus.BOUNDARYMethod
BOUNDARY(self::AbaqusExporter, mesh, nodes, is_fixed::AbstractArray{B,2}, fixed_value::AbstractArray{F,2}) where {B, F}

Write out the *BOUNDARY option.

The boundary condition is applied to the nodes specified in the array nodes, in the mesh (or node set) meshornset.

meshornset = mesh or node set (default is empty) nodes = array of node numbers, the node numbers are attached to the mesh label, is_fixed= array of Boolean flags (true means fixed, or prescribed), one row per node, fixed_value=array of displacements to which the corresponding displacement components is fixed

Example

BOUNDARY(AE, "ASSEM1.INSTNC1", 1:4, fill(true, 4, 1), reshape([uy(fens.xyz[i, :]...) for i in 1:4], 4, 1))
FinEtools.MeshExportModule.Abaqus.CLOADMethod
CLOAD(self::AbaqusExporter, NSET::AbstractString, dof::Integer,
magnitude::F) where {F}

Write out the *CLOAD option.

NSET=Node set dof= 1, 2, 3, magnitude= signed multiplier

FinEtools.MeshExportModule.Abaqus.CLOADMethod
CLOAD(self::AbaqusExporter, nodenumber::Integer, dof::Integer,
magnitude::F) where {F}

Write out the *CLOAD option.

nodenumber=Number of node dof= 1, 2, 3, magnitude= signed multiplier

FinEtools.MeshExportModule.Abaqus.ELASTICMethod
ELASTIC(self::AbaqusExporter, E1::F, E2::F, E3::F, nu12::F, nu13::F, nu23::F,
G12::F, G13::F, G23::F) where {F}

Write out the *ELASTIC,TYPE=ENGINEERING CONSTANTS option.

FinEtools.MeshExportModule.Abaqus.ELEMENTMethod
ELEMENT(self::AbaqusExporter, TYPE::AbstractString, ELSET::AbstractString,
start::Integer, conn::AbstractArray{T, 2}) where {T<:Integer}

Write out the *ELEMENT option.

TYPE= element type code, ELSET= element set to which the elements belong, start= start the element numbering at this integer, conn= connectivity array for the elements, one row per element

FinEtools.MeshExportModule.Abaqus.ELSET_ELSETMethod
ELSET_ELSET(self::AbaqusExporter, ELSET::AbstractString, n::AbstractArray{T, 1}) where {T<:Integer}

Write out the *ELSET option.

ELSET = name of the set, n = array of the node numbers

FinEtools.MeshExportModule.Abaqus.NSET_NSETMethod
NSET_NSET(self::AbaqusExporter, NSET::AbstractString,
n::AbstractVector{T}) where {T<:Integer}

Write out the *NSET option.

NSET = name of the set, n = array of the node numbers

FinEtools.MeshExportModule.Abaqus.ORIENTATIONMethod
ORIENTATION(self::AbaqusExporter, ORIENTATION::AbstractString,
a::AbstractArray{T,1}, b::AbstractArray{T,1})

Write out the *ORIENTATION option.

Invoke at level: Part, Part instance, Assembly

FinEtools.MeshExportModule.Abaqus.SOLID_SECTIONMethod
SOLID_SECTION(self::AbaqusExporter, MATERIAL::AbstractString,
ORIENTATION::AbstractString, ELSET::AbstractString,
CONTROLS::AbstractString)

Write out the *SOLID SECTION option.

Level: Part, Part instance

#### NASTRAN

Base.closeMethod
close(self::NASTRANExporter)

Close the stream opened by the exporter.

FinEtools.MeshExportModule.NASTRAN.MAT1Method
MAT1(
self::NASTRANExporter,
mid::Int,
E::T,
nu::T,
rho::T = 0.0,
A::T = 0.0,
TREF::T = 0.0,
GE::T = 0.0,
) where {T}

Write a statement for an isotropic elastic material.

#### STL

Base.closeMethod
close(self::STLExporter)

Close the stream opened by the exporter.

#### VTKWrite

FinEtools.MeshExportModule.VTKWrite.vtkwriteMethod
vtkwrite(theFile::String, Connectivity, Points, celltype; vectors=nothing, scalars=nothing)

Export mesh to VTK as an unstructured grid (binary format).

Arguments:

• theFile = file name,
• Connectivity = array of connectivities, one row per element,
• Points = array of node coordinates, one row per node,
• Cell_type = type of the cell, refer to the predefined constants WriteVTK.P1, WriteVTK.L2, ..., WriteVTK.H20, ...
• scalars = array of tuples, (name, data)
• vectors = array of tuples, (name, data)

For the scalars: If data is a vector, that data is exported as a single field. On the other hand, if it is an 2d array, each column is exported as a separate field.

Return the vtk file.

FinEtools.MeshExportModule.VTKWrite.vtkwriteMethod
vtkwrite(theFile::String, fens::FENodeSet, fes::T; opts...) where {T<:AbstractFESet}

Export mesh to VTK as an unstructured grid (binary file).

Arguments:

• theFile = file name,
• fens = finite element node set,
• fes = finite element set,
• opts = keyword argument list, where scalars = array of tuples, (name, data), vectors = array of tuples, (name, data)

For the scalars: If data is a vector, that data is exported as a single field. On the other hand, if it is an 2d array, each column is exported as a separate field.

FinEtools.MeshExportModule.VTKWrite.vtkwritecollectionMethod
vtkwritecollection(theFile::String, Connectivity, Points, celltype, times; vectors=nothing, scalars=nothing)

Write a collection of VTK files (.pvd file).

times: array of times

All the other arguments are the same as for vtkwrite. If scalars or vectors are supplied, they correspond to the times in the times array.

See the vtkwritecollection methods.

FinEtools.MeshExportModule.VTKWrite.vtkwritecollectionMethod
vtkwritecollection(theFile::String, fens::FENodeSet, fes::T, times; opts...) where {T<:AbstractFESet}

Write a collection of VTK files (.pvd file).

times: array of times

All the other arguments are the same as for vtkwrite. If scalars or vectors are supplied, they correspond to the times in the times array.

See the vtkwritecollection methods.

## FEM machines

### Base

FinEtools.FEMMBaseModule.associategeometry!Method
associategeometry!(self::AbstractFEMM, geom::NodalField{GFT}) where {GFT}

Associate geometry field with the FEMM.

There may be operations that could benefit from pre-computations that involve a geometry field. If so, associating the geometry field gives the FEMM a chance to save on repeated computations.

Geometry field is normally passed into any routine that evaluates some forms (integrals) over the mesh. Whenever the geometry passed into a routine is not consistent with the one for which associategeometry!() was called before, associategeometry!() needs to be called with the new geometry field.

FinEtools.FEMMBaseModule.bilform_convectionMethod
bilform_convection(
self::FEMM,
assembler::A,
geom::NodalField{FT},
u::NodalField{T},
Q::NodalField{QT},
rhof::DC
) where {FEMM<:AbstractFEMM, A<:AbstractSysmatAssembler, FT, T, QT, DC<:DataCache}

Compute the sparse matrix implied by the bilinear form of the "convection" type.

$$$\int_{V} {w} \rho \mathbf{u} \cdot \nabla q \; \mathrm{d} V$$$

Here $w$ is the scalar test function, $\mathbf{u}$ is the convective velocity, $q$ is the scalar trial function, $\rho$ is the mass density; $\rho$ is computed by rhof, which is a given function(data). Both test and trial functions are assumed to be from the same approximation space. rhof is represented with DataCache, and needs to return a scalar mass density.

The integral is with respect to the volume of the domain $V$ (i.e. a three dimensional integral).

Arguments

• self = finite element machine;
• assembler = assembler of the global matrix;
• geom = geometry field;
• u = convective velocity field;
• Q = nodal field to define the degree of freedom numbers;
• rhof= data cache, which is called to evaluate the coefficient $\rho$, given the location of the integration point, the Jacobian matrix, and the finite element label.
FinEtools.FEMMBaseModule.bilform_diffusionMethod
bilform_diffusion(
self::FEMM,
assembler::A,
geom::NodalField{FT},
u::NodalField{T},
cf::DC
) where {FEMM<:AbstractFEMM, A<:AbstractSysmatAssembler, FT, T, DC<:DataCache}

Compute the sparse matrix implied by the bilinear form of the "diffusion" type.

$$$\int_{V} \nabla w \cdot c \cdot \nabla u \; \mathrm{d} V$$$

Here $\nabla w$ is the gradient of the scalar test function, $\nabla u$ is the gradient of the scalar trial function, $c$ is a square symmetric matrix of coefficients or a scalar; $c$ is computed by cf, which is a given function (data). Both test and trial functions are assumed to be from the same approximation space. cf is represented with DataCache, and needs to return a symmetric square matrix (to represent general anisotropic diffusion) or a scalar (to represent isotropic diffusion).

The coefficient matrix $c$ can be given in the so-called local material coordinates: coordinates that are attached to a material point and are determined by a local cartesian coordinates system (mcsys).

The integral is with respect to the volume of the domain $V$ (i.e. a three dimensional integral).

Arguments

• self = finite element machine;
• assembler = assembler of the global matrix;
• geom = geometry field;
• u = nodal field to define the degree of freedom numbers;
• cf= data cache, which is called to evaluate the coefficient $c$, given the location of the integration point, the Jacobian matrix, and the finite element label.
FinEtools.FEMMBaseModule.bilform_div_gradMethod
bilform_div_grad(
self::FEMM,
assembler::A,
geom::NodalField{FT},
u::NodalField{T},
viscf::DC
) where {FEMM<:AbstractFEMM, A<:AbstractSysmatAssembler, FT, T, DC<:DataCache}

Compute the sparse matrix implied by the bilinear form of the "div grad" type.

$$$\int_{V} \mu \nabla \mathbf{w}: \nabla\mathbf{u} \; \mathrm{d} V$$$

Here $\mathbf{w}$ is the vector test function, $\mathbf{u}$ is the velocity, $\mu$ is the dynamic viscosity (or kinematic viscosity, depending on the formulation); $\mu$ is computed by viscf, which is a given function (data). Both test and trial functions are assumed to be from the same approximation space. viscf is represented with DataCache, and needs to return a scalar viscosity.

The integral is with respect to the volume of the domain $V$ (i.e. a three dimensional integral).

Arguments

• self = finite element machine;
• assembler = assembler of the global matrix;
• geom = geometry field;
• u = velocity field;
• viscf= data cache, which is called to evaluate the coefficient $\mu$, given the location of the integration point, the Jacobian matrix, and the finite element label.
FinEtools.FEMMBaseModule.bilform_dotMethod
bilform_dot(
self::FEMM,
assembler::A,
geom::NodalField{FT},
u::NodalField{T},
cf::DC
) where {FEMM<:AbstractFEMM, A<:AbstractSysmatAssembler, FT, T, DC<:DataCache}

Compute the sparse matrix implied by the bilinear form of the "dot" type.

$$$\int_{\Omega} \mathbf{w} \cdot \mathbf{c} \cdot \mathbf{u} \; \mathrm{d} \Omega$$$

Here $\mathbf{w}$ is the test function, $\mathbf{u}$ is the trial function, $\mathbf{c}$ is a square matrix of coefficients; $\mathbf {c}$ is computed by cf, which is a given function (data). Both trial and test functions are assumed to be vectors(even if of length 1). cf is represented with DataCache, and needs to return a square matrix, with dimension equal to the number of degrees of freedom per node in the u field.

The integral domain $\Omega$ can be the volume of the domain $V$ (i.e. a three dimensional integral), or a surface $S$ (i.e. a two dimensional integral), or a line domain $L$ (i.e. a one dimensional integral).

Arguments

• self = finite element machine;
• assembler = assembler of the global object;
• geom = geometry field;
• u = nodal field to define the degree of freedom numbers;
• cf= data cache, which is called to evaluate the coefficient $c$, given the location of the integration point, the Jacobian matrix, and the finite element label.
• m = manifold dimension (default is 3).
FinEtools.FEMMBaseModule.bilform_lin_elasticMethod
bilform_lin_elastic(
self::FEMM,
assembler::A,
geom::NodalField{FT},
u::NodalField{T},
cf::DC
) where {FEMM<:AbstractFEMM, A<:AbstractSysmatAssembler, FT, T, DC<:DataCache}

Compute the sparse matrix implied by the bilinear form of the "linearized elasticity" type.

$$$\int_{V} (B \mathbf{w})^T C B \mathbf{u} \; \mathrm{d} V$$$

Here $\mathbf{w}$ is the vector test function, $\mathbf{u}$ is the displacement (velocity), $C$ is the elasticity (viscosity) matrix; $C$ is computed by cf, which is a given function(data). Both test and trial functions are assumed to be from the same approximation space. cf is represented with DataCache, and needs to return a matrix of the appropriate size.

The integral is with respect to the volume of the domain $V$ (i.e. a three dimensional integral).

Arguments

• self = finite element machine;
• assembler = assembler of the global matrix;
• geom = geometry field;
• u = velocity field;
• viscf= data cache, which is called to evaluate the coefficient $\mu$, given the location of the integration point, the Jacobian matrix, and the finite element label.
FinEtools.FEMMBaseModule.connectionmatrixMethod
connectionmatrix(self::FEMM, nnodes) where {FEMM<:AbstractFEMM}

Compute the connection matrix.

The matrix has a nonzero in all the rows and columns which correspond to nodes connected by some finite element.

FinEtools.FEMMBaseModule.distribloadsMethod
distribloads(
self::FEMM,
assembler::A,
geom::NodalField{FT},
P::NodalField{T},
fi::ForceIntensity,
m,
) where {FEMM<:AbstractFEMM, A<:AbstractSysvecAssembler, FT<:Number, T}

Arguments

• fi=force intensity object
• m= manifold dimension, 0= vertex (point), 1= curve, 2= surface, 3= volume. For body loads m is set to 3, for tractions on the surface it is set to 2, and so on.

The actual work is done by linform_dot().

FinEtools.FEMMBaseModule.dualconnectionmatrixMethod
dualconnectionmatrix(
self::FEMM,
fens::FENodeSet,
minnodes = 1,
) where {FEMM<:AbstractFEMM}

Compute the dual connection matrix.

The matrix has a nonzero in all the rows and columns which correspond to elements connected by some finite element nodes.

• minnodes: minimum number of nodes that the elements needs to share in order to be neighbors (default 1)
FinEtools.FEMMBaseModule.elemfieldfromintegpointsMethod
elemfieldfromintegpoints(
self::FEMM,
geom::NodalField{GFT},
u::NodalField{UFT},
dT::NodalField{TFT},
quantity::Symbol,
component::AbstractVector{IT};
context...,
) where {FEMM<:AbstractFEMM, GFT<:Number, UFT<:Number, TFT<:Number, IT<:Integer}

Construct elemental field from integration points.

Arguments

geom - reference geometry field u - displacement field dT - temperature difference field quantity - this is what you would assign to the 'quantity' argument of the material update!() method. component- component of the 'quantity' array: see the material update() method.

Output

• the new field that can be used to map values to colors and so on
FinEtools.FEMMBaseModule.ev_integrateMethod
ev_integrate(
self::FEMM,
geom::NodalField{FT},
f::DC,
initial::R,
m,
) where {FEMM<:AbstractFEMM, FT<:Number, DC<:DataCache, R}

Compute the integral of a given function over a mesh domain.

$$$\int_{\Omega} {f} \; \mathrm{d} \Omega$$$

Here ${f}$ is a given function (data). The data ${f}$ is represented with DataCache.

Arguments

• self = finite element machine;
• geom = geometry field;
• f= data cache, which is called to evaluate the integrand based on the location, the Jacobian matrix, the finite element identifier, and the quadrature point;
• initial = initial value of the integral,
• m= manifold dimension, 0= vertex (point), 1= curve, 2= surface, 3= volume. For body loads m is set to 3, for tractions on the surface it is set to 2, and so on.
FinEtools.FEMMBaseModule.field_elem_to_nodal!Method
field_elem_to_nodal!(
self::AbstractFEMM,
geom::NodalField{FT},
ef::EFL,
nf::NFL;
kind = :weighted_average,
) where {FT, T<:Number, EFL<:ElementalField{T}, NFL<:NodalField{T}}

Make a nodal field from an elemental field over the discrete manifold.

ef = ELEMENTAL field to supply the values nf = NODAL field to receive the values kind = default is :weighted_average; other options: :max

Returns nf.

FinEtools.FEMMBaseModule.field_nodal_to_elem!Method
field_nodal_to_elem!(
self::AbstractFEMM,
geom::NodalField{FT},
nf::NFL,
ef::EFL;
kind = :weighted_average,
) where {FT<:Number, T, EFL<:ElementalField{T}, NFL<:NodalField{T}}

Make an elemental field from a nodal field over the discrete manifold.

nf = NODAL field to supply the values ef = ELEMENTAL field to receive the values kind = default is :weighted_average; other options: :max

Returns ef.

FinEtools.FEMMBaseModule.fieldfromintegpointsMethod
fieldfromintegpoints(
self::FEMM,
geom::NodalField{GFT},
u::NodalField{UFT},
dT::NodalField{TFT},
quantity::Symbol,
component::AbstractVector{IT};
context...,
) where {FEMM<:AbstractFEMM, GFT<:Number, UFT<:Number, TFT<:Number, IT<:Integer}

Construct nodal field from integration points.

Arguments

• geom - reference geometry field
• u - displacement field
• dT - temperature difference field
• quantity - this is what you would assign to the 'quantity' argument of the material update!() method.
• component- component of the 'quantity' array: see the material update() method.

Keyword arguments

• nodevalmethod = :invdistance (the default) or :averaging;
• reportat = at which point should the element quantities be reported? This argument is interpreted inside the inspectintegpoints() method.

Output

• the new field that can be used to map values to colors and so on
FinEtools.FEMMBaseModule.innerproductMethod
innerproduct(
self::FEMM,
assembler::A,
geom::NodalField{FT},
afield::NodalField{T},
) where {FEMM<:AbstractFEMM, A<:AbstractSysmatAssembler, FT, T}

Compute the inner-product (Gram) matrix.

FinEtools.FEMMBaseModule.inspectintegpointsFunction
inspectintegpoints(self::FEMM,
geom::NodalField{GFT},
u::NodalField{FT},
dT::NodalField{FT},
felist::AbstractVector{IT},
inspector::F,
idat,
quantity = :Cauchy;
context...,) where {FEMM<:AbstractFEMM, GFT, IT, FT, F <: Function}

Inspect integration points.

FinEtools.FEMMBaseModule.integratefieldfunctionMethod
integratefieldfunction(
self::AbstractFEMM,
geom::NodalField{GFT},
afield::FL,
fh::F;
initial::R = zero(FT),
m = -1,
) where {GFT, T, FL<:ElementalField{T}, F<:Function,R}

Integrate a elemental-field function over the discrete manifold.

• afield = ELEMENTAL field to supply the value within the element (one value per element),
• fh = function taking position and an array of field values for the element as arguments, returning value of type R. The function fh must take two arguments, x which is the location, and val which is the value of the field at that location. The rectangular array of field values val has one row, and as many columns as there are degrees of freedom per node.
• m = dimension of the manifold over which to integrate; m < 0 means that the dimension is controlled by the manifold dimension of the elements.

Integrates a function returning a scalar value of type R, which is initialized by initial.

FinEtools.FEMMBaseModule.integratefieldfunctionMethod
integratefieldfunction(
self::AbstractFEMM,
geom::NodalField{GFT},
afield::FL,
fh::F;
initial::R,
m = -1,
) where {GFT, T, FL<:NodalField{T}, F<:Function,R}

Integrate a nodal-field function over the discrete manifold.

• afield = NODAL field to supply the values at the nodes, which are interpolated to the quadrature points,
• fh = function taking position and an array of field values for the element as arguments, returning value of type R. The function fh must take two arguments, x which is the location, and val which is the value of the field at that location. The rectangular array of field values val has one row, and as many columns as there are degrees of freedom per node.
• m = dimension of the manifold over which to integrate; m < 0 means that the dimension is controlled by the manifold dimension of the elements.

Integrates a function returning a scalar value of type R, which is initialized by initial.

FinEtools.FEMMBaseModule.integratefunctionMethod
integratefunction(
self::AbstractFEMM,
geom::NodalField{GFT},
fh::F;
initial::R = zero(typeof(fh(zeros(ndofs(geom), 1)))),
m = -1,
) where {GFT<:Number, F<:Function, R<:Number}

Integrate a function over the discrete manifold.

Integrate some scalar function over the geometric cells. The function takes a single argument, the position vector.

When the scalar function returns just +1 (such as (x) -> 1.0), the result measures the volume (number of points, length, area, 3-D volume, according to the manifold dimension). When the function returns the mass density, the method measures the mass, when the function returns the x-coordinate equal measure the static moment with respect to the y- axis, and so on.

Example:

Compute the volume of the mesh and then its center of gravity:

V = integratefunction(femm, geom, (x) ->  1.0, 0.0)
Sx = integratefunction(femm, geom, (x) ->  x[1], 0.0)
Sy = integratefunction(femm, geom, (x) ->  x[2], 0.0)
Sz = integratefunction(femm, geom, (x) ->  x[3], 0.0)
CG = vec([Sx Sy Sz]/V)

Compute a moment of inertia of the mesh relative to the origin:

Ixx = integratefunction(femm, geom, (x) ->  x[2]^2 + x[3]^2)
FinEtools.FEMMBaseModule.linform_dotMethod
linform_dot(
self::FEMM,
assembler::A,
geom::NodalField{FT},
P::NodalField{T},
f::DC,
m,
) where {FEMM<:AbstractFEMM, A<:AbstractSysvecAssembler, FT<:Number, T, DC<:DataCache}

Compute the discrete vector implied by the linear form "dot".

$$$\int_{V} \mathbf{w} \cdot \mathbf{f} \; \mathrm{d} V$$$

Here $\mathbf{w}$ is the test function, $\mathbf{f}$ is a given function (data). Both are assumed to be vectors, even if they are of length 1, representing scalars. The data $\mathbf{f}$ is represented with DataCache.

Arguments

• self = finite element machine;
• assembler = assembler of the global vector;
• geom = geometry field;
• P = nodal field to define the degree of freedom numbers;
• f= data cache, which is called to evaluate the integrand based on the location, the Jacobian matrix, the finite element identifier, and the quadrature point;
• m= manifold dimension, 0= vertex (point), 1= curve, 2= surface, 3= volume. For body loads m is set to 3, for tractions on the surface it is set to 2, and so on.
FinEtools.FEMMBaseModule.transferfield!Method
transferfield!(
ff::F,
fensf::FENodeSet{FT},
fesf::AbstractFESet,
fc::F,
fensc::FENodeSet{FT},
fesc::AbstractFESet,
geometricaltolerance::FT;
parametrictolerance::FT = 0.01,
) where {FT<:Number, F<:ElementalField{T}, T}

Transfer an elemental field from a coarse mesh to a finer one.

Arguments

• ff = the fine-mesh field (modified and also returned)
• fensf = finite element node set for the fine-mesh
• fc = the coarse-mesh field
• fensc = finite element node set for the fine-mesh,
• fesc = finite element set for the coarse mesh
• tolerance = tolerance in physical space for searches of the adjacent nodes

Output

Elemental field ff transferred to the fine mesh is output.

FinEtools.FEMMBaseModule.transferfield!Method
transferfield!(
ff::F,
fensf::FENodeSet{FT},
fesf::AbstractFESet,
fc::F,
fensc::FENodeSet{FT},
fesc::AbstractFESet,
geometricaltolerance::FT;
parametrictolerance::FT = 0.01,
) where {FT<:Number, F<:NodalField{T}, T}

Transfer a nodal field from a coarse mesh to a finer one.

Arguments

• ff = the fine-mesh field (modified and also returned)
• fensf = finite element node set for the fine-mesh
• fc = the coarse-mesh field
• fensc = finite element node set for the fine-mesh,
• fesc = finite element set for the coarse mesh
• geometricaltolerance = tolerance in physical space for searches of the adjacent nodes
• parametrictolerance = tolerance in parametric space for for check whether node is inside an element

Output

Nodal field ff transferred to the fine mesh is output.

## Algorithms

### Base

FinEtools.AlgoBaseModule.bisectMethod
bisect(fun, xl, xu, tolx, tolf)

Implementation of the bisection method.

Tolerance both on x and on f(x) is used.

• fun = function,
• xl= lower value of the bracket,
• xu= upper Value of the bracket,
• tolx= tolerance on the location of the root,
• tolf= tolerance on the function value
FinEtools.AlgoBaseModule.bisectMethod
bisect(fun, xl, xu, fl, fu, tolx, tolf)

Implementation of the bisection method.

Tolerance both on x and on f(x) is used.

• fun = function,
• xl,xu= lower and upper value of the bracket,
• fl,fu= function value at the lower and upper limit of the bracket.

The true values must have opposite signs (that is they must constitute a bracket). Otherwise this algorithm will fail.

• tolx= tolerance on the location of the root,
• tolf= tolerance on the function value
FinEtools.AlgoBaseModule.evalconvergencestudyMethod
evalconvergencestudy(modeldatasequence)

Evaluate a convergence study from a model-data sequence.

• modeldatasequence = array of modeldata dictionaries. At least two must be included.

Refer to methods fieldnorm and fielddiffnorm for details on the required keys in the dictionaries.

Output

• elementsizes = element size array,
• errornorms = norms of the error,
• convergencerate = rate of convergence
FinEtools.AlgoBaseModule.fielddiffnormMethod
fielddiffnorm(modeldatacoarse, modeldatafine)

Compute norm of the difference of the fields.

Arguments

• modeldatacoarse, modeldatafine = data dictionaries.

For both the "coarse"- and "fine"-mesh modeldata the data dictionaries need to contain the mandatory keys:

• "fens" = finite element node set
• "regions" = array of regions
• "targetfields" = array of fields, one for each region
• "geom" = geometry field
• "elementsize" = representative element size,
• "geometricaltolerance" = geometrical tolerance (used in field transfer; refer to the documentation of transferfield!)
• "parametrictolerance" = parametric tolerance (used in field transfer; refer to the documentation of transferfield!)

Output

• Norm of the field as floating-point scalar.
FinEtools.AlgoBaseModule.fieldnormMethod
fieldnorm(modeldata)

Compute norm of the target field.

Argument

• modeldata = data dictionary, mandatory keys:
• fens = finite element node set
• regions = array of regions
• targetfields = array of fields, one for each region
• geom = geometry field
• elementsize = representative element size,

Output

• Norm of the field as floating-point scalar.
FinEtools.AlgoBaseModule.matrix_blockedFunction
matrix_blocked(A, row_nfreedofs, col_nfreedofs = row_nfreedofs)

Partition matrix into blocks.

The function returns the sparse matrix as a named tuple of its constituent blocks. The matrix is assumed to be composed of four blocks

A = [A_ff A_fd
A_df A_dd]

The named tuple is the value (ff = A_ff, fd = A_fd, df = A_df, dd = A_dd). Index into this named tuple to retrieve the parts of the matrix that you want.

Here f stands for free, and d stands for data (i.e. fixed, prescribed, ...). The size of the ff block is row_nfreedofs, col_nfreedofs. Neither one of the blocks is square, unless row_nfreedofs == col_nfreedofs.

When row_nfreedofs == col_nfreedofs, only the number of rows needs to be given.

Example

Both

K_ff, K_fd = matrix_blocked(K, nfreedofs, nfreedofs)[(:ff, :fd)]
K_ff, K_fd = matrix_blocked(K, nfreedofs)[(:ff, :fd)]

define a square K_ff matrix and, in general a rectangular, matrix K_fd.

This retrieves all four partitions of the matrix

A_ff, A_fd, A_df, A_dd = matrix_blocked(A, nfreedofs)[(:ff, :fd, :df, :dd)]

This retrieves the complete named tuple, and then the matrices can be referenced with a dot syntax.

A_b = matrix_blocked(A, nfreedofs, nfreedofs)
@test size(A_b.ff) == (nfreedofs, nfreedofs)
@test size(A_b.fd) == (nfreedofs, size(A, 1) - nfreedofs)
FinEtools.AlgoBaseModule.penaltyebc!Method
penaltyebc!(K, F, dofnums, prescribedvalues, penfact)

Apply penalty essential boundary conditions.

Arguments

• K = stiffness matrix
• F = global load vector
• dofnums, prescribedvalues = arrays computed by prescribeddofs()
• penfact = penalty multiplier, in relative terms: how many times the maximum absolute value of the diagonal elements should the penalty term be?

Output

• Updated matrix K and vector F.
FinEtools.AlgoBaseModule.qcovarianceMethod
qcovariance(ps::VecOrMat{T}, xs::VecOrMat{T}, ys::VecOrMat{T}; ws = nothing) where {T<:Number}

Compute the covariance for two 'functions' given by the arrays xs and ys at the values of the parameter ps. ws is the optional weights vector; if it is not supplied, uniformly distributed default weights are assumed.

Notes:

– The mean is subtracted from both functions. – This function is not particularly efficient: it computes the mean of both functions and it allocates arrays instead of overwriting the contents of the arguments.

FinEtools.AlgoBaseModule.qtrapMethod
qtrap(ps::VecOrMat{T}, xs::VecOrMat{T}) where {T<:Number}

Compute the area under the curve given by a set of parameters along an interval and the values of the 'function' at those parameter values. The parameter values need not be uniformly distributed.

Trapezoidal rule is used to evaluate the integral. The 'function' is assumed to vary linearly inbetween the given points.

FinEtools.AlgoBaseModule.qvarianceMethod
qvariance(ps, xs; ws = nothing)

Compute the variance of a function given by the array xs at the values of the parameter ps. ws is the optional weights vector with unit default weights.

FinEtools.AlgoBaseModule.richextrapolMethod
richextrapol(solns::T, params::T; lower_conv_rate = 0.001, upper_conv_rate = 10.0) where {T<:AbstractArray{Tn} where {Tn}}

Richardson extrapolation.

Arguments

• solns = array of three solution values
• params = array of values of three parameters for which the solns have been obtained.

The assumption is that the error of the solution is expanded in a Taylor series, and only the first term in the Taylor series is kept. qex - qapprox ~ C param^beta Here qex is the true solution, qapprox is an approximate solution, param is the element size, or the relative element size, in other words the parameter of the extrapolation, and beta is the convergence rate. The constant C is the third unknown quantity in this expansion. If we obtain three successive approximations, we can solve for the three unknown quantities, qex, beta, and C.

It is assumed that the first solution is obtained for the largest value of the extrapolation parameter, while the last solution in the list is obtained for the smallest value of the extrapolation parameter: params[1] > params[2] > params[3]

Output

• solnestim= estimate of the asymptotic solution from the data points in the solns array
• beta= convergence rate
• c = constant in the estimate error=c*h^beta
• maxresidual = maximum residual after equations from which the above quantities were solved (this is a measure of how accurately was the system solved).
FinEtools.AlgoBaseModule.richextrapoluniformMethod
richextrapoluniform(solns::T, params::T) where {T<:AbstractArray{Tn} where {Tn}}

Richardson extrapolation.

Argument

• solns = array of solution values
• params = array of values of parameters for which the solns have been obtained. This function is applicable only to fixed (uniform) ratio between the mesh sizes, params[1]/params[2) = params[2)/params[3).

Output

• solnestim= estimate of the asymptotic solution from the data points in the solns array
• beta= convergence rate
• c = constant in the estimate error=c*h^beta
• residual = residual after equations from which the above quantities were solved (this is a measure of how accurately was the system solved).
FinEtools.AlgoBaseModule.solve_blockedMethod
solve_blocked(A::M, b::VB, x::VX, nfreedofs::IT) where {M<:AbstractMatrix, VB<:AbstractVector, VX<:AbstractVector, IT<:Integer}

Solve a blocked system of linear algebraic equations.

The matrix is blocked as

A = [A_ff A_fd
A_df A_dd]

and the solution and the righthand side vector are blocked accordingly

x = [x_f
x_d]

and

b = [b_f
b_d]

Above, b_f andxdare known,xf(solution) andb_d (reactions) need to be computed.

FinEtools.AlgoBaseModule.vector_blockedMethod
vector_blocked(V, row_nfreedofs, which = (:all, ))

Partition vector into two pieces.

The vector is composed of two blocks

V = [V_f
V_d]

which are returned as a named tuple (f = V_f, d = V_d)`.