You are on page 1of 18

Appendix E

CASF ALGORITHM AND MATLAB ROUTINES




&217(176

E.1 SUBROUTINES TO INTERPOLATE EXTRACTION AND MOVEMENT ZONES..............................................300


( 'DWDILOH³,0=BLQWHUSRODWLRQP´
( 'DWDILOH³,(=BLQWHUSRODWLRQP´ 
E.2 CASF’S ALGORITHM .........................................................................................................................305
( 'DWDILOH³&$6)P´
( 'DWDILOH³6HWBXSB&$6)P´
( 'DWDILOH³([WUDFWLRQP´ 
( 'DWDILOH³&$6)BFRQILQHGBWUDQVLWLRQBIXQFWLRQ´ 
( 'DWDILOH³3LOHBGUDZEHOO´ 
( 'DWDILOH³&$6)BXQFRQILQHGBWUDQVLWLRQBIXQFWLRQ´ 
( 'DWDILOH³GLVSODFHBIORDWLQJBEORFNVP´ 

299
Appendix E: Matlab Subroutines

( 6XEURXWLQHVWRLQWHUSRODWHH[WUDFWLRQDQGPRYHPHQW]RQHV

E.1.1 Data file “IMZ_interpolation.m”


% This program interpolate the movement zone and calculates the maximum height and width at half
% height.
% x_exp is the file with x,y sensor location and mass draw for sensor triggering
% x_step and y_step are the dimensions of the cell to be interpolated.
% griddata is a non regular interpolant using Voronoi algorithm

x_step=10;
z_step=10;
[XI,ZI]=meshgrid(min(x_exp(:,1))-10:x_step:max(x_exp(:,1))+10,0:z_step:max(x_exp(:,2)));
w = griddata(x_exp(:,1),x_exp(:,2),x_exp(:,3),XI,ZI,’linear’);
w_dp= griddata(x_exp_ndp(:,1),x_exp_ndp(:,2),x_exp_ndp(:,3),XI,ZI,’linear’);
mass=0:10:max(x_exp(:,3));
IMZ=zeros(length(mass)+1,3);
h=2;
for j=2:length(mass)+1
max_z=0;
for i=1:size(w,1)
if sum(w(i,:)<=mass(j-1))>0
max_z=ZI(i,1);
else
if sum(isfinite(w4(i,:)))>0
break;
end
end
end
l=find(ZI(:,1)==round(max_z/2-mod(max_z/2,z_step)));
l2=find(ZI(:,1)==round(max_z/4-mod(max_z/4,z_step)));
l3=find(ZI(:,1)==round(max_z*3/4-mod(max_z*3/4,z_step)));
if length(XI(l,(min(find(w4(l,:)<=mass(j-1))))))>0 && length(XI(l,(max(find(w4(l,:)<=mass(j-
1))))))>0
IMZ(h,1)=max_z;
IMZ(h,2)=(XI(l,max(find(w4(l,:)<=mass(j-1))))-XI(l,min(find(w(l,:)<=mass(j-1)))));
if length(XI(l2,(min(find(w4(l2,:)<=mass(j-1))))))>0 &&
length(XI(l2,(max(find(w(l2,:)<=mass(j-1))))))>0
IMZ(h,3)=(XI(l2,max(find(w4(l2,:)<=mass(j-1))))-XI(l2,min(find(w4(l2,:)<=mass(j-1)))));
end
if length(XI(l3,(min(find(w4(l3,:)<=mass(j-1))))))>0 &&
length(XI(l3,(max(find(w(l3,:)<=mass(j-1))))))>0
IMZ(h,4)=(XI(l3,max(find(w4(l3,:)<=mass(j-1))))-XI(l3,min(find(w(l3,:)<=mass(j-1)))));
end
IMZ(h,5)=mass(j-1);
h=h+1;
end; end

E.1.2 Data file “IEZ_interpolation.m”

%This program interpolates the extraction zone in three-dimensions
% Raw data is in x_exp(x,y,z,mass) file
% calculates drawzone dimensions and area
300
Appendix E: Matlab Subroutines
x_step=20;
y_step=20;
z_step=50;
[XI,YI,ZI]=meshgrid(min(x_exp(:,1))-10:x_step:max(x_exp(:,1))+10,min(x_exp(:,2))-
10:y_step:max(x_exp(:,2))+10,0:z_step:max(x_exp(:,3)));
w = griddata3(x_exp(:,1),x_exp(:,2),x_exp(:,3),x_exp(:,4),XI,YI,ZI);

%Calculates curves for IEZ (front view at sy)


mass=0.0001:100:2200;
[nx ny nz]=size(XI);
sy=[0];
[xi2,yi2,zi2] = meshgrid(XI(1,:,1),sy,ZI(1,1,:));
vi = interp3(XI,YI,ZI,w,xi2,yi2,zi2);
xi3=reshape(xi2,[ny nz]);
zi3=reshape(zi2,[ny nz]);
vi3=reshape(vi,[ny,nz]);
pcolor(xi3,zi3,vi3);
axis equal
IEZ=zeros(length(mass)+1,3);
h=2;
for j=2:length(mass)+1
max_z=0;
for i=1:size(zi3,2)
if sum(vi3(:,i)<=mass(j-1))>0
max_z=zi3(1,i);
else
if sum(isfinite(vi3(:,i)))>0
break;
end
end
end
l=find(zi3(1,:)==round(max_z/2)-mod(max_z/2,z_step));
if length((xi3((max(find(vi3(:,l)<=mass(j-1)))),l)))>0 && length(xi3((min(find(vi3(:,l)<=mass(j-
1)))),l))>0
IEZ(h,1)=xi3((max(find(vi3(:,l)<=mass(j-1)))),l)-(xi3((min(find(vi3(:,l)<=mass(j-1)))),l));
IEZ(h,2)=max_z;
IEZ(h,3)=mass(j-1);
h=h+1;
end
end

% plot dimensions of IEZ in three graphs


figure;plot(IEZ(:,2),IEZ(:,1),’.b’);
figure;plot(IEZ(:,3),IEZ(:,2),’.b’); figure;plot(IEZ(:,3),IEZ(:,1),’.b’);

%Calculates curves for IEZ (side view at sx coordinate)


mass=0:20:3000;
%mass=10:100:min(x_exp(find(x_exp(:,3)==max(x_exp(:,3))),4));
sx=0;
[nx ny nz]=size(XI);
[xi4,yi4,zi4] = meshgrid(sx,YI(:,1,1),ZI(1,1,:));
vi4 = interp3(XI,YI,ZI,w,xi4,yi4,zi4);
yi5=reshape(yi4,[nx nz]);
zi5=reshape(zi4,[nx nz]);
vi5=reshape(vi4,[nx,nz]);
301
Appendix E: Matlab Subroutines
pcolor(yi5,zi5,vi5);
axis equal
axis([-500 1000 0 3300]);
IEZ_sideview=zeros(length(mass)+1,3);
h=2;
for j=2:length(mass)+1
max_z=0;
for i=1:size(zi5,2)
if sum(vi5(:,i)<=mass(j-1))>0
max_z=zi5(1,i);
else
if sum(isfinite(vi5(:,i)))>0
break;
end
end
end
l=find(zi5(1,:)==round(max_z/2-mod(max_z/2,z_step)));

for hh=1;
zi=round(max_z*(hh/4))-mod(max_z*(hh/4),z_step);
[xi6,yi6,zi6] = meshgrid(XI(1,:,1),YI(:,1,1),zi);
vi6 = interp3(XI,YI,ZI,w,xi6,yi6,zi6);
area(1,hh)=sum(sum(vi6(:,:)<=mass(j-1)))*x_step*y_step;
height_measured(1,hh)=zi;
end
%determine dimensions of IMZ/IEZ
if length((yi5((max(find(vi5(:,l)<=mass(j-1)))),l)))>0 && length(yi5((min(find(vi5(:,l)<=mass(j-
1)))),l))>0
IEZ_sideview(h,1)=yi5((max(find(vi5(:,l)<=mass(j-1)))),l)-(yi5((min(find(vi5(:,l)<=mass(j-
1)))),l));
IEZ_sideview(h,2)=max_z;
IEZ_sideview(h,3)=mass(j-1);
IEZ_sideview(h,4:6)=area;
IEZ_sideview(h,7:9)=height_measured;
h=h+1;
end
end
figure;plot(IEZ_sideview(:,2),IEZ_sideview(:,1),’.b’);
figure;plot(IEZ_sideview(:,3),IEZ_sideview(:,2),’.b’);
figure;plot(IEZ_sideview(:,3),IEZ_sideview(:,1),’.b’);

)XQFWLRQ³JULGGDWDP´

function [xi,yi,zi] = griddata(x,y,z,xi,yi,method,options)


%GRIDDATA Data gridding and surface fitting.
% Copyright 1984-2003 The MathWorks, Inc.
% Revision: 5.33.4.3

error(nargchk(5,7,nargin))
[msg,x,y,z,xi,yi] = xyzchk(x,y,z,xi,yi);
if ~isempty(msg), error(msg); end

if ( nargin < 6 || isempty(method) ), method = ’linear’; end


if ~ischar(method),
error(’MATLAB:griddata:InvalidMethod’,...
302
Appendix E: Matlab Subroutines
’METHOD must be one of ’’linear’’,’’cubic’’,’’nearest’’, or ’’v4’’.’);
end

if nargin == 7
if ~iscellstr(options)
error(’MATLAB:OptsNotStringCell’,...
’OPTIONS should be cell array of strings.’);
end
opt = options;
else
opt = [];
end

% Sort x and y so duplicate points can be averaged before passing to delaunay

%Need x,y and z to be column vectors


sz = numel(x);
x = reshape(x,sz,1);
y = reshape(y,sz,1);
z = reshape(z,sz,1);
sxyz = sortrows([x y z],[2 1]);
x = sxyz(:,1);
y = sxyz(:,2);
z = sxyz(:,3);
myeps = max(max(abs(x)),max(abs(y)))*eps^(1/3);
ind = [0; ((abs(diff(y)) < myeps) & (abs(diff(x)) < myeps)); 0];

if sum(ind) > 0
warning(’MATLAB:griddata:DuplicateDataPoints’,[’Duplicate x-y data points ’ ...
’detected: using average of the z values.’]);
fs = find(ind(1:end-1) == 0 & ind(2:end) == 1);
fe = find(ind(1:end-1) == 1 & ind(2:end) == 0);
for i = 1 : length(fs)
% averaging z values
z(fe(i)) = mean(z(fs(i):fe(i)));
end
x = x(~ind(2:end));
y = y(~ind(2:end));
z = z(~ind(2:end));
end

switch lower(method),
case ’linear’
zi = linear(x,y,z,xi,yi,opt);
case ’cubic’
zi = cubic(x,y,z,xi,yi,opt);
case ’nearest’
zi = nearest(x,y,z,xi,yi,opt);
case {’invdist’,’v4’}
zi = gdatav4(x,y,z,xi,yi);
otherwise

error(’MATLAB:griddata:UnknownMethod’, ’Unknown method.’);


end

303
Appendix E: Matlab Subroutines

if nargout<=1, xi = zi; end

)XQFWLRQ]L OLQHDU [\][L\LRSW 

%LINEAR Triangle-based linear interpolation


% Reference: David F. Watson, "Contouring: A guide
% to the analysis and display of spacial data", Pergamon, 1994.

siz = size(xi);
xi = xi(:); yi = yi(:); % Treat these as columns
x = x(:); y = y(:); % Treat these as columns

% Triangularize the data


if isempty(opt)
tri = delaunayn([x y]);
else
tri = delaunayn([x y],opt);
end

if isempty(tri),
warning(’MATLAB:griddata:CannotTriangulate’,’Data cannot be triangulated.’);
zi = repmat(NaN,size(xi));
return
end

% Find the nearest triangle (t)


t = tsearch(x,y,tri,xi,yi);

% Only keep the relevant triangles.


out = find(isnan(t));
if ~isempty(out), t(out) = ones(size(out)); end
tri = tri(t,:);

% Compute Barycentric coordinates (w)


del = (x(tri(:,2))-x(tri(:,1))) .* (y(tri(:,3))-y(tri(:,1))) - ...
(x(tri(:,3))-x(tri(:,1))) .* (y(tri(:,2))-y(tri(:,1)));
w(:,3) = ((x(tri(:,1))-xi).*(y(tri(:,2))-yi) - ...
(x(tri(:,2))-xi).*(y(tri(:,1))-yi)) ./ del;
w(:,2) = ((x(tri(:,3))-xi).*(y(tri(:,1))-yi) - ...
(x(tri(:,1))-xi).*(y(tri(:,3))-yi)) ./ del;
w(:,1) = ((x(tri(:,2))-xi).*(y(tri(:,3))-yi) - ...
(x(tri(:,3))-xi).*(y(tri(:,2))-yi)) ./ del;
w(out,:) = zeros(length(out),3);
z = z(:).’; % Treat z as a row so that code below involving
% z(tri) works even when tri is 1-by-3.
zi = sum(z(tri) .* w,2);
zi = reshape(zi,siz);
if ~isempty(out), zi(out) = NaN; end

304
Appendix E: Matlab Subroutines
( &$6)¶V$OJRULWKP

CASF could be executed calling CASF.m from the MATLAB command. This FDOOV RWKHU
VXEURXWLQHV³VHWBXSB&$6)´ZKLFKVHWXSWKHLQLWLDOPRGHOSDUDPHWHUV³extraction.m” which
simulates the extraction sequence, stores the extracted material and calls the CASF transition
functions for unconfined and confined granular flow.

E.2.1 Data file “ CASF.m” .


% This is the main program of CASF
profile on
tic; % time per simulation
6HWBXSB&$6);
([WUDFWLRQB&$6);
disp(’Time sim:’);
disp(num2str(toc));
profile viewer

E.2.2 Data file “ Set_up_CASF.m”


% this subroutine set up CASF initial input parameters
%set up cell dimensions
b_dim_z=40;
b_dim_x=40;
b_dim_y=40;

% inverse distance probabilities


prob2=[0 0.351 0.459 0.567 0.675 0.783 0.837 0.892 0.946];
jstp2=[0 -1 1 0 0 -1 1 -1 1];
kstp2=[0 0 0 1 -1 -1 -1 1 1];
refill=1;
pile_threshold=2; % determine angle of pile

%seed state if state if 0 use same seed number previous to each simulation
rand(’state’,0);

% use different seed number previous to each simulation for statistical analysis
%state_seed=sum(100*clock);
%rand(’state’,state_seed);

% define material characteristics


dens=1900; %cell density
m_block=(b_dim_x*b_dim_y*b_dim_z*10^-9)*dens; % mass per block
runs=6; % number of runs
v_number=4; %cv threshold

%graphics on if see is 1 off if equal to 1


see=0;
d=1;
counter=0;
counter2=0;
counter3=0;
305
Appendix E: Matlab Subroutines

%boundary conditions
nz=round((3600+100)/b_dim_z); % measured from the drawpoint floor
nx=round(3300/b_dim_x);
ny=round(3300/b_dim_y);
a=zeros(nx,ny,nz);
aa=repmat((1:nx)’*(10^3),1,nx)+repmat(1:nx,nx,1);

%drawpoint dimensions
W_dp=round(120/b_dim_x);
H_db=round(400/b_dim_z);
H_dp=round(100/b_dim_z);
L_db=round(1200/b_dim_x);
alpha=22; %angle front view of drawbell
betha=0; % angle side view across drawbell

for i=1:nz
a(:,:,i)=(10^6)*i+aa;
end

%solids in production level including drifts


a(1:nx,1:nx,1:H_db+1)=-2*10^6;

%position of drawbells in the layout


drawbell_minorapex=(500/b_dim_x);
angle_drawbell=30;
x_db(1)=round(nx/2-W_dp/2);
y_db(1)=round(nx/2-L_db/2);
x_db(2)=round(x_db(1)-drawbell_minorapex);
y_db(2)=round(y_db(1)-tan(angle_drawbell*pi()/180)*drawbell_minorapex);
x_db(3)=round(x_db(1)+drawbell_minorapex);
y_db(3)=round(y_db(1)+tan(angle_drawbell*pi()/180)*drawbell_minorapex);
active_drawbells=[1]; % # of active drawbells in this geometry
drawbells=length(active_drawbells);
dp=2; % # active drawpoints in the drawbell
drawpoint_number=dp*drawbells;

%voids near the drawpoint


for j=1:drawbells
for i=1:H_dp
xi=x_db(j);
yi=y_db(j);
xf=x_db(j)+W_dp-1;
yf=y_db(j)+L_db-1;
h=(xi:xf);
b=(yi:yf);
aa=repmat(h’*1000,1,yf-yi+1)+repmat(b,xf-xi+1,1);
a(h,b,i)=aa+(10^6)*i;
%define voids at the drawpoint
b1=(1:yi-1);
b2=(yf+1:ny);
a(h,b1,i)=0;
a(h,b2,i)=0;
end
end
306
Appendix E: Matlab Subroutines

%set up material within drawbell


for j=1:drawbells
for i=H_dp+1:H_db+1
xi=x_db(j)-round((i-1)*(b_dim_z/b_dim_x)*tan(alpha*pi/180));
yi=y_db(j)-round((i-1)*(b_dim_z/b_dim_x)*tan(betha*pi/180));
xf=x_db(j)+round((i-1)*(b_dim_z/b_dim_x)*tan(alpha*pi/180))+W_dp-1;
yf=y_db(j)+round((i-1)*(b_dim_z/b_dim_x)*tan(betha*pi/180))+L_db-1;
h=(xi:xf);
b=(yi:yf);
aa=repmat(h’*1000,1,yf-yi+1)+repmat(b,xf-xi+1,1);
a(h,b,i)=aa+(10^6)*i;
end
end

%initialize matrices for stroring results


extr=zeros(nx,ny,nz)-1; % initialize IEZ matrix
extracted=zeros(nx,ny,nz); % extracted bt whom matrix
IMZ=zeros(nx,ny,nz)-1; % IMZ matrix
moved=zeros(nx,ny,nz)-1; % when extracted moved by whom matix
blocks(1:drawpoint_number)=0; % number of cells extracted per drawpoint
w_blocks(1:drawpoint_number)=0;
waste(1:drawpoint_number)=0; %amount of waste
hangups(1:drawpoint_number)=0; %hang ups matrix
dil(1:drawpoint_number)=0;
dilution=cell(10,1);
pointer_void=cell(nz,1); %void location matrix
matrix_up=zeros(3,3); %matrix for cv
for i=1:drawpoint_number
dilution{i}(:,:)=zeros(100,3);
end
b=zeros(nz,1); %initialize void lists\
for i=1:nz
pointer_void{i}=zeros(300,2);
end

for tt=1:drawbells %location of drawpoint’s base


ix(tt*2-1,:)=x_db(tt):x_db(tt)+W_dp-1;
ix(tt*2,:)=x_db(tt):x_db(tt)+W_dp-1;
iy(tt*2-1,:)=y_db(tt):round(y_db(tt)+round(100/b_dim_x)-1);
iy(2*tt,:)=y_db(tt)+L_db-1:-1:y_db(tt)+L_db-round(100/b_dim_x);
end

for tt=1:drawbells
Pile_drawbell; % call for unconfined fu for all drawpoints
end

% display view of initial set up (optional)


display_view(a,nz,nx,b_dim_x,b_dim_z,floor(nx/2));

E.2.3 Data file “ Extraction.m”


% This function extract material from drawpoints according to a sequence of draw simulating
% concurrent draw. The position of extracted cells is stored to determine the extraction zone from
% the data.

307
Appendix E: Matlab Subroutines
extr_level=1;
extractions=1;

while extr_level<runs && sum(waste>100)<drawpoint_number

for nb=1:drawbells
for active_drawpoint=1:dp % active drawpoints
if active_drawpoint==1
drawpoint=(active_drawpoint*nb*2)-1;
else
drawpoint=(active_drawpoint*nb);
end
mass_drawn=0;

while mass_drawn < 3 && waste(drawpoint)< 100 % stop at dilution entry & draw 3 kg each time
if active_drawpoint==1;
for i=1:H_dp
exit=a(ix(drawpoint,:),iy(drawpoint)-10:iy(drawpoint)-1,i);
ext=exit(exit~=0);
a(ix(drawpoint,:),iy(drawpoint)-10:iy(drawpoint)-1,i)=0;
waste(drawpoint)=sum(find(ext==-10^6))+waste(drawpoint);
if (length(ext)>0)
mass_drawn=length(ext)*m_block+mass_drawn;
% store in draw the extraction per drawpoint
blocks(drawpoint)=blocks(drawpoint)+length(ext);
w_blocks(drawpoint)=blocks(drawpoint)*m_block; % accumulate mass drawn
if waste(drawpoint)>0
dil(drawpoint)=dil(drawpoint)+1;

dilution{drawpoint}(dil(drawpoint),1:3)=[w_blocks(drawpoint),(waste(drawpoint)*m_block),waste(dr
awpoint)/blocks(drawpoint)*100];
ext=ext(ext~=-10^6); end
x_IEZ=floor(ext/1000)-floor(ext/10^6)*10^3; %calculates initial position of blocks
y_IEZ=ext-floor(ext/10^3)*10^3;
z_IEZ=floor(ext/10^6);
for i=1:length(x_IEZ)
extr(x_IEZ(i),y_IEZ(i),z_IEZ(i))=w_blocks(drawpoint); % store IEZ matrix
extracted(x_IEZ(i),y_IEZ(i),z_IEZ(i))=drawpoint; % store drawpoint
end;
else
if i==1
hangups(drawpoint)=hangups(drawpoint)+1;
mass_hangups(drawpoint,hangups(drawpoint))=w_blocks(drawpoint);
end
end
end % end for drawpoint condition
else
for i=1:H_dp
exit=a(ix(drawpoint,:),iy(drawpoint)+1:iy(drawpoint)+10,i);
ext=exit(exit~=0);
waste(drawpoint)=sum(find(ext==-10^6))+waste(drawpoint);
a(ix(drawpoint,:),iy(drawpoint)+1:iy(drawpoint)+10,i)=0;
if (length(ext)>0)
mass_drawn=length(ext)*m_block+mass_drawn; % store in draw
blocks(drawpoint)=blocks(drawpoint)+length(ext);
308
Appendix E: Matlab Subroutines
w_blocks(drawpoint)=blocks(drawpoint)*m_block; % accumulate mass
if waste(drawpoint)>0
dil(drawpoint)=dil(drawpoint)+1;

dilution{drawpoint}(dil(drawpoint),1:3)=[w_blocks(drawpoint),(waste(drawpoint)*m_block),waste(dr
awpoint)/blocks(drawpoint)*100];
ext=ext(ext~=-10^6);
end

x_IEZ=floor(ext/1000)-floor(ext/10^6)*10^3; %calculates initial position of


blocks
y_IEZ=ext-floor(ext/10^3)*10^3;
z_IEZ=floor(ext/10^6);

for i=1:length(x_IEZ)
extr(x_IEZ(i),y_IEZ(i),z_IEZ(i))=w_blocks(drawpoint); % store IEZ matrix
extracted(x_IEZ(i),y_IEZ(i),z_IEZ(i))=drawpoint; % store drawpoint
end
else
if i==1
hangups(drawpoint)=hangups(drawpoint)+1;
mass_hangups(drawpoint,hangups(drawpoint))=w_blocks(drawpoint);
end
end
end %end for extr. drawpoint
end %end if for drawpoint
CASF_confined_transition_function; % call fc and move voids upwards
Displace_floating_blocks_gravity;
CASF_unconfined_transition_function;
end % next draw
end %next drawpoint in drawbell
end %next drawbell
extr_level=extr_level+1; end; %next extraction in the level

E.2.4 Datafile “ CASF_confined_transition_function”

% This function is the void_diffusion function which applies fc to voids at the drawpoint brow
% upwards

if active_drawpoint==1
for i=1:H_dp
[j k]=find(a{i}(ix(drawpoint,:),iy(drawpoint,:))==0);
b(i)=length(j);
pointer_void{i}(1:b(i),1:2)=[j+ix(drawpoint)-1,k+iy(drawpoint)-1];
end
else
for i=1:H_dp
[j k]=find(a{i}(ix(drawpoint,:),iy(drawpoint,:))==0);
b(i)=length(j);
pointer_void{i}(1:b(i),1:2)=[j+ix(drawpoint)-1,iy(drawpoint)-k+1];
end
end
i=1;
while i<nz
i1=i+1;
309
Appendix E: Matlab Subroutines
if b(i)==0 && i>H_dp
break; % no voids in those levels means exit from the loop
end
if b(i)>0
pointer_aux=zeros(b(i),3);
pointer_aux(1:b(i),1)=pointer_void{i}(1:b(i),1); % j position of voids at level i
pointer_aux(1:b(i),2)=pointer_void{i}(1:b(i),2); % k position of voids at level
pointer_aux(1:b(i),3)=(-1)*rand(b(i),1); %generates random
pointer_aux=sortrows(pointer_aux,3); % choose random
pointer_void{i}(1:b(i),1:2)=pointer_aux(1:b(i),1:2);

for ii=1:b(i) % move voids in this level


j=pointer_aux(ii,1);
k=pointer_aux(ii,2);

if(j>1 && j<nx && k>1 && k<ny)


matrix_up=a{i1}(j-1:j+1,k-1:k+1); %looks upwards
count_up=sum(sum(matrix_up==0)); %count voids at void level +1
count_level=sum(sum(a{i}(j-1:j+1,k-1:k+1)==0)); %count voids at void level
count=count_up+count_level;
if i<=H_db
count_solid=sum(sum(matrix_up==-10^6));
else
count_solid=0;
end
p=rand;
if(count <v_number) % no movement
indx=0;
else
if count_up>0 && count_up+count_solid<9 %there is voids above but no only voids
[u1 u2]=find(matrix_up>0);
jstp=u2-2;
kstp=u1-2;
prob=0:1/(9-count_up-count_solid): 1-(1/(9-count_up-count_solid));
indx=sum(prob<p);
if indx>0
j1=j+jstp(indx);
k1=k+kstp(indx);
end
else
if count_up+count_solid==9 % %only voids there is transaction
indx=0;
else
indx=sum(prob2<p);
if(indx>0)
j1=j+jstp2(indx);
k1=k+kstp2(indx);
end
end
end
end
if(indx>0) % if the void could move
t=a{i+1}(j1,k1);
%at=atribute{i+1}(j1,k1); % could see flow if activated
if i1==nz && refill==1 % at model top level
310
Appendix E: Matlab Subroutines
t=1.2;
a{i}(j,k)=t; % assign waste
a{i1}(j1,k1)=-2; %refill with waste
atribute{i1}(j1,k1)=color_waste;
at=color_waste;
pointer_void{i}(ii,1:2)=0; %erase void in list
bi1=b(i1)+1;
b(i1)=bi1;
else
if(t~=0 && t~=-10^6) % solid and voids do not move
a{i}(j,k)=t;
atribute{i}(j,k)=at;
a{i1}(j1,k1)=0;
atribute{i1}(j1,k1)=color_void(1);
pointer_void{i}(ii,1:2)=0; % erase moved void
bi1=b(i1)+1;
b(i1)=bi1;
pointer_void{i1}(bi1,1)=j1; %upgrade pointer to voids
pointer_void{i1}(bi1,2)=k1;
if (j1==floor(nx/2) && see==1)
counter=counter+1;
if mod(counter,100)==0
m(d)=display_view(a,nz,nx,b_dim_x,b_dim_z,floor(nx/2)); % for movie
d=d+1;
counter=1;
end
end
if IMZ(j1,k1,i1)< 0 % for determining MZ
IMZ(j1,k1,i1)=w_blocks(drawpoint);
moved(j1,k1,i1)=drawpoint;
end; end; end; end; end; end
t1=find(pointer_void{i}(1:b(i),1)>0); % upgrade pointer
t2=length(t1);
b(i)=t2;
pointer_void{i}(1:t2,1)=pointer_void{i}(t1,1);
pointer_void{i}(1:t2,2)=pointer_void{i}(t1,2);
end
i=i1;
end %move to next level

E.2.5 Datafile “ Pile_drawbell”


% applies fu for all drawbells
%3D pile using deterministic CA-SOC
c=a(ix(2*tt-1,:),1:ny,1:H_dp);
for i=1:size(c,1)
for j=1:size(c,2)
height_pile(i,j,:)=sum(c(i,j,:)~=0 & c(i,j,:)~=-2*10^6 );
end
end

%right side of the drawbell


j=1;
in=y_db(tt)+floor(L_db/2);
fin=min(in+10,nx-1);

311
Appendix E: Matlab Subroutines
for i=in:fin
diff_height(:,j)=height_pile(:,i)-height_pile(:,i+1);
j=j+1;
end

for k=1:size(diff_height,1) %rows


while sum(diff_height(k,:)>=pile_threshold)>0

for i=1:size(diff_height,2)-1 %columns


if diff_height(k,i)>=pile_threshold
%first fall from the upper side
a(x_db(tt)+k-1,in+i,height_pile(k,i+in)+1)=a(x_db(tt)+k-1,in+i-1,height_pile(k,i+in-1));
a(x_db(tt)+k-1,in+i-1,height_pile(k,i+in-1))=0;
height_pile(k,i+in-1)=height_pile(k,i+in-1)-1;
height_pile(k,i+in)=height_pile(k,i+in)+1;
if i==1
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
else
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
diff_height(k,i-1)=diff_height(k,i-1)+1;
end
end
end
end
end

%left side of the drawbell


j=1;
in=y_db(tt)+floor(L_db/2);
fin=max(2,in-10);

for i=in:-1:fin
diff_height(:,j)=height_pile(:,i)-height_pile(:,i-1);
j=j+1;
end

for k=1:size(diff_height,1) %rows


while sum(diff_height(k,:)>=pile_threshold)>0
for i=1:size(diff_height,2)-1 %columns
if diff_height(k,i)>=pile_threshold
a(x_db(tt)+k-1,in-i,height_pile(k,in-i)+1)=a(x_db(tt)+k-1,in-i+1,height_pile(k,in-i+1));
a(x_db(tt)+k-1,in-i+1,height_pile(k,in-i+1))=0;
height_pile(k,in-i+1)=height_pile(k,in-i+1)-1;
height_pile(k,in-i)=height_pile(k,in-i)+1;
if i==1
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
else
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
diff_height(k,i-1)=diff_height(k,i-1)+1;
end
end
312
Appendix E: Matlab Subroutines
end
end
end

E.2.6 Datafile “ CASF_unconfined_transition_function”


%This is the 3D unconfined flow algorithm algorithm using a deterministic CA-SOC (self organised
critically)
c(:,:,1:H_dp)=a(ix(drawpoint,:),1:ny,1:H_dp);
for i=1:size(c,1)
for j=1:size(c,2)
height_pile(i,j,:)=sum(c(i,j,:)~=0 & c(i,j,:)~=-2*10^6);
end
end
if active_drawpoint==2 %right side of the drawbell
j=1;
in=y_db(nb)+floor(L_db/2);
fin=min(in+50,nx-1);
for i=in:fin
diff_height(:,j)=height_pile(:,i)-height_pile(:,i+1);
j=j+1;
end
for k=1:size(diff_height,1) %rows
while sum(diff_height(k,:)>=pile_threshold)>0
for i=1:size(diff_height,2)-1 %columns
if diff_height(k,i)>=pile_threshold

%first fall from the upper side


a(x_db(nb)+k-1,in+i,height_pile(k,i+in)+1)=a(x_db(nb)+k-1,in+i-1,height_pile(k,i+in-1));
a(x_db(nb)+k-1,in+i-1,height_pile(k,i+in-1))=0;

height_pile(k,i+in-1)=height_pile(k,i+in-1)-1;
height_pile(k,i+in)=height_pile(k,i+in)+1;
if i==1
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
else
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
diff_height(k,i-1)=diff_height(k,i-1)+1;
end
end
end; end; end

else %left side of the drawbell


j=1;
in=y_db(nb)+floor(L_db/2);
fin=max(2,in-50);

for i=in:-1:fin
diff_height(:,j)=height_pile(:,i)-height_pile(:,i-1);
j=j+1;
end

for k=1:size(diff_height,1) %rows


while sum(diff_height(k,:)>=pile_threshold)>0
313
Appendix E: Matlab Subroutines

for i=1:size(diff_height,2)-1 %columns


if diff_height(k,i)>=pile_threshold
a(x_db(nb)+k-1,in-i,height_pile(k,in-i)+1)=a(x_db(nb)+k-1,in-i+1,height_pile(k,in-i+1));
a(x_db(nb)+k-1,in-i+1,height_pile(k,in-i+1))=0;
height_pile(k,in-i+1)=height_pile(k,in-i+1)-1;
height_pile(k,in-i)=height_pile(k,in-i)+1;
if i==1
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
else
diff_height(k,i)=diff_height(k,i)-2;
diff_height(k,i+1)=diff_height(k,i+1)+1;
diff_height(k,i-1)=diff_height(k,i-1)+1;
end
end
end
end
end
end

E.2.7 Data file “ Displace_floating_blocks_gravity.m”


%This function displace floating blocks near the drawpoint simulating gravity
if active_drawpoint==1
[j2 k2]=find(a(ix(drawpoint,:),iy(drawpoint,:),H_dp)>=-10^6);
j2=j2+ix(drawpoint)-1;
k2=k2+iy(drawpoint)-1;
else
[j2 k2]=find(a(ix(drawpoint,:),iy(drawpoint,:),H_dp)>=-10^6);
j2=j2+ix(drawpoint)-1;
k2=iy(drawpoint)-k2+1;
end

%apply gravity to blocks


for i=1:length(j2)
move=H_dp;
for j=H_dp-1:-1:1
if a(j2(i),k2(i),j)==0
move=j;
else
break
end
end
if move <H_dp
a(j2(i),k2(i),move)=a(j2(i),k2(i),H_dp);
a(j2(i),k2(i),H_dp)=0;
end
end

314
Appendix E: Matlab Subroutines

315
Appendix E: Matlab Subroutines

316