Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add solver dependent storage macro #184

Merged
merged 3 commits into from
Oct 19, 2024
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
1 change: 1 addition & 0 deletions src/core/parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ end
function macrocheck_input_material(material)
material isa Symbol && return nothing
(material isa Expr && material.head === :.) && return nothing
(material isa Expr && material.head === :escape) && return nothing
return throw(ArgumentError("argument `$material` is not a valid material input!\n"))
end

Expand Down
40 changes: 24 additions & 16 deletions src/core/storages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,17 @@
macro storage(material, storage)
macrocheck_input_material(material)
macrocheck_input_storage_struct(storage)
return __storage(material, storage)
end

macro storage(material, solver, storage)
macrocheck_input_material(material)
macrocheck_input_timesolver(solver)
macrocheck_input_storage_struct(storage)
return __storage(material, storage, solver)
end

function __storage(material, storage, timesolver=AbstractTimeSolver)
local _storage_struct_data = get_storage_structdef(storage)
local _storage_struct = _storage_struct_data.storage_struct
local _storage_type = _storage_struct_data.storage_type
Expand All @@ -35,9 +45,8 @@
local _halo_field_names = (_htl_field_names..., _lth_field_names...)

local _constructor = quote
function $(esc(_storage_type))(mat::$(esc(material)),
solver::Peridynamics.AbstractTimeSolver,
system::Peridynamics.AbstractSystem)
function $(esc(_storage_type))(mat::$(esc(material)), solver::$(esc(timesolver)),
system::Peridynamics.AbstractSystem)
fields = Base.fieldnames($(esc(_storage_type)))
args = (Peridynamics.init_field(mat, solver, system, Val(field))
for field in fields)
Expand All @@ -52,8 +61,7 @@
end

