diff --git a/Project.toml b/Project.toml index a6fa8a00..88aab294 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "IndividualDisplacements" uuid = "b92f0c32-5b7e-11e9-1d7b-238b2da8b0e6" authors = ["gaelforget "] -version = "0.4.8" +version = "0.5.0" [deps] Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/examples/worldwide/ECCO_FlowFields.jl b/examples/worldwide/ECCO_FlowFields.jl index 7dc15b74..ce4762b8 100644 --- a/examples/worldwide/ECCO_FlowFields.jl +++ b/examples/worldwide/ECCO_FlowFields.jl @@ -90,7 +90,7 @@ function setup_FlowFields(k::Int,Ξ“::NamedTuple,func::Function,pth::String) end """ - update_FlowFields!(𝑃::F_MeshArray2D,D::NamedTuple,t::Float64) + update_FlowFields!(𝑃::uvMeshArrays,D::NamedTuple,t::Float64) Update flow field arrays (in 𝑃), 𝑃.T, and ancillary variables (in D) according to the chosen time `t` (in `seconds`). @@ -99,7 +99,7 @@ _Note: for now, it is assumed that (1) the time interval `dt` between consecutive records is diff(𝑃.T), (2) monthly climatologies are used with a periodicity of 12 months, (3) vertical 𝑃.k is selected_ """ -function update_FlowFields!(𝑃::F_MeshArray2D,D::NamedTuple,t::AbstractFloat) +function update_FlowFields!(𝑃::uvMeshArrays,D::NamedTuple,t::AbstractFloat) dt=𝑃.T[2]-𝑃.T[1] m0=Int(floor((t+dt/2.0)/dt)) @@ -133,7 +133,7 @@ function update_FlowFields!(𝑃::F_MeshArray2D,D::NamedTuple,t::AbstractFloat) end """ - update_FlowFields!(𝑃::F_MeshArray3D,D::NamedTuple,t::Float64) + update_FlowFields!(𝑃::uvwMeshArrays,D::NamedTuple,t::Float64) Update flow field arrays (in 𝑃), 𝑃.T, and ancillary variables (in D) according to the chosen time `t` (in `seconds`). @@ -142,7 +142,7 @@ _Note: for now, it is assumed that (1) the time interval `dt` between consecutive records is diff(𝑃.T), (2) monthly climatologies are used with a periodicity of 12 months, (3) vertical 𝑃.k is selected_ """ -function update_FlowFields!(𝑃::F_MeshArray3D,D::NamedTuple,t::Float64) +function update_FlowFields!(𝑃::uvwMeshArrays,D::NamedTuple,t::Float64) dt=𝑃.T[2]-𝑃.T[1] m0=Int(floor((t+dt/2.0)/dt)) diff --git a/examples/worldwide/OCCA_FlowFields.jl b/examples/worldwide/OCCA_FlowFields.jl index 3bd38d49..d8413ebe 100644 --- a/examples/worldwide/OCCA_FlowFields.jl +++ b/examples/worldwide/OCCA_FlowFields.jl @@ -125,7 +125,7 @@ customπŸ”΄ = DataFrame(ID=Int[], fid=Int[], x=Float64[], y=Float64[], lon=Float64[], lat=Float64[], dlon=Float64[], dlat=Float64[], year=Float64[], col=Symbol[]) -function customπŸ”§(sol,𝑃::F_MeshArray3D,D::NamedTuple;id=missing,T=missing) +function customπŸ”§(sol,𝑃::uvwMeshArrays,D::NamedTuple;id=missing,T=missing) df=postprocess_MeshArray(sol,𝑃,D,id=id,T=T) add_lonlat!(df,D.XC,D.YC) df.dlon=0*df.lon diff --git a/src/API.jl b/src/API.jl index 13d2dd9b..c8a705e0 100644 --- a/src/API.jl +++ b/src/API.jl @@ -16,10 +16,10 @@ Also by convention, velocity fields are expected to have been normalized to grid before sending them to one of the supported `FlowFields` constructors (using either `Array` or `MeshArray`): ``` -F_Array2D(u0,u1,v0,v1,T) -F_Array3D(u0,u1,v0,v1,w0,w1,T) -F_MeshArray2D(u0,u1,v0,v1,T,update_location!) -F_MeshArray3D(u0,u1,v0,v1,w0,w1,T,update_location!) +uvArrays(u0,u1,v0,v1,T) +uvwArrays(u0,u1,v0,v1,w0,w1,T) +uvMeshArrays(u0,u1,v0,v1,T,update_location!) +uvwMeshArrays(u0,u1,v0,v1,w0,w1,T,update_location!) ``` Using the `FlowFields` constructor which gets selected by the type of `u0` etc. For example : @@ -34,7 +34,7 @@ as shown in the online documentation examples. """ abstract type FlowFields end -struct F_Array2D{Ty} <: FlowFields +struct uvArrays{Ty} <: FlowFields u0::Array{Ty,2} u1::Array{Ty,2} v0::Array{Ty,2} @@ -50,10 +50,10 @@ function FlowFields(u0::Array{Ty,2},u1::Array{Ty,2}, tst=prod([(size(u0)==size(tmp)) for tmp in (u1,v0,v1)]) !tst ? error("inconsistent array sizes") : nothing #call constructor - F_Array2D(u0,u1,v0,v1,T) + uvArrays(u0,u1,v0,v1,T) end -struct F_Array3D{Ty} <: FlowFields +struct uvwArrays{Ty} <: FlowFields u0::Array{Ty,3} u1::Array{Ty,3} v0::Array{Ty,3} @@ -127,10 +127,10 @@ function FlowFields(u0::Array{Ty,3},u1::Array{Ty,3},v0::Array{Ty,3},v1::Array{Ty tst=tst*prod([(size(u0)==size(tmp).-(0,0,1)) for tmp in (w0,w1)]) !tst ? error("inconsistent array sizes") : nothing #call constructor - F_Array3D(u0,u1,v0,v1,w0,w1,T) + uvwArrays(u0,u1,v0,v1,w0,w1,T) end -struct F_MeshArray2D{Ty} <: FlowFields +struct uvMeshArrays{Ty} <: FlowFields u0::AbstractMeshArray{Ty,1} u1::AbstractMeshArray{Ty,1} v0::AbstractMeshArray{Ty,1} @@ -148,10 +148,10 @@ function FlowFields(u0::AbstractMeshArray{Ty,1},u1::AbstractMeshArray{Ty,1}, tst=prod([(size(u0)==size(tmp))*(u0.fSize==tmp.fSize) for tmp in (u1,v0,v1)]) !tst ? error("inconsistent array sizes") : nothing #call constructor - F_MeshArray2D(u0,u1,v0,v1,T,update_location!) + uvMeshArrays(u0,u1,v0,v1,T,update_location!) end -struct F_MeshArray3D{Ty} <: FlowFields +struct uvwMeshArrays{Ty} <: FlowFields u0::AbstractMeshArray{Ty,2} u1::AbstractMeshArray{Ty,2} v0::AbstractMeshArray{Ty,2} @@ -173,7 +173,7 @@ function FlowFields(u0::AbstractMeshArray{Ty,2},u1::AbstractMeshArray{Ty,2}, tst=tst*prod([(size(u0)==size(tmp).-(0,1))*(u0.fSize==tmp.fSize) for tmp in (w0,w1)]) !tst ? error("inconsistent array sizes") : nothing #call constructor - F_MeshArray3D(u0,u1,v0,v1,w0,w1,T,update_location!) + uvwMeshArrays(u0,u1,v0,v1,w0,w1,T,update_location!) end """ @@ -191,7 +191,7 @@ function ensemble_solver(prob;solver=Tsit5(),reltol=1e-8,abstol=1e-8,safetycopy= end a=fill(0.0,1,1) -default_flowfields = F_Array2D{Float64}(a,a,a,a,[0. 1.]) +default_flowfields = uvArrays{Float64}(a,a,a,a,[0. 1.]) default_recorder = DataFrame(ID=Int[], x=Float64[], y=Float64[], t=Float64[]) default_postproc = (x->x) @@ -216,10 +216,10 @@ Unicode cheatsheet: Simple constructors that use `FlowFields` to choose adequate defaults: -- Individuals(F::F_Array2D,x,y) -- Individuals(F::F_Array3D,x,y,z) -- Individuals(F::F_MeshArray2D,x,y,fid) -- Individuals(F::F_MeshArray3D,x,y,z,fid) +- Individuals(F::uvArrays,x,y) +- Individuals(F::uvwArrays,x,y,z) +- Individuals(F::uvMeshArrays,x,y,fid) +- Individuals(F::uvwMeshArrays,x,y,z,fid) Further customization is achievable via keyword constructors: @@ -266,7 +266,7 @@ function Individuals(NT::NamedTuple) Individuals{T,ndims(πŸ“Œ)}(πŸ“Œ=πŸ“Œ,πŸ”΄=πŸ”΄,πŸ†”=πŸ†”,πŸš„=πŸš„,∫=∫,πŸ”§=πŸ”§,P=P,D=D,M=M) end -function Individuals(F::F_Array2D,x,y, NT::NamedTuple = NamedTuple()) +function Individuals(F::uvArrays,x,y, NT::NamedTuple = NamedTuple()) πŸ“Œ=permutedims([[x[i];y[i]] for i in eachindex(x)]) if length(πŸ“Œ)==1 πŸ“Œ=πŸ“Œ[1] @@ -293,7 +293,7 @@ function Individuals(F::F_Array2D,x,y, NT::NamedTuple = NamedTuple()) Individuals{T,ndims(πŸ“Œ)}(P=F,πŸ“Œ=πŸ“Œ,πŸ”΄=πŸ”΄,πŸ†”=πŸ†”,πŸš„=dxdt!,∫=∫,πŸ”§=πŸ”§,D=D) end -function Individuals(F::F_Array3D,x,y,z, NT::NamedTuple = NamedTuple()) +function Individuals(F::uvwArrays,x,y,z, NT::NamedTuple = NamedTuple()) πŸ“Œ=permutedims([[x[i];y[i];z[i]] for i in eachindex(x)]) if length(πŸ“Œ)==1 πŸ“Œ=πŸ“Œ[1] @@ -306,7 +306,7 @@ function Individuals(F::F_Array3D,x,y,z, NT::NamedTuple = NamedTuple()) πŸ”΄ = DataFrame(ID=Int[], x=Float64[], y=Float64[], z=Float64[], t=Float64[]) haskey(NT,:πŸ”΄) ? πŸ”΄=NT.πŸ”΄ : nothing - function πŸ”§(sol,F::F_Array3D,D::NamedTuple;id=missing,T=missing) + function πŸ”§(sol,F::uvwArrays,D::NamedTuple;id=missing,T=missing) df=postprocess_xy(sol,F,D,id=id,T=T) if isa(sol,EnsembleSolution) np=length(sol) @@ -330,7 +330,7 @@ function Individuals(F::F_Array3D,x,y,z, NT::NamedTuple = NamedTuple()) Individuals{T,ndims(πŸ“Œ)}(P=F,πŸ“Œ=πŸ“Œ,πŸ”΄=πŸ”΄,πŸ†”=πŸ†”,πŸš„=dxdt!,∫=∫,πŸ”§=πŸ”§,D=D) end -function Individuals(F::F_MeshArray2D,x,y,fid, NT::NamedTuple = NamedTuple()) +function Individuals(F::uvMeshArrays,x,y,fid, NT::NamedTuple = NamedTuple()) πŸ“Œ=permutedims([[x[i];y[i];fid[i]] for i in eachindex(x)]) if length(πŸ“Œ)==1 πŸ“Œ=πŸ“Œ[1] @@ -357,7 +357,7 @@ function Individuals(F::F_MeshArray2D,x,y,fid, NT::NamedTuple = NamedTuple()) Individuals{T,ndims(πŸ“Œ)}(P=F,πŸ“Œ=πŸ“Œ,πŸ”΄=πŸ”΄,πŸ†”=πŸ†”,πŸš„=dxdt!,∫=∫,πŸ”§=πŸ”§,D=D) end -function Individuals(F::F_MeshArray3D,x,y,z,fid, NT::NamedTuple = NamedTuple()) +function Individuals(F::uvwMeshArrays,x,y,z,fid, NT::NamedTuple = NamedTuple()) πŸ“Œ=permutedims([[x[i];y[i];z[i];fid[i]] for i in eachindex(x)]) if length(πŸ“Œ)==1 πŸ“Œ=πŸ“Œ[1] @@ -370,7 +370,7 @@ function Individuals(F::F_MeshArray3D,x,y,z,fid, NT::NamedTuple = NamedTuple()) πŸ”΄ = DataFrame(ID=Int[], x=Float64[], y=Float64[], z=Float64[], fid=Int64[], t=Float64[]) haskey(NT,:πŸ”΄) ? πŸ”΄=NT.πŸ”΄ : nothing - function πŸ”§(sol,F::F_MeshArray3D,D::NamedTuple;id=missing,T=missing) + function πŸ”§(sol,F::uvwMeshArrays,D::NamedTuple;id=missing,T=missing) df=postprocess_MeshArray(sol,F,D,id=id,T=T) if isa(sol,EnsembleSolution) np=length(sol) @@ -417,7 +417,7 @@ function ∫!(I::Individuals,T::Tuple) if isa(sol,EnsembleSolution) np=length(sol) πŸ“Œ[:] = deepcopy([sol[i].u[end] for i in 1:np]) - if isa(P,F_MeshArray3D)||isa(P,F_MeshArray2D) + if isa(P,uvwMeshArrays)||isa(P,uvMeshArrays) [update_location!(i,P) for i in I.πŸ“Œ] end else diff --git a/src/IndividualDisplacements.jl b/src/IndividualDisplacements.jl index 6dfbd36c..a843b438 100644 --- a/src/IndividualDisplacements.jl +++ b/src/IndividualDisplacements.jl @@ -15,7 +15,7 @@ DataFrames.DataFrame(I::Individuals) = I.πŸ”΄ export Individuals, ∫!, solve!, DataFrame, groupby export FlowFields, convert_to_FlowFields -export F_Array3D, F_Array2D, F_MeshArray3D, F_MeshArray2D +export uvwArrays, uvArrays, uvwMeshArrays, uvMeshArrays export dxdt!, dxy_dt_CyclicArray, dxy_dt_replay export postprocess_MeshArray, add_lonlat!, postprocess_xy, interp_to_xy export nearest_to_xy, randn_lonlat, interp_to_lonlat diff --git a/src/compute.jl b/src/compute.jl index b665d3eb..a2db134b 100644 --- a/src/compute.jl +++ b/src/compute.jl @@ -12,7 +12,7 @@ fview(f::Array{Array{Float32,2},2},i::Int,j::Int) = view(f[i,j],:,:) fview(f::Array{Array{Float64,2},2},i::Int,j::Int) = view(f[i,j],:,:) """ - dxdt!(du,u,p::F_MeshArray3D,tim) + dxdt!(du,u,p::uvwMeshArrays,tim) Interpolate velocity from gridded fields (3D; with halos) to position `u` (`x,y,z,fIndex`) to compute the derivative of position v time `du_dt`. @@ -34,7 +34,7 @@ prod(isapprox.(I.πŸ“Œ,ref,atol=1.0)) # hide true ``` """ -function dxdt!(du::Array{T,1},u::Array{T,1},P::F_MeshArray3D,tim) where T +function dxdt!(du::Array{T,1},u::Array{T,1},P::uvwMeshArrays,tim) where T dt=mydt(tim,P.T) g=P.u0.grid # @@ -95,7 +95,7 @@ function dxdt!(du::Array{T,1},u::Array{T,1},P::F_MeshArray3D,tim) where T end """ - dxdt!(du,u,p::F_MeshArray2D,tim) + dxdt!(du,u,p::uvMeshArrays,tim) Interpolate velocity from gridded fields (2D; with halos) to position `u` (`x,y,fIndex`) to compute the derivative of position v time `du_dt`. @@ -116,7 +116,7 @@ isa(I.πŸ“Œ,Vector) true ``` """ -function dxdt!(du::Array{T,1},u::Array{T,1},P::F_MeshArray2D,tim) where T +function dxdt!(du::Array{T,1},u::Array{T,1},P::uvMeshArrays,tim) where T #compute positions in index units dt=mydt(tim,P.T) g=P.u0.grid @@ -157,7 +157,7 @@ function dxdt!(du::Array{T,1},u::Array{T,1},P::F_MeshArray2D,tim) where T end """ - dxdt!(du,u,P::F_Array3D,tim) + dxdt!(du,u,P::uvwArrays,tim) Interpolate velocity from gridded fields (3D; NO halos) to position `u` (`x,y,z`) to compute the derivative of position v time `du_dt`. @@ -179,7 +179,7 @@ prod(isapprox.(I.πŸ“Œ,ref,atol=1.0)) # hide true ``` """ -function dxdt!(du::Array{T,1},u::Array{T,1},P::F_Array3D,tim) where T +function dxdt!(du::Array{T,1},u::Array{T,1},P::uvwArrays,tim) where T #compute positions in index units dt=mydt(tim,P.T) # @@ -226,12 +226,12 @@ function dxdt!(du::Array{T,1},u::Array{T,1},P::F_Array3D,tim) where T return du end -function dxdt!(du::Array{T,2},u::Array{T,2},P::F_Array3D,tim) where T +function dxdt!(du::Array{T,2},u::Array{T,2},P::uvwArrays,tim) where T [dxdt!(du[i],u[i],P,tim) for i=1:size(u,2)] end """ - dxdt!(du,u,P::F_Array2D,tim) + dxdt!(du,u,P::uvArrays,tim) Interpolate velocity from gridded fields (2D; NO halos) to position `u` (`x,y`) to compute the derivative of position v time `du_dt`. @@ -252,7 +252,7 @@ isa(I.πŸ“Œ,Vector) true ``` """ -function dxdt!(du::Array{T,1},u::Array{T,1},P::F_Array2D,tim) where T +function dxdt!(du::Array{T,1},u::Array{T,1},P::uvArrays,tim) where T dt=mydt(tim,P.T) # (nx,ny) = size(P.u0) diff --git a/src/data_wrangling.jl b/src/data_wrangling.jl index 71b80856..0b499fc6 100644 --- a/src/data_wrangling.jl +++ b/src/data_wrangling.jl @@ -2,7 +2,7 @@ convert_to_FlowFields(U::Array{T,2},V::Array{T,2},t1::T) where T Convert a pair of U,V arrays (staggered C-grid velocity field in 2D) to -a `F_MeshArray2D` struct ready for integration of individual displacements +a `uvMeshArrays` struct ready for integration of individual displacements from time `t0=0` to time `t1`. """ function convert_to_FlowFields(U::Array{T,2},V::Array{T,2},t1::T) where T @@ -15,7 +15,7 @@ function convert_to_FlowFields(U::Array{T,2},V::Array{T,2},t1::T) where T (u,v)=exchange(u,v,1) func=(u -> MeshArrays.update_location_dpdo!(u,g)) - F_MeshArray2D{eltype(u)}(u,u,v,v,[0,t1],func) + uvMeshArrays{eltype(u)}(u,u,v,v,[0,t1],func) end """