-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit version from 15th Feb 2021
- Loading branch information
0 parents
commit 9505c6e
Showing
54 changed files
with
6,772 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
double click on the file carboCATGUI.m to open Matlab and load this file. | ||
Run the function either by enterting the function name carboCATGUI at the command prompt, | ||
or by clicking run in the editor tab | ||
|
||
The GUI should be reasonably intuitive; click on the Initialise button to set up the model | ||
ready to run, then click on Run CA Model, then on PLot run and you should see the | ||
results from the paramsProcess.txt and the paramsInputValues.txt input files I have set up | ||
in the params folder. You can edit both of these files to run different models. | ||
You can also use the code in the utilities folder to make new initial topography, | ||
intial facies maps, sea-level curves and other inputs you might need to create | ||
useful models | ||
|
||
Any questions, e-mail peter.burgess@liverpool.ac.uk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
clear all | ||
clc | ||
|
||
%%load saved data | ||
strata=load('C:\EquinorProject\Meeting\28Apr\WaveNorth\strata.mat'); | ||
glob.strata=strata.strata; | ||
numberOfLayers=load('C:\EquinorProject\Meeting\28Apr\WaveNorth\numberOfLayers.mat'); | ||
glob.numberOfLayers=numberOfLayers.numberOfLayers; | ||
facies=load('C:\EquinorProject\Meeting\28Apr\WaveNorth\facies.mat'); | ||
glob.facies=facies.facies; | ||
glob.ySize=size(glob.strata,1); | ||
glob.xSize=size(glob.strata,2); | ||
iteration=size(glob.strata,3); | ||
glob.dx=250; %cell size | ||
deltaT=100; %calculate platform margin at every 100 iterations | ||
T=linspace(deltaT,iteration,iteration/deltaT); | ||
|
||
% %%for diagonal cross section where y=x; | ||
% long=min(glob.xSize,glob.ySize); | ||
% gradDiag=zeros(long,iteration); | ||
% PfDiag=zeros(long,iteration); | ||
% Zdiag=zeros(long,iteration); | ||
% for y=1:long-1 | ||
% xPos=y; | ||
% for t=2:iteration | ||
% | ||
% g=glob.strata(y+1,xPos+1,t)-glob.strata(y,xPos,t); | ||
% gradDiag(y,t)=g/25; | ||
% for m=1:glob.numberOfLayers(y,xPos,t) | ||
% if glob.facies{y+1,xPos,t}(1)==10 && glob.facies{y,xPos,t}(m)==1 | ||
% PfDiag(y,t)=1; | ||
% Zdiag(y,t)=glob.strata(y,xPos,t); | ||
% elseif glob.facies{y,xPos,t}(m)==10 && glob.facies{y,xPos,t}(m)==11 && glob.facies{y+1,xPos,t}(1)==1 | ||
% PfDiag(y,t)=1; | ||
% end | ||
% end | ||
% | ||
% | ||
% end | ||
% | ||
% end | ||
% gradDiag(gradDiag>1)=1; | ||
% gradDiag=abs(gradDiag); | ||
% for i=1:length(T) | ||
% t=T(i); | ||
% PDiag(:,i)=gradDiag(:,t).*PfDiag(:,t); | ||
% end | ||
% [Xdiag,Zdiag] = find(PDiag); | ||
% for i=1:size(Xdiag,1) | ||
% Z2diag(i)=glob.strata(Xdiag(i),Xdiag(i),Zdiag(i)*deltaT); | ||
% end | ||
% figure | ||
% subplot(2,1,1) | ||
% scatter(Xdiag,Zdiag,200,'r'); | ||
% ylabel('EMT','FontSize',18,'FontWeight','bold'); | ||
% xlabel('km','FontSize',18,'FontWeight','bold'); | ||
% title(['Diagonal, t= ', num2str(0.001*iteration),'My'],'FontSize',20); | ||
% xticks([1, 0.25*(long+2), 0.5*(long+2), 0.75*(long+2),long+1]); | ||
% xticklabels (round([0 ,long*1.414*glob.dx/4000 ,long*1.414*glob.dx/2000,long*1.414*3*glob.dx/4000,long*1.414*glob.dx/1000])); | ||
% % yticks([0 ,5, 10]); | ||
% % yticklabels ([0 0.5*iteration/1000,iteration/1000]); | ||
% axis([1 long+1 0 iteration/deltaT]) | ||
% ax=gca; | ||
% ax.LineWidth = 0.6; | ||
% ax.FontSize = 24; | ||
% ax.FontWeight = 'bold'; | ||
% | ||
% subplot(2,1,2) | ||
% scatter(Xdiag,Z2diag,200,'r'); | ||
% ylabel('Elevation (m)','FontSize',18,'FontWeight','bold'); | ||
% xlabel('km','FontSize',18,'FontWeight','bold'); | ||
% xticks([1, 0.25*(long+2), 0.5*(long+2), 0.75*(long+2),long+1]); | ||
% xticklabels (round([0 ,long*1.414*glob.dx/4000 ,long*1.414*glob.dx/2000,long*1.414*3*glob.dx/4000,long*1.414*glob.dx/1000])); | ||
% % yticks([0 ,5, 10]); | ||
% % yticklabels ([0 0.5*iteration/1000,iteration/1000]); | ||
% axis([1 long+1 0 1500]) | ||
% ax=gca; | ||
% ax.LineWidth = 0.6; | ||
% ax.FontSize = 24; | ||
% ax.FontWeight = 'bold'; | ||
|
||
|
||
%%for othogonal cross section along y axis | ||
xPos=glob.xSize/2; | ||
gradY=zeros(glob.ySize,iteration); %to store elevation difference between adjacent cells | ||
Pfy=zeros(glob.ySize,iteration); %to store probability of facies transition | ||
Zy=zeros(glob.ySize,iteration); %to store elevation values of platform margins | ||
for y=1:glob.ySize-1 | ||
|
||
for t=2:iteration | ||
|
||
g=glob.strata(y+1,xPos,t)-glob.strata(y,xPos,t); | ||
gradY(y,t)=g/50; | ||
for m=1:glob.numberOfLayers(y,xPos,t) | ||
if glob.facies{y+1,xPos,t}(1)==10 && glob.facies{y,xPos,t}(m)==1 | ||
Pfy(y,t)=1; | ||
Zy(y,t)=glob.strata(y,xPos,t); | ||
elseif glob.facies{y,xPos,t}(m)==10 && glob.facies{y,xPos,t}(m)==11 && glob.facies{y+1,xPos,t}(1)==1 | ||
Pfy(y,t)=1; | ||
end | ||
end | ||
|
||
|
||
end | ||
end | ||
%turn the calculated gradient into a value between 0 and 1 | ||
gradY(gradY>1)=1; | ||
gradY=abs(gradY); | ||
for i=1:length(T) | ||
t=T(i); | ||
Py(:,i)=gradY(:,t).*Pfy(:,t); | ||
end | ||
[X1,Z] = find(Py); | ||
for i=1:size(X1,1) | ||
Z2(i)=glob.strata(X1(i),xPos,Z(i)*deltaT); | ||
end | ||
|
||
%%plot figure in time | ||
figure | ||
subplot('Position',[0.14, 0.55, 0.72 0.35]) | ||
scatter(X1,Z,200,'r'); | ||
ylabel('EMT','FontSize',18,'FontWeight','bold'); | ||
xlabel('y(km)','FontSize',18,'FontWeight','bold'); | ||
title(['t= ', num2str(0.001*iteration),'My'],'FontSize',20); | ||
xticks([1 10 20 30 40 50 60 70 80 90 100]); | ||
xticklabels (0:(glob.dx/100):20); | ||
% yticks([0 ,5, 10]); | ||
% yticklabels ([0 0.5*iteration/1000,iteration/1000]); | ||
axis([1 glob.ySize 0 iteration/deltaT]) | ||
ax=gca; | ||
ax.LineWidth = 0.6; | ||
ax.FontSize = 24; | ||
ax.FontWeight = 'bold'; | ||
|
||
%%for othogonal cross section along x axis | ||
yPos=glob.ySize/2; | ||
gradX=zeros(glob.xSize,iteration); | ||
Pfx=zeros(glob.xSize,iteration); | ||
for x=1:glob.xSize-1 | ||
|
||
for t=2:iteration | ||
g=glob.strata(yPos,x+1,t)-glob.strata(yPos,x,t); | ||
gradX(x,t)=g/50; | ||
for m=1:glob.numberOfLayers(yPos,x,t) | ||
if glob.facies{yPos,x+1,t}(1)==10 && glob.facies{yPos,x,t}(m)==1 | ||
Pfx(x,t)=1; | ||
elseif glob.facies{yPos,x,t}(m)==10 && glob.facies{yPos,x,t}(m)==11 && glob.facies{yPos,x+1,t}(1)==1 | ||
Pfx(x,t)=1; | ||
end | ||
end | ||
|
||
|
||
end | ||
end | ||
gradX(gradX>1)=1; | ||
gradX=abs(gradX); | ||
[row, col] = find(Pfx(:,1:iteration)>0); | ||
for i=1:length(T) | ||
t=T(i); | ||
Px(:,i)=gradX(:,t).*Pfx(:,t); | ||
end | ||
|
||
[X2,Z] = find(Px); | ||
for i=1:size(X2,1) | ||
Z3(i)=glob.strata(yPos,X2(i),Z(i)*deltaT); | ||
end | ||
subplot('Position',[0.14, 0.1, 0.68 0.35]) | ||
scatter(X2,Z,200,'r'); | ||
ylabel('EMT','FontSize',18,'FontWeight','bold'); | ||
xlabel('x(km)','FontSize',18,'FontWeight','bold'); | ||
xticks([1 10 20 30 40 50 60 70 80 90 100]); | ||
xticklabels (0:(glob.dx/100):20); | ||
% yticks([0 ,5, 10]); | ||
% yticklabels ([0 0.5*iteration/1000,iteration/1000]); | ||
axis([1 glob.xSize 0 iteration/deltaT]) | ||
ax=gca; | ||
ax.LineWidth = 0.6; | ||
ax.FontSize = 24; | ||
ax.FontWeight = 'bold'; | ||
|
||
|
||
%%plot cross section in depth | ||
figure | ||
subplot('Position',[0.14, 0.55, 0.72 0.35]) | ||
scatter(X1,Z2,200,'r'); | ||
ylabel('Elevation (m)','FontSize',18,'FontWeight','bold'); | ||
xlabel('y(km)','FontSize',18,'FontWeight','bold'); | ||
title(['t= ', num2str(0.001*iteration),'My'],'FontSize',20); | ||
xticks([1 10 20 30 40 50 60 70 80 90 100]); | ||
xticklabels (0:(glob.dx/100):20); | ||
axis([1 glob.ySize 0 1500]) | ||
ax=gca; | ||
ax.LineWidth = 0.6; | ||
ax.FontSize = 24; | ||
ax.FontWeight = 'bold'; | ||
|
||
subplot('Position',[0.14, 0.1, 0.68 0.35]) | ||
scatter(X2,Z3,200,'r'); | ||
ylabel('Elevation (m)','FontSize',18,'FontWeight','bold'); | ||
xlabel('x(km)','FontSize',18,'FontWeight','bold'); | ||
xticks([1 10 20 30 40 50 60 70 80 90 100]); | ||
xticklabels (0:(glob.dx/100):20); | ||
axis([1 glob.xSize 0 1500]) | ||
ax=gca; | ||
ax.LineWidth = 0.6; | ||
ax.FontSize = 24; | ||
ax.FontWeight = 'bold'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
function [glob] = calculateFaciesCAProdDependent(glob, iteration) | ||
% Calculate the facies cellular automata according to neighbour rules in | ||
% glob.CARules and modify production rate modifier for each cell according to number of neighbours. | ||
% The order in which facies are checked depends on the production value at the depth of the cell | ||
|
||
j = iteration - 1; | ||
k = iteration; | ||
|
||
% Neighbours contains a count of neighbours for each facies at each grid point and is populated by the countAllNeighbours function | ||
neighbours = zeros(glob.ySize, glob.xSize, glob.maxProdFacies); | ||
|
||
[neighbours] = countAllNeighbours(glob, j, neighbours); | ||
glob.faciesProdAdjust = zeros(glob.ySize, glob.xSize); | ||
|
||
tempFaciesProd = zeros(glob.ySize, glob.xSize, glob.maxProdFacies); % need a CA array for each prod facies | ||
|
||
for y = 1 : glob.ySize | ||
for x= 1 : glob.xSize | ||
|
||
oneFacies = glob.facies{y,x,j}(1); | ||
|
||
% Only do anything here if the latest stratal surface is below sea-level, i.e. | ||
% water depth > 0.001 and if the concentration is enough to maintain production | ||
if glob.wd(y,x,k) > 0.001 | ||
|
||
% For a subaerial hiatus, now reflooded because from above wd > 0 | ||
if oneFacies == 9 % 9 is the code for subaerial exposure | ||
checkProcess=strcmp(glob.refloodingRoutine,'pre-exposed'); | ||
if checkProcess==1 | ||
% Get the facies from the pre-exposed | ||
glob.facies{y,x,k}(1) = findPreHiatusFacies(glob, x,y,iteration); % reoccupy with facies from below hiatus | ||
glob.numberOfLayers(y,x,k)=1; | ||
else | ||
% Set facies =0; | ||
glob.facies{y,x,k}(1) = 0; | ||
glob.numberOfLayers(y,x,k)=0; | ||
end | ||
if glob.facies{y,x,k}(1)> glob.maxProdFacies || glob.facies{y,x,k}(1)==0 | ||
glob.facies{y,x,k}(1) = 0; | ||
glob.numberOfLayers(y,x,k)=0; | ||
end | ||
|
||
% For cells already containing producing facies | ||
elseif (oneFacies <= glob.maxProdFacies && oneFacies>0) && glob.numberOfLayers(y,x,j)==1 | ||
|
||
% Check if neighbours is less than min for survival CARules(i,2) or | ||
% greater than max for survival CARules(i,3), or if water depth is greater than production cutoff and if so kill | ||
% that facies | ||
thick = glob.carbonateVolMap(y,x) / (glob.ySize*glob.xSize); | ||
checkProcess=strcmp(glob.concentrationRoutine,'on'); | ||
|
||
if (neighbours(y,x,oneFacies) < glob.CARules(oneFacies,2)) ||... | ||
(neighbours(y,x,oneFacies) > glob.CARules(oneFacies,3)) ||... | ||
(glob.wd(y,x,iteration) >= glob.prodRateWDCutOff(oneFacies)) ||... | ||
( checkProcess == 1 && thick < 0.01) | ||
glob.facies{y,x,k}(1) = 0; | ||
else % The right number of neighbours exists | ||
glob.facies{y,x,k}(1) = oneFacies; | ||
glob.numberOfLayers(y,x,k)=1; | ||
end | ||
|
||
else % Otherwise cell must be empty or contain transported product so see if it can be colonised with a producing facies | ||
% Check again the carbonate concentration | ||
thick = glob.carbonateVolMap(y,x) / (glob.ySize*glob.xSize); | ||
checkProcess=strcmp(glob.concentrationRoutine,'on'); | ||
if checkProcess == 0 || thick > 0.01 | ||
for f = 1:glob.maxProdFacies | ||
% Check if number of neighbours is within range to trigger new | ||
% facies cell, and only allow new cell if the water depth is less the production cut off depth | ||
if (neighbours(y,x,f) >= glob.CARules(f,4)) && (neighbours(y,x,f) <= glob.CARules(f,5)) && (glob.wd(y,x,iteration) < glob.prodRateWDCutOff(f)) | ||
tempFaciesProd(y,x,f) = f; % new facies cell triggered at y,x | ||
end | ||
end | ||
|
||
prodRate = zeros(1,glob.maxProdFacies); | ||
for f = 1:glob.maxProdFacies | ||
if tempFaciesProd(y,x,f) > 0 | ||
prodRate(f) = glob.prodRate(f) * calculateProductionWDAdjustment(glob, x,y, f, iteration); | ||
end | ||
end | ||
|
||
% Find the highest production rate and assign a fraction of 1 at the correct position in the glob.fraction array | ||
[sortedArray,index]=sort(prodRate); | ||
if sum(sortedArray(:))==0 | ||
glob.facies{y,x,k}(1)=0; | ||
else | ||
glob.facies{y,x,k}(1)=index(glob.maxProdFacies); % the last element in the array has the largest production | ||
glob.numberOfLayers(y,x,k)=1; | ||
end | ||
end | ||
end | ||
|
||
% Finally, calculate the production adjustment factor for the current facies distribution | ||
oneFacies = glob.facies{y,x,k}(1); | ||
glob.faciesProdAdjust(y,x)=calculateFaciesProductionAdjustementFactor(glob,y,x,oneFacies,neighbours); | ||
else | ||
glob.facies{y,x,k}(1) = 9; % Set to above sea-level facies because must be at or above sea-level | ||
glob.numberOfLayers(y,x,k)=1; | ||
|
||
end | ||
end | ||
end | ||
end | ||
|
||
function [neighbours] = countAllNeighbours(glob, j, neighbours) | ||
% Function to count the number of cells within radius containing facies 1 | ||
% to maxFacies across the whole grid and store results in neihgbours matrix | ||
|
||
ySize=int16(glob.ySize); | ||
xSize=int16(glob.xSize); | ||
for yco = 1 : ySize | ||
for xco = 1 : xSize | ||
oneFacies = glob.facies{yco,xco,j}(1); | ||
if oneFacies>0 && oneFacies<=glob.maxProdFacies | ||
radius = glob.CARules(oneFacies,1); | ||
else | ||
radius = glob.CARules(1,1); | ||
end | ||
for l = -radius : radius | ||
for m = -radius : radius | ||
|
||
y = yco + l; | ||
x = xco + m; | ||
|
||
checkProcess=strcmp(glob.wrapRoutine,'unwrap'); | ||
if checkProcess==1 | ||
%if near the edge, complete in a mirror-like image the | ||
%neighbours array | ||
if y<1; y=1+(1-y); end | ||
if x<1; x=1+(1-x); end | ||
if y>ySize; y=ySize+(ySize-y); end | ||
if x>xSize; x=xSize+(xSize-x); end | ||
else | ||
%or wrap around the corners | ||
if y<1; y=ySize+1+l; end | ||
if x<1; x=xSize+1+m; end | ||
if y>ySize; y=l; end | ||
if x>xSize; x=m; end | ||
end | ||
%now count the neighbours using the x-y indeces | ||
|
||
%Don't include cell that has over a certain wd | ||
%difference, and penalise the CA with a factor | ||
wdDiff=abs(glob.wd(yco,xco,j)-glob.wd(y,x,j)); | ||
|
||
if wdDiff>glob.BathiLimit | ||
wdDiffFactor=0; | ||
else | ||
wdDiffFactor=(-1/glob.BathiLimit)*wdDiff+1; | ||
end | ||
if wdDiffFactor>0.9; wdDiffFactor=1; end | ||
faciesType=glob.facies{y,x,j}(1); | ||
% Count producing facies as neighbours but do not include the center cell - | ||
% neighbours count should not include itself | ||
if faciesType > 0 && faciesType <= glob.maxProdFacies && not (l == 0 && m == 0) | ||
neighbours(yco,xco,faciesType) = neighbours(yco,xco,faciesType) + (1*wdDiffFactor); | ||
end | ||
|
||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
function [preHiatusFacies] = findPreHiatusFacies(glob, x,y,iteration) | ||
|
||
k = iteration - 1; | ||
|
||
while k > 0 && glob.facies{y,x,k}(1) == 9 | ||
k = k - 1; | ||
end | ||
|
||
preHiatusFacies = glob.facies{y,x,k}(1); | ||
end |
Oops, something went wrong.