tadjust grain linear positions according to boundary periodicity - Granular.jl … | |
git clone git://src.adamsgaard.dk/Granular.jl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 2f86b2f3bb054dd34b2ea35c1a65ebe455b15646 | |
parent 6040ef7fcf67910a07df699fe383a365fde93796 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Fri, 3 Nov 2017 16:13:59 -0400 | |
adjust grain linear positions according to boundary periodicity | |
Diffstat: | |
M src/grid.jl | 60 +++++++++++++++++++++++++++++… | |
M src/temporal_integration.jl | 7 +++++-- | |
M test/periodic-boundaries.jl | 66 +++++++++++++++++++++++++++++… | |
3 files changed, 131 insertions(+), 2 deletions(-) | |
--- | |
diff --git a/src/grid.jl b/src/grid.jl | |
t@@ -732,3 +732,63 @@ function reportGridBoundaryConditions(grid::Any) | |
"\t($(grid.bc_north))") | |
nothing | |
end | |
+ | |
+""" | |
+ moveGrainsAcrossPeriodicBoundaries!(simulation::Simulation) | |
+ | |
+If the ocean or atmosphere grids are periodic, move grains that are placed | |
+outside the domain correspondingly across the domain. This function is to be | |
+called after temporal integration of the grain positions. | |
+""" | |
+function moveGrainsAcrossPeriodicBoundaries!(sim::Simulation) | |
+ | |
+ | |
+ # return if grids are not enabled | |
+ if typeof(sim.ocean.input_file) == Bool && | |
+ typeof(sim.atmosphere.input_file) == Bool | |
+ return nothing | |
+ end | |
+ | |
+ # return immediately if no boundaries are periodic | |
+ if sim.ocean.bc_west != 2 && | |
+ sim.ocean.bc_south != 2 && | |
+ sim.ocean.bc_east != 2 && | |
+ sim.ocean.bc_north != 2 | |
+ return nothing | |
+ end | |
+ | |
+ # throw error if ocean and atmosphere grid BCs are different and both are | |
+ # enabled | |
+ if (typeof(sim.ocean.input_file) != Bool && | |
+ typeof(sim.atmosphere.input_file) != Bool) && | |
+ (sim.ocean.bc_west != sim.atmosphere.bc_west && | |
+ sim.ocean.bc_south != sim.atmosphere.bc_south && | |
+ sim.ocean.bc_east != sim.atmosphere.bc_east && | |
+ sim.ocean.bc_north != sim.atmosphere.bc_north) | |
+ error("Ocean and Atmosphere grid boundary conditions differ") | |
+ end | |
+ | |
+ for grain in sim.grains | |
+ | |
+ # -x -> +x | |
+ if sim.ocean.bc_west == 2 && grain.lin_pos[1] < sim.ocean.xq[1] | |
+ grain.lin_pos[1] += sim.ocean.xq[end] - sim.ocean.xq[1] | |
+ end | |
+ | |
+ # -y -> +y | |
+ if sim.ocean.bc_south == 2 && grain.lin_pos[2] < sim.ocean.yq[1] | |
+ grain.lin_pos[2] += sim.ocean.yq[end] - sim.ocean.yq[1] | |
+ end | |
+ | |
+ # +x -> -x | |
+ if sim.ocean.bc_east == 2 && grain.lin_pos[1] > sim.ocean.xq[end] | |
+ grain.lin_pos[1] -= sim.ocean.xq[end] - sim.ocean.xq[1] | |
+ end | |
+ | |
+ # +y -> -y | |
+ if sim.ocean.bc_east == 2 && grain.lin_pos[2] > sim.ocean.yq[end] | |
+ grain.lin_pos[2] -= sim.ocean.yq[end] - sim.ocean.yq[1] | |
+ end | |
+ end | |
+ nothing | |
+end | |
diff --git a/src/temporal_integration.jl b/src/temporal_integration.jl | |
t@@ -4,7 +4,9 @@ export updateGrainKinematics! | |
method::String = "Three-term Taylor"]) | |
Update the grain kinematic parameters using a temporal integration scheme, | |
-the current force and torque balance, and gravitational acceleration. | |
+the current force and torque balance, and gravitational acceleration. If the | |
+simulation contains a grid with periodic boundaries, affected grain positions | |
+are adjusted accordingly. | |
# Arguments | |
* `simulation::Simulation`: update the grain positions in this object | |
t@@ -17,7 +19,7 @@ the current force and torque balance, and gravitational acce… | |
precision if the time step is 1/10 the length. | |
""" | |
function updateGrainKinematics!(simulation::Simulation; | |
- method::String = "Three-term Taylor") | |
+ method::String = "Three-term Taylor") | |
if method == "Two-term Taylor" | |
for grain in simulation.grains | |
t@@ -36,6 +38,7 @@ function updateGrainKinematics!(simulation::Simulation; | |
else | |
error("Unknown integration method '$method'") | |
end | |
+ moveGrainsAcrossPeriodicBoundaries!(simulation) | |
nothing | |
end | |
diff --git a/test/periodic-boundaries.jl b/test/periodic-boundaries.jl | |
t@@ -122,3 +122,69 @@ Test.@test 2 == sim.grains[1].contacts[1] | |
Test.@test 1 == sim.grains[1].n_contacts | |
Test.@test 1 == sim.grains[2].n_contacts | |
+ | |
+info("Test grain position adjustment across periodic boundaries") | |
+# do not readjust inside grid, inactive boundaries | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "inactive", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [0.1, 0.5], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+ | |
+# do not readjust inside grid, periodic boundaries | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [0.1, 0.5], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+ | |
+# do not readjust outside grid, inactive boundaries | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "inactive", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [-0.1, 0.5], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [-0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+ | |
+# readjust outside grid, periodic boundaries, -x | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [-0.1, 0.5], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [0.9, 0.5] ≈ sim.grains[1].lin_pos | |
+ | |
+# readjust outside grid, periodic boundaries, +x | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [1.1, 0.5], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+ | |
+# readjust outside grid, periodic boundaries, -y | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [0.3, -0.1], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [0.3, 0.9] ≈ sim.grains[1].lin_pos | |
+ | |
+# readjust outside grid, periodic boundaries, +y | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [0.3, 1.1], 0.11, 0.1, verbose=false) | |
+Granular.moveGrainsAcrossPeriodicBoundaries!(sim) | |
+Test.@test [0.3, 0.1] ≈ sim.grains[1].lin_pos | |
+ | |
+# throw error if atmosphere and ocean BCs differ | |
+sim = Granular.createSimulation() | |
+sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [1., 1., 1.]) | |
+sim.atmosphere = Granular.createRegularAtmosphereGrid([5, 5, 2], [1., 1., 1.]) | |
+Granular.setGridBoundaryConditions!(sim.ocean, "periodic", verbose=false) | |
+Granular.addGrainCylindrical!(sim, [0.3, 1.1], 0.11, 0.1, verbose=false) | |
+Test.@test_throws ErrorException Granular.moveGrainsAcrossPeriodicBoundaries!(… | |
+ |