Skip to content

Commit

Permalink
call update with arbitrary arguments, fix #207
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed May 14, 2018
1 parent fb3cc17 commit bfeead4
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 38 deletions.
5 changes: 2 additions & 3 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ GENERATEDEXAMPLES = [joinpath("examples", "generated", f) for f in (
makedocs(
format = :html,
sitename = "JuAFEM.jl",
doctest = false,
# strict = VERSION.minor == 6 && sizeof(Int) == 8, # only strict mode on 0.6 and Int64
strict = false,
doctest = true,
strict = VERSION.minor == 6 && sizeof(Int) == 8, # only strict mode on 0.6 and Int64
pages = Any[
"Home" => "index.md",
"manual/fe_intro.md",
Expand Down
13 changes: 6 additions & 7 deletions docs/src/examples/heat_equation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,18 @@ ch = ConstraintHandler(dh);

# Now we are set up to define our constraint. We specify which field
# the condition is for, and our combined face set `∂Ω`. The last
# argument is a function which takes the spatial coordinate $x$ and
# the current time $t$ and returns the prescribed value. In this case
# it is trivial -- no matter what $x$ and $t$ we return $0$. When we have
# argument is a function which takes the spatial coordinate $x$ (and
# optionally other arguments) and returns the prescribed value. In this case
# it is trivial -- no matter what $x$ is we return $0$. When we have
# specified our constraint we `add!` it to `ch`.
dbc = Dirichlet(:u, ∂Ω, (x, t) -> 0)
dbc = Dirichlet(:u, ∂Ω, (x) -> 0)
add!(ch, dbc);

# We also need to `close!` and `update!` our boundary conditions. When we call `close!`
# the dofs which will be constrained by the boundary conditions are calculated and stored
# in our `ch` object. Since the boundary conditions are, in this case,
# independent of time we can `update!` them directly with e.g. $t = 0$.
# in our `ch` object. We also call `update!`, which calculates the prescribed values.
close!(ch)
update!(ch, 0.0);
update!(ch);

# ### Assembling the linear system
# Now we have all the pieces needed to assemble the linear system, $K u = f$.
Expand Down
5 changes: 2 additions & 3 deletions docs/src/examples/incompressible_elasticity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ end;
# We specify a homogeneous Dirichlet bc on the displacement field, `:u`.
function create_bc(dh)
dbc = ConstraintHandler(dh)
add!(dbc, Dirichlet(:u, getfaceset(dh.grid, "clamped"), (x,t) -> zero(Vec{2}), [1,2]))
add!(dbc, Dirichlet(:u, getfaceset(dh.grid, "clamped"), (x) -> zero(Vec{2}), [1,2]))
close!(dbc)
t = 0.0
update!(dbc, t)
update!(dbc)
return dbc
end;

Expand Down
1 change: 1 addition & 0 deletions docs/src/reference/boundary_conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ ConstraintHandler
Dirichlet
add!
close!
update!
```
5 changes: 2 additions & 3 deletions examples/cantilever.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,10 @@
"# Boundaryconditions\n",
"dbcs = ConstraintHandler(dh)\n",
"# Add a homogenoush boundary condition on the \"clamped\" edge\n",
"dbc = Dirichlet(:u, getfaceset(grid, \"left\"), (x,t) -> [0.0, 0.0, 0.0], collect(1:dim))\n",
"dbc = Dirichlet(:u, getfaceset(grid, \"left\"), (x) -> [0.0, 0.0, 0.0], collect(1:dim))\n",
"add!(dbcs, dbc)\n",
"close!(dbcs)\n",
"t = 0.0\n",
"update!(dbcs, t)"
"update!(dbcs)"
]
},
{
Expand Down
5 changes: 2 additions & 3 deletions examples/cooks_membrane_mixed_up.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@
"function create_boundaryconditions(dh, grid)\n",
" dbc = ConstraintHandler(dh)\n",
" # Add a homogenoush boundary condition on the \"clamped\" edge\n",
" add!(dbc, Dirichlet(:u, getfaceset(grid, \"clamped\"), (x,t) -> zero(Vec{2}), [1,2]))\n",
" add!(dbc, Dirichlet(:u, getfaceset(grid, \"clamped\"), (x) -> zero(Vec{2}), [1,2]))\n",
" close!(dbc)\n",
" t = 0.0\n",
" update!(dbc, t)\n",
" update!(dbc)\n",
" return dbc\n",
"end;"
]
Expand Down
4 changes: 2 additions & 2 deletions examples/heat_square.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@
"outputs": [],
"source": [
"dbcs = ConstraintHandler(dh)\n",
"dbc = Dirichlet(:T, union(getfaceset(grid, \"left\"), getfaceset(grid, \"right\"), getfaceset(grid, \"top\"), getfaceset(grid, \"bottom\")), (x,t)->0)\n",
"dbc = Dirichlet(:T, union(getfaceset(grid, \"left\"), getfaceset(grid, \"right\"), getfaceset(grid, \"top\"), getfaceset(grid, \"bottom\")), (x)->0)\n",
"add!(dbcs, dbc)\n",
"close!(dbcs)\n",
"update!(dbcs, 0.0)"
"update!(dbcs)"
]
},
{
Expand Down
4 changes: 2 additions & 2 deletions examples/helmholtz.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@
"outputs": [],
"source": [
"dbcs = ConstraintHandler(dh)\n",
"dbc = Dirichlet(:u, union(getfaceset(grid, \"top\"), getfaceset(grid, \"right\")), (x,t) -> u_ana(x))\n",
"dbc = Dirichlet(:u, union(getfaceset(grid, \"top\"), getfaceset(grid, \"right\")), (x) -> u_ana(x))\n",
"add!(dbcs, dbc)\n",
"close!(dbcs)\n",
"update!(dbcs, 0.0)"
"update!(dbcs)"
]
},
{
Expand Down
29 changes: 18 additions & 11 deletions src/Dofs/ConstraintHandler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
Dirichlet(u, ∂Ω, f, component)
Create a Dirichlet boundary condition on `u` on the `∂Ω` part of
the boundary. `f` is a function that takes two arguments, `x` and `t`
where `x` is the spatial coordinate and `t` is the current time,
and returns the prescribed value. For example, here we create a
Dirichlet condition for the `:u` field, on the faceset called
the boundary. `f` is a function that return the prescribed value.
`f` will be called by [`update!`](@ref) with the spatial coordinate
`x` as first argument. For example, here we create a
Dirichlet condition for the `:u` field, on the face set called
`∂Ω` and the value given by the `sin` function:
```julia
dbc = Dirichlet(:u, ∂Ω, (x, t) -> sin(t))
dbc = Dirichlet(:u, ∂Ω, (x, t = 1.0) -> sin(t))
```
If `:u` is a vector field we can specify which component the condition
should be applied to by specifying `component`. `component` can be given
either as an integer, or as a vector, for example:
```julia
dbc = Dirichlet(:u, ∂Ω, (x, t) -> sin(t), 1) # applied to component 1
dbc = Dirichlet(:u, ∂Ω, (x, t) -> sin(t), [1, 3]) # applied to component 1 and 3
dbc = Dirichlet(:u, ∂Ω, (x, t = 1.0) -> sin(t), 1) # applied to component 1
dbc = Dirichlet(:u, ∂Ω, (x, t = 1.0) -> (sin(t), cos(t)), [1, 3]) # applied to component 1 and 3
```
`Dirichlet` boundary conditions are added to a [`ConstraintHandler`](@ref)
Expand Down Expand Up @@ -155,19 +155,26 @@ function _add!(ch::ConstraintHandler, dbc::Dirichlet, interpolation::Interpolati
end

# Updates the DBC's to the current time `time`
function update!(ch::ConstraintHandler, time::Float64=0.0)
"""
update!(ch::ConstraintHandler; args...; kwargs...)
Update the constraints in the ConstraintHandler.
`update!` propagates `args` and `kwargs` to the update function specified
when creating the constraint.
"""
function update!(ch::ConstraintHandler, args...; kwargs...)
@assert ch.closed[]
for dbc in ch.dbcs
field_idx = find_field(ch.dh, dbc.field_name)
# Function barrier
_update!(ch.values, dbc.f, dbc.faces, dbc.field_name, dbc.local_face_dofs, dbc.local_face_dofs_offset,
dbc.components, ch.dh, ch.dh.bc_values[field_idx], ch.dofmapping, time)
dbc.components, ch.dh, ch.dh.bc_values[field_idx], ch.dofmapping, args, kwargs)
end
end

function _update!(values::Vector{Float64}, f::Function, faces::Set{Tuple{Int,Int}}, field::Symbol, local_face_dofs::Vector{Int}, local_face_dofs_offset::Vector{Int},
components::Vector{Int}, dh::DofHandler{dim,N,T,M}, facevalues::BCValues,
dofmapping::Dict{Int,Int}, time::Float64) where {dim,N,T,M}
dofmapping::Dict{Int,Int}, args, kwargs) where {dim,N,T,M}
grid = dh.grid

xh = zeros(Vec{dim, T}, N) # pre-allocate
Expand All @@ -186,7 +193,7 @@ function _update!(values::Vector{Float64}, f::Function, faces::Set{Tuple{Int,Int

for location in 1:getnquadpoints(facevalues)
x = spatial_coordinate(facevalues, location, xh)
bc_value = f(x, time)
bc_value = f(x, args...; kwargs...)
@assert length(bc_value) == length(components)

for i in 1:length(components)
Expand Down
8 changes: 4 additions & 4 deletions test/test_grid_dofhandler_vtk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ end
push!(dofhandler, :displacement, 3)
close!(dofhandler)
ch = ConstraintHandler(dofhandler)
dbc = Dirichlet(:temperature, union(getfaceset(grid, "left"), getfaceset(grid, "right-faceset")), (x,t)->1)
dbc = Dirichlet(:temperature, union(getfaceset(grid, "left"), getfaceset(grid, "right-faceset")), (x)->1)
add!(ch, dbc)
dbc = Dirichlet(:temperature, getfaceset(grid, "middle-faceset"), (x,t)->4)
dbc = Dirichlet(:temperature, getfaceset(grid, "middle-faceset"), (x)->4)
add!(ch, dbc)
for d in 1:dim
dbc = Dirichlet(:displacement, union(getfaceset(grid, "left")), (x,t) -> d, d)
dbc = Dirichlet(:displacement, union(getfaceset(grid, "left")), (x) -> d, d)
add!(ch, dbc)
end
close!(ch)
update!(ch, 0.0)
update!(ch)
srand(1234)
u = rand(ndofs(dofhandler))
apply!(u, ch)
Expand Down

0 comments on commit bfeead4

Please sign in to comment.