Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "FiniteElementContainers"
uuid = "d08262e4-672f-4e7f-a976-f2cea5767631"
version = "0.13.5"
version = "0.14.0"
authors = ["Craig M. Hamel <cmhamel32@gmail.com> and contributors"]

[deps]
Expand Down
27 changes: 23 additions & 4 deletions src/AppTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ end
# polynomial_type::String
# end

# TODO currently only supports blocks
struct ICSettings{T <: Number}
ics::Vector{InitialCondition{ScalarExpressionFunction{T}}}

Expand All @@ -444,14 +445,32 @@ struct ICSettings{T <: Number}
ic_settings = data["initial_conditions"]::Vector{Any}
for ic in ic_settings
temp = ic::Dict{String, Any}
blocks = temp["blocks"]::Vector{String}
func = temp["function"]::String
func = functions.scalar_expr_funcs[func]
vars = temp["variables"]::Vector{String}
for block in blocks
for var in vars
push!(ics, InitialCondition(var, func, block))
if haskey(temp, "blocks")
blocks = temp["blocks"]::Vector{String}
for block in blocks
for var in vars
push!(ics, InitialCondition(var, func; block_name = block))
end
end
elseif haskey(temp, "nodesets")
nodesets = temp["nodesets"]::Vector{String}
for nodeset in nodesets
for var in vars
push!(ics, InitialCondition(var, func; nodeset_name = nodeset))
end
end
elseif haskey(temp, "sidesets")
sidesets = temp["sidesets"]::Vector{String}
for sideset in sidesets
for var in vars
push!(ics, InitialCondition(var, func; sideset_name = sideset))
end
end
else
@assert false "Couldn't find blocks, nodesets, or sidesets."
end
end
end
Expand Down
68 changes: 63 additions & 5 deletions src/InitialConditions.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,49 @@
abstract type AbstractInitialCondition{F} end
abstract type AbstractInitialConditionContainer end

"""
$(TYPEDEF)
$(TYPEDSIGNATURES)
$(TYPEDFIELDS)
User facing API to define a ```InitialCondition```.
"""
struct InitialCondition{F} <: AbstractInitialCondition{F}
var_name::String
func::F
block_name::String
block_name::EntityName
nset_name::EntityName
sset_name::EntityName
var_name::String

"""
$(TYPEDEF)
$(TYPEDSIGNATURES)
$(TYPEDFIELDS)
"""
function InitialCondition(
var_name::String, func::Function;
block_name::EntityName = nothing,
nodeset_name::EntityName = nothing,
sideset_name::EntityName = nothing
)
if block_name === nothing && nodeset_name === nothing && sideset_name === nothing
_entity_not_provided_error(
"block_name, nodeset_name, or sideset_name required" *
" as input arguments in DirichletBC"
)
end
count = (block_name !== nothing) +
(nodeset_name !== nothing) +
(sideset_name !== nothing)
if count != 1
_unsure_entity_type_error("More than one entity type specificed in DirichletBC")
end
# new{typeof(func)}(func, block_name, nodeset_name, sideset_name, var_name)
return InitialCondition{typeof(func)}(var_name, func, block_name, nodeset_name, sideset_name)
end

function InitialCondition{F}(var_name::String, func::F, block_name, nodeset_name, sideset_name) where F
new{typeof(func)}(func, block_name, nodeset_name, sideset_name, var_name)
end
end

