tMerge pull request #6 from anders-dc/ridging - Granular.jl - Julia package for… | |
git clone git://src.adamsgaard.dk/Granular.jl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 76c46ba160aa80b209aa7e20e302b170c87ef454 | |
parent 2379861ee82b96220b667e149c44ed11172f7dc4 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Mon, 9 Jul 2018 11:31:33 -0400 | |
Merge pull request #6 from anders-dc/ridging | |
Implement compressive failure parameterization | |
Diffstat: | |
M src/atmosphere.jl | 12 ++++++------ | |
M src/contact_search.jl | 12 +++++++----- | |
M src/datatypes.jl | 14 +++++++++----- | |
M src/grain.jl | 347 +++++++++++++++++------------… | |
M src/grid.jl | 22 ++++++++++++---------- | |
M src/interaction.jl | 213 ++++++++++++++++++++---------… | |
M src/io.jl | 53 ++++++++++++++++++++++++++---… | |
M src/ocean.jl | 11 ++++++----- | |
M src/packing.jl | 12 ++++++------ | |
M src/simulation.jl | 2 +- | |
M src/temporal_integration.jl | 22 ++++++++++++++-------- | |
M src/util.jl | 28 ++++++++++++++++++++++++++++ | |
M src/wall.jl | 28 ++++++++++++++-------------- | |
M test/atmosphere.jl | 24 +++++++++++------------- | |
M test/cohesion.jl | 49 +++++++++++++++++------------… | |
M test/collision-2floes-normal.jl | 2 -- | |
M test/collision-2floes-oblique.jl | 129 ++++++++++++++++-------------… | |
M test/collision-5floes-normal.jl | 2 -- | |
A test/compressive_failure.jl | 184 +++++++++++++++++++++++++++++… | |
M test/contact-search-and-geometry.jl | 92 +++++++++++++++--------------… | |
M test/grain.jl | 28 +++++++++++++--------------- | |
M test/grid-boundaries.jl | 18 ++++++++---------- | |
M test/grid.jl | 2 -- | |
M test/jld.jl | 2 -- | |
M test/netcdf.jl | 2 -- | |
M test/ocean.jl | 24 +++++++++++------------- | |
M test/packing.jl | 2 -- | |
M test/profiling.jl | 2 -- | |
M test/runtests.jl | 40 ++++++++++++++++++-----------… | |
M test/util.jl | 13 +++++++++++-- | |
M test/vtk.jl | 6 ++---- | |
M test/wall.jl | 8 +++----- | |
32 files changed, 885 insertions(+), 520 deletions(-) | |
--- | |
diff --git a/src/atmosphere.jl b/src/atmosphere.jl | |
t@@ -169,10 +169,10 @@ function applyAtmosphereDragToGrain!(grain::GrainCylindr… | |
drag_force = ρ_a * π * | |
(2.0*grain.ocean_drag_coeff_vert*grain.areal_radius*.1*grain.thickness + | |
grain.atmosphere_drag_coeff_horiz*grain.areal_radius^2.0) * | |
- ([u, v] - grain.lin_vel)*norm([u, v] - grain.lin_vel) | |
+ ([u, v] - grain.lin_vel[1:2])*norm([u, v] - grain.lin_vel[1:2]) | |
- grain.force += drag_force | |
- grain.atmosphere_stress = drag_force/grain.horizontal_surface_area | |
+ grain.force += vecTo3d(drag_force) | |
+ grain.atmosphere_stress = vecTo3d(drag_force/grain.horizontal_surface_area) | |
nothing | |
end | |
t@@ -186,12 +186,12 @@ function applyAtmosphereVorticityToGrain!(grain::GrainCy… | |
atmosphere_curl::Float64) | |
ρ_a = 1.2754 # atmosphere density | |
- grain.torque += | |
+ grain.torque[3] += | |
π * grain.areal_radius^4. * ρ_a * | |
(grain.areal_radius / 5. * grain.atmosphere_drag_coeff_horiz + | |
.1 * grain.thickness * grain.atmosphere_drag_coeff_vert) * | |
- abs(.5 * atmosphere_curl - grain.ang_vel) * | |
- (.5 * atmosphere_curl - grain.ang_vel) | |
+ norm(.5 * atmosphere_curl - grain.ang_vel[3]) * | |
+ (.5 * atmosphere_curl - grain.ang_vel[3]) | |
nothing | |
end | |
diff --git a/src/contact_search.jl b/src/contact_search.jl | |
t@@ -109,7 +109,7 @@ Perform an O(n*log(n)) cell-based contact search between a… | |
""" | |
function findContactsInGrid!(simulation::Simulation, grid::Any) | |
- distance_modifier = [0., 0.] | |
+ distance_modifier = [0., 0., 0.] | |
i_corrected = 0 | |
j_corrected = 0 | |
t@@ -173,7 +173,7 @@ function checkForContacts(simulation::Simulation, | |
r_candidate::Float64; | |
return_when_overlap_found::Bool=false) | |
- distance_modifier = zeros(2) | |
+ distance_modifier = zeros(3) | |
overlaps_found::Integer = 0 | |
# Inter-grain position vector and grain overlap | |
t@@ -225,7 +225,7 @@ function periodicBoundaryCorrection!(grid::Any, i::Integer… | |
# vector for correcting inter-particle distance in case of | |
# boundary periodicity | |
- distance_modifier = zeros(2) | |
+ distance_modifier = zeros(3) | |
# i and j are not corrected for periodic boundaries | |
i_corrected = i | |
t@@ -275,7 +275,7 @@ written to `simulation.contact_parallel_displacement`. | |
boundaries. | |
""" | |
function checkAndAddContact!(sim::Simulation, i::Int, j::Int, | |
- distance_modifier::Vector{Float64} = [0., 0.]) | |
+ distance_modifier::Vector{Float64} = [0., 0., 0.]) | |
if i < j | |
@inbounds if !sim.grains[i].enabled || !sim.grains[j].enabled | |
t@@ -327,8 +327,10 @@ function checkAndAddContact!(sim::Simulation, i::Int, j::… | |
position_ij | |
@inbounds fill!(sim.grains[i]. | |
contact_parallel_displacement[ic] , 0.) | |
- @inbounds sim.grains[i].contact_rotation[ic] = 0. | |
+ @inbounds fill!(sim.grains[i].contact_rotation[ic] , 0… | |
@inbounds sim.grains[i].contact_age[ic] = 0. | |
+ @inbounds sim.grains[i].contact_area[ic] = 0. | |
+ @inbounds sim.grains[i].compressive_failure[ic] = false | |
break | |
end | |
end | |
diff --git a/src/datatypes.jl b/src/datatypes.jl | |
t@@ -24,15 +24,16 @@ mutable struct GrainCylindrical | |
lin_disp::Vector{Float64} | |
# Angular kinematic degrees of freedom for vertical rotation around center | |
- ang_pos::Float64 | |
- ang_vel::Float64 | |
- ang_acc::Float64 | |
- torque::Float64 | |
+ ang_pos::Vector{Float64} | |
+ ang_vel::Vector{Float64} | |
+ ang_acc::Vector{Float64} | |
+ torque::Vector{Float64} | |
# Kinematic constraint flags | |
fixed::Bool | |
allow_x_acc::Bool | |
allow_y_acc::Bool | |
+ allow_z_acc::Bool | |
rotating::Bool | |
enabled::Bool | |
t@@ -65,8 +66,10 @@ mutable struct GrainCylindrical | |
contacts::Vector{Int} | |
position_vector::Vector{Vector{Float64}} | |
contact_parallel_displacement::Vector{Vector{Float64}} | |
- contact_rotation::Vector{Float64} | |
+ contact_rotation::Vector{Vector{Float64}} | |
contact_age::Vector{Float64} | |
+ contact_area::Vector{Float64} | |
+ compressive_failure::Vector{Bool} | |
granular_stress::Vector{Float64} | |
ocean_stress::Vector{Float64} | |
t@@ -128,6 +131,7 @@ mutable struct GrainArrays | |
fixed::Vector{Int} | |
allow_x_acc::Vector{Int} | |
allow_y_acc::Vector{Int} | |
+ allow_z_acc::Vector{Int} | |
rotating::Vector{Int} | |
enabled::Vector{Int} | |
diff --git a/src/grain.jl b/src/grain.jl | |
t@@ -24,7 +24,7 @@ export addGrainCylindrical! | |
atmosphere_drag_coeff_vert, | |
atmosphere_drag_coeff_horiz, | |
pressure, fixed, | |
- allow_x_acc, allow_y_acc, | |
+ allow_x_acc, allow_y_acc, allow_z_acc, | |
rotating, enabled, verbose, | |
ocean_grid_pos, atmosphere_grid_pos, | |
n_contact, granular_stress, ocean_stress, | |
t@@ -39,21 +39,34 @@ are optional, and come with default values. The only requ… | |
# Arguments | |
* `simulation::Simulation`: the simulation object where the grain should be | |
added to. | |
-* `lin_pos::Vector{Float64}`: linear position of grain center [m]. | |
+* `lin_pos::Vector{Float64}`: linear position of grain center [m]. If a | |
+ two-component vector is used, the values will be mapped to *x* and *y*, and | |
+ the *z* component will be set to zero. | |
* `contact_radius::Float64`: grain radius for granular interaction [m]. | |
* `thickness::Float64`: grain thickness [m]. | |
* `areal_radius = false`: grain radius for determining sea-ice concentration | |
[m]. | |
-* `lin_vel::Vector{Float64} = [0., 0.]`: linear velocity [m/s]. | |
-* `lin_acc::Vector{Float64} = [0., 0.]`: linear acceleration [m/s^2]. | |
-* `force::Vector{Float64} = [0., 0.]`: linear force balance [N]. | |
-* `ang_pos::Float64 = 0.`: angular position around its center vertical axis | |
- [rad]. | |
-* `ang_vel::Float64 = 0.`: angular velocity around its center vertical axis | |
- [rad/s]. | |
-* `ang_acc::Float64 = 0.`: angular acceleration around its center vertical axis | |
- [rad/s^2]. | |
-* `torque::Float64 = 0.`: torque around its center vertical axis [N*m] | |
+* `lin_vel::Vector{Float64} = [0., 0., 0.]`: linear velocity [m/s]. If a | |
+ two-component vector is used, the values will be mapped to *x* and *y*, and | |
+ the *z* component will be set to zero. | |
+* `lin_acc::Vector{Float64} = [0., 0., 0.]`: linear acceleration [m/s^2]. If a | |
+ two-component vector is used, the values will be mapped to *x* and *y*, and | |
+ the *z* component will be set to zero. | |
+* `force::Vector{Float64} = [0., 0., 0.]`: linear force balance [N]. If a | |
+ two-component vector is used, the values will be mapped to *x* and *y*, and | |
+ the *z* component will be set to zero. | |
+* `ang_pos::Float64 = [0., 0., 0.]`: angular position around its center vertic… | |
+ axis [rad]. If a scalar is used, the value will be mapped to *z*, and the | |
+ *x* and *y* components will be set to zero. | |
+* `ang_vel::Float64 = [0., 0., 0.]`: angular velocity around its center vertic… | |
+ axis [rad/s]. If a scalar is used, the value will be mapped to *z*, and the | |
+ *x* and *y* components will be set to zero. | |
+* `ang_acc::Float64 = [0., 0., 0.]`: angular acceleration around its center | |
+ vertical axis [rad/s^2]. If a scalar is used, the value will be mapped to | |
+ *z*, and the *x* and *y* components will be set to zero. | |
+* `torque::Float64 = [0., 0., 0.]`: torque around its center vertical axis | |
+ [N*m]. If a scalar is used, the value will be mapped to *z*, and the *x* a… | |
+ *y* components will be set to zero. | |
* `density::Float64 = 934.`: grain mean density [kg/m^3]. | |
* `contact_stiffness_normal::Float64 = 1e7`: contact-normal stiffness [N/m]; | |
overridden if `youngs_modulus` is set to a positive value. | |
t@@ -75,8 +88,8 @@ are optional, and come with default values. The only requir… | |
* `shear_strength::Float64 = 0.`: shear strength of bonded contacts [Pa]. | |
* `strength_heal_rate::Float64 = 0.`: rate at which contact bond | |
strength is obtained [Pa/s]. | |
-* `fracture_toughness::Float64 = 0.`: maximum compressive | |
- strength on granular contact (not currently enforced) [m^{1/2}*Pa]. A value | |
+* `fracture_toughness::Float64 = 0.`: fracture toughness which influences the | |
+ maximum compressive strength on granular contact [m^{1/2}*Pa]. A value | |
of 1.285e3 m^{1/2}*Pa is used for sea ice by Hopkins 2004. | |
* `ocean_drag_coeff_vert::Float64 = 0.85`: vertical drag coefficient for ocean | |
against grain sides [-]. | |
t@@ -90,6 +103,7 @@ are optional, and come with default values. The only requi… | |
* `fixed::Bool = false`: grain is fixed to a constant velocity (e.g. zero). | |
* `allow_x_acc::Bool = false`: override `fixed` along `x`. | |
* `allow_y_acc::Bool = false`: override `fixed` along `y`. | |
+* `allow_z_acc::Bool = false`: override `fixed` along `z`. | |
* `rotating::Bool = true`: grain is allowed to rotate. | |
* `enabled::Bool = true`: grain interacts with other grains. | |
* `verbose::Bool = true`: display diagnostic information during the function | |
t@@ -99,11 +113,11 @@ are optional, and come with default values. The only req… | |
* `atmosphere_grid_pos::Array{Int, 1} = [0, 0]`: position of grain in the | |
atmosphere grid. | |
* `n_contacts::Int = 0`: number of contacts with other grains. | |
-* `granular_stress::Vector{Float64} = [0., 0.]`: resultant stress on grain | |
+* `granular_stress::Vector{Float64} = [0., 0., 0.]`: resultant stress on grain | |
from granular interactions [Pa]. | |
-* `ocean_stress::Vector{Float64} = [0., 0.]`: resultant stress on grain from | |
+* `ocean_stress::Vector{Float64} = [0., 0., 0.]`: resultant stress on grain fr… | |
ocean drag [Pa]. | |
-* `atmosphere_stress::Vector{Float64} = [0., 0.]`: resultant stress on grain | |
+* `atmosphere_stress::Vector{Float64} = [0., 0., 0.]`: resultant stress on gra… | |
from atmosphere drag [Pa]. | |
* `thermal_energy::Float64 = 0.0`: thermal energy of grain [J]. | |
* `color::Int=0`: type number, usually used for associating a color to the gra… | |
t@@ -111,12 +125,13 @@ are optional, and come with default values. The only re… | |
# Examples | |
The most basic example adds a new grain to the simulation `sim`, with a | |
-center at `[1., 2.]`, a radius of `1.` meter, and a thickness of `0.5` | |
+center at `[1., 2., 0.]`, a radius of `1.` meter, and a thickness of `0.5` | |
meter: | |
```julia | |
Granular.addGrainCylindrical!(sim, [1., 2.], 1., .5) | |
``` | |
+Note that the *z* component is set to zero if a two-component vector is passed. | |
The following example will create a grain with tensile and shear strength, and… | |
velocity of 0.5 m/s towards -x: | |
t@@ -142,13 +157,13 @@ function addGrainCylindrical!(simulation::Simulation, | |
contact_radius::Float64, | |
thickness::Float64; | |
areal_radius = false, | |
- lin_vel::Vector{Float64} = [0., 0.], | |
- lin_acc::Vector{Float64} = [0., 0.], | |
- force::Vector{Float64} = [0., 0.], | |
- ang_pos::Float64 = 0., | |
- ang_vel::Float64 = 0., | |
- ang_acc::Float64 = 0., | |
- torque::Float64 = 0., | |
+ lin_vel::Vector{Float64} = [0., 0., 0.], | |
+ lin_acc::Vector{Float64} = [0., 0., 0.], | |
+ force::Vector{Float64} = [0., 0., 0.], | |
+ ang_pos::Vector{Float64} = [0., 0., 0.], | |
+ ang_vel::Vector{Float64} = [0., 0., 0.], | |
+ ang_acc::Vector{Float64} = [0., 0., 0.], | |
+ torque::Vector{Float64} = [0., 0., 0.], | |
density::Float64 = 934., | |
contact_stiffness_normal::Float64 = 1e7, | |
contact_stiffness_tangential::Float64 = 0., | |
t@@ -170,30 +185,52 @@ function addGrainCylindrical!(simulation::Simulation, | |
fixed::Bool = false, | |
allow_x_acc::Bool = false, | |
allow_y_acc::Bool = false, | |
+ allow_z_acc::Bool = false, | |
rotating::Bool = true, | |
enabled::Bool = true, | |
verbose::Bool = true, | |
ocean_grid_pos::Array{Int, 1} = [0, 0], | |
atmosphere_grid_pos::Array{Int, 1} = [0, 0], | |
n_contacts::Int = 0, | |
- granular_stress::Vector{Float64} = [0., 0.], | |
- ocean_stress::Vector{Float64} = [0., 0.], | |
- atmosphere_stress::Vector{Float64} = [0., 0.], | |
+ granular_stress::Vector{Float64} = [0., 0., 0.… | |
+ ocean_stress::Vector{Float64} = [0., 0., 0.], | |
+ atmosphere_stress::Vector{Float64} = [0., 0., … | |
thermal_energy::Float64 = 0., | |
color::Int = 0) | |
# Check input values | |
- if length(lin_pos) != 2 | |
- error("Linear position must be a two-element array " * | |
- "(lin_pos = $lin_pos)") | |
+ if length(lin_pos) != 3 | |
+ lin_pos = vecTo3d(lin_pos) | |
end | |
- if length(lin_vel) != 2 | |
- error("Linear velocity must be a two-element array " * | |
- "(lin_vel = $lin_vel)") | |
+ if length(lin_vel) != 3 | |
+ lin_vel = vecTo3d(lin_vel) | |
end | |
- if length(lin_acc) != 2 | |
- error("Linear acceleration must be a two-element array " * | |
- "(lin_acc = $lin_acc)") | |
+ if length(lin_acc) != 3 | |
+ lin_acc = vecTo3d(lin_acc) | |
+ end | |
+ if length(force) != 3 | |
+ force = vecTo3d(force) | |
+ end | |
+ if length(ang_pos) != 3 | |
+ ang_pos = vecTo3d(ang_pos) | |
+ end | |
+ if length(ang_vel) != 3 | |
+ ang_vel = vecTo3d(ang_vel) | |
+ end | |
+ if length(ang_acc) != 3 | |
+ ang_acc = vecTo3d(ang_acc) | |
+ end | |
+ if length(torque) != 3 | |
+ torque = vecTo3d(torque) | |
+ end | |
+ if length(granular_stress) != 3 | |
+ granular_stress = vecTo3d(granular_stress) | |
+ end | |
+ if length(ocean_stress) != 3 | |
+ ocean_stress = vecTo3d(ocean_stress) | |
+ end | |
+ if length(atmosphere_stress) != 3 | |
+ atmosphere_stress = vecTo3d(atmosphere_stress) | |
end | |
if contact_radius <= 0.0 | |
error("Radius must be greater than 0.0 " * | |
t@@ -212,81 +249,87 @@ function addGrainCylindrical!(simulation::Simulation, | |
position_vector = Vector{Vector{Float64}}(undef, simulation.Nc_max) | |
contact_parallel_displacement = | |
Vector{Vector{Float64}}(undef, simulation.Nc_max) | |
- contact_rotation::Vector{Float64} = zeros(Float64, simulation.Nc_max) | |
+ contact_rotation = Vector{Vector{Float64}}(undef, simulation.Nc_max) | |
contact_age::Vector{Float64} = zeros(Float64, simulation.Nc_max) | |
+ contact_area::Vector{Float64} = zeros(Float64, simulation.Nc_max) | |
+ compressive_failure::Vector{Bool} = zeros(Bool, simulation.Nc_max) | |
for i=1:simulation.Nc_max | |
- position_vector[i] = zeros(2) | |
- contact_parallel_displacement[i] = zeros(2) | |
+ position_vector[i] = zeros(3) | |
+ contact_rotation[i] = zeros(3) | |
+ contact_parallel_displacement[i] = zeros(3) | |
end | |
# Create grain object with placeholder values for surface area, volume, | |
# mass, and moment of inertia. | |
grain = GrainCylindrical(density, | |
- thickness, | |
- contact_radius, | |
- areal_radius, | |
- 1.0, # circumreference | |
- 1.0, # horizontal_surface_area | |
- 1.0, # side_surface_area | |
- 1.0, # volume | |
- 1.0, # mass | |
- 1.0, # moment_of_inertia | |
- lin_pos, | |
- lin_vel, | |
- lin_acc, | |
- force, | |
- [0., 0.], # external_body_force | |
- [0., 0.], # lin_disp | |
- | |
- ang_pos, | |
- ang_vel, | |
- ang_acc, | |
- torque, | |
- | |
- fixed, | |
- allow_x_acc, | |
- allow_y_acc, | |
- rotating, | |
- enabled, | |
- | |
- contact_stiffness_normal, | |
- contact_stiffness_tangential, | |
- contact_viscosity_normal, | |
- contact_viscosity_tangential, | |
- contact_static_friction, | |
- contact_dynamic_friction, | |
- | |
- youngs_modulus, | |
- poissons_ratio, | |
- tensile_strength, | |
- shear_strength, | |
- strength_heal_rate, | |
- fracture_toughness, | |
- | |
- ocean_drag_coeff_vert, | |
- ocean_drag_coeff_horiz, | |
- atmosphere_drag_coeff_vert, | |
- atmosphere_drag_coeff_horiz, | |
- | |
- pressure, | |
- n_contacts, | |
- ocean_grid_pos, | |
- atmosphere_grid_pos, | |
- contacts, | |
- position_vector, | |
- contact_parallel_displacement, | |
- contact_rotation, | |
- contact_age, | |
- | |
- granular_stress, | |
- ocean_stress, | |
- atmosphere_stress, | |
- | |
- thermal_energy, | |
- | |
- color | |
- ) | |
+ thickness, | |
+ contact_radius, | |
+ areal_radius, | |
+ 1.0, # circumreference | |
+ 1.0, # horizontal_surface_area | |
+ 1.0, # side_surface_area | |
+ 1.0, # volume | |
+ 1.0, # mass | |
+ 1.0, # moment_of_inertia | |
+ lin_pos, | |
+ lin_vel, | |
+ lin_acc, | |
+ force, | |
+ [0., 0., 0.], # external_body_force | |
+ [0., 0., 0.], # lin_disp | |
+ | |
+ ang_pos, | |
+ ang_vel, | |
+ ang_acc, | |
+ torque, | |
+ | |
+ fixed, | |
+ allow_x_acc, | |
+ allow_y_acc, | |
+ allow_z_acc, | |
+ rotating, | |
+ enabled, | |
+ | |
+ contact_stiffness_normal, | |
+ contact_stiffness_tangential, | |
+ contact_viscosity_normal, | |
+ contact_viscosity_tangential, | |
+ contact_static_friction, | |
+ contact_dynamic_friction, | |
+ | |
+ youngs_modulus, | |
+ poissons_ratio, | |
+ tensile_strength, | |
+ shear_strength, | |
+ strength_heal_rate, | |
+ fracture_toughness, | |
+ | |
+ ocean_drag_coeff_vert, | |
+ ocean_drag_coeff_horiz, | |
+ atmosphere_drag_coeff_vert, | |
+ atmosphere_drag_coeff_horiz, | |
+ | |
+ pressure, | |
+ n_contacts, | |
+ ocean_grid_pos, | |
+ atmosphere_grid_pos, | |
+ contacts, | |
+ position_vector, | |
+ contact_parallel_displacement, | |
+ contact_rotation, | |
+ contact_age, | |
+ contact_area, | |
+ compressive_failure, | |
+ | |
+ granular_stress, | |
+ ocean_stress, | |
+ atmosphere_stress, | |
+ | |
+ thermal_energy, | |
+ | |
+ color | |
+ ) | |
# Overwrite previous placeholder values | |
grain.circumreference = grainCircumreference(grain) | |
t@@ -400,6 +443,8 @@ function convertGrainDataToArrays(simulation::Simulation) | |
Array{Int}(undef, length(simulation.grains)), | |
## allow_y_acc | |
Array{Int}(undef, length(simulation.grains)), | |
+ ## allow_z_acc | |
+ Array{Int}(undef, length(simulation.grains)), | |
## rotating | |
Array{Int}(undef, length(simulation.grains)), | |
## enabled | |
t@@ -479,22 +524,23 @@ function convertGrainDataToArrays(simulation::Simulation) | |
ifarr.mass[i] = simulation.grains[i].mass | |
ifarr.moment_of_inertia[i] = simulation.grains[i].moment_of_inertia | |
- ifarr.lin_pos[1:2, i] = simulation.grains[i].lin_pos | |
- ifarr.lin_vel[1:2, i] = simulation.grains[i].lin_vel | |
- ifarr.lin_acc[1:2, i] = simulation.grains[i].lin_acc | |
- ifarr.force[1:2, i] = simulation.grains[i].force | |
- ifarr.external_body_force[1:2, i] = | |
+ ifarr.lin_pos[1:3, i] = simulation.grains[i].lin_pos | |
+ ifarr.lin_vel[1:3, i] = simulation.grains[i].lin_vel | |
+ ifarr.lin_acc[1:3, i] = simulation.grains[i].lin_acc | |
+ ifarr.force[1:3, i] = simulation.grains[i].force | |
+ ifarr.external_body_force[1:3, i] = | |
simulation.grains[i].external_body_force | |
- ifarr.lin_disp[1:2, i] = simulation.grains[i].lin_disp | |
+ ifarr.lin_disp[1:3, i] = simulation.grains[i].lin_disp | |
- ifarr.ang_pos[3, i] = simulation.grains[i].ang_pos | |
- ifarr.ang_vel[3, i] = simulation.grains[i].ang_vel | |
- ifarr.ang_acc[3, i] = simulation.grains[i].ang_acc | |
- ifarr.torque[3, i] = simulation.grains[i].torque | |
+ ifarr.ang_pos[1:3, i] = simulation.grains[i].ang_pos | |
+ ifarr.ang_vel[1:3, i] = simulation.grains[i].ang_vel | |
+ ifarr.ang_acc[1:3, i] = simulation.grains[i].ang_acc | |
+ ifarr.torque[1:3, i] = simulation.grains[i].torque | |
ifarr.fixed[i] = Int(simulation.grains[i].fixed) | |
ifarr.allow_x_acc[i] = Int(simulation.grains[i].allow_x_acc) | |
ifarr.allow_y_acc[i] = Int(simulation.grains[i].allow_y_acc) | |
+ ifarr.allow_z_acc[i] = Int(simulation.grains[i].allow_z_acc) | |
ifarr.rotating[i] = Int(simulation.grains[i].rotating) | |
ifarr.enabled[i] = Int(simulation.grains[i].enabled) | |
t@@ -531,10 +577,9 @@ function convertGrainDataToArrays(simulation::Simulation) | |
ifarr.pressure[i] = simulation.grains[i].pressure | |
ifarr.n_contacts[i] = simulation.grains[i].n_contacts | |
- ifarr.granular_stress[1:2, i] = simulation.grains[i].granular_stress | |
- ifarr.ocean_stress[1:2, i] = simulation.grains[i].ocean_stress | |
- ifarr.atmosphere_stress[1:2, i] = | |
- simulation.grains[i].atmosphere_stress | |
+ ifarr.granular_stress[1:3, i] = simulation.grains[i].granular_stress | |
+ ifarr.ocean_stress[1:3, i] = simulation.grains[i].ocean_stress | |
+ ifarr.atmosphere_stress[1:3, i] = simulation.grains[i].atmosphere_stre… | |
ifarr.thermal_energy[i] = simulation.grains[i].thermal_energy | |
t@@ -576,6 +621,7 @@ function deleteGrainArrays!(ifarr::GrainArrays) | |
ifarr.fixed = i1 | |
ifarr.allow_x_acc = i1 | |
ifarr.allow_y_acc = i1 | |
+ ifarr.allow_z_acc = i1 | |
ifarr.rotating = i1 | |
ifarr.enabled = i1 | |
t@@ -643,22 +689,23 @@ function printGrainInfo(f::GrainCylindrical) | |
println(" fixed: $(f.fixed)") | |
println(" allow_x_acc: $(f.allow_x_acc)") | |
println(" allow_y_acc: $(f.allow_y_acc)") | |
+ println(" allow_z_acc: $(f.allow_z_acc)") | |
println(" rotating: $(f.rotating)") | |
println(" enabled: $(f.enabled)\n") | |
- println(" k_n: $(f.contact_stiffness_normal) N/m") | |
- println(" k_t: $(f.contact_stiffness_tangential) N/m") | |
+ println(" k_n: $(f.contact_stiffness_normal) N/m") | |
+ println(" k_t: $(f.contact_stiffness_tangential) N/m") | |
println(" γ_n: $(f.contact_viscosity_normal) N/(m/s)") | |
println(" γ_t: $(f.contact_viscosity_tangential) N/(m/s)") | |
- println(" μ_s: $(f.contact_static_friction)") | |
- println(" μ_d: $(f.contact_dynamic_friction)\n") | |
+ println(" μ_s: $(f.contact_static_friction)") | |
+ println(" μ_d: $(f.contact_dynamic_friction)\n") | |
- println(" E: $(f.youngs_modulus) Pa") | |
- println(" ν: $(f.poissons_ratio)") | |
- println(" tensile_strength: $(f.tensile_strength) Pa") | |
- println(" shear_strength: $(f.shear_strength) Pa") | |
- println(" strength_heal_rate: $(f.strength_heal_rate) Pa/s") | |
- println(" fracture_toughness: $(f.fracture_toughness) m^0.5 Pa\n") | |
+ println(" E: $(f.youngs_modulus) Pa") | |
+ println(" ν: $(f.poissons_ratio)") | |
+ println(" tensile_strength: $(f.tensile_strength) Pa") | |
+ println(" shear_strength: $(f.shear_strength) Pa") | |
+ println(" strength_heal_rate: $(f.strength_heal_rate) Pa/s") | |
+ println(" fracture_toughness: $(f.fracture_toughness) m^0.5 Pa\n") | |
println(" c_o_v: $(f.ocean_drag_coeff_vert)") | |
println(" c_o_h: $(f.ocean_drag_coeff_horiz)") | |
t@@ -754,7 +801,7 @@ Add to the value of the external body force on a grain. | |
* `force::Vector{Float64}`: a vector of force [N] | |
""" | |
function addBodyForce!(grain::GrainCylindrical, force::Vector{Float64}) | |
- grain.external_body_force += force | |
+ grain.external_body_force += vecTo3d(force) | |
end | |
export setBodyForce! | |
t@@ -768,7 +815,7 @@ Set the value of the external body force on a grain. | |
* `force::Vector{Float64}`: a vector of force [N] | |
""" | |
function setBodyForce!(grain::GrainCylindrical, force::Vector{Float64}) | |
- grain.external_body_force = force | |
+ grain.external_body_force = vecTo3d(force) | |
end | |
export compareGrains | |
t@@ -781,11 +828,9 @@ function compareGrains(if1::GrainCylindrical, if2::GrainC… | |
@test if1.density ≈ if2.density | |
@test if1.thickness ≈ if2.thickness | |
- @test if1.contact_radius ≈ | |
- if2.contact_radius | |
+ @test if1.contact_radius ≈ if2.contact_radius | |
@test if1.areal_radius ≈ if2.areal_radius | |
- @test if1.circumreference ≈ | |
- if2.circumreference | |
+ @test if1.circumreference ≈ if2.circumreference | |
@test if1.horizontal_surface_area ≈ if2.horizontal_surface_area | |
@test if1.side_surface_area ≈ if2.side_surface_area | |
@test if1.volume ≈ if2.volume | |
t@@ -809,11 +854,9 @@ function compareGrains(if1::GrainCylindrical, if2::GrainC… | |
@test if1.enabled == if2.enabled | |
@test if1.contact_stiffness_normal ≈ if2.contact_stiffness_normal | |
- @test if1.contact_stiffness_tangential ≈ | |
- if2.contact_stiffness_tangential | |
+ @test if1.contact_stiffness_tangential ≈ if2.contact_stiffness_tangential | |
@test if1.contact_viscosity_normal ≈ if2.contact_viscosity_normal | |
- @test if1.contact_viscosity_tangential ≈ | |
- if2.contact_viscosity_tangential | |
+ @test if1.contact_viscosity_tangential ≈ if2.contact_viscosity_tangential | |
@test if1.contact_static_friction ≈ if2.contact_static_friction | |
@test if1.contact_dynamic_friction ≈ if2.contact_dynamic_friction | |
t@@ -822,25 +865,23 @@ function compareGrains(if1::GrainCylindrical, if2::Grain… | |
@test if1.tensile_strength ≈ if2.tensile_strength | |
@test if1.shear_strength ≈ if2.shear_strength | |
@test if1.strength_heal_rate ≈ if2.strength_heal_rate | |
- @test if1.fracture_toughness ≈ | |
- if2.fracture_toughness | |
+ @test if1.fracture_toughness ≈ if2.fracture_toughness | |
@test if1.ocean_drag_coeff_vert ≈ if2.ocean_drag_coeff_vert | |
@test if1.ocean_drag_coeff_horiz ≈ if2.ocean_drag_coeff_horiz | |
- @test if1.atmosphere_drag_coeff_vert ≈ | |
- if2.atmosphere_drag_coeff_vert | |
- @test if1.atmosphere_drag_coeff_horiz ≈ | |
- if2.atmosphere_drag_coeff_horiz | |
+ @test if1.atmosphere_drag_coeff_vert ≈ if2.atmosphere_drag_coeff_vert | |
+ @test if1.atmosphere_drag_coeff_horiz ≈ if2.atmosphere_drag_coeff_horiz | |
@test if1.pressure ≈ if2.pressure | |
@test if1.n_contacts == if2.n_contacts | |
@test if1.ocean_grid_pos == if2.ocean_grid_pos | |
@test if1.contacts == if2.contacts | |
@test if1.position_vector == if2.position_vector | |
- @test if1.contact_parallel_displacement == | |
- if2.contact_parallel_displacement | |
+ @test if1.contact_parallel_displacement == if2.contact_parallel_displaceme… | |
@test if1.contact_rotation == if2.contact_rotation | |
@test if1.contact_age ≈ if2.contact_age | |
+ @test if1.contact_area ≈ if2.contact_area | |
+ @test if1.compressive_failure ≈ if2.compressive_failure | |
@test if1.granular_stress ≈ if2.granular_stress | |
@test if1.ocean_stress ≈ if2.ocean_stress | |
t@@ -905,12 +946,12 @@ rotational) to zero in order to get rid of all kinetic e… | |
""" | |
function zeroKinematics!(sim::Simulation) | |
for grain in sim.grains | |
- grain.lin_vel .= zeros(2) | |
- grain.lin_acc .= zeros(2) | |
- grain.force .= zeros(2) | |
- grain.lin_disp .= zeros(2) | |
- grain.ang_vel = 0. | |
- grain.ang_acc = 0. | |
- grain.torque = 0. | |
+ grain.lin_vel .= zeros(3) | |
+ grain.lin_acc .= zeros(3) | |
+ grain.force .= zeros(3) | |
+ grain.lin_disp .= zeros(3) | |
+ grain.ang_vel .= zeros(3) | |
+ grain.ang_acc .= zeros(3) | |
+ grain.torque .= zeros(3) | |
end | |
end | |
diff --git a/src/grid.jl b/src/grid.jl | |
t@@ -161,14 +161,15 @@ function sortGrainsInGrid!(simulation::Simulation, grid:… | |
!grid.regular_grid && | |
i_old > 0 && j_old > 0 && | |
isPointInCell(grid, i_old, j_old, | |
- simulation.grains[idx].lin_pos, sw, se, ne, nw) | |
+ simulation.grains[idx].lin_pos[1:2], sw, se, ne, nw) | |
i = i_old | |
j = j_old | |
else | |
if grid.regular_grid | |
- i, j = Int.(floor.((simulation.grains[idx].lin_pos - grid.orig… | |
+ i, j = Int.(floor.((simulation.grains[idx].lin_pos[1:2] | |
+ - grid.origo) | |
./ grid.dx[1:2])) + [1,1] | |
else | |
t@@ -185,8 +186,9 @@ function sortGrainsInGrid!(simulation::Simulation, grid::A… | |
j_t = max(min(j_old + j_rel, ny), 1) | |
@inbounds if isPointInCell(grid, i_t, j_t, | |
- simulation.grains[idx].lin_pos, | |
- sw, se, ne, nw) | |
+ simulation.grains[idx]. | |
+ lin_pos[1:2], | |
+ sw, se, ne, nw) | |
i = i_t | |
j = j_t | |
found = true | |
t@@ -201,7 +203,7 @@ function sortGrainsInGrid!(simulation::Simulation, grid::A… | |
if !found | |
i, j = findCellContainingPoint(grid, | |
simulation.grains[idx]. | |
- lin_pos, | |
+ lin_pos[1:2], | |
sw, se, ne, nw) | |
end | |
end | |
t@@ -285,10 +287,10 @@ This function is a wrapper for `getCellCornerCoordinates… | |
function getNonDimensionalCellCoordinates(grid::Any, i::Int, j::Int, | |
point::Vector{Float64}) | |
if grid.regular_grid | |
- return (point - Float64.([i-1,j-1]).*grid.dx[1:2])./grid.dx[1:2] | |
+ return (point[1:2] - Float64.([i-1,j-1]).*grid.dx[1:2])./grid.dx[1:2] | |
else | |
sw, se, ne, nw = getCellCornerCoordinates(grid.xq, grid.yq, i, j) | |
- return conformalQuadrilateralCoordinates(sw, se, ne, nw, point) | |
+ return conformalQuadrilateralCoordinates(sw, se, ne, nw, point[1:2]) | |
end | |
end | |
t@@ -308,7 +310,7 @@ function isPointInCell(grid::Any, i::Int, j::Int, | |
method::String="Conformal") | |
if grid.regular_grid | |
- if [i,j] == Int.(floor.((point - grid.origo) ./ grid.dx[1:2])) + [1,1] | |
+ if [i,j] == Int.(floor.((point[1:2] - grid.origo) ./ grid.dx[1:2])) + … | |
return true | |
else | |
return false | |
t@@ -620,8 +622,8 @@ function findEmptyPositionInGridCell(simulation::Simulatio… | |
# traverse list of grains in the target cell and check | |
# for overlaps | |
for grain_idx in grid.grain_list[it, jt] | |
- overlap = norm(simulation.grains[grain_idx].lin_pos - | |
- pos) - | |
+ overlap = norm(simulation.grains[grain_idx]. | |
+ lin_pos[1:2] - pos) - | |
(simulation.grains[grain_idx].contact_radius + r) | |
if overlap < 0. | |
diff --git a/src/interaction.jl b/src/interaction.jl | |
t@@ -63,10 +63,11 @@ function interactWalls!(sim::Simulation) | |
# get overlap distance by projecting grain position onto wall-norm… | |
# vector. Overlap when δ_n < 0.0 | |
- δ_n = abs(dot(sim.walls[iw].normal, sim.grains[i].lin_pos) - | |
- sim.walls[iw].pos) - sim.grains[i].contact_radius | |
+ δ_n = norm(dot(sim.walls[iw].normal[1:2], | |
+ sim.grains[i].lin_pos[1:2]) - | |
+ sim.walls[iw].pos) - sim.grains[i].contact_radius | |
- vel_n = dot(sim.walls[iw].normal, sim.grains[i].lin_vel) | |
+ vel_n = dot(sim.walls[iw].normal[1:2], sim.grains[i].lin_vel[1:2]) | |
if δ_n < 0. | |
if sim.grains[i].youngs_modulus > 0. | |
t@@ -98,7 +99,7 @@ function interactWalls!(sim::Simulation) | |
end | |
sim.grains[i].force += -force_n .* sim.walls[iw].normal .* | |
- orientation | |
+ orientation | |
sim.walls[iw].force += force_n * orientation | |
end | |
end | |
t@@ -127,7 +128,7 @@ function interactGrains!(simulation::Simulation, i::Int, j… | |
# Inter-position vector, use stored value which is corrected for boundary | |
# periodicity | |
- p = simulation.grains[i].position_vector[ic] | |
+ p = simulation.grains[i].position_vector[ic][1:2] | |
dist = norm(p) | |
r_i = simulation.grains[i].contact_radius | |
t@@ -137,11 +138,12 @@ function interactGrains!(simulation::Simulation, i::Int,… | |
δ_n = dist - (r_i + r_j) | |
# Local axes | |
- n = p/dist | |
+ n = p/max(dist, 1e-12) | |
t = [-n[2], n[1]] | |
- # Contact kinematics | |
- vel_lin = simulation.grains[i].lin_vel - simulation.grains[j].lin_vel | |
+ # Contact kinematics (2d) | |
+ vel_lin = simulation.grains[i].lin_vel[1:2] - | |
+ simulation.grains[j].lin_vel[1:2] | |
vel_n = dot(vel_lin, n) | |
if !simulation.grains[i].rotating && !simulation.grains[j].rotating | |
t@@ -152,25 +154,38 @@ function interactGrains!(simulation::Simulation, i::Int,… | |
if rotation | |
vel_t = dot(vel_lin, t) - | |
- harmonicMean(r_i, r_j)*(simulation.grains[i].ang_vel + | |
- simulation.grains[j].ang_vel) | |
+ harmonicMean(r_i, r_j)*(simulation.grains[i].ang_vel[3] + | |
+ simulation.grains[j].ang_vel[3]) | |
# Correct old tangential displacement for contact rotation and add new | |
- δ_t0 = simulation.grains[i].contact_parallel_displacement[ic] | |
- δ_t = dot(t, δ_t0 - (n*dot(n, δ_t0))) + vel_t*simulation.time_step | |
+ δ_t0 = simulation.grains[i].contact_parallel_displacement[ic][1:2] | |
+ if !simulation.grains[i].compressive_failure[ic] | |
+ δ_t = dot(t, δ_t0 - (n*dot(n, δ_t0))) + vel_t*simulation.time_s… | |
+ else | |
+ # Use δ_t as total slip-distance vector | |
+ δ_t = δ_t0 .+ (vel_lin .+ vel_t.*t) .* simulation.time_step | |
+ end | |
- # Determine the contact rotation | |
- θ_t = simulation.grains[i].contact_rotation[ic] + | |
- (simulation.grains[j].ang_vel - simulation.grains[i].ang_vel) * | |
- simulation.time_step | |
+ # Determine the contact rotation (2d) | |
+ θ_t = simulation.grains[i].contact_rotation[ic][3] + | |
+ (simulation.grains[j].ang_vel[3] - | |
+ simulation.grains[i].ang_vel[3]) * simulation.time_step | |
end | |
# Effective radius | |
R_ij = harmonicMean(r_i, r_j) | |
+ # Determine which ice floe is the thinnest | |
+ h_min, idx_thinnest = findmin([simulation.grains[i].thickness, | |
+ simulation.grains[j].thickness]) | |
+ idx_thinnest == 1 ? idx_thinnest = i : idx_thinnest = j | |
+ | |
+ # Contact length along z | |
+ Lz_ij = h_min | |
+ | |
# Contact area | |
- A_ij = R_ij*min(simulation.grains[i].thickness, | |
- simulation.grains[j].thickness) | |
+ A_ij = R_ij*Lz_ij | |
+ simulation.grains[i].contact_area[ic] = A_ij | |
# Contact mechanical parameters | |
if simulation.grains[i].youngs_modulus > 0. && | |
t@@ -190,7 +205,7 @@ function interactGrains!(simulation::Simulation, i::Int, j… | |
else # Micromechanical parameterization: k_n and k_t set explicitly | |
k_n = harmonicMean(simulation.grains[i].contact_stiffness_normal, | |
- simulation.grains[j].contact_stiffness_normal) | |
+ simulation.grains[j].contact_stiffness_normal) | |
if rotation | |
k_t = harmonicMean(simulation.grains[i].contact_stiffness_tangenti… | |
t@@ -223,26 +238,20 @@ function interactGrains!(simulation::Simulation, i::Int,… | |
end | |
else | |
- error("unknown contact_normal_rheology (k_n = $k_n, γ_n = $γ_n") | |
+ error("unknown contact_normal_rheology (k_n = $k_n, γ_n = $γ_n, | |
+ E = $E, A_ij = $A_ij, R_ij = $R_ij) | |
+ ") | |
end | |
- # Determine which grain is the weakest | |
- compressive_strength = simulation.grains[i].fracture_toughness * | |
- sqrt(simulation.grains[i].thickness) | |
- compressive_strength_j = simulation.grains[j].fracture_toughness * | |
- sqrt(simulation.grains[j].thickness) | |
- idx_weakest = i | |
- if compressive_strength_j < compressive_strength | |
- compressive_strength = compressive_strength_j | |
- idx_weakest = j | |
- end | |
+ # Determine the compressive strength in Pa by the contact thickness and the | |
+ # minimum compressive strength [N] | |
+ compressive_strength = min(simulation.grains[i].fracture_toughness, | |
+ simulation.grains[j].fracture_toughness) * | |
+ Lz_ij^1.5 | |
# Grain-pair moment of inertia [m^4] | |
- if rotation | |
- I_ij = 2.0/3.0*R_ij^3*min(simulation.grains[i].thickness, | |
- simulation.grains[j].thickness) | |
- end | |
- | |
+ I_ij = 2.0/3.0*R_ij^3*min(simulation.grains[i].thickness, | |
+ simulation.grains[j].thickness) | |
# Contact tensile strength increases linearly with contact age until | |
# tensile stress exceeds tensile strength. | |
t@@ -264,7 +273,7 @@ function interactGrains!(simulation::Simulation, i::Int, j… | |
# Reset contact age (breaking bond) if bond strength is exceeded | |
if rotation | |
- if δ_n >= 0.0 && abs(force_n)/A_ij + abs(M_t)*R_ij/I_ij > tensile_str… | |
+ if δ_n >= 0.0 && norm(force_n)/A_ij + norm(M_t)*R_ij/I_ij > tensile_s… | |
force_n = 0. | |
force_t = 0. | |
simulation.grains[i].contacts[ic] = 0 # remove contact | |
t@@ -272,7 +281,7 @@ function interactGrains!(simulation::Simulation, i::Int, j… | |
simulation.grains[j].n_contacts -= 1 | |
end | |
else | |
- if δ_n >= 0.0 && abs(force_n)/A_ij > tensile_strength | |
+ if δ_n >= 0.0 && norm(force_n)/A_ij > tensile_strength | |
force_n = 0. | |
force_t = 0. | |
simulation.grains[i].contacts[ic] = 0 # remove contact | |
t@@ -281,36 +290,20 @@ function interactGrains!(simulation::Simulation, i::Int,… | |
end | |
end | |
- # Limit compressive stress if the prefactor is set to a positive value | |
- if δ_n <= 0.0 && compressive_strength > 0. && | |
- abs(force_n) >= compressive_strength | |
- | |
- # Determine the overlap distance where yeild stress is reached | |
- δ_n_yield = -compressive_strength*A_ij/k_n | |
- | |
- # Determine the excess overlap distance relative to yield | |
- Δr = abs(δ_n) - abs(δ_n_yield) | |
- | |
- # Adjust radius and thickness of the weakest grain | |
- simulation.grains[idx_weakest].contact_radius -= Δr | |
- simulation.grains[idx_weakest].areal_radius -= Δr | |
- simulation.grains[idx_weakest].thickness += 1.0/(π*Δr) | |
- end | |
- | |
- if rotation | |
+ if rotation && !simulation.grains[i].compressive_failure[ic] | |
if k_t ≈ 0. && γ_t ≈ 0. | |
# do nothing | |
elseif k_t ≈ 0. && γ_t > 0. | |
- force_t = abs(γ_t * vel_t) | |
+ force_t = norm(γ_t * vel_t) | |
# Coulomb slip | |
- if force_t > μ_d_minimum*abs(force_n) | |
- force_t = μ_d_minimum*abs(force_n) | |
+ if force_t > μ_d_minimum*norm(force_n) | |
+ force_t = μ_d_minimum*norm(force_n) | |
# Nguyen et al 2009 "Thermomechanical modelling of friction ef… | |
# in granular flows using the discrete element method" | |
- E_shear = abs(force_t)*abs(vel_t)*simulation.time_step | |
+ E_shear = norm(force_t)*norm(vel_t)*simulation.time_step | |
# Assume equal thermal properties | |
simulation.grains[i].thermal_energy += 0.5*E_shear | |
t@@ -325,13 +318,13 @@ function interactGrains!(simulation::Simulation, i::Int,… | |
force_t = -k_t*δ_t - γ_t*vel_t | |
# Coulomb slip | |
- if abs(force_t) > μ_d_minimum*abs(force_n) | |
- force_t = μ_d_minimum*abs(force_n)*force_t/abs(force_t) | |
+ if norm(force_t) > μ_d_minimum*norm(force_n) | |
+ force_t = μ_d_minimum*norm(force_n)*force_t/norm(force_t) | |
δ_t = (-force_t - γ_t*vel_t)/k_t | |
- # Nguyen et al 2009 "Thermomechanical modelling of friction ef… | |
- # in granular flows using the discrete element method" | |
- E_shear = abs(force_t)*abs(vel_t)*simulation.time_step | |
+ # Nguyen et al 2009 "Thermomechanical modelling of friction | |
+ # effects in granular flows using the discrete element method" | |
+ E_shear = norm(force_t)*norm(vel_t)*simulation.time_step | |
# Assume equal thermal properties | |
simulation.grains[i].thermal_energy += 0.5*E_shear | |
t@@ -343,28 +336,104 @@ function interactGrains!(simulation::Simulation, i::Int… | |
end | |
end | |
+ just_failed = false | |
+ # Detect compressive failure if compressive force exceeds compressive | |
+ # strength | |
+ if δ_n <= 0.0 && compressive_strength > 0. && | |
+ !simulation.grains[i].compressive_failure[ic] && | |
+ norm(force_n.*n .+ force_t.*t) >= compressive_strength | |
+ | |
+ # Register that compressive failure has occurred for this contact | |
+ simulation.grains[i].compressive_failure[ic] = true | |
+ just_failed = true | |
+ end | |
+ | |
+ # Overwrite previous force results if compressive failure occurred | |
+ if simulation.grains[i].compressive_failure[ic] && δ_n < 0.0 | |
+ | |
+ # Normal stress on horizontal interface, assuming bending stresses are | |
+ # negligible (ocean density and gravity are hardcoded for now) | |
+ σ_n = (1e3 - simulation.grains[i].density) * 9.81 * | |
+ (simulation.grains[i].thickness + simulation.grains[j].thickness) | |
+ | |
+ # Horizontal overlap area (two overlapping circles) | |
+ if 2.0*min(r_i, r_j) <= abs(δ_n) | |
+ | |
+ # Complete overlap | |
+ A_h = π*min(r_i, r_j)^2 | |
+ | |
+ else | |
+ # Partial overlap, eq 14 from | |
+ # http://mathworld.wolfram.com/Circle-CircleIntersection.html | |
+ A_h = r_i^2.0*acos((dist^2.0 + r_i^2.0 - r_j^2.0)/(2.0*dist*r_i)) + | |
+ r_j^2.0*acos((dist^2.0 + r_j^2.0 - r_i^2.0)/(2.0*dist*r_j)) - | |
+ 0.5*sqrt((-dist + r_i + r_j)* | |
+ ( dist + r_i - r_j)* | |
+ ( dist - r_i + r_j)* | |
+ ( dist + r_i + r_j)) | |
+ end | |
+ simulation.grains[i].contact_area[ic] = A_h | |
+ | |
+ if just_failed | |
+ # Use δ_t as travel distance on horizontal slip surface, and set … | |
+ # original displacement to Coulomb-frictional limit in the directi… | |
+ # of the pre-failure force | |
+ F = force_n.*n .+ force_t.*t | |
+ σ_t = μ_d_minimum*norm(σ_n).*F/norm(F) | |
+ δ_t = σ_t*A_h/(-k_t) | |
+ | |
+ # Save energy loss in E_shear | |
+ E_shear = norm(F)*norm(vel_lin)*simulation.time_step | |
+ simulation.grains[i].thermal_energy += 0.5*E_shear | |
+ simulation.grains[j].thermal_energy += 0.5*E_shear | |
+ | |
+ else | |
+ | |
+ # Find horizontal stress on slip interface | |
+ σ_t = -k_t*δ_t/A_h | |
+ | |
+ # Check for Coulomb-failure on the slip interface | |
+ if norm(σ_t) > μ_d_minimum*norm(σ_n) | |
+ | |
+ σ_t = μ_d_minimum*norm(σ_n)*σ_t/norm(σ_t) | |
+ δ_t = σ_t*A_h/(-k_t) | |
+ | |
+ E_shear = norm(σ_t*A_h)*norm(vel_lin)*simulation.time_step | |
+ simulation.grains[i].thermal_energy += 0.5*E_shear | |
+ simulation.grains[j].thermal_energy += 0.5*E_shear | |
+ end | |
+ end | |
+ | |
+ force_n = dot(σ_t, n)*A_h | |
+ force_t = dot(σ_t, t)*A_h | |
+ end | |
+ | |
# Break bond under extension through bending failure | |
if δ_n < 0.0 && tensile_strength > 0.0 && rotation && | |
- shear_strength > 0.0 && abs(force_t)/A_ij > shear_strength | |
+ shear_strength > 0.0 && norm(force_t)/A_ij > shear_strength | |
force_n = 0. | |
force_t = 0. | |
simulation.grains[i].contacts[ic] = 0 # remove contact | |
simulation.grains[i].n_contacts -= 1 | |
simulation.grains[j].n_contacts -= 1 | |
+ else | |
+ simulation.grains[i].contact_age[ic] += simulation.time_step | |
end | |
- simulation.grains[i].contact_age[ic] += simulation.time_step | |
- | |
if rotation | |
- simulation.grains[i].contact_parallel_displacement[ic] = δ_t*t | |
- simulation.grains[i].contact_rotation[ic] = θ_t | |
+ if simulation.grains[i].compressive_failure[ic] | |
+ simulation.grains[i].contact_parallel_displacement[ic] = vecTo3d(�… | |
+ else | |
+ simulation.grains[i].contact_parallel_displacement[ic] = vecTo3d(�… | |
+ end | |
+ simulation.grains[i].contact_rotation[ic] = [0., 0., θ_t] | |
- simulation.grains[i].force += force_n*n + force_t*t; | |
- simulation.grains[j].force -= force_n*n + force_t*t; | |
+ simulation.grains[i].force += vecTo3d(force_n.*n + force_t.*t); | |
+ simulation.grains[j].force -= vecTo3d(force_n.*n + force_t.*t); | |
- simulation.grains[i].torque += -force_t*R_ij + M_t | |
- simulation.grains[j].torque += -force_t*R_ij - M_t | |
+ simulation.grains[i].torque[3] += -force_t*R_ij + M_t | |
+ simulation.grains[j].torque[3] += -force_t*R_ij - M_t | |
else | |
simulation.grains[i].force += force_n*n; | |
simulation.grains[j].force -= force_n*n; | |
diff --git a/src/io.jl b/src/io.jl | |
t@@ -393,6 +393,8 @@ function writeGrainVTK(simulation::Simulation, | |
"Fixed but allow (x) acceleration [-]") | |
WriteVTK.vtk_point_data(vtkfile, ifarr.allow_y_acc, | |
"Fixed but allow (y) acceleration [-]") | |
+ WriteVTK.vtk_point_data(vtkfile, ifarr.allow_z_acc, | |
+ "Fixed but allow (z) acceleration [-]") | |
WriteVTK.vtk_point_data(vtkfile, ifarr.rotating, "Free to rotate [-]") | |
WriteVTK.vtk_point_data(vtkfile, ifarr.enabled, "Enabled [-]") | |
t@@ -481,8 +483,10 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
contact_stiffness = Float64[] | |
tensile_stress = Float64[] | |
shear_displacement = Vector{Float64}[] | |
- contact_rotation = Float64[] | |
+ contact_rotation = Vector{Float64}[] | |
contact_age = Float64[] | |
+ contact_area = Float64[] | |
+ compressive_failure = Int[] | |
for i=1:length(simulation.grains) | |
for ic=1:simulation.Nc_max | |
t@@ -549,6 +553,9 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
simulation.grains[i].contact_rotation[ic]) | |
push!(contact_age, simulation.grains[i].contact_age[ic]) | |
+ push!(contact_area, simulation.grains[i].contact_area[ic]) | |
+ push!(compressive_failure, | |
+ Int(simulation.grains[i].compressive_failure[ic])) | |
end | |
end | |
end | |
t@@ -577,7 +584,7 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
for i=1:length(i1) | |
write(f, "$(inter_particle_vector[i][1]) ") | |
write(f, "$(inter_particle_vector[i][2]) ") | |
- write(f, "0.0 ") | |
+ write(f, "$(inter_particle_vector[i][3]) ") | |
end | |
write(f, "\n") | |
write(f, " </DataArray>\n") | |
t@@ -587,7 +594,7 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
for i=1:length(i1) | |
@inbounds write(f, "$(shear_displacement[i][1]) ") | |
@inbounds write(f, "$(shear_displacement[i][2]) ") | |
- write(f, "0.0 ") | |
+ @inbounds write(f, "$(shear_displacement[i][3]) ") | |
end | |
write(f, "\n") | |
write(f, " </DataArray>\n") | |
t@@ -637,10 +644,12 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
write(f, " </DataArray>\n") | |
write(f, " <DataArray type=\"Float32\" " * | |
- "Name=\"Contact rotation [rad]\" NumberOfComponents=\"1\" | |
+ "Name=\"Contact rotation [rad]\" NumberOfComponents=\"3\" | |
format=\"ascii\">\n") | |
for i=1:length(i1) | |
- @inbounds write(f, "$(contact_rotation[i]) ") | |
+ @inbounds write(f, "$(contact_rotation[i][1]) ") | |
+ @inbounds write(f, "$(contact_rotation[i][2]) ") | |
+ @inbounds write(f, "$(contact_rotation[i][3]) ") | |
end | |
write(f, "\n") | |
write(f, " </DataArray>\n") | |
t@@ -654,6 +663,24 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
write(f, "\n") | |
write(f, " </DataArray>\n") | |
+ write(f, " <DataArray type=\"Float32\" " * | |
+ "Name=\"Contact area [m*m]\" NumberOfComponents=\"1\" | |
+ format=\"ascii\">\n") | |
+ for i=1:length(i1) | |
+ @inbounds write(f, "$(contact_area[i]) ") | |
+ end | |
+ write(f, "\n") | |
+ write(f, " </DataArray>\n") | |
+ | |
+ write(f, " <DataArray type=\"Float32\" " * | |
+ "Name=\"Compressive failure [-]\" NumberOfComponents=\"1\" | |
+ format=\"ascii\">\n") | |
+ for i=1:length(i1) | |
+ @inbounds write(f, "$(Int(compressive_failure[i])) ") | |
+ end | |
+ write(f, "\n") | |
+ write(f, " </DataArray>\n") | |
+ | |
write(f, " </CellData>\n") | |
write(f, " <Points>\n") | |
t@@ -662,7 +689,7 @@ function writeGrainInteractionVTK(simulation::Simulation, | |
write(f, " <DataArray type=\"Float32\" Name=\"Points\" " * | |
"NumberOfComponents=\"3\" format=\"ascii\">\n") | |
for i in simulation.grains | |
- @inbounds write(f, "$(i.lin_pos[1]) $(i.lin_pos[2]) 0.0 ") | |
+ @inbounds write(f, "$(i.lin_pos[1]) $(i.lin_pos[2]) $(i.lin_pos[3]… | |
end | |
write(f, "\n") | |
write(f, " </DataArray>\n") | |
t@@ -868,6 +895,7 @@ imagegrains.PointArrayStatus = [ | |
'Fixed in space [-]', | |
'Fixed but allow (x) acceleration [-]', | |
'Fixed but allow (y) acceleration [-]', | |
+'Fixed but allow (z) acceleration [-]', | |
'Free to rotate [-]', | |
'Enabled [-]', | |
'Contact stiffness (normal) [N m^-1]', | |
t@@ -1103,6 +1131,12 @@ function render(simulation::Simulation; pvpython::Strin… | |
if isfile("$(simulation.id)/$(simulation.id).mp4") | |
rm("$(simulation.id)/$(simulation.id).avi") | |
end | |
+ catch return_signal | |
+ if isa(return_signal, Base.UVError) | |
+ Compat.@warn "Could not run external ffmpeg command, " * | |
+ "skipping conversion from " * | |
+ "$(simulation.id)/$(simulation.id).avi to mp4." | |
+ end | |
end | |
end | |
t@@ -1131,7 +1165,7 @@ function render(simulation::Simulation; pvpython::String… | |
end | |
catch return_signal | |
if isa(return_signal, Base.UVError) | |
- Compat.@info "Skipping gif merge since `$convert` " * | |
+ Compat.@warn "Skipping gif merge since `$convert` " * | |
"was not found." | |
end | |
end | |
t@@ -1321,8 +1355,9 @@ function plotGrains(sim::Simulation; | |
contact_stiffness = Float64[] | |
tensile_stress = Float64[] | |
shear_displacement = Vector{Float64}[] | |
- contact_rotation = Float64[] | |
+ contact_rotation = Vector{Float64}[] | |
contact_age = Float64[] | |
+ compressive_failure = Int[] | |
for i=1:length(sim.grains) | |
for ic=1:sim.Nc_max | |
if sim.grains[i].contacts[ic] > 0 | |
t@@ -1374,6 +1409,8 @@ function plotGrains(sim::Simulation; | |
sim.grains[i].contact_rotation[ic]) | |
push!(contact_age, sim.grains[i].contact_age[ic]) | |
+ push!(compressive_failure, | |
+ sim.grains[i].compressive_failure[ic]) | |
end | |
end | |
end | |
diff --git a/src/ocean.jl b/src/ocean.jl | |
t@@ -388,10 +388,10 @@ function applyOceanDragToGrain!(grain::GrainCylindrical, | |
drag_force = ρ_o * π * | |
(2.0*grain.ocean_drag_coeff_vert*grain.areal_radius*draft + | |
grain.ocean_drag_coeff_horiz*grain.areal_radius^2.0) * | |
- ([u, v] - grain.lin_vel)*norm([u, v] - grain.lin_vel) | |
+ ([u, v] - grain.lin_vel[1:2])*norm([u, v] - grain.lin_vel[1:2]) | |
- grain.force += drag_force | |
- grain.ocean_stress = drag_force/grain.horizontal_surface_area | |
+ grain.force += vecTo3d(drag_force) | |
+ grain.ocean_stress = vecTo3d(drag_force/grain.horizontal_surface_area) | |
nothing | |
end | |
t@@ -407,11 +407,12 @@ function applyOceanVorticityToGrain!(grain::GrainCylindr… | |
ρ_o = 1000. # ocean density | |
draft = grain.thickness - freeboard # height of submerged thickness | |
- grain.torque += | |
+ grain.torque[3] += | |
π * grain.areal_radius^4. * ρ_o * | |
(grain.areal_radius/5. * grain.ocean_drag_coeff_horiz + | |
draft * grain.ocean_drag_coeff_vert) * | |
- abs(.5 * ocean_curl - grain.ang_vel) * (.5 * ocean_curl - grain.ang_ve… | |
+ norm(.5 * ocean_curl - grain.ang_vel[3]) * | |
+ (.5 * ocean_curl - grain.ang_vel[3]) | |
nothing | |
end | |
diff --git a/src/packing.jl b/src/packing.jl | |
t@@ -124,7 +124,7 @@ function generateNeighboringPoint(x_i::Vector, r_i::Real, | |
#R = rand() * (r_i + r_j) * max_padding_factor + 2. * (r_i + r_j) | |
R = r_i + r_j + padding | |
T = rand() * 2. * pi | |
- return [x_i[1] + R * sin(T), x_i[2] + R * cos(T)], r_j | |
+ return [x_i[1] + R * sin(T), x_i[2] + R * cos(T), x_i[3]], r_j | |
end | |
function generateRandomDirection() | |
t@@ -132,7 +132,7 @@ function generateRandomDirection() | |
end | |
function getPositionDistancedFromPoint(T::Real, x_i::Vector, dist::Real) | |
- return [x_i[1] + dist * sin(T), x_i[2] + dist * cos(T)] | |
+ return [x_i[1] + dist * sin(T), x_i[2] + dist * cos(T), x_i[3]] | |
end | |
export irregularPacking! | |
t@@ -224,7 +224,7 @@ function irregularPacking!(simulation::Simulation; | |
# and add it to the active list. If after `sample_limit` attempts no such | |
# point is found, instead remove `i` from the active list. | |
j = 0; | |
- x_active = zeros(2); x_candidate = zeros(2); | |
+ x_active = zeros(3); x_candidate = zeros(3); | |
r_active = 0.; r_candidate = 0.; T = 0. | |
n = 0 | |
neighbor_found = false | |
t@@ -456,9 +456,9 @@ function rasterMap(sim::Simulation, dx::Real) | |
#i, j = Int.(floor.((grain.lin_pos - origo) ./ dx)) + [1,1] | |
# Find corner indexes for box spanning the grain | |
- min_i, min_j = Int.(floor.((grain.lin_pos - origo .- | |
+ min_i, min_j = Int.(floor.((grain.lin_pos[1:2] - origo .- | |
grain.contact_radius) ./ dx)) .+ [1,1] | |
- max_i, max_j = Int.(floor.((grain.lin_pos - origo .+ | |
+ max_i, max_j = Int.(floor.((grain.lin_pos[1:2] - origo .+ | |
grain.contact_radius) ./ dx)) .+ [1,1] | |
# For each cell in box, check if the grain is contained | |
t@@ -466,7 +466,7 @@ function rasterMap(sim::Simulation, dx::Real) | |
for j = min_j:max_j | |
cell_mid_point = dx .* Vector{Float64}([i,j]) .- 0.5 * dx | |
- if (norm(cell_mid_point - grain.lin_pos) - | |
+ if (norm(cell_mid_point - grain.lin_pos[1:2]) - | |
grain.contact_radius < dist) | |
occupied[i,j] = true | |
end | |
diff --git a/src/simulation.jl b/src/simulation.jl | |
t@@ -259,7 +259,7 @@ export zeroForcesAndTorques! | |
function zeroForcesAndTorques!(simulation::Simulation) | |
for grain in simulation.grains | |
grain.force .= grain.external_body_force | |
- grain.torque = 0. | |
+ grain.torque = zeros(3) | |
grain.pressure = 0. | |
end | |
for wall in simulation.walls | |
diff --git a/src/temporal_integration.jl b/src/temporal_integration.jl | |
t@@ -51,7 +51,7 @@ Use a two-term Taylor expansion for integrating the kinemati… | |
for a `grain`. | |
""" | |
function updateGrainKinematicsTwoTermTaylor!(grain::GrainCylindrical, | |
- simulation::Simulation) | |
+ simulation::Simulation) | |
grain.lin_acc = grain.force/grain.mass | |
grain.ang_acc = grain.torque/grain.moment_of_inertia | |
t@@ -62,9 +62,12 @@ function updateGrainKinematicsTwoTermTaylor!(grain::GrainCy… | |
if !grain.allow_y_acc | |
grain.lin_acc[2] = 0. | |
end | |
- grain.ang_acc = 0. | |
+ if !grain.allow_z_acc | |
+ grain.lin_acc[3] = 0. | |
+ end | |
+ grain.ang_acc = zeros(3) | |
elseif !grain.rotating | |
- grain.ang_acc = 0. | |
+ grain.ang_acc = zeros(3) | |
end | |
grain.lin_pos += | |
t@@ -90,11 +93,11 @@ Use a three-term Taylor expansion for integrating the kine… | |
freedom for a `grain`. | |
""" | |
function updateGrainKinematicsThreeTermTaylor!(grain::GrainCylindrical, | |
- simulation::Simulation) | |
+ simulation::Simulation) | |
if simulation.time_iteration == 0 | |
- lin_acc_0 = zeros(2) | |
- ang_acc_0 = 0. | |
+ lin_acc_0 = zeros(3) | |
+ ang_acc_0 = zeros(3) | |
else | |
lin_acc_0 = grain.lin_acc | |
ang_acc_0 = grain.ang_acc | |
t@@ -110,9 +113,12 @@ function updateGrainKinematicsThreeTermTaylor!(grain::Gra… | |
if !grain.allow_y_acc | |
grain.lin_acc[2] = 0. | |
end | |
- grain.ang_acc = 0. | |
+ if !grain.allow_z_acc | |
+ grain.lin_acc[3] = 0. | |
+ end | |
+ grain.ang_acc = zeros(3) | |
elseif !grain.rotating | |
- grain.ang_acc = 0. | |
+ grain.ang_acc = zeros(3) | |
end | |
# Temporal gradient in acceleration using backwards differences | |
diff --git a/src/util.jl b/src/util.jl | |
t@@ -42,3 +42,31 @@ function harmonicMean(a::Number, b::Number)::Number | |
return 2. * a * b / (a + b) | |
end | |
end | |
+ | |
+export vecTo3d | |
+""" | |
+ function vecTo3d(input, fill) | |
+ | |
+Convert a scalar or 2d vector to 3d by filling the missing component with the | |
+value `fill`. The returned 3-component vector is a Vector (or 1d Array) of | |
+the same type as the input. | |
+ | |
+# Arguments | |
+* `input`: a scalar or two-component vector. | |
+* `fill::Real`: value to use for third | |
+""" | |
+function vecTo3d(input::Any; fill::Real = 0.0) | |
+ if length(input) > 3 | |
+ error("vecTo3d requires a scalar or input vector to of length 3 or " * | |
+ "less, but input is $input") | |
+ elseif length(input) == 3 | |
+ return input | |
+ elseif length(input) == 2 | |
+ return [input[1], input[2], typeof(input[1])(fill)] | |
+ elseif length(input) == 1 | |
+ return [input[1], typeof(input[1])(fill), typeof(input[1])(fill)] | |
+ else | |
+ error("input not understood: $input") | |
+ end | |
+end | |
+ | |
diff --git a/src/wall.jl b/src/wall.jl | |
t@@ -16,9 +16,10 @@ The only required arguments are | |
# Arguments | |
* `simulation::Simulation`: the simulation object where the wall should be | |
added to. | |
-* `normal::Vector{Float64}`: 2d vector denoting the normal to the wall [m]. T… | |
+* `normal::Vector{Float64}`: 3d vector denoting the normal to the wall [m]. T… | |
wall will only interact in the opposite direction of this vector, so the | |
- normal vector should point in the direction of the grains. | |
+ normal vector should point in the direction of the grains. If a 2d vector … | |
+ passed, the third (z) component is set to zero. | |
* `pos::Float64`: position along axis parallel to the normal vector [m]. | |
* `bc::String="fixed"`: boundary condition, possible values are `"fixed"` | |
(default), `"normal stress"`, or `"velocity"`. | |
t@@ -50,13 +51,13 @@ wall-face normal of `[1., 0.]` (wall along *y* and normal … | |
`1.5` meter: | |
```julia | |
-Granular.addWallLinearFrictionless!(sim, [1., 0.], 1.5) | |
+Granular.addWallLinearFrictionless!(sim, [1., 0., 0.], 1.5) | |
``` | |
The following example creates a wall with a velocity of 0.5 m/s towards *-y*: | |
```julia | |
-Granular.addWallLinearFrictionless!(sim, [0., 1.], 1.5, | |
+Granular.addWallLinearFrictionless!(sim, [0., 1., 0.], 1.5, | |
bc="velocity", | |
vel=-0.5) | |
``` | |
t@@ -65,7 +66,7 @@ To create a wall parallel to the *y* axis pushing downwards … | |
normal stress of 100 kPa, starting at a position of y = 3.5 m: | |
```julia | |
-Granular.addWallLinearFrictionless!(sim, [0., 1.], 3.5, | |
+Granular.addWallLinearFrictionless!(sim, [0., 1., 0.], 3.5, | |
bc="normal stress", | |
normal_stress=100e3) | |
``` | |
t@@ -85,20 +86,19 @@ function addWallLinearFrictionless!(simulation::Simulation, | |
verbose::Bool=true) | |
# Check input values | |
- if length(normal) != 2 | |
- error("Wall normal must be a two-element array (normal = " * | |
- "$normal)") | |
+ if length(normal) != 3 | |
+ normal = vecTo3d(normal) | |
end | |
if bc != "fixed" && bc != "velocity" && bc != "normal stress" | |
error("Wall BC must be 'fixed', 'velocity', or 'normal stress'.") | |
end | |
- if !(normal ≈ [1., 0.]) && !(normal ≈ [0., 1.]) | |
+ if !(normal ≈ [1., 0., 0.]) && !(normal ≈ [0., 1., 0.]) | |
error("Currently only walls with normals orthogonal to the " * | |
"coordinate system are allowed, i.e. normals parallel to the " * | |
"x or y axes. Accepted values for `normal` " * | |
- "are [1., 0.] and [0., 1.]. The passed normal was $normal") | |
+ "are [1., 0., 0.] and [0., 1., 0.]. The passed normal was $norma… | |
end | |
# if not set, set wall mass to equal the mass of all grains. | |
t@@ -171,10 +171,10 @@ Returns the surface area of the wall given the grid size… | |
""" | |
function getWallSurfaceArea(sim::Simulation, wall_index::Integer) | |
- if sim.walls[wall_index].normal ≈ [1., 0.] | |
+ if sim.walls[wall_index].normal ≈ [1., 0., 0.] | |
return (sim.ocean.yq[end,end] - sim.ocean.yq[1,1]) * | |
sim.walls[wall_index].thickness | |
- elseif sim.walls[wall_index].normal ≈ [0., 1.] | |
+ elseif sim.walls[wall_index].normal ≈ [0., 1., 0.] | |
return (sim.ocean.xq[end,end] - sim.ocean.xq[1,1]) * | |
sim.walls[wall_index].thickness | |
else | |
t@@ -185,9 +185,9 @@ end | |
function getWallSurfaceArea(sim::Simulation, normal::Vector{Float64}, | |
thickness::Float64) | |
- if normal ≈ [1., 0.] | |
+ if length(normal) == 3 && normal ≈ [1., 0., 0.] | |
return (sim.ocean.yq[end,end] - sim.ocean.yq[1,1]) * thickness | |
- elseif normal ≈ [0., 1.] | |
+ elseif length(normal) == 3 && normal ≈ [0., 1., 0.] | |
return (sim.ocean.xq[end,end] - sim.ocean.xq[1,1]) * thickness | |
else | |
error("Wall normal not understood") | |
diff --git a/test/atmosphere.jl b/test/atmosphere.jl | |
t@@ -3,8 +3,6 @@ | |
# Check if atmosphere-specific functions and grid operations are functioning | |
# correctly | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Testing regular grid generation" | |
sim = Granular.createSimulation() | |
sim.atmosphere = Granular.createRegularAtmosphereGrid([6, 6, 6], [1., 1., 1.]) | |
t@@ -54,15 +52,15 @@ E_kin_rot_final = Granular.totalGrainKineticRotationalEner… | |
Compat.@info "Testing vortex interaction (static atmosphere)" | |
sim = deepcopy(sim_init) | |
-sim.grains[1].ang_vel = 0.1 | |
+sim.grains[1].ang_vel[3] = 0.1 | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_rot_init > E_kin_rot_final # energy lost to atmosphere | |
-@test sim.grains[1].ang_vel > 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos > 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] > 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] > 0. # check angular position orientation | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
Compat.@info "Testing vortex interaction (static ice floe)" | |
t@@ -77,8 +75,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel > 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos > 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] > 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] > 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to atm vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
t@@ -93,8 +91,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel < 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos < 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] < 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] < 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to atm vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
t@@ -109,8 +107,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnerg… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel < 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos < 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] < 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] < 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to atm vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
t@@ -125,8 +123,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnerg… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel > 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos > 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] > 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] > 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to atm vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
diff --git a/test/cohesion.jl b/test/cohesion.jl | |
t@@ -5,8 +5,6 @@ import Granular | |
# Check for conservation of kinetic energy (=momentum) during a normal collisi… | |
# between two ice cylindrical grains | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
verbose=false | |
sim_init = Granular.createSimulation() | |
t@@ -21,6 +19,7 @@ sim = deepcopy(sim_init) | |
Granular.setTotalTime!(sim, 10.) | |
sim.time_step = 1. | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].contact_age[1] ≈ sim.time | |
Compat.@info "# Check if bonds add tensile strength" | |
t@@ -31,12 +30,13 @@ sim.grains[1].lin_vel[1] = 0.1 | |
Granular.setTimeStep!(sim) | |
Granular.setTotalTime!(sim, 10.) | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].lin_vel[1] > 0. | |
@test sim.grains[1].lin_vel[2] ≈ 0. | |
@test sim.grains[2].lin_vel[1] > 0. | |
@test sim.grains[2].lin_vel[2] ≈ 0. | |
-@test sim.grains[1].ang_vel ≈ 0. | |
-@test sim.grains[2].ang_vel ≈ 0. | |
+@test sim.grains[1].ang_vel ≈ zeros(3) | |
+@test sim.grains[2].ang_vel ≈ zeros(3) | |
Compat.@info "# Add shear strength and test bending resistance (one grain rota… | |
sim = Granular.createSimulation(id="cohesion") | |
t@@ -44,7 +44,7 @@ Granular.addGrainCylindrical!(sim, [0., 0.], 10.1, 1., tensi… | |
shear_strength=500e3) | |
Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, | |
shear_strength=500e3) | |
-sim.grains[1].ang_vel = 0.1 | |
+sim.grains[1].ang_vel[3] = 0.1 | |
Granular.findContacts!(sim) # make sure contact is registered | |
sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
t@@ -53,12 +53,13 @@ Granular.setTimeStep!(sim) | |
Granular.setTotalTime!(sim, 5.) | |
#Granular.setOutputFileInterval!(sim, 0.1) | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].lin_vel[1] ≈ 0. | |
@test sim.grains[1].lin_vel[2] ≈ 0. | |
@test sim.grains[2].lin_vel[1] ≈ 0. | |
@test sim.grains[2].lin_vel[2] ≈ 0. | |
-@test sim.grains[1].ang_vel != 0. | |
-@test sim.grains[2].ang_vel != 0. | |
+@test sim.grains[1].ang_vel[3] != 0. | |
+@test sim.grains[2].ang_vel[3] != 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
E_therm_final = Granular.totalGrainThermalEnergy(sim) | |
t@@ -71,7 +72,7 @@ Granular.addGrainCylindrical!(sim, [0., 0.], 10.1, 1., tensi… | |
shear_strength=500e3) | |
Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, | |
shear_strength=500e3) | |
-sim.grains[2].ang_vel = 0.1 | |
+sim.grains[2].ang_vel[3] = 0.1 | |
Granular.findContacts!(sim) # make sure contact is registered | |
sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
t@@ -80,12 +81,13 @@ Granular.setTimeStep!(sim) | |
Granular.setTotalTime!(sim, 5.) | |
#Granular.setOutputFileInterval!(sim, 0.1) | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].lin_vel[1] ≈ 0. | |
@test sim.grains[1].lin_vel[2] ≈ 0. | |
@test sim.grains[2].lin_vel[1] ≈ 0. | |
@test sim.grains[2].lin_vel[2] ≈ 0. | |
-@test sim.grains[1].ang_vel != 0. | |
-@test sim.grains[2].ang_vel != 0. | |
+@test sim.grains[1].ang_vel[3] != 0. | |
+@test sim.grains[2].ang_vel[3] != 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
E_therm_final = Granular.totalGrainThermalEnergy(sim) | |
t@@ -98,8 +100,8 @@ Granular.addGrainCylindrical!(sim, [0., 0.], 10.0000001, 1.… | |
shear_strength=500e3) | |
Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, | |
shear_strength=500e3) | |
-sim.grains[1].ang_vel = 0.1 | |
-sim.grains[2].ang_vel = -0.1 | |
+sim.grains[1].ang_vel[3] = 0.1 | |
+sim.grains[2].ang_vel[3] = -0.1 | |
Granular.findContacts!(sim) # make sure contact is registered | |
sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
t@@ -108,12 +110,13 @@ Granular.setTimeStep!(sim) | |
Granular.setTotalTime!(sim, 5.) | |
#Granular.setOutputFileInterval!(sim, 0.1) | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].lin_vel[1] ≈ 0. | |
@test sim.grains[1].lin_vel[2] ≈ 0. | |
@test sim.grains[2].lin_vel[1] ≈ 0. | |
@test sim.grains[2].lin_vel[2] ≈ 0. | |
-@test sim.grains[1].ang_vel != 0. | |
-@test sim.grains[2].ang_vel != 0. | |
+@test sim.grains[1].ang_vel[3] != 0. | |
+@test sim.grains[2].ang_vel[3] != 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
E_therm_final = Granular.totalGrainThermalEnergy(sim) | |
t@@ -126,8 +129,8 @@ Granular.addGrainCylindrical!(sim, [0., 0.], 10.0000001, 1… | |
shear_strength=500e3) | |
Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, | |
shear_strength=500e3) | |
-sim.grains[1].ang_vel = 100 | |
-sim.grains[2].ang_vel = -100 | |
+sim.grains[1].ang_vel[3] = 100 | |
+sim.grains[2].ang_vel[3] = -100 | |
Granular.findContacts!(sim) # make sure contact is registered | |
sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
t@@ -136,12 +139,13 @@ Granular.setTimeStep!(sim) | |
Granular.setTotalTime!(sim, 5.) | |
#Granular.setOutputFileInterval!(sim, 0.1) | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].lin_vel[1] ≈ 0. | |
@test sim.grains[1].lin_vel[2] ≈ 0. | |
@test sim.grains[2].lin_vel[1] ≈ 0. | |
@test sim.grains[2].lin_vel[2] ≈ 0. | |
-@test sim.grains[1].ang_vel != 0. | |
-@test sim.grains[2].ang_vel != 0. | |
+@test sim.grains[1].ang_vel[3] != 0. | |
+@test sim.grains[2].ang_vel[3] != 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
E_therm_final = Granular.totalGrainThermalEnergy(sim) | |
t@@ -155,8 +159,8 @@ Granular.addGrainCylindrical!(sim, [0., 0.], 10.1, 1., ten… | |
shear_strength=50e3) | |
Granular.addGrainCylindrical!(sim, [20., 0.], 10., 1., tensile_strength=500e3, | |
shear_strength=50e3) | |
-sim.grains[1].ang_vel = 100 | |
-sim.grains[2].ang_vel = 0.0 | |
+sim.grains[1].ang_vel[3] = 100 | |
+sim.grains[2].ang_vel[3] = 0.0 | |
Granular.findContacts!(sim) # make sure contact is registered | |
sim.grains[1].contact_radius=10.0 # decrease radius so there isn't compression | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
t@@ -165,12 +169,13 @@ Granular.setTimeStep!(sim) | |
Granular.setTotalTime!(sim, 5.) | |
#Granular.setOutputFileInterval!(sim, 0.1) | |
Granular.run!(sim, verbose=verbose) | |
+Granular.removeSimulationFiles(sim) | |
@test sim.grains[1].lin_vel[1] ≈ 0. | |
@test sim.grains[1].lin_vel[2] ≈ 0. | |
@test sim.grains[2].lin_vel[1] ≈ 0. | |
@test sim.grains[2].lin_vel[2] ≈ 0. | |
-@test sim.grains[1].ang_vel != 0. | |
-@test sim.grains[2].ang_vel != 0. | |
+@test sim.grains[1].ang_vel[3] != 0. | |
+@test sim.grains[2].ang_vel[3] != 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
E_therm_final = Granular.totalGrainThermalEnergy(sim) | |
diff --git a/test/collision-2floes-normal.jl b/test/collision-2floes-normal.jl | |
t@@ -3,8 +3,6 @@ | |
# Check for conservation of kinetic energy (=momentum) during a normal collisi… | |
# between two ice cylindrical grains | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
verbose=false | |
Compat.@info "# One ice floe fixed" | |
diff --git a/test/collision-2floes-oblique.jl b/test/collision-2floes-oblique.jl | |
t@@ -3,8 +3,6 @@ | |
# Check for conservation of kinetic energy (=momentum) during a normal collisi… | |
# between two ice cylindrical grains | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
verbose=false | |
Compat.@info "## Contact-normal elasticity only" | |
t@@ -36,9 +34,6 @@ Granular.run!(sim, temporal_integration_method="Two-term Tay… | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
E_thermal_final = Granular.totalGrainThermalEnergy(sim) | |
-println(E_kin_lin_init) | |
-println(E_kin_lin_final) | |
-println(E_thermal_final) | |
@test E_kin_lin_init ≈ E_kin_lin_final+E_thermal_final atol=E_kin_lin_init*t… | |
@test E_kin_rot_init ≈ E_kin_rot_final | |
t@@ -136,19 +131,25 @@ sim_init.grains[2].contact_dynamic_friction = 1e2 # no … | |
sim_init.grains[2].fixed = true | |
sim = deepcopy(sim_init) | |
+ | |
Compat.@info "Testing kinetic energy conservation with Two-term Taylor scheme" | |
Granular.setTimeStep!(sim, epsilon=0.07) | |
tol = 0.1 | |
Compat.@info "Relative tolerance: $(tol*100.)% with time step: $(sim.time_step… | |
+Granular.setOutputFileInterval!(sim, 1.0) | |
Granular.run!(sim, temporal_integration_method="Two-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos ≈ 0. | |
-@test sim.grains[2].ang_vel ≈ 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] ≈ 0. | |
+@test sim.grains[2].ang_vel[3] ≈ 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
+println(E_kin_lin_init) | |
+println(E_kin_lin_final) | |
+println(E_kin_rot_init) | |
+println(E_kin_rot_final) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
Compat.@info "mu_d = 0." | |
t@@ -162,9 +163,9 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnerg… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos ≈ 0. | |
-@test sim.grains[1].ang_vel ≈ 0. | |
-@test sim.grains[2].ang_pos ≈ 0. | |
+@test sim.grains[1].ang_pos[3] ≈ 0. | |
+@test sim.grains[1].ang_vel[3] ≈ 0. | |
+@test sim.grains[2].ang_pos[3] ≈ 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init ≈ E_kin_lin_final atol=E_kin_lin_init*tol | |
t@@ -178,10 +179,10 @@ Compat.@info "Relative tolerance: $(tol*100.)%" | |
Granular.run!(sim, temporal_integration_method="Two-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos ≈ 0. | |
-@test sim.grains[2].ang_vel ≈ 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] ≈ 0. | |
+@test sim.grains[2].ang_vel[3] ≈ 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -195,10 +196,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos ≈ 0. | |
-@test sim.grains[2].ang_vel ≈ 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] ≈ 0. | |
+@test sim.grains[2].ang_vel[3] ≈ 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -228,10 +229,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Two-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -257,10 +258,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -291,10 +292,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Two-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos > 0. | |
-@test sim.grains[1].ang_vel > 0. | |
-@test sim.grains[2].ang_pos > 0. | |
-@test sim.grains[2].ang_vel > 0. | |
+@test sim.grains[1].ang_pos[3] > 0. | |
+@test sim.grains[1].ang_vel[3] > 0. | |
+@test sim.grains[2].ang_pos[3] > 0. | |
+@test sim.grains[2].ang_vel[3] > 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -320,10 +321,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos > 0. | |
-@test sim.grains[1].ang_vel > 0. | |
-@test sim.grains[2].ang_pos > 0. | |
-@test sim.grains[2].ang_vel > 0. | |
+@test sim.grains[1].ang_pos[3] > 0. | |
+@test sim.grains[1].ang_vel[3] > 0. | |
+@test sim.grains[2].ang_pos[3] > 0. | |
+@test sim.grains[2].ang_vel[3] > 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -352,10 +353,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Two-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -381,10 +382,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -421,10 +422,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Two-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -450,10 +451,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init ≈ E_kin_lin_final+E_kin_rot_final atol=E… | |
t@@ -503,10 +504,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init > E_kin_lin_final+E_kin_rot_final | |
t@@ -556,10 +557,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init > E_kin_lin_final+E_kin_rot_final | |
t@@ -609,10 +610,10 @@ Compat.@info "Relative tolerance: $(tol*100.)% with time… | |
Granular.run!(sim, temporal_integration_method="Three-term Taylor", | |
verbose=verbose) | |
-@test sim.grains[1].ang_pos < 0. | |
-@test sim.grains[1].ang_vel < 0. | |
-@test sim.grains[2].ang_pos < 0. | |
-@test sim.grains[2].ang_vel < 0. | |
+@test sim.grains[1].ang_pos[3] < 0. | |
+@test sim.grains[1].ang_vel[3] < 0. | |
+@test sim.grains[2].ang_pos[3] < 0. | |
+@test sim.grains[2].ang_vel[3] < 0. | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_lin_init+E_kin_rot_init > E_kin_lin_final+E_kin_rot_final | |
diff --git a/test/collision-5floes-normal.jl b/test/collision-5floes-normal.jl | |
t@@ -4,8 +4,6 @@ using Compat.LinearAlgebra | |
# Check for conservation of kinetic energy (=momentum) during a normal collisi… | |
# between two ice cylindrical grains | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
verbose=false | |
Compat.@info "# One ice floe fixed" | |
diff --git a/test/compressive_failure.jl b/test/compressive_failure.jl | |
t@@ -0,0 +1,184 @@ | |
+#!/usr/bin/env julia | |
+using Compat.Test | |
+import Granular | |
+ | |
+verbose = false | |
+debug = false | |
+if debug | |
+ import PyPlot | |
+end | |
+ | |
+function plot_interaction(sim::Granular.Simulation, output::String) | |
+ time = Float64[] | |
+ force_n_1 = Float64[] | |
+ force_n_2 = Float64[] | |
+ force_t_1 = Float64[] | |
+ force_t_2 = Float64[] | |
+ torque_1 = Float64[] | |
+ torque_2 = Float64[] | |
+ compressive_failure = Bool[] | |
+ while sim.time < sim.time_total | |
+ Granular.run!(sim, verbose=verbose, single_step=true) | |
+ append!(time, sim.time) | |
+ append!(compressive_failure, sim.grains[1].compressive_failure[1]) | |
+ append!(force_n_1, sim.grains[1].force[1]) | |
+ append!(force_n_2, sim.grains[2].force[1]) | |
+ append!(force_t_1, sim.grains[1].force[2]) | |
+ append!(force_t_2, sim.grains[2].force[2]) | |
+ append!(torque_1, sim.grains[1].torque[3]) | |
+ append!(torque_2, sim.grains[2].torque[3]) | |
+ end | |
+ PyPlot.clf() | |
+ PyPlot.subplot(3,1,1) | |
+ PyPlot.plot(time, force_n_1, "-b", label="1") | |
+ PyPlot.plot(time, force_n_2, "--y", label="2") | |
+ PyPlot.legend(loc="upper right") | |
+ PyPlot.ylabel("\$f_x\$ [N]") | |
+ PyPlot.subplot(3,1,2) | |
+ PyPlot.plot(time, force_t_1, "-b", label="1") | |
+ PyPlot.plot(time, force_t_2, "--y", label="2") | |
+ PyPlot.legend(loc="upper right") | |
+ PyPlot.ylabel("\$f_y\$ [N]") | |
+ PyPlot.subplot(3,1,3) | |
+ PyPlot.plot(time, torque_1, "-b", label="1") | |
+ PyPlot.plot(time, torque_2, "--y", label="2") | |
+ PyPlot.legend(loc="upper right") | |
+ PyPlot.ylabel("Torque [Nm]") | |
+ PyPlot.xlabel("Time [s]") | |
+ PyPlot.tight_layout() | |
+ PyPlot.savefig(output) | |
+end | |
+ | |
+Compat.@info "Testing compressive failure: uniaxial compression" | |
+sim = Granular.createSimulation("compressive_failure_uniaxial") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1285e3, | |
+ lin_vel=[1., 0.], fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [2.,0.], 1., 0.5, | |
+ fracture_toughness=1285e3, | |
+ fixed=true, verbose=verbose) | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 0 | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+ | |
+if debug | |
+ Granular.removeSimulationFiles(sim) | |
+ Granular.setOutputFileInterval!(sim, 0.01) | |
+ plot_interaction(sim, sim.id * ".pdf") | |
+else | |
+ Granular.run!(sim, verbose=verbose) | |
+end | |
+ | |
+@test sim.grains[1].compressive_failure[1] == true | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 1 | |
+@test sim.grains[1].force[1] < 0.0 | |
+@test sim.grains[1].force[2] ≈ 0.0 | |
+@test sim.grains[2].force[1] > 0.0 | |
+@test sim.grains[2].force[2] ≈ 0.0 | |
+@test sim.grains[1].torque ≈ zeros(3) | |
+@test sim.grains[2].torque ≈ zeros(3) | |
+ | |
+Compat.@info "Testing compressive failure: shear" | |
+sim = Granular.createSimulation("compressive_failure_shear") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1285e3, | |
+ lin_vel=[0., 1.], fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [1.5,1.5], 1., 0.5, | |
+ fracture_toughness=1285e3, | |
+ fixed=true, verbose=verbose) | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 0 | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+ | |
+if debug | |
+ Granular.removeSimulationFiles(sim) | |
+ Granular.setOutputFileInterval!(sim, 0.01) | |
+ plot_interaction(sim, sim.id * ".pdf") | |
+else | |
+ Granular.run!(sim, verbose=verbose) | |
+end | |
+ | |
+@test sim.grains[1].compressive_failure[1] == true | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 1 | |
+@test sim.grains[1].force[1] > 0.0 | |
+@test sim.grains[1].force[2] < 0.0 | |
+@test abs(sim.grains[1].force[1]) < abs(sim.grains[1].force[2]) | |
+@test sim.grains[2].force[1] < 0.0 | |
+@test sim.grains[2].force[2] > 0.0 | |
+@test abs(sim.grains[2].force[1]) < abs(sim.grains[2].force[2]) | |
+@test sim.grains[1].torque[1:2] ≈ zeros(2) | |
+@test sim.grains[1].torque[3] < 0.0 | |
+@test sim.grains[2].torque[1:2] ≈ zeros(2) | |
+@test sim.grains[2].torque[3] < 0.0 | |
+ | |
+Compat.@info "Testing robustness of overlap calculations" | |
+sim = Granular.createSimulation("overlap") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1285e3, | |
+ lin_vel=[0., 1.], fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [2.,0.], 1., 0.5, | |
+ fracture_toughness=1285e3, | |
+ fixed=true, verbose=verbose) | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 0 | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+Granular.run!(sim, single_step=true, verbose=verbose) | |
+@test sim.grains[1].compressive_failure[1] == false | |
+@test sim.grains[1].contact_area[1] == 0.0 | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 0 | |
+ | |
+sim = Granular.createSimulation("overlap") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [0.0+1e-9,0.], 1., 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+Granular.run!(sim, single_step=true, verbose=verbose) | |
+@test sim.grains[1].compressive_failure[1] == true | |
+@test sim.grains[1].contact_area[1] ≈ π*1.0^2 | |
+ | |
+sim = Granular.createSimulation("overlap") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [0.1,0.], 1., 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+Granular.run!(sim, single_step=true, verbose=verbose) | |
+@test sim.grains[1].compressive_failure[1] == true | |
+@test sim.grains[1].contact_area[1] < π*1.0^2 | |
+@test sim.grains[1].contact_area[1] > 0. | |
+ | |
+sim = Granular.createSimulation("overlap") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [0.+1e-9,0.], 0.1, 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 0 | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+Granular.run!(sim, single_step=true, verbose=verbose) | |
+@test sim.grains[1].position_vector[1] ≈ [-1e-9, 0., 0.] | |
+@test sim.grains[1].compressive_failure[1] == true | |
+@test sim.grains[1].contact_area[1] ≈ π*0.1^2 | |
+ | |
+sim = Granular.createSimulation("overlap") | |
+Granular.addGrainCylindrical!(sim, [0.,0.], 1., 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+Granular.addGrainCylindrical!(sim, [0.3,0.4], 0.1, 0.5, | |
+ fracture_toughness=1., | |
+ fixed=true, verbose=verbose) | |
+@test count(x->x==true, sim.grains[1].compressive_failure) == 0 | |
+Granular.setTimeStep!(sim, verbose=verbose) | |
+Granular.setTotalTime!(sim, 1.0) | |
+Granular.run!(sim, single_step=true, verbose=verbose) | |
+@test sim.grains[1].compressive_failure[1] == true | |
+@test sim.grains[1].contact_area[1] ≈ π*0.1^2 | |
diff --git a/test/contact-search-and-geometry.jl b/test/contact-search-and-geom… | |
t@@ -4,8 +4,6 @@ import Granular | |
# Check the contact search and geometry of a two-particle interaction | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Testing interGrainPositionVector(...) and findOverlap(...)" | |
sim = Granular.createSimulation("test") | |
sim = Granular.createSimulation(id="test") | |
t@@ -15,7 +13,7 @@ Granular.addGrainCylindrical!(sim, [18.01, 0.01], 10., 1., v… | |
position_ij = Granular.interGrainPositionVector(sim, 1, 2) | |
overlap_ij = Granular.findOverlap(sim, 1, 2, position_ij) | |
-@test [-18., 0.] ≈ position_ij | |
+@test [-18., 0., 0.] ≈ position_ij | |
@test -2. ≈ overlap_ij | |
t@@ -31,16 +29,16 @@ Granular.findContacts!(sim) | |
sim.grains[1].enabled = false | |
# The contact should be registered in ice floe 1, but not ice floe 2 | |
@test 2 == sim.grains[1].contacts[1] | |
-@test [-18., 0.] ≈ sim.grains[1].position_vector[1] | |
+@test [-18., 0., 0.] ≈ sim.grains[1].position_vector[1] | |
for ic=2:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 1 == sim.grains[1].n_contacts | |
@test 1 == sim.grains[2].n_contacts | |
t@@ -50,16 +48,16 @@ sim = deepcopy(sim_copy) | |
Granular.findContacts!(sim) | |
@test 2 == sim.grains[1].contacts[1] | |
-@test [-18., 0.] ≈ sim.grains[1].position_vector[1] | |
+@test [-18., 0., 0.] ≈ sim.grains[1].position_vector[1] | |
for ic=2:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 1 == sim.grains[1].n_contacts | |
@test 1 == sim.grains[2].n_contacts | |
t@@ -72,13 +70,13 @@ sim.grains[2].enabled = false | |
Granular.findContacts!(sim) | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 0 == sim.grains[1].n_contacts | |
@test 0 == sim.grains[2].n_contacts | |
t@@ -89,13 +87,13 @@ Granular.disableGrain!(sim, 1) | |
Granular.findContacts!(sim) | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 0 == sim.grains[1].n_contacts | |
@test 0 == sim.grains[2].n_contacts | |
t@@ -107,13 +105,13 @@ Granular.disableGrain!(sim, 2) | |
Granular.findContacts!(sim) | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 0 == sim.grains[1].n_contacts | |
@test 0 == sim.grains[2].n_contacts | |
t@@ -125,16 +123,16 @@ Granular.interact!(sim) | |
Granular.findContacts!(sim) | |
@test 2 == sim.grains[1].contacts[1] | |
-@test [-18., 0.] ≈ sim.grains[1].position_vector[1] | |
+@test [-18., 0., 0.] ≈ sim.grains[1].position_vector[1] | |
for ic=2:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 1 == sim.grains[1].n_contacts | |
@test 1 == sim.grains[2].n_contacts | |
t@@ -149,13 +147,13 @@ Granular.findContactsInGrid!(sim, sim.ocean) | |
@test 2 == sim.grains[1].contacts[1] | |
for ic=2:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 1 == sim.grains[1].n_contacts | |
@test 1 == sim.grains[2].n_contacts | |
t@@ -170,13 +168,13 @@ Granular.findContactsInGrid!(sim, sim.ocean) | |
@test 2 == sim.grains[1].contacts[1] | |
for ic=2:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 1 == sim.grains[1].n_contacts | |
@test 1 == sim.grains[2].n_contacts | |
t@@ -191,13 +189,13 @@ Granular.findContactsInGrid!(sim, sim.ocean) | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 0 == sim.grains[1].n_contacts | |
@test 0 == sim.grains[2].n_contacts | |
t@@ -211,13 +209,13 @@ Granular.findContacts!(sim) | |
@test 2 == sim.grains[1].contacts[1] | |
for ic=2:sim.Nc_max | |
@test 0 == sim.grains[1].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[1].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[1].contact_parallel_displacement[ic] | |
end | |
for ic=1:sim.Nc_max | |
@test 0 == sim.grains[2].contacts[ic] | |
- @test [0., 0.] ≈ sim.grains[2].position_vector[ic] | |
- @test [0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].position_vector[ic] | |
+ @test [0., 0., 0.] ≈ sim.grains[2].contact_parallel_displacement[ic] | |
end | |
@test 1 == sim.grains[1].n_contacts | |
@test 1 == sim.grains[2].n_contacts | |
t@@ -302,5 +300,3 @@ for j=2:(ny-1) | |
@test sim.grains[idx].n_contacts == 4 | |
end | |
end | |
- | |
- | |
diff --git a/test/grain.jl b/test/grain.jl | |
t@@ -2,22 +2,20 @@ | |
# Check the basic icefloe functionality | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Writing simple simulation to VTK file" | |
sim = Granular.createSimulation(id="test") | |
Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 1., verbose=false) | |
Granular.printGrainInfo(sim.grains[1]) | |
Compat.@info "Testing grain value checks " | |
-@test_throws ErrorException Granular.addGrainCylindrical!(sim, [.1, .1, .1], | |
+@test_throws ErrorException Granular.addGrainCylindrical!(sim, [.1, .1, .1, .1… | |
10., 1.) | |
@test_throws ErrorException Granular.addGrainCylindrical!(sim, [.1, .1], | |
10., 1., | |
- lin_vel=[.2,.2,.2]) | |
+ lin_vel=[.2,.2,.2,.2… | |
@test_throws ErrorException Granular.addGrainCylindrical!(sim, [.1, .1], | |
10., 1., | |
- lin_acc=[.2,.2,.2]) | |
+ lin_acc=[.2,.2,.2,.2… | |
@test_throws ErrorException Granular.addGrainCylindrical!(sim, [.1, .1], | |
0., 1.) | |
@test_throws ErrorException Granular.addGrainCylindrical!(sim, [.1, .1], | |
t@@ -82,18 +80,18 @@ end | |
Compat.@info "Testing external body force routines" | |
sim = Granular.createSimulation(id="test") | |
Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 1., verbose=false) | |
-Granular.setBodyForce!(sim.grains[1], [1., 2.]) | |
-@test sim.grains[1].external_body_force ≈ [1., 2.] | |
-Granular.addBodyForce!(sim.grains[1], [1., 2.]) | |
-@test sim.grains[1].external_body_force ≈ [2., 4.] | |
+Granular.setBodyForce!(sim.grains[1], [1., 2., 0.]) | |
+@test sim.grains[1].external_body_force ≈ [1., 2., 0.] | |
+Granular.addBodyForce!(sim.grains[1], [1., 2., 0.]) | |
+@test sim.grains[1].external_body_force ≈ [2., 4., 0.] | |
Compat.@info "Testing zeroKinematics!()" | |
-sim.grains[1].force .= ones(2) | |
-sim.grains[1].lin_acc .= ones(2) | |
-sim.grains[1].lin_vel .= ones(2) | |
-sim.grains[1].torque = 1. | |
-sim.grains[1].ang_acc = 1. | |
-sim.grains[1].ang_vel = 1. | |
+sim.grains[1].force .= ones(3) | |
+sim.grains[1].lin_acc .= ones(3) | |
+sim.grains[1].lin_vel .= ones(3) | |
+sim.grains[1].torque .= ones(3) | |
+sim.grains[1].ang_acc .= ones(3) | |
+sim.grains[1].ang_vel .= ones(3) | |
Granular.zeroKinematics!(sim) | |
@test Granular.totalGrainKineticTranslationalEnergy(sim) ≈ 0. | |
@test Granular.totalGrainKineticRotationalEnergy(sim) ≈ 0. | |
diff --git a/test/grid-boundaries.jl b/test/grid-boundaries.jl | |
t@@ -1,8 +1,6 @@ | |
#!/usr/bin/env julia | |
import Compat | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
verbose=false | |
Compat.@info "## Inactive/Periodic BCs" | |
t@@ -185,7 +183,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+@test [0.1, 0.5, 0.] ≈ sim.grains[1].lin_pos | |
# do not readjust inside grid, periodic boundaries | |
sim = Granular.createSimulation() | |
t@@ -193,7 +191,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+@test [0.1, 0.5, 0.] ≈ sim.grains[1].lin_pos | |
# do not readjust outside grid, inactive boundaries | |
sim = Granular.createSimulation() | |
t@@ -201,7 +199,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [-0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+@test [-0.1, 0.5, 0.] ≈ sim.grains[1].lin_pos | |
# readjust outside grid, periodic boundaries, -x | |
sim = Granular.createSimulation() | |
t@@ -209,7 +207,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.9, 0.5] ≈ sim.grains[1].lin_pos | |
+@test [0.9, 0.5, 0.] ≈ sim.grains[1].lin_pos | |
# readjust outside grid, periodic boundaries, +x | |
sim = Granular.createSimulation() | |
t@@ -217,7 +215,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+@test [0.1, 0.5, 0.] ≈ sim.grains[1].lin_pos | |
# readjust outside grid, periodic boundaries, -y | |
sim = Granular.createSimulation() | |
t@@ -225,7 +223,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.3, 0.9] ≈ sim.grains[1].lin_pos | |
+@test [0.3, 0.9, 0.] ≈ sim.grains[1].lin_pos | |
# readjust outside grid, periodic boundaries, +y | |
sim = Granular.createSimulation() | |
t@@ -233,7 +231,7 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.3, 0.1] ≈ sim.grains[1].lin_pos | |
+@test [0.3, 0.1, 0.] ≈ sim.grains[1].lin_pos | |
# throw error if atmosphere and ocean BCs differ | |
sim = Granular.createSimulation() | |
t@@ -253,4 +251,4 @@ sim.ocean = Granular.createRegularOceanGrid([5, 5, 2], [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 [0.1, 0.5] ≈ sim.grains[1].lin_pos | |
+@test [0.1, 0.5, 0.] ≈ sim.grains[1].lin_pos | |
diff --git a/test/grid.jl b/test/grid.jl | |
t@@ -5,8 +5,6 @@ import Granular | |
# Check the grid interpolation and sorting functions | |
verbose = false | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
if Granular.hasNetCDF | |
ocean = Granular.readOceanNetCDF("Baltic/00010101.ocean_month.nc", | |
"Baltic/ocean_hgrid.nc") | |
diff --git a/test/jld.jl b/test/jld.jl | |
t@@ -1,8 +1,6 @@ | |
#!/usr/bin/env julia | |
import Compat | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Determining if JLD is installed" | |
if Granular.hasJLD | |
Compat.@info "JLD found, proceeding with JLD-specific tests" | |
diff --git a/test/netcdf.jl b/test/netcdf.jl | |
t@@ -2,8 +2,6 @@ | |
# Check if NetCDF files are read correctly from the disk. | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
@test_throws ErrorException Granular.readOceanStateNetCDF("nonexistentfile") | |
@test_throws ErrorException Granular.readOceanGridNetCDF("nonexistentfile") | |
diff --git a/test/ocean.jl b/test/ocean.jl | |
t@@ -3,8 +3,6 @@ | |
# Check if ocean-specific functions and grid operations are functioning | |
# correctly | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Testing regular grid generation" | |
sim = Granular.createSimulation() | |
sim.ocean = Granular.createRegularOceanGrid([6, 6, 6], [1., 1., 1.]) | |
t@@ -58,15 +56,15 @@ E_kin_rot_final = Granular.totalGrainKineticRotationalEner… | |
Compat.@info "Testing vortex interaction (static ocean)" | |
sim = deepcopy(sim_init) | |
-sim.grains[1].ang_vel = 0.1 | |
+sim.grains[1].ang_vel[3] = 0.1 | |
E_kin_lin_init = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(sim) | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
@test E_kin_rot_init > E_kin_rot_final # energy lost to ocean | |
-@test sim.grains[1].ang_vel > 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos > 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] > 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] > 0. # check angular position orientation | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
Compat.@info "Testing vortex interaction (static ice floe)" | |
t@@ -81,8 +79,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel > 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos > 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] > 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] > 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to ocean vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
t@@ -97,8 +95,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnergy(… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel < 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos < 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] < 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] < 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to ocean vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
t@@ -113,8 +111,8 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnerg… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel < 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos < 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] < 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] < 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to ocean vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
t@@ -129,7 +127,7 @@ E_kin_rot_init = Granular.totalGrainKineticRotationalEnerg… | |
Granular.run!(sim, verbose=false) | |
E_kin_lin_final = Granular.totalGrainKineticTranslationalEnergy(sim) | |
E_kin_rot_final = Granular.totalGrainKineticRotationalEnergy(sim) | |
-@test sim.grains[1].ang_vel > 0. # check angular velocity orientation | |
-@test sim.grains[1].ang_pos > 0. # check angular position orientation | |
+@test sim.grains[1].ang_vel[3] > 0. # check angular velocity orientation | |
+@test sim.grains[1].ang_pos[3] > 0. # check angular position orientation | |
@test E_kin_rot_init < E_kin_rot_final # rotation after due to ocean vortex | |
@test E_kin_lin_init ≈ E_kin_lin_final # no linear velocity gained | |
diff --git a/test/packing.jl b/test/packing.jl | |
t@@ -6,8 +6,6 @@ verbose = false | |
plot = false | |
plot_packings=false | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Testing regular packing generation (power law GSD)" | |
sim = Granular.createSimulation() | |
Granular.regularPacking!(sim, [2, 2], 1., 1., size_distribution="powerlaw") | |
diff --git a/test/profiling.jl b/test/profiling.jl | |
t@@ -9,8 +9,6 @@ import Plots | |
import Granular | |
import CurveFit | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
verbose=false | |
Compat.@info "Testing performance with many interacting grains" | |
diff --git a/test/runtests.jl b/test/runtests.jl | |
t@@ -3,22 +3,28 @@ using Compat.Test | |
using Compat.LinearAlgebra | |
import Granular | |
-include("collision-2floes-normal.jl") | |
-include("collision-5floes-normal.jl") | |
-include("collision-2floes-oblique.jl") | |
-include("grid.jl") | |
-include("contact-search-and-geometry.jl") | |
-include("grid-boundaries.jl") | |
-include("ocean.jl") | |
-include("atmosphere.jl") | |
-include("wall.jl") | |
-include("grain.jl") | |
-include("packing.jl") | |
-include("util.jl") | |
-include("temporal.jl") | |
-include("cohesion.jl") | |
+function run_test(filename::String) | |
+ Compat.printstyled("Info: #### $filename ####\n", color=:green) | |
+ include(filename) | |
+end | |
+ | |
+run_test("compressive_failure.jl") | |
+run_test("cohesion.jl") | |
+run_test("grain.jl") | |
+run_test("vtk.jl") | |
+run_test("collision-2floes-normal.jl") | |
+run_test("collision-5floes-normal.jl") | |
+run_test("collision-2floes-oblique.jl") | |
+run_test("grid.jl") | |
+run_test("contact-search-and-geometry.jl") | |
+run_test("grid-boundaries.jl") | |
+run_test("ocean.jl") | |
+run_test("atmosphere.jl") | |
+run_test("wall.jl") | |
+run_test("packing.jl") | |
+run_test("util.jl") | |
+run_test("temporal.jl") | |
if Granular.hasNetCDF | |
- include("netcdf.jl") | |
+ run_test("netcdf.jl") | |
end | |
-include("vtk.jl") | |
-include("jld.jl") | |
+run_test("jld.jl") | |
diff --git a/test/util.jl b/test/util.jl | |
t@@ -1,8 +1,8 @@ | |
#!/usr/bin/env julia | |
+import Granular | |
import Compat | |
using Compat.Random | |
- | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
+using Compat.Test | |
Compat.@info "Testing power-law RNG" | |
t@@ -26,3 +26,12 @@ for i=1:10^5 | |
@test 0. <= minimum(Granular.randpower(5, 1., 0., 1.)) | |
@test 1. >= minimum(Granular.randpower(5, 1., 0., 1.)) | |
end | |
+ | |
+@test [1,2,0] == Granular.vecTo3d([1,2]) | |
+@test [1,2,3] == Granular.vecTo3d([1,2], fill=3) | |
+@test [1,3,3] == Granular.vecTo3d([1], fill=3) | |
+@test [1,3,3] == Granular.vecTo3d(1, fill=3) | |
+@test [1.,2.,3.] == Granular.vecTo3d([1.,2.], fill=3.) | |
+@test [1.,3.,3.] == Granular.vecTo3d(1., fill=3.) | |
+@test [1.,0.,0.] == Granular.vecTo3d(1.) | |
+@test [1.,0.,0.] == Granular.vecTo3d([1.]) | |
diff --git a/test/vtk.jl b/test/vtk.jl | |
t@@ -3,8 +3,6 @@ import Compat | |
# Check the contact search and geometry of a two-particle interaction | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "Writing simple simulation to VTK file" | |
sim = Granular.createSimulation(id="test") | |
Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 1., verbose=false) | |
t@@ -29,12 +27,12 @@ end | |
grainpath = "test/test.grains.1.vtu" | |
grainchecksum = | |
-"eff130f14975dd5da06186c5b61c0c1a9d679f2188d03019c8144898ddc902b6 " * | |
+"b1748cb82e8270d951d9c1acaea0d151f0a5c48a1255e75de350bf9bcbc15fe9 " * | |
grainpath * "\n" | |
graininteractionpath = "test/test.grain-interaction.1.vtp" | |
graininteractionchecksum = | |
-"c61f314a997c4405eaa98e6a4e3f81368ab2e1c60d06d9a0d998b69d7c8fb1bf " * | |
+"b8e49252a0ac87c2fce05e68ffab46589853429dc9f75d89818e4a37b953b137 " * | |
graininteractionpath * "\n" | |
oceanpath = "test/test.ocean.1.vts" | |
diff --git a/test/wall.jl b/test/wall.jl | |
t@@ -2,14 +2,12 @@ | |
# Check the basic dynamic wall functionality | |
-Compat.@info "#### $(basename(@__FILE__)) ####" | |
- | |
Compat.@info "# Test wall initialization" | |
Compat.@info "Testing argument value checks" | |
sim = Granular.createSimulation() | |
Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 2., verbose=false) | |
@test_throws ErrorException Granular.addWallLinearFrictionless!(sim, | |
- [.1, .1, .1], | |
+ [.1, .1, .1, .… | |
1.) | |
@test_throws ErrorException Granular.addWallLinearFrictionless!(sim, | |
[1., 1.], | |
t@@ -18,7 +16,7 @@ Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 2., verbo… | |
[.1, .1, .1], | |
1.) | |
@test_throws ErrorException Granular.addWallLinearFrictionless!(sim, | |
- [0., 1.], 1., | |
+ [0., 1., 1.], … | |
bc="asdf") | |
sim = Granular.createSimulation() | |
@test_throws ErrorException Granular.addWallLinearFrictionless!(sim, [1., 0.], | |
t@@ -56,7 +54,7 @@ sim.walls[1].force = 1.0 | |
@test Granular.getWallNormalStress(sim, wall_index=1, stress_type="effective")… | |
@test_throws ErrorException Granular.getWallNormalStress(sim, wall_index=1, st… | |
-sim.walls[1].normal = [1.0, 1.0] | |
+sim.walls[1].normal = [1.0, 1.0, 1.0] | |
@test_throws ErrorException Granular.getWallSurfaceArea(sim, 1) | |
@test_throws ErrorException Granular.getWallSurfaceArea(sim, [1.,1.], 0.5) | |