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
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ MetisExt = "Metis"
PartitionedArraysExt = "PartitionedArrays"

[compat]
AMDGPU = "2"
AbaqusReader = "0.2.7"
AcceleratedKernels = "0.4"
Adapt = "4"
AMDGPU = "2"
Atomix = "1"
BlockArrays = "1"
CUDA = "5, 6"
Expand All @@ -53,6 +53,7 @@ Exodus = "0.14"
ForwardDiff = "1"
GPUArrays = "11"
Gmsh = "0.3"
JuliaC = "0.3"
KernelAbstractions = "0.9"
Krylov = "0.10"
LinearAlgebra = "1"
Expand All @@ -72,9 +73,10 @@ julia = "1"

[extras]
Gmsh = "705231aa-382f-11e9-3f0c-b7cb4346fdeb"
JuliaC = "acedd4c2-ced6-4a15-accc-2607eb759ba2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe"

[targets]
test = ["Gmsh", "Test", "TestItemRunner", "TestItems"]
test = ["Gmsh", "JuliaC", "Test", "TestItemRunner", "TestItems"]
33 changes: 32 additions & 1 deletion src/AppTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ trim mode for small binaries
"""
module AppTools

export App

import ..DirichletBC
import ..Expressions.ExpressionFunction
import ..ExodusMesh
Expand Down Expand Up @@ -622,11 +624,15 @@ end
#########################################################################
# tools to create new projects
#########################################################################
function build_app(; path::String = pwd())
run(`julia --project=$path $(joinpath(path, "build.jl"))`)
end

function generate_app(
name::String;
backends::Vector{String} = ["cpu"],
directory::String = pwd(),
trim::Bool = false
trim::Bool = true
)
path = joinpath(directory, name)
@info "Creating new FiniteElementContainers app at $path"
Expand Down Expand Up @@ -686,9 +692,20 @@ function generate_app(
# create basic src file
open(joinpath(path, "src", "$(name).jl"), "w") do io
src = """
import FiniteElementContainers as FEC
import FiniteElementContainers.AppTools as AT
using Exodus
using FiniteElementContainers