local _get_storage = quote
function Peridynamics.get_storage(mat::$(esc(material)),
solver::Peridynamics.AbstractTimeSolver,
function Peridynamics.get_storage(mat::$(esc(material)), solver::$(esc(timesolver)),
system::Peridynamics.AbstractSystem)
return $(esc(_storage_type))(mat, solver, system)
end
Expand Down Expand Up @@ -245,24 +253,24 @@
function macrocheck_input_storage_type(storage)
storage isa Symbol && return nothing
(storage isa Expr && storage.head === :.) && return nothing
(storage isa Expr && storage.head === :escape) && return nothing

Check warning on line 256 in src/core/storages.jl

View check run for this annotation

Codecov / codecov/patch

src/core/storages.jl#L256

Added line #L256 was not covered by tests
msg = "argument `$storage` is not a valid storage input!\n"
return throw(ArgumentError(msg))
end

function macrocheck_input_storage_struct(storage)
if !(storage isa Expr && storage.head === :struct)
msg = "specified input is not a valid point parameter struct expression!\n"
throw(ArgumentError(msg))
end
return nothing
(storage isa Expr && storage.head === :struct) && return nothing
(storage isa Expr && storage.head === :escape) && return nothing
msg = "specified input is not a valid point parameter struct expression!\n"
return throw(ArgumentError(msg))

Check warning on line 265 in src/core/storages.jl

View check run for this annotation

Codecov / codecov/patch

src/core/storages.jl#L263-L265

Added lines #L263 - L265 were not covered by tests
end

# function macrocheck_input_timesolver(timesolver)
# timesolver isa Symbol && return nothing
# (timesolver isa Expr && timesolver.head === :.) && return nothing
# msg = "argument `$timesolver` is not a valid time solver input!\n"
# return throw(ArgumentError(msg))
# end
function macrocheck_input_timesolver(timesolver)
timesolver isa Symbol && return nothing
(timesolver isa Expr && timesolver.head === :.) && return nothing
msg = "argument `$timesolver` is not a valid time solver input!\n"
return throw(ArgumentError(msg))

Check warning on line 272 in src/core/storages.jl

View check run for this annotation

Codecov / codecov/patch

src/core/storages.jl#L270-L272

Added lines #L270 - L272 were not covered by tests
end

function macrocheck_input_fields(fields...)
for field in fields
Expand Down
55 changes: 43 additions & 12 deletions test/integration/material_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ end
end

@testitem "Storage declaration" begin
import Peridynamics: AbstractBondSystemMaterial, NoCorrection,
AbstractInteractionSystemMaterial, InterfaceError
import Peridynamics: @storage, AbstractBondSystemMaterial, NoCorrection,
AbstractInteractionSystemMaterial, InterfaceError,
AbstractTimeSolver, AbstractSystem

struct Mat1 <: AbstractBondSystemMaterial{NoCorrection} end
struct Mat2 <: AbstractInteractionSystemMaterial end
Expand All @@ -104,7 +105,7 @@ end
struct StorageWrong1 <: Peridynamics.AbstractStorage end
@test_throws InterfaceError Peridynamics.point_data_fields(StorageWrong1)

@test_throws ErrorException Peridynamics.@storage Mat1 struct StorageMissing1
@test_throws ErrorException @storage Mat1 struct StorageMissing1
@lthfield position::Matrix{Float64}
# @pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -120,7 +121,7 @@ end
@pointfield n_active_bonds::Vector{Int}
end

@test_throws ErrorException Peridynamics.@storage Mat1 struct StorageMissing2
@test_throws ErrorException @storage Mat1 struct StorageMissing2
@lthfield position::Matrix{Float64}
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -136,7 +137,7 @@ end
# @pointfield n_active_bonds::Vector{Int}
end

@test_throws ErrorException Peridynamics.@storage Mat2 struct StorageMissing3
@test_throws ErrorException @storage Mat2 struct StorageMissing3
@lthfield position::Matrix{Float64}
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -154,7 +155,7 @@ end

try
eval(quote
Peridynamics.@storage Mat1 struct StorageUntyped1
@storage Mat1 struct StorageUntyped1
@lthfield position
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -178,7 +179,7 @@ end

try
eval(quote
Peridynamics.@storage Mat1 struct StorageUntyped1
@storage Mat1 struct StorageUntyped1
@lthfield position
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -202,7 +203,7 @@ end

try
eval(quote
Peridynamics.@storage Mat1 struct StorageUntyped1
@storage Mat1 struct StorageUntyped1
@lthfield position
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -226,7 +227,7 @@ end

try
eval(quote
Peridynamics.@storage Mat1 struct StorageUntyped1
@storage Mat1 struct StorageUntyped1
@lthfield position
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -248,7 +249,7 @@ end
@test isa(e, LoadError)
end

Peridynamics.@storage Mat1 struct Storage1 <: Peridynamics.AbstractStorage
@storage Mat1 VelocityVerlet struct Storage1 <: Peridynamics.AbstractStorage
@lthfield position::Matrix{Float64}
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
Expand All @@ -266,17 +267,47 @@ end
end

@test hasmethod(Peridynamics.storage_type, Tuple{Mat1})
@test hasmethod(Storage1, Tuple{Mat1,VelocityVerlet,Peridynamics.AbstractSystem})
mat, vv = Mat1(), VelocityVerlet(steps=1)
@test Peridynamics.storage_type(mat) == Storage1

@test hasmethod(Peridynamics.loc_to_halo_fields, Tuple{Storage1})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage1,Val{:position}})
@test hasmethod(Peridynamics.is_halo_field,
Tuple{Storage1,Val{:displacement}})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage1,Val{:displacement}})

@test hasmethod(Peridynamics.halo_to_loc_fields, Tuple{Storage1})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage1,Val{:b_int}})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage1,Val{:b_ext}})

@storage Mat1 struct Storage2 <: Peridynamics.AbstractStorage
@lthfield position::Matrix{Float64}
@pointfield displacement::Matrix{Float64}
@pointfield velocity::Matrix{Float64}
@pointfield velocity_half::Matrix{Float64}
@pointfield velocity_half_old::Matrix{Float64}
@pointfield acceleration::Matrix{Float64}
@pointfield b_int::Matrix{Float64}
@pointfield b_int_old::Matrix{Float64}
@pointfield b_ext::Matrix{Float64}
@pointfield density_matrix::Matrix{Float64}
@pointfield damage::Vector{Float64}
bond_active::Vector{Bool}
@pointfield n_active_bonds::Vector{Int}
@pointfield mycustomfield::Vector{Float64}
end

@test hasmethod(Peridynamics.storage_type, Tuple{Mat1})
@test hasmethod(Storage2, Tuple{Mat1,AbstractTimeSolver,AbstractSystem})
mat, vv = Mat1(), VelocityVerlet(steps=1)
@test Peridynamics.storage_type(mat) == Storage2

@test hasmethod(Peridynamics.loc_to_halo_fields, Tuple{Storage2})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage2,Val{:position}})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage2,Val{:displacement}})

@test hasmethod(Peridynamics.halo_to_loc_fields, Tuple{Storage2})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage2,Val{:b_int}})
@test hasmethod(Peridynamics.is_halo_field, Tuple{Storage2,Val{:b_ext}})
end

@testitem "Custom Materials" begin
Expand Down
Loading