Granular.jl

Julia package for granular dynamics simulation
git clone git://src.adamsgaard.dk/Granular.jl
Log | Files | Refs | README | LICENSE

commit e07ff2fd09377cda10a4da88a74ea2e4b06f5e62
parent 55b6301591042d961a0592758304217d4afc3397
Author: Anders Damsgaard <andersd@riseup.net>
Date:   Sun, 30 Apr 2017 13:04:58 -0400

change to south-west convention for corner indexing for consistency with memory layout

Diffstat:
Msrc/contact_search.jl | 14+++++++++++++-
Msrc/datatypes.jl | 13+++++--------
Msrc/grid.jl | 28++++++++++++++++------------
Mtest/grid.jl | 56++++++++++++++++++++++++++++----------------------------
4 files changed, 62 insertions(+), 49 deletions(-)

diff --git a/src/contact_search.jl b/src/contact_search.jl @@ -1,17 +1,29 @@ ## Contact mapping export findContacts! """ + findContacts!(simulation[, method]) + Top-level function to perform an inter-ice floe contact search, based on ice floe linear positions and contact radii. The simplest contact search algorithm (`method="all to all"`) is the most -computationally expensive (O(n^2)). +computationally expensive (O(n^2)). The method "ocean grid" bins the ice floes +into their corresponding cells on the ocean grid and searches for contacts only +within the vicinity. When this method is applied, it is assumed that the +`contact_radius` values of the ice floes are *smaller than half the cell size*. + +# Arguments +* `simulation::Simulation`: the simulation object containing the ice floes. +* `method::String`: the contact-search method to apply. Valid options are "all + to all" and "ocean grid". """ function findContacts!(simulation::Simulation, method::String = "all to all") if method == "all to all" findContactsAllToAll!(simulation) + elseif method == "ocean grid" + findContactsOceanGrid!(simulation) else error("Unknown contact search method '$method'") end diff --git a/src/datatypes.jl b/src/datatypes.jl @@ -94,11 +94,11 @@ end #= Type containing all relevant data from MOM6 NetCDF files. The ocean grid is a -staggered of Arakawa-C type, with north-east convention centered on the - h-points. During read, the velocities are interpolated to the cell corners - (q-points). +staggered of Arakawa-C type, with south-west convention centered on the +h-points. During read, the velocities are interpolated to the cell corners +(q-points). - q(i-1, j) ------------------ q( i, j) + q( i,j+1) ------------------ q(i+1,j+1) | | | | | | @@ -108,10 +108,7 @@ staggered of Arakawa-C type, with north-east convention centered on the | | | | | | - q(i-1,j-1) ------------------ q( i,j-1) - -Source: -https://mom6.readthedocs.io/en/latest/api/generated/pages/Horizontal_indexing.html + q( i, j) ------------------ q(i+1, j) # Fields * `input_file::String`: path to input NetCDF file diff --git a/src/grid.jl b/src/grid.jl @@ -1,7 +1,7 @@ """ Use bilinear interpolation to interpolate a staggered grid to an arbitrary -position in a cell. Assumes north-east convention, i.e. (i,j) is located at the -north-east corner. +position in a cell. Assumes south-west convention, i.e. (i,j) is located at the +south-west (-x, -y)-facing corner. # Arguments * `field::Array{Float64, 4}`: a scalar field to interpolate from @@ -22,10 +22,10 @@ function bilinearInterpolation(field::Array{Float64, 4}, error("relative coordinates outside bounds ($(x_tilde), $(y_tilde))") end - return (field[i, j, k, it]*x_tilde + - field[i-1, j, k, it]*(1. - x_tilde))*y_tilde + - (field[i, j-1, k, it]*x_tilde + - field[i-1, j-1, k, it]*(1. - x_tilde))*(1. - y_tilde) + return (field[i+1, j+1, k, it]*x_tilde + + field[i, j+1, k, it]*(1. - x_tilde))*y_tilde + + (field[i+1, j, k, it]*x_tilde + + field[i, j, k, it]*(1. - x_tilde))*(1. - y_tilde) end export sortIceFloesInOceanGrid! @@ -58,8 +58,8 @@ Returns the `i`, `j` index of the ocean grid cell containing the `point`. function findCellContainingPoint(ocean::Ocean, point::Array{float, 1}) found = false - for i=2:(size(ocean.h)[1] + 1) - for j=2:(size(ocean.h)[2] + 1) + for i=1:size(ocean.h, 1) + for j=1:size(ocean.h, 2) if isPointInCell(ocean, i, j, point) return i, j end @@ -131,10 +131,14 @@ Returns ocean-grid corner coordinates in the following order (south-west corner, south-east corner, north-east corner, north-west corner). """ function getCellCornerCoordinates(ocean::Ocean, i::Int, j::Int) - sw = [ocean.xq[i-1, j-1], ocean.yq[i-1, j-1]] - se = [ocean.xq[ i, j-1], ocean.yq[ i, j-1]] - ne = [ocean.xq[ i, j], ocean.yq[ i, j]] - nw = [ocean.xq[i-1, j], ocean.yq[i-1, j]] + #sw = [ocean.xq[i-1, j-1], ocean.yq[i-1, j-1]] + #se = [ocean.xq[ i, j-1], ocean.yq[ i, j-1]] + #ne = [ocean.xq[ i, j], ocean.yq[ i, j]] + #nw = [ocean.xq[i-1, j], ocean.yq[i-1, j]] + sw = [ocean.xq[ i, j], ocean.yq[ i, j]] + se = [ocean.xq[i+1, j], ocean.yq[i+1, j]] + ne = [ocean.xq[i+1, j+1], ocean.yq[i+1, j+1]] + nw = [ocean.xq[ i, j+1], ocean.yq[ i, j+1]] return sw, se, ne, nw end diff --git a/test/grid.jl b/test/grid.jl @@ -13,23 +13,23 @@ info("Testing area-determination methods") @test SeaIce.areaOfQuadrilateral([1., 0.], [0., 1.], [0., 0.], [1., 1.]) ≈ 1. info("Testing area-based cell content determination") -@test SeaIce.isPointInCell(ocean, 2, 2, [6.5, 53.5]) == true -@test SeaIce.getNonDimensionalCellCoordinates(ocean, 2, 2, [6.5, 53.5]) ≈ +@test SeaIce.isPointInCell(ocean, 1, 1, [6.5, 53.5]) == true +@test SeaIce.getNonDimensionalCellCoordinates(ocean, 1, 1, [6.5, 53.5]) ≈ [.5, .5] -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.5]) == true -@test SeaIce.getNonDimensionalCellCoordinates(ocean, 2, 2, [6.1, 53.5]) ≈ +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.5]) == true +@test SeaIce.getNonDimensionalCellCoordinates(ocean, 1, 1, [6.1, 53.5]) ≈ [.1, .5] -@test SeaIce.isPointInCell(ocean, 2, 2, [6.0, 53.5]) == true -@test SeaIce.getNonDimensionalCellCoordinates(ocean, 2, 2, [6.0, 53.5]) ≈ +@test SeaIce.isPointInCell(ocean, 1, 1, [6.0, 53.5]) == true +@test SeaIce.getNonDimensionalCellCoordinates(ocean, 1, 1, [6.0, 53.5]) ≈ [.0, .5] -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.7]) == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.9]) == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.99999]) == true -@test SeaIce.getNonDimensionalCellCoordinates(ocean, 2, 2, [6.1, 53.99999]) ≈ +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.7]) == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.9]) == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.99999]) == true +@test SeaIce.getNonDimensionalCellCoordinates(ocean, 1, 1, [6.1, 53.99999]) ≈ [.1, .99999] -@test SeaIce.isPointInCell(ocean, 2, 2, [7.5, 53.5]) == false -@test SeaIce.isPointInCell(ocean, 2, 2, [0.0, 53.5]) == false -x_tilde, _ = SeaIce.getNonDimensionalCellCoordinates(ocean, 2, 2, [0., 53.5]) +@test SeaIce.isPointInCell(ocean, 1, 1, [7.5, 53.5]) == false +@test SeaIce.isPointInCell(ocean, 1, 1, [0.0, 53.5]) == false +x_tilde, _ = SeaIce.getNonDimensionalCellCoordinates(ocean, 1, 1, [0., 53.5]) @test x_tilde < 0. info("Testing conformal mapping methods") @@ -55,16 +55,16 @@ info("Testing conformal mapping methods") [7.5,-1.5]) info("Checking cell content using conformal mapping methods") -@test SeaIce.isPointInCell(ocean, 2, 2, [6.4, 53.4], method="Conformal") == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.5], method="Conformal") == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.0, 53.5], method="Conformal") == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.7], method="Conformal") == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.9], method="Conformal") == true -@test SeaIce.isPointInCell(ocean, 2, 2, [6.1, 53.99999], +@test SeaIce.isPointInCell(ocean, 1, 1, [6.4, 53.4], method="Conformal") == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.5], method="Conformal") == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.0, 53.5], method="Conformal") == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.7], method="Conformal") == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.9], method="Conformal") == true +@test SeaIce.isPointInCell(ocean, 1, 1, [6.1, 53.99999], method="Conformal") == true -@test SeaIce.isPointInCell(ocean, 2, 2, [7.5, 53.5], +@test SeaIce.isPointInCell(ocean, 1, 1, [7.5, 53.5], method="Conformal") == false -@test SeaIce.isPointInCell(ocean, 2, 2, [0.0, 53.5], +@test SeaIce.isPointInCell(ocean, 1, 1, [0.0, 53.5], method="Conformal") == false info("Testing bilinear interpolation scheme on conformal mapping") @@ -72,13 +72,13 @@ ocean.u[1, 1, 1, 1] = 1.0 ocean.u[2, 1, 1, 1] = 1.0 ocean.u[2, 2, 1, 1] = 0.0 ocean.u[1, 2, 1, 1] = 0.0 -@test SeaIce.bilinearInterpolation(ocean.u, .5, .5, 2, 2, 1, 1) ≈ .5 -@test SeaIce.bilinearInterpolation(ocean.u, 1., 1., 2, 2, 1, 1) ≈ .0 -@test SeaIce.bilinearInterpolation(ocean.u, 0., 0., 2, 2, 1, 1) ≈ 1. -@test SeaIce.bilinearInterpolation(ocean.u, .25, .25, 2, 2, 1, 1) ≈ .75 -@test SeaIce.bilinearInterpolation(ocean.u, .75, .75, 2, 2, 1, 1) ≈ .25 +@test SeaIce.bilinearInterpolation(ocean.u, .5, .5, 1, 1, 1, 1) ≈ .5 +@test SeaIce.bilinearInterpolation(ocean.u, 1., 1., 1, 1, 1, 1) ≈ .0 +@test SeaIce.bilinearInterpolation(ocean.u, 0., 0., 1, 1, 1, 1) ≈ 1. +@test SeaIce.bilinearInterpolation(ocean.u, .25, .25, 1, 1, 1, 1) ≈ .75 +@test SeaIce.bilinearInterpolation(ocean.u, .75, .75, 1, 1, 1, 1) ≈ .25 info("Testing cell binning") -@test SeaIce.findCellContainingPoint(ocean, [6.2, 53.4]) == (2, 2) -@test SeaIce.findCellContainingPoint(ocean, [7.2, 53.4]) == (3, 2) +@test SeaIce.findCellContainingPoint(ocean, [6.2, 53.4]) == (1, 1) +@test SeaIce.findCellContainingPoint(ocean, [7.2, 53.4]) == (2, 1) @test_throws ErrorException SeaIce.findCellContainingPoint(ocean, [0.2, 53.4])