mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-20 18:18:31 +00:00
- problem can be now represented using potential energy or residual
force vector, autodiff takes care of linearization - elasticity equations are now solved using e.g. principle of minimum potential energy. syntax is quite good, see notebook. - updated how to interpolate fields, by introducing function spaces. syntax is now good. still have to figure out how to do time derivatives - etc. etc. tutorial is broken at the moment, i took of get_lhs and get_rhs because they didn't really work.
This commit is contained in:
@@ -10,6 +10,9 @@ using Lexicon
|
||||
using Logging
|
||||
@Logging.configure(level=DEBUG)
|
||||
|
||||
using ForwardDiff
|
||||
autodiffcache = ForwardDiffCache()
|
||||
|
||||
""" Simple linspace extension to arrays.
|
||||
|
||||
Examples
|
||||
|
||||
+116
-71
@@ -8,20 +8,18 @@ Related notebooks
|
||||
2015-08-29-developing-juliafem.ipynb
|
||||
=#
|
||||
|
||||
using JuliaFEM: interpolate
|
||||
using FactCheck
|
||||
using ForwardDiff
|
||||
|
||||
|
||||
abstract Element
|
||||
|
||||
""" Get FieldSet from element. """
|
||||
function Base.getindex(element::Element, field_name::Union{Symbol, ASCIIString})
|
||||
function Base.getindex(element::Element, field_name)
|
||||
element.fields[symbol(field_name)]
|
||||
end
|
||||
|
||||
""" Add new FieldSet to element. """
|
||||
function Base.setindex!(element::Element, fieldset::FieldSet, fieldset_name::Union{Symbol, ASCIIString})
|
||||
function Base.setindex!(element::Element, fieldset::FieldSet, fieldset_name)
|
||||
fieldset.name = symbol(fieldset_name)
|
||||
element.fields[fieldset.name] = fieldset
|
||||
end
|
||||
@@ -126,103 +124,150 @@ function test_element(element_type)
|
||||
fieldset = FieldSet("field1")
|
||||
push!(fieldset, field)
|
||||
push!(element, fieldset)
|
||||
@fact element["field1"][1] --> fld
|
||||
push!(element, FieldSet("geometry", [Field(0.0, Vector[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])]))
|
||||
|
||||
# evaluate basis functions at middle point of element
|
||||
mid = zeros(dim)
|
||||
try
|
||||
get_basis(element)(mid)
|
||||
basis = get_basis(element)
|
||||
val1 = basis(mid, 0.0)
|
||||
Logging.info("basis at $mid: $val1")
|
||||
val2 = basis("field1", mid, 0.0)
|
||||
Logging.info("field val at $mid: $val2")
|
||||
catch
|
||||
Logging.error("""
|
||||
Unable to evaluate basis, define function 'get_basis' for
|
||||
this element.""")
|
||||
end
|
||||
try
|
||||
get_dbasisdxi(element)(mid)
|
||||
basis = get_basis(element)
|
||||
dbasis = grad(basis)
|
||||
val3 = dbasis(mid, 0.0)
|
||||
Logging.info("derivative of basis at $mid: $val3")
|
||||
val4 = dbasis("field1", mid, 0.0)
|
||||
Logging.info("field val at $mid: $val4")
|
||||
catch
|
||||
Logging.error("""
|
||||
Unable to evaluate partial derivatives of basis,
|
||||
define function 'get_dbasisdxi' for this element.""")
|
||||
end
|
||||
|
||||
Logging.info("Interpolating scalar field at $mid")
|
||||
i = interpolate(element, "field1", mid, 0.0)
|
||||
Logging.info("Value: $i")
|
||||
Logging.info("Element $element_type passed tests.")
|
||||
end
|
||||
|
||||
|
||||
get_connectivity(el::Element) = el.connectivity
|
||||
|
||||
""" Get basis functions of element. """
|
||||
get_basis(el::Element) = el.basis
|
||||
get_basis(el::Element, xi::Vector) = el.basis(xi)
|
||||
Base.call(el::Element, xi::Vector) = el.basis(xi)
|
||||
|
||||
""" Get partial derivatives of basis functions of element. """
|
||||
get_dbasisdxi(el::Element) = el.basis.dbasisdxi
|
||||
get_dbasisdxi(el::Element, xi::Vector) = el.basis.dbasisdxi(xi)
|
||||
get_dbasisdxi(el::Element, ip::IntegrationPoint) = el.basis.dbasisdxi(ip.xi)
|
||||
|
||||
""" Interpolate field on element. """
|
||||
function interpolate(element::Element, field_name, xi::Vector, time::Number)
|
||||
fieldset = element[field_name]
|
||||
field = interpolate(fieldset, time)
|
||||
basis = get_basis(element)
|
||||
interpolate(basis, field, xi)
|
||||
end
|
||||
function interpolate(element::Element, field_name, ip::IntegrationPoint, time::Number)
|
||||
interpolate(element, field_name, ip.xi, time)
|
||||
function get_connectivity(el::Element)
|
||||
el.connectivity
|
||||
end
|
||||
|
||||
""" Interpolate derivative of field on element. """
|
||||
function dinterpolate(element::Element, field_name, xi::Vector, time::Number)
|
||||
fieldset = element[field_name]
|
||||
field = interpolate(fieldset, time)
|
||||
basis = get_basis(element)
|
||||
dinterpolate(basis, field, xi)
|
||||
type MixedFunctionSpace
|
||||
element1 :: Element
|
||||
element2 :: Element
|
||||
end
|
||||
function dinterpolate(element::Element, field_name, ip::IntegrationPoint, time::Number)
|
||||
dinterpolate(element, field_name, ip.xi, time)
|
||||
|
||||
type FunctionSpace
|
||||
element :: Element
|
||||
end
|
||||
|
||||
type GradientFunctionSpace
|
||||
element :: Element
|
||||
end
|
||||
|
||||
function grad(u::FunctionSpace)
|
||||
GradientFunctionSpace(u.element)
|
||||
end
|
||||
|
||||
""" Evaluate field on element function space. """
|
||||
function call(u::FunctionSpace, field_name, xi::Vector, t::Number=Inf, variation=nothing)
|
||||
f = !isa(variation, Void) ? variation : u.element[field_name](t)
|
||||
if length(f) == 1
|
||||
return f.values
|
||||
end
|
||||
h = u.element.basis.basis(xi)
|
||||
return h*f
|
||||
end
|
||||
|
||||
""" If basis is called without a field, return basis functions evaluated at that point. """
|
||||
function call(u::FunctionSpace, xi::Vector, t::Number=Inf)
|
||||
return u.element.basis.basis(xi)'
|
||||
end
|
||||
|
||||
""" Evaluate gradient of field on element function space. """
|
||||
function call(gradu::GradientFunctionSpace, field_name, xi::Vector, t::Number=Inf, variation=nothing)
|
||||
f = !isa(variation, Void) ? variation : gradu.element[field_name](t)
|
||||
X = gradu.element["geometry"](t)
|
||||
b = gradu.element.basis.dbasisdxi(xi)
|
||||
return b*f*inv(b*X)
|
||||
end
|
||||
|
||||
""" If gradient of basis is called without a field, return "empty" gradient evaluated at that point. """
|
||||
function call(gradu::GradientFunctionSpace, xi::Vector, t::Number=Inf)
|
||||
X = gradu.element["geometry"](t)
|
||||
b = gradu.element.basis.dbasisdxi(xi)
|
||||
return (b*inv(b*X))'
|
||||
end
|
||||
|
||||
# on-line functions to get api more easy to use, ip -> xi.ip
|
||||
call(u::FunctionSpace, ip::IntegrationPoint, t::Number) = call(u, ip.xi, t)
|
||||
call(u::FunctionSpace, ip::IntegrationPoint) = call(u, ip.xi)
|
||||
call(u::GradientFunctionSpace, ip::IntegrationPoint, t::Number) = call(u, ip.xi, t)
|
||||
call(u::GradientFunctionSpace, ip::IntegrationPoint) = call(u, ip.xi)
|
||||
|
||||
""" Return field from function space. """
|
||||
function get_field(u::FunctionSpace, field_name, time=Inf)
|
||||
return u.element[field_name](time)
|
||||
end
|
||||
|
||||
""" Return field from function space. """
|
||||
function get_field(u::FunctionSpace, field_name, time=Inf, variation=nothing)
|
||||
return !isa(variation, Void) ? variation : u.element[field_name](time)
|
||||
end
|
||||
|
||||
""" Return fieldset from function space. """
|
||||
function get_fieldset(u::FunctionSpace, field_name)
|
||||
return u.element[field_name]
|
||||
end
|
||||
|
||||
# i think these will be the most called functions.
|
||||
call(u::FunctionSpace, field_name, ip::IntegrationPoint, t::Number, variation=nothing) = call(u, field_name, ip.xi, t, variation)
|
||||
call(u::GradientFunctionSpace, field_name, ip::IntegrationPoint, t::Number, variation=nothing) = call(u, field_name, ip.xi, t, variation)
|
||||
|
||||
function jacobian(u::FunctionSpace, xi, t)
|
||||
u.element.basis.dbasisdxi(xi)*u.element["geometry"](t)
|
||||
end
|
||||
|
||||
function jacobian(u::FunctionSpace, ip::IntegrationPoint, t::Number)
|
||||
jacobian(u, ip.xi, t)
|
||||
end
|
||||
|
||||
function jacobian(u::FunctionSpace, xi)
|
||||
jacobian(u, xi, Inf)
|
||||
end
|
||||
|
||||
function LinAlg.det(u::FunctionSpace)
|
||||
function detJ(args...)
|
||||
J = jacobian(u, args...)
|
||||
m, n = size(J)
|
||||
return m == n ? det(J) : norm(J)
|
||||
end
|
||||
return detJ
|
||||
end
|
||||
|
||||
function get_basis(element::Element)
|
||||
return FunctionSpace(element)
|
||||
end
|
||||
|
||||
Base.(:+)(u::FunctionSpace, v::FunctionSpace) = (args...) -> u(args...) + v(args...)
|
||||
Base.(:-)(u::FunctionSpace, v::FunctionSpace) = (args...) -> u(args...) - v(args...)
|
||||
Base.(:+)(u::GradientFunctionSpace, v::GradientFunctionSpace) = (args...) -> u(args...) + v(args...)
|
||||
Base.(:-)(u::GradientFunctionSpace, v::GradientFunctionSpace) = (args...) -> u(args...) - v(args...)
|
||||
|
||||
|
||||
""" Check does fieldset exist. """
|
||||
function Base.haskey(element::Element, what)
|
||||
haskey(element.fields, symbol(what))
|
||||
end
|
||||
|
||||
"""
|
||||
Get jacobian of element evaluated at point ξ on element in reference configuration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
element :: Element
|
||||
xi :: Vector
|
||||
spatial coordinate
|
||||
time :: Float64
|
||||
temporal coordinate
|
||||
geometry_field :: optional
|
||||
|
||||
Returns
|
||||
-------
|
||||
Vector or Matrix
|
||||
depending on element dimension
|
||||
|
||||
"""
|
||||
function get_jacobian(element::Element, xi, time, geometry_field="geometry")
|
||||
dinterpolate(element, geometry_field, xi, time)
|
||||
end
|
||||
|
||||
""" Evaluate partial derivatives of basis, dbasis/dX, at some time t"""
|
||||
function get_dbasisdX(el::Element, xi, t)
|
||||
dbasisdxi = get_dbasisdxi(el, xi)
|
||||
J = get_jacobian(el, xi, t)
|
||||
dbasisdxi*inv(J)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# FIXME: These two needs integration -- maybe not in elements.jl ..?
|
||||
"""
|
||||
|
||||
+151
-45
@@ -3,68 +3,174 @@
|
||||
|
||||
abstract Equation
|
||||
|
||||
abstract Assembly
|
||||
|
||||
""" Local element assembly. """
|
||||
type LocalAssembly <: Assembly
|
||||
ndofs :: Int
|
||||
mass_matrix :: Matrix
|
||||
stiffness_matrix :: Matrix
|
||||
force_vector :: Matrix
|
||||
potential_energy# :: Union{Array, Float64}
|
||||
residual_vector :: Vector
|
||||
end
|
||||
|
||||
function LocalAssembly(ndofs, mass_matrix, stiffness_matrix, force_vector::Matrix)
|
||||
LocalAssembly(ndofs, mass_matrix, stiffness_matrix, force_vector[:])
|
||||
end
|
||||
|
||||
""" Initialize workspace for local assembly. """
|
||||
function LocalAssembly(equation::Equation)
|
||||
ndofs = size(equation)
|
||||
mass_matrix = zeros(ndofs, ndofs)
|
||||
stiffness_matrix = zeros(ndofs, ndofs)
|
||||
force_vector = zeros(ndofs, 1)
|
||||
potential_energy = 0.0
|
||||
residual_vector = zeros(ndofs)
|
||||
return LocalAssembly(ndofs, mass_matrix, stiffness_matrix, force_vector,
|
||||
potential_energy, residual_vector)
|
||||
end
|
||||
|
||||
function initialize_local_assembly(equation::Equation)
|
||||
LocalAssembly(equation)
|
||||
end
|
||||
|
||||
function initialize_local_assembly(equation::Equation, assembly::LocalAssembly)
|
||||
if size(equation) != assembly.ndofs
|
||||
# if problem size changes, automatically initialize new work space
|
||||
return initialize_local_assembly(equation)
|
||||
end
|
||||
# otherwise, empty workspace ready for next iteration
|
||||
fill!(assembly.mass_matrix, 0.0)
|
||||
fill!(assembly.stiffness_matrix, 0.0)
|
||||
fill!(assembly.force_vector, 0.0)
|
||||
assembly.potential_energy = 0.0
|
||||
fill!(assembly.residual_vector, 0.0)
|
||||
return assembly
|
||||
end
|
||||
function initialize_local_assembly(assembly::LocalAssembly, equation::Equation)
|
||||
initialize_local_assembly(equation, assembly)
|
||||
end
|
||||
|
||||
function get_unknown_field_name(equation::Equation)
|
||||
eqtype = typeof(equation)
|
||||
error("define get_unknown_field_name for this equation type $eqtype")
|
||||
end
|
||||
|
||||
|
||||
has_lhs(eq::Equation) = false
|
||||
get_lhs(eq::Equation, xi) = nothing
|
||||
has_rhs(eq::Equation) = false
|
||||
get_rhs(eq::Equation, xi) = nothing
|
||||
get_element(eq::Equation) = eq.element
|
||||
get_integration_points(eq::Equation) = eq.integration_points
|
||||
|
||||
# couple convenient functions -- could make weak form definition easier
|
||||
get_connectivity(eq::Equation) = get_connectivity(get_element(eq))
|
||||
get_basis(eq::Equation, ip::IntegrationPoint) = get_basis(get_element(eq), ip.xi)
|
||||
get_dbasisdx(eq::Equation, ip::IntegrationPoint) = get_dbasisdx(get_element(eq), ip.xi)
|
||||
interpolate(eq::Equation, field::Union{ASCIIString, Symbol}, ip::IntegrationPoint) = interpolate(get_element(el), field, ip.xi)
|
||||
integrate_lhs(eq::Equation, t::Number) = has_lhs(eq) ? integrate(eq, get_lhs, t) : nothing
|
||||
integrate_rhs(eq::Equation, t::Number) = has_rhs(eq) ? integrate(eq, get_rhs, t) : nothing
|
||||
get_lhs(eq::Equation, t::Number) = has_lhs(eq) ? integrate(eq, get_lhs, t) : nothing
|
||||
get_rhs(eq::Equation, t::Number) = has_rhs(eq) ? integrate(eq, get_rhs, t) : nothing
|
||||
has_mass_matrix(equation::Equation) = false
|
||||
get_mass_matrix(equation::Equation, ip, time) = nothing
|
||||
has_stiffness_matrix(equation::Equation) = false
|
||||
get_stiffness_matrix(equation::Equation, ip, time) = nothing
|
||||
has_force_vector(equation::Equation) = false
|
||||
get_force_vector(equation::Equation, ip, time) = nothing
|
||||
has_residual_vector(equation::Equation) = false
|
||||
get_residual_vector(equation::Equation, ip, time) = nothing
|
||||
has_potential_energy(equation::Equation) = false
|
||||
get_potential_energy(equation::Equation, ip, time) = nothing
|
||||
get_element(equation::Equation) = equation.element
|
||||
get_number_of_dofs(equation::Equation) = nothing
|
||||
get_integration_points(equation::Equation) = equation.integration_points
|
||||
|
||||
|
||||
"""
|
||||
Return determinant of Jacobian for numerical integration.
|
||||
"""
|
||||
function get_detJ(eq::Equation, ip::IntegrationPoint, t::Float64)
|
||||
el = get_element(eq)
|
||||
get_detJ(el, ip, t)
|
||||
end
|
||||
function get_detJ(el::Element, ip::IntegrationPoint, t::Float64)
|
||||
get_detJ(el, ip.xi, t)
|
||||
end
|
||||
function get_detJ(el::Element, xi::Vector, t::Float64)
|
||||
J = get_jacobian(el, xi, t)
|
||||
s = size(J)
|
||||
return s[1] == s[2] ? det(J) : norm(J)
|
||||
end
|
||||
""" Return a local assembly for element. """
|
||||
function calculate_local_assembly!(assembly::LocalAssembly, equation::Equation, time::Number=Inf)
|
||||
|
||||
"""
|
||||
Integrate f over element
|
||||
initialize_local_assembly(assembly, equation) # zero all
|
||||
|
||||
Parameters
|
||||
----------
|
||||
eq::Equation
|
||||
element = get_element(equation)
|
||||
basis = get_basis(element)
|
||||
detJ = det(basis)
|
||||
field_name = get_unknown_field_name(equation)
|
||||
|
||||
f::Function
|
||||
Function to integrate
|
||||
"""
|
||||
function integrate(eq::Equation, f::Function, t::Float64)
|
||||
target = []
|
||||
for ip in get_integration_points(eq)
|
||||
push!(target, ip.weight*f(eq, ip, t)*get_detJ(eq, ip, t))
|
||||
# 1. if equations are defined we just integrate them
|
||||
if has_mass_matrix(equation) || has_stiffness_matrix(equation) || has_force_vector(equation)
|
||||
for ip in get_integration_points(equation)
|
||||
s = ip.weight*detJ(ip)
|
||||
if has_mass_matrix(equation)
|
||||
assembly.mass_matrix += s*get_mass_matrix(equation, ip, time)
|
||||
end
|
||||
if has_stiffness_matrix(equation)
|
||||
assembly.stiffness_matrix += s*get_stiffness_matrix(equation, ip, time)
|
||||
end
|
||||
if has_force_vector(equation)
|
||||
assembly.force_vector += s*get_force_vector(equation, ip, time)[:]
|
||||
end
|
||||
# external loads -- if any nodal loads is defined add to force vector
|
||||
if haskey(element, "$field_name nodal load")
|
||||
assembly.force_vector += element["$field_name nodal load"](time)[:]
|
||||
end
|
||||
end
|
||||
end
|
||||
return sum(target)
|
||||
|
||||
# 2. variational / energy form - user has defined some potential energy / variational form
|
||||
if has_potential_energy(equation)
|
||||
field_name = get_unknown_field_name(equation)
|
||||
element = get_element(equation)
|
||||
field = element[field_name](time)
|
||||
function potential_energy(data::Vector)
|
||||
# calculate potential energy for some setting. this is needed by forwarddiff
|
||||
assembly.potential_energy = 0.0
|
||||
df = similar(field, data)
|
||||
# integrate potential energy
|
||||
for ip in get_integration_points(equation)
|
||||
dw = get_potential_energy(equation, ip, time; variation=df)
|
||||
assembly.potential_energy += ip.weight * dw * detJ(ip)
|
||||
end
|
||||
# external energy -- if any nodal loads is defined, decrease from potential energy
|
||||
if haskey(element, "$field_name nodal load")
|
||||
P = element["$field_name nodal load"](time)
|
||||
assembly.potential_energy -= dot(P[:], df[:])
|
||||
end
|
||||
if isa(assembly.potential_energy, Array)
|
||||
return assembly.potential_energy[1]
|
||||
end
|
||||
return assembly.potential_energy
|
||||
end
|
||||
hessian, allresults = ForwardDiff.hessian(potential_energy, field[:],
|
||||
AllResults, cache=autodiffcache)
|
||||
assembly.stiffness_matrix += hessian
|
||||
assembly.force_vector -= ForwardDiff.gradient(allresults) # <--- minus explained in tutorial
|
||||
assembly.potential_energy = ForwardDiff.value(allresults)
|
||||
end
|
||||
|
||||
# 3. virtual work form - user has defined residual vector δW_int(u,δu) + δW_ext(u,δu) = 0 ∀ v
|
||||
if has_residual_vector(equation)
|
||||
field_name = get_unknown_field_name(equation)
|
||||
element = get_element(equation)
|
||||
field = element[field_name](time)
|
||||
function residual_vector(data::Vector)
|
||||
fill!(assembly.residual_vector, 0.0)
|
||||
df = similar(field, data)
|
||||
# integrate W
|
||||
for ip in get_integration_points(equation)
|
||||
dr = get_residual_vector(equation, ip, time; variation=df)
|
||||
assembly.residual_vector += ip.weight*dr*detJ(ip)
|
||||
end
|
||||
# external loads -- if any nodal loads is defined, remove from residual
|
||||
if haskey(element, "$field_name nodal load")
|
||||
assembly.residual_vector -= element["$field_name nodal load"](time)[:]
|
||||
end
|
||||
return assembly.residual_vector
|
||||
end
|
||||
jacobian, allresults = ForwardDiff.jacobian(residual_vector, field[:],
|
||||
AllResults, cache=autodiffcache)
|
||||
assembly.stiffness_matrix += jacobian
|
||||
assembly.force_vector -= ForwardDiff.value(allresults) # <-- minus explained in tutorial
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function calculate_local_assembly!(equation::Equation, assembly::LocalAssembly, time::Number=Inf)
|
||||
calculate_local_assembly!(assembly, equation)
|
||||
end
|
||||
|
||||
|
||||
""" Get global degrees of freedom for this element. """
|
||||
function get_global_dofs(eq::Equation)
|
||||
eq.global_dofs
|
||||
end
|
||||
|
||||
""" Set global degrees of freedom for this element. """
|
||||
function set_global_dofs!(eq::Equation, dofs)
|
||||
eq.global_dofs = dofs
|
||||
end
|
||||
|
||||
+2
-3
@@ -59,8 +59,7 @@ function interpolate(basis::Basis, field::Field, ip::IntegrationPoint)
|
||||
interpolate(basis, field, ip.xi)
|
||||
end
|
||||
|
||||
function dinterpolate(N::Basis, u::Field, xi::Array{Float64, 1})
|
||||
dN = diff(N)
|
||||
dN(xi)*u
|
||||
function dinterpolate(basis::Basis, u::Field, xi::Array{Float64, 1})
|
||||
basis.dbasisdxi(xi)*u
|
||||
end
|
||||
|
||||
|
||||
+14
-7
@@ -70,12 +70,17 @@ JuliaFEM.Field{Array{Array{T,1},1}}(0.5,1,Array{T,1}[[1.0,1.0],[1.0,1.0]])
|
||||
|
||||
"""
|
||||
function Base.similar(field::Field, data::Vector)
|
||||
fdim = round(Int, length(data)/length(field)) # dimension of field variable
|
||||
if fdim == 1
|
||||
new_field = Field(field.time, data)
|
||||
return new_field
|
||||
end
|
||||
new_field = Field(field.time, similar(field.values))
|
||||
data = reshape(data, round(Int, length(data)/length(field)), length(field))
|
||||
data = reshape(data, fdim, length(field))
|
||||
for i=1:length(new_field)
|
||||
new_field.values[i] = data[:,i]
|
||||
end
|
||||
new_field
|
||||
return new_field
|
||||
end
|
||||
|
||||
|
||||
@@ -117,7 +122,6 @@ function Base.endof(fieldset::FieldSet)
|
||||
end
|
||||
|
||||
|
||||
|
||||
""" Basis function. """
|
||||
type Basis
|
||||
basis :: Function
|
||||
@@ -128,9 +132,9 @@ function Basis(basis)
|
||||
Basis(basis, ForwardDiff.jacobian(basis))
|
||||
end
|
||||
""" Get partial derivative of basis function. """
|
||||
diff(h::Basis) = h.dbasisdxi
|
||||
derivative(h::Basis) = h.dbasisdxi
|
||||
|
||||
function grad(basis::Basis)
|
||||
(ip) -> basis.dbasisdxi(ip.xi)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
@@ -158,7 +162,10 @@ end
|
||||
|
||||
# convenient functions -- maybe this is not correct place for them
|
||||
""" Evaluate basis function in point ξ. """
|
||||
call(b::Basis, xi) = b.basis(xi)
|
||||
call(b::Basis, xi::Vector) = b.basis(xi)
|
||||
call(b::Basis, ip::IntegrationPoint) = b.basis(ip.xi)
|
||||
Base.(:*)(basis::Basis, fs::FieldSet) = (xi, t) -> basis(xi)*fs(t)
|
||||
|
||||
#""" Interpolate field (h*f)(ξ) """
|
||||
#Base.(:*)(f::Function, fld::Field) = (x) -> f(x)*fld
|
||||
#""" Interpolate from set of fields with basis b, i.e. f(t) = b(t)*[f1, f2] """
|
||||
|
||||
Reference in New Issue
Block a user