struct InitialConditionContainer{
Expand All @@ -21,9 +60,28 @@ struct InitialConditionContainer{
# to "do the right thing" depending upon the field type
# this is set up
function InitialConditionContainer(mesh, dof, ic::InitialCondition)
bk = BCBookKeeping(mesh, dof, ic.var_name; block_name = ic.block_name)
vals = zeros(length(bk.dofs))
new{typeof(bk.dofs), typeof(vals)}(bk.dofs, bk.nodes, vals)
# bk = BCBookKeeping(mesh, dof, ic.var_name; block_name = ic.block_name)
dof_index = _dof_index_from_var_name(dof, ic.var_name)
all_dofs = reshape(1:length(dof), size(dof))
if ic.block_name !== nothing
conns = mesh.element_conns[ic.block_name]
nodes = sort(unique(conns))
elseif ic.nset_name !== nothing
nodes = mesh.nodeset_nodes[ic.nset_name]
elseif ic.sset_name !== nothing
nodes = mesh.sideset_nodes[ic.sset_name]
end

# gather dofs associated with nodes
dofs = all_dofs[dof_index, nodes]

# sort nodes and dofs for dirichlet bc
dof_perm = _unique_sort_perm(dofs)
dofs = dofs[dof_perm]
nodes = nodes[dof_perm]

vals = zeros(length(dofs))
new{typeof(dofs), typeof(vals)}(dofs, nodes, vals)
end
end

Expand Down
2 changes: 2 additions & 0 deletions src/bcs/BoundaryConditions.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const EntityName = Union{Nothing, String}

struct EntityNameNotProvidedError <: AbstractFECError
msg::String
end
Expand Down
10 changes: 4 additions & 6 deletions src/bcs/DirichletBCs.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
abstract type AbstractDirichletBC{F} <: AbstractBC{F} end

const EntityName = Union{Nothing, String}

"""
$(TYPEDEF)
$(TYPEDSIGNATURES)
$(TYPEDFIELDS)
User facing API to define a ```DirichletBC````.
User facing API to define a ```DirichletBC```.
"""
struct DirichletBC{F} <: AbstractDirichletBC{F}
func::F
Expand All @@ -22,9 +20,9 @@ struct DirichletBC{F} <: AbstractDirichletBC{F}
"""
function DirichletBC(
var_name::String, func::Function;
block_name::Union{Nothing, String} = nothing,
nodeset_name::Union{Nothing, String} = nothing,
sideset_name::Union{Nothing, String} = nothing
block_name::EntityName = nothing,
nodeset_name::EntityName = nothing,
sideset_name::EntityName = nothing
)
if block_name === nothing && nodeset_name === nothing && sideset_name === nothing
_entity_not_provided_error(
Expand Down
61 changes: 34 additions & 27 deletions test/TestAppTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,34 +73,41 @@ end
@test AT.get_cli_arg(parser, "--backend") == "cpu"
@test AT.get_cli_arg(parser, "--verbose") == "true"

# help message case long name
args = [
"--input-file", "input-file.toml",
"--log-file", "log.log",
"--backend", "cpu",
"--verbose",
"--help"
]
@test_throws AssertionError AT.parse!(parser, args)
# TODO
# currently the help cli arg exits the app cleanly
# so there isn't really a good way to test for
# it in an isolated parse! command
# we should probably rewrite parse to return
# a flag for whether or not to exit the program
#
# # help message case long name
# args = [
# "--input-file", "input-file.toml",
# "--log-file", "log.log",
# "--backend", "cpu",
# "--verbose",
# "--help"
# ]
# @test_throws AssertionError AT.parse!(parser, args)

# help message case short name
args = [
"--input-file", "input-file.toml",
"--log-file", "log.log",
"--backend", "cpu",
"--verbose",
"--h"
]
@test_throws AssertionError AT.parse!(parser, args)
# # help message case short name
# args = [
# "--input-file", "input-file.toml",
# "--log-file", "log.log",
# "--backend", "cpu",
# "--verbose",
# "--h"
# ]
# @test_throws AssertionError AT.parse!(parser, args)

# test missing option that is required
args = [
"--input-file", "input-file.toml",
"--log-file", "log.log",
"--verbose",
"--h"
]
@test_throws AssertionError AT.parse!(parser, args)
# # test missing option that is required
# args = [
# "--input-file", "input-file.toml",
# "--log-file", "log.log",
# "--verbose",
# "--h"
# ]
# @test_throws AssertionError AT.parse!(parser, args)
end

@testitem "AppTools - SimpleApp" begin
Expand All @@ -110,7 +117,7 @@ end
"--log-file", "log.log",
"--backend", "cpu"
]
app = AT.App("MyApp")
app = AT.App{1}("MyApp")
AT.add_cli_arg!(app, "--backend")
AT.parse!(app.cli_arg_parser, args)
arg = AT.get_cli_arg(app, "--backend")
Expand Down
38 changes: 34 additions & 4 deletions test/TestICs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
end

@testitem "ICs - test_ic_input" setup=[ICHelper] begin
ic = InitialCondition("my_var", dummy_ic_func_1, "my_block")
ic = InitialCondition("my_var", dummy_ic_func_1; block_name = "my_block")
@test ic.block_name == "my_block"
@test ic.nset_name === nothing
@test ic.sset_name === nothing
@test typeof(ic.func) == typeof(dummy_ic_func_1)
@test ic.var_name == "my_var"
end

@testitem "ICs - ic_container_init_and_update" setup=[ICHelper] begin
ic_in = InitialCondition("displ_x", dummy_ic_func_1, "block_1")
@testitem "ICs - ic_container_init_and_update - block" setup=[ICHelper] begin
ic_in = InitialCondition("displ_x", dummy_ic_func_1; block_name = "block_1")
ics = InitialConditions(mesh, dof, [ic_in])
@show ics
U = create_field(dof)
Expand All @@ -26,10 +28,38 @@ end
@test all(U[2, :] .== 0.)
end

@testitem "ICs - ic_container_init_and_update - nodeset" setup=[ICHelper] begin
nodes = mesh.nodeset_nodes["nset_1"]
ic_in = InitialCondition("displ_x", dummy_ic_func_1; nodeset_name = "nset_1")
ics = InitialConditions(mesh, dof, [ic_in])
@show ics
U = create_field(dof)
X = mesh.nodal_coords
FiniteElementContainers.update_ic_values!(ics, X)
@test all(values(ics.ic_caches)[1].vals .== 3.)
update_field_ics!(U, ics)
@test all(U[1, nodes] .== 3.)
@test all(U[2, nodes] .== 0.)
end

@testitem "ICs - ic_container_init_and_update - sideset" setup=[ICHelper] begin
nodes = mesh.sideset_nodes["sset_1"]
ic_in = InitialCondition("displ_x", dummy_ic_func_1; sideset_name = "sset_1")
ics = InitialConditions(mesh, dof, [ic_in])
@show ics
U = create_field(dof)
X = mesh.nodal_coords
FiniteElementContainers.update_ic_values!(ics, X)
@test all(values(ics.ic_caches)[1].vals .== 3.)
update_field_ics!(U, ics)
@test all(U[1, nodes] .== 3.)
@test all(U[2, nodes] .== 0.)
end

@testitem "ICs - ic_container_init_and_update_juliac_safe" setup=[ICHelper] begin
import FiniteElementContainers.Expressions: ScalarExpressionFunction
expr_func = ScalarExpressionFunction{Float64}("3.0", ["x", "y"])
ic_in = InitialCondition{ScalarExpressionFunction{Float64}}("displ_x", expr_func, "block_1")
ic_in = InitialCondition{ScalarExpressionFunction{Float64}}("displ_x", expr_func, "block_1", nothing, nothing)
ics = InitialConditions(mesh, dof, [ic_in])
@show ics
U = create_field(dof)
Expand Down
4 changes: 2 additions & 2 deletions test/input-file.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
backend = "cpu"

[functions.zero]
type = "constant"
type = "scalar expression"
expression = "0.0"
variables = ["x", "y"]

[functions.one]
type = "constant"
type = "scalar expression"
expression = "1.0"
variables = ["x", "y"]

Expand Down
Loading