function app_main(ARGS::Vector{String})
app = AT.App(\"$(name)\")
AT.add_cli_arg(app, \"--backend\"; default = \"cpu\")
sim = AT.setup(app, ARGS)
println(sim.log_file.io, "Setup complete")
end

function @main(ARGS::Vector{String})
app_main(ARGS)
return 0
end
"""
Expand Down Expand Up @@ -736,4 +753,18 @@ function generate_app(
end
end

function run_app(
args::Vector{String};
exe_name::Union{Nothing, String} = nothing,
path::String = pwd()
)
# first figure out exe name
if exe_name === nothing
data = TOML.parsefile(joinpath(path, "Project.toml"))
exe_name = lowercase(data["name"])
end
run_cmds = pushfirst!(args, joinpath(path, "build", "bin", exe_name))
run(Cmd(run_cmds))
end

end # module AppTools
5 changes: 3 additions & 2 deletions src/Parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ struct Parameters{
RT <: Number,
IV <: AbstractVector{<:Integer},
RV <: AbstractVector{RT},
RM <: AbstractMatrix,
ICFuncs <: AbstractVector,
DBCFuncs <: AbstractVector,
SrcFuncs <: AbstractVector,
NBCs,
RBCs,
SRCs,
Phys,
Props,
Coords <: AbstractField,
Expand All @@ -28,7 +29,7 @@ struct Parameters{
dirichlet_bcs::DirichletBCs{DBCFuncs, IV, RV}
neumann_bcs::NBCs
robin_bcs::RBCs
sources::SRCs
sources::Sources{SrcFuncs, RM}
times::TimeStepper{RT}
physics::Phys
properties::Props
Expand Down
9 changes: 0 additions & 9 deletions src/bcs/NeumannBCs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@ struct NeumannBC{F} <: AbstractBC{F}
end
end

# """
# $(TYPEDEF)
# $(TYPEDSIGNATURES)
# $(TYPEDFIELDS)
# """
# function NeumannBC(var_name::String, func::Function, sset_name::String)
# return NeumannBC(Symbol(var_name), func, Symbol(sset_name))
# end

"""
$(TYPEDEF)
$(TYPEDSIGNATURES)
Expand Down
126 changes: 72 additions & 54 deletions src/bcs/Sources.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@ volume quadrature points for one block.
and have assemblers just ping the correct block
"""
struct SourceContainer{
RV <: AbstractArray{<:Union{<:Number, <:SVector}, 2}
RM <: AbstractArray{<:Union{<:Number, <:SVector}, 2}
}
vals::RV # size (NQ_cell, nelem) of SVector{ND}
vals::RM # size (NQ_cell, nelem) of SVector{ND}
is_constant::Bool # skip re-evaluation after first call
initialized::Base.RefValue{Bool}

function SourceContainer(vals::RM, is_constant, initialized) where RM
new{RM}(vals, is_constant, initialized)
end
end

_vals_type(::Vector{SourceContainer{RM}}) where RM = RM

function Adapt.adapt_structure(to, source::SourceContainer)
SourceContainer(
adapt(to, source.vals),
Expand All @@ -61,81 +67,89 @@ function _update_source_values!(vals, func, ref_fe, conns, coffset, X, t)
end
end

struct SourceFunction{F} <: AbstractBCFunction{F}
func::F
end

function (f::SourceFunction)(x, t)
return f.func(x, t)
end

"""
$(TYPEDEF)
$(TYPEDSIGNATURES)
$(TYPEDFIELDS)
Collection of body force containers, one per specified body force entry.
"""
struct Sources{
RV <: AbstractArray{<:Union{<:Number, <:SVector}, 2},
SourceFuncs <: NamedTuple
SourceFuncs,
RM <: AbstractArray{<:Union{<:Number, <:SVector}, 2},
} <: AbstractBCs{SourceFuncs}
source_block_ids::Vector{Int} # note this is the id order in FEC not the id in exodus
source_block_names::Vector{String}
source_caches::Vector{SourceContainer{RV}}
source_caches::Vector{SourceContainer{RM}}
source_funcs::SourceFuncs
end

function Sources(mesh, dof::DofManager, sources::Vector{Source})
if length(sources) == 0
return Sources(Int[], String[], SourceContainer{Matrix{Float64}}[], NamedTuple())
function Sources{SourceFuncs, RM}(
source_block_ids, source_block_names, source_caches, source_funcs
) where {SourceFuncs, RM}
new{SourceFuncs, RM}(source_block_ids, source_block_names, source_caches, source_funcs)
end

fspace = function_space(dof)
ND = length(dof.var)
caches = []
funcs = Function[]
source_block_ids = Int[]
source_block_names = String[]
for source in sources
block_name = source.block_name
# block_id = indexin([block_name], collect(keys(fspace.ref_fes)))
# @assert length(block_id) == 1
# block_id = block_id[1]
block_id = findfirst(x -> x == block_name, mesh.element_block_names)
push!(source_block_ids, block_id)
push!(source_block_names, block_name)
NQ, NE = block_quadrature_size(fspace, block_id)
# conns = Connectivity([conns_full])
# if ND == 1
# vals = zeros(Float64, NQ, nelem)
# else
vals = zeros(SVector{ND, Float64}, NQ, NE)
# end

# Detect constant: the is_constant flag is set by the caller (Carina)
# via the Source struct. For now, default to false (re-evaluate every step).
is_constant = false

# push!(caches, SourceContainer(conns, ref_fe, vals, is_constant, Ref(false)))
push!(caches, SourceContainer(vals, is_constant, Ref(false)))
push!(funcs, source.func)
end
# TODO should we really allow for scalar funcs for this in the case of scalar variables?
function Sources(mesh, dof::DofManager, sources::Vector{Source}, ::Type{RT} = Float64) where RT <: Number
ND = size(dof, 1)
caches = SourceContainer{Matrix{SVector{ND, RT}}}[]
funcs = SourceFunction[]
if length(sources) == 0
return Sources{typeof(funcs), Matrix{SVector{ND, RT}}}(Int[], String[], SourceContainer{Matrix{RT}}[], funcs)
end

# what happens if they're not all the same type?
caches = convert(Vector{typeof(caches[1])}, caches)
fspace = function_space(dof)
ND = length(dof.var)
source_block_ids = Int[]
source_block_names = String[]
for source in sources
block_name = source.block_name
block_id = findfirst(x -> x == block_name, mesh.element_block_names)
push!(source_block_ids, block_id)
push!(source_block_names, block_name)
NQ, NE = block_quadrature_size(fspace, block_id)
# conns = Connectivity([conns_full])
# if ND == 1
# vals = zeros(Float64, NQ, nelem)
# else
vals = zeros(SVector{ND, Float64}, NQ, NE)
# end

# Detect constant: the is_constant flag is set by the caller (Carina)
# via the Source struct. For now, default to false (re-evaluate every step).
is_constant = false

push!(caches, SourceContainer(vals, is_constant, Ref(false)))
push!(funcs, SourceFunction(source.func))
end

syms = tuple(map(x -> Symbol("source_$x"), 1:length(caches))...)
return Sources(
source_block_ids, source_block_names, caches,
NamedTuple{syms}(tuple(funcs...)),
)
# return Sources(source_block_ids, source_block_names, caches, funcs)
return Sources{typeof(funcs), Matrix{SVector{ND, RT}}}(
source_block_ids, source_block_names, caches, funcs
)
end
end

function Adapt.adapt(to, sources::Sources)
function Adapt.adapt(to, sources::Sources{SourceFuncs, RM}) where {SourceFuncs, RM}
# needed due to failures on 1.10 and 1.11
if length(sources.source_caches) == 0
caches = Vector{SourceContainer{Matrix{Float64}}}(undef, 0)
else
caches = map(x -> adapt(to, x), sources.source_caches)
end

return Sources(
return Sources{SourceFuncs, _vals_type(caches)}(
sources.source_block_ids,
sources.source_block_names,
caches,
adapt(to, sources.source_funcs)
sources.source_funcs
)
end

Expand All @@ -151,15 +165,19 @@ end

function update_source_values!(sources::Sources, assembler, X, t)
fspace = function_space(assembler)
for (block_id, source, func) in zip(sources.source_block_ids, sources.source_caches, sources.source_funcs)
if source.is_constant && source.initialized[]
for n in axes(sources.source_block_ids, 1)
block_id = sources.source_block_ids[n]
cache = sources.source_caches[n]
if cache.is_constant && cache.initialized[]
continue
end
ref_fe = fspace.ref_fes[block_id]

func = sources.source_funcs[n]
ref_fe = block_reference_element(fspace, block_id)
conns_data = fspace.elem_conns.data
coffset = fspace.elem_conns.offsets[block_id]
_update_source_values!(source.vals, func, ref_fe, conns_data, coffset, X, t)
source.initialized[] = true
_update_source_values!(cache.vals, func, ref_fe, conns_data, coffset, X, t)
cache.initialized[] = true
end
return nothing
end
7 changes: 6 additions & 1 deletion test/TestAppTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,19 @@ end
# sim = AT.setup(app, args)
end

@testitem "AppTools - generate app" begin
@testitem "AppTools - generate/build/run app" begin
import FiniteElementContainers.AppTools as AT
if isdir("MyApp/")
rm("MyApp/"; force = true, recursive = true)
end
AT.generate_app("MyApp")
@test isdir("MyApp")
@test isfile("MyApp/build.jl")
@test isfile("MyApp/Project.toml")
@test isdir("MyApp/src")
@test isfile("MyApp/src/MyApp.jl")
# TODO re-enable after future release
# AT.build_app(; path = "MyApp")
rm("MyApp"; force = true, recursive = true)

mkdir("app_dir")
Expand Down
Loading