Closed arturgower closed 6 years ago
Having the sources as a container of two functions is attractive, but what about this for a Julian solution: sources can contain two Expr
s instead of functions. Here's a quick draft
# MultipleScattering/src/source.jl
include("domain/particle.jl")
"Immutable struct"
struct Source
field_expr::Expr
coef_expr::Expr
end
import Base.(+)
function +(a::Source,b::Source)
Source(
parse(string(string(a.field_expr)," + ",string(b.field_expr))),
parse(string(string(a.coef_expr)," + ",string(b.coef_expr))),
)
end
"Helper function to return a plane wave source"
function planar_wave_source{T}(magnitude::Complex{T},direction::Vector{T})
# Have to use string interpolation
Source(
:(($(magnitude))*exp(k*(x[1]*$(direction[1])+ x[2]*$(direction[2])))),
:([1.0+0.0im]),
)
end
"Safe access function for getting values of function from Source. DOESN'T WORK"
function get_source_field{T}(source::Source,x::Vector{T},k::T)::Complex{T}
return eval(source.field_expr)
end
"Safe access function for getting coefficients from Source. DOESN'T WORK"
function get_coefs{T}(source::Source,p::Particle{T},k::T)::Vector{Complex{T}}
return eval(source.coef_expr)
end
The basics work really well in global scope (try adding two planar waves!).
include("src/source.jl")
pw = planar_wave_source(1.0+0.0im,[1.0,0.0])
pw2 = planar_wave_source(1.0+0.0im,[0.0,1.0])
sum_pw = pw + pw2
x= [1.0,1.0]
k=10.0
eval(sum_pw.field_expr)
But unfortunately eval only works in the global scope. Is there a solution somewhere here? Could we just use expressions when saving the FrequencySimulation
?
In the experimental branch there is generic type
type Source{P<:PhysicalProperties,T<:AbstractFloat}
field::Function
coef::Function
end
which although crude is very simple and allows us to naturally take linear combinations of different source types.
This however means it is hard to save such objects. Instead of trying to develop complicated and brittle solutions like using Expr
s, I would suggest that if you want to save a simulation, just save the script you used to generate it. This will of course be much more practical now that we have a separate SimulationResult
type.
Clearly having the option to use a point source (or collection of point sources) or an incident plane wave, will greatly increase the usefulness of this library. So we need a type for all Incident waves.
The essential data for this type is a scattering function (x,y) -> scattering coefficients, i.e. given any point returns the scattering coefficients of a Bessel J expansion. One major issue is that we are not allowed to save functions. So we can not have this scattering function as a field of, say, FrequencySimulation. This is why I removed the impulse function and replaced with an impulse vector for the Fourier transforms. One possible solution is to allow for only plane waves or sum of point sources, then by recording which one was used, we can then recreate scattering function.