Skip to content

Commit

Permalink
add time-dependent elastic thickness
Browse files Browse the repository at this point in the history
  • Loading branch information
tristan-salles committed Nov 27, 2017
1 parent d015983 commit c11619c
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 10 deletions.
146 changes: 146 additions & 0 deletions Examples/input_complete.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
<maxdt>1000.</maxdt>
<!-- Display interval [a] -->
<display>5000.</display>
<!-- Mesh output frequency based on the display interval. (integer)
Considering a display interval of T yrs and a mesh output of K
the mesh will be stored every T*K yrs - (optional default is 1) -->
<meshout>28</meshout>
</time>

<!-- Simulation stratigraphic structure -->
Expand Down Expand Up @@ -374,11 +378,145 @@
<caerial>0.001</caerial>
<!-- Marine diffusion coefficient [m2/a] -->
<cmarine>0.005</cmarine>
<!-- Critical slope for non-linear diffusion [m/m] - optional.
Default value is set to 0 meaning non-lnear diffusion is not considered. -->
<cslp>0.8</cslp>
<!-- River transported sediment diffusion
coefficient in marine realm [m2/a] -->
<criver>10.</criver>
</creep>

<!-- Wave global parameters structure -->
<waveglobal>
<!-- Wave model to consider either SWAN or WaveSed.
Default is WaveSed (wmodel = 0). -->
<wmodel>0</wmodel>
<!-- Wave interval [a] -->
<twave>250.</twave>
<!-- Wave grid resolution [m] -->
<wres>1000.</wres>
<!-- Maximum depth for wave influence [m] -->
<wbase>20</wbase>
<!-- Number of wave climate temporal events. -->
<events>1</events>
<!-- Mean grain size diameter [m] -->
<d50>0.0001</d50>
<!-- Wave sediment diffusion coefficient. Default is 50. -->
<wCd>50.</wCd>
<!-- Wave sediment entrainment coefficient. Value needs to be
set between ]0,1]. Default is 0.5 -->
<wCe>0.35</wCe>
<!-- Maximum wave-induced erosion [m] -->
<wEro>0.5</wEro>
<!-- Maximum depth for wave influence [m] -->
<wbase>10</wbase>
<!-- Steps used to perform sediment transport.
Default is 1000. -->
<tsteps>500</tsteps>
<!-- Steps used to perform sediment diffusion.
Default is 1000. -->
<dsteps>500</dsteps>
</waveglobal>

<!-- Wave definition based on wave global structure.
The wave field needs to be ordered by increasing start time.
The time needs to be continuous between each field without overlaps. -->
<wave>
<!-- Wave start time [a] -->
<start>-14000.</start>
<!-- Wave end time [a] -->
<end>0</end>
<!-- Wave climates number -->
<climNb>3</climNb>
<!-- Climatic wave definition for WaveSed model. -->
<climate>
<!-- Percentage of time this event is active during the time interval. -->
<perc>0.3</perc>
<!-- Significant wave height (in m) -->
<hs>2.</hs>
<!-- Wave direction in degrees (between 0 and 360) from the
X-axis (horizontal) anti-clock wise. It specifies where the waves are
actually coming from. The wave directions are reduced to 8 possible ones:
East (dir = 0) - North (dir = 90) - West (dir = 180) - South (dir = 270) -
NE (0<dir<90) - NW (90<dir<180) - SW (180<dir<270) - SE (dir>270). -->
<dir>0</dir>
</climate>
<!-- Climatic wave definition for WaveSed model. -->
<climate>
<!-- Percentage of time this event is active during the time interval. -->
<perc>0.3</perc>
<!-- Significant wave height (in m) -->
<hs>2.</hs>
<!-- Wave direction in degrees (between 0 and 360) from the
X-axis (horizontal) anti-clock wise. It specifies where the waves are
actually coming from. The wave directions are reduced to 8 possible ones:
East (dir = 0) - North (dir = 90) - West (dir = 180) - South (dir = 270) -
NE (0<dir<90) - NW (90<dir<180) - SW (180<dir<270) - SE (dir>270). -->
<dir>30</dir>
</climate>
<!-- Climatic wave definition for WaveSed model. -->
<climate>
<!-- Percentage of time this event is active during the time interval. -->
<perc>0.4</perc>
<!-- Significant wave height (in m) -->
<hs>2.</hs>
<!-- Wave direction in degrees (between 0 and 360) from the
X-axis (horizontal) anti-clock wise. It specifies where the waves are
actually coming from. The wave directions are reduced to 8 possible ones:
East (dir = 0) - North (dir = 90) - West (dir = 180) - South (dir = 270) -
NE (0<dir<90) - NW (90<dir<180) - SW (180<dir<270) - SE (dir>270). -->
<dir>300</dir>
</climate>
</wave>

<!-- Specify species 1 growth functions based on 3 main controlling forces: depth,
sedimentation rate and ocean wave height.
These functions are defined as csv files produced using pre-processing IPython
notebook. -->

<carb>
<!-- Specify initial basement structure (0) for hard rock and (1) for loose sediment. -->
<baseMap>data/base500south.csv</baseMap>
<!-- Wave interval [a] -->
<tcarb>50.</tcarb>
</carb>

<species1>
<!-- Species 1 growth rate [m/yr]. -->
<growth>0.009</growth>
<!-- Depth control on species 1 evolution. -->
<depthControl>data/depthcontrol1.csv</depthControl>
<!-- Ocean wave height control on species 1 evolution. -->
<waveControl>data/wavecontrolcarb1.csv</waveControl>
<!-- Sedimentation control on species 1 evolution. -->
<sedControl>data/sedcontrolcarb1.csv</sedControl>
</species1>

<!-- Specify species 2 growth functions based on 3 main controlling forces: depth,
sedimentation rate and ocean wave height.
These functions are defined as csv files produced using pre-processing IPython
notebook. -->
<species2>
<!-- Species 2 growth rate [m/yr]. -->
<growth>0.005</growth>
<!-- Depth control on species 2 evolution. -->
<depthControl>data/depthcontrol2.csv</depthControl>
<!-- Ocean wave height control on species 2 evolution. -->
<waveControl>data/wavecontrolcarb2.csv</waveControl>
<!-- Sedimentation control on species 2 evolution. -->
<sedControl>data/sedcontrolcarb2.csv</sedControl>
</species2>

<!-- Specify pelagic deposition functions based on depth control.
The function is defined as csv file produced using pre-processing IPython
notebook. -->
<pelagic>
<!-- Pelagic deposition rate [m/yr]. -->
<growth>0.00005</growth>
<!-- Depth control on pelagic deposition. -->
<depthControl>data/pelagiccontrol.csv</depthControl>
</pelagic>

<!-- Flexural isostasy parameters:
Parameterisation of the flexural isostasy using the gFlex model from Wickert 2015.
The current wrapper limits the functionnality of the gFlex algorithm and only uses
Expand Down Expand Up @@ -411,6 +549,14 @@
Te value [m]. You will need to ensure that the grid dimensions match the number of
points given for the flexural grid resolution - (optional) -->
<elasticGrid>data/elasticthickness.csv</elasticGrid>
<!-- In case where the lithospheric elastic thickness (Te) varies with time.
The elastic thickness relates to the age of the lithosphere with a simple equation that
results from the square-root time dependence of lithospheric cooling via thermal conduction.
Te = a1 x sqrt(dt) + a2
You will need to define the coefficient for a1 and a2 where a1 is the slope of the dependency
and a2 the initial elastic thickness [m] at the start of the simulation - (optional) -->
<elasticA1>2.7</elasticA1>
<elasticA2>10000.</elasticA2>
<!-- Finite difference boundary conditions:
+ 0Displacement0Slope: 0-displacement-0-slope boundary condition
+ 0Moment0Shear: "Broken plate" boundary condition: second and
Expand Down
25 changes: 22 additions & 3 deletions pyBadlands/forcing/isoFlex.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ def __init__(self):
self.tree = None
self.Te = None
self.searchpts = None
self.Te1 = None
self.dtime = 0.
self.ftime = None

return

def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
elasticT, Boundaries, xyTIN):
elasticT, elasticT2, Boundaries, xyTIN, ftime):
"""
gFlex initialisation function.
Expand All @@ -77,6 +80,9 @@ def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
elasticT
The elastic thickness. Can be scalar or an array
elasticT2
The initial elastic thickness.
Boundaries
List of string describing boundary conditions for West, East, South and North.
Expand All @@ -85,6 +91,9 @@ def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
xyTIN
Numpy float-type array containing the coordinates for each nodes in the TIN (in m)
ftime
Flexure time step
"""
# Build the flexural grid
self.nx = nx
Expand All @@ -96,6 +105,7 @@ def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
self.ygrid = numpy.linspace(ymin,ymax,num=self.ny)
self.xi, self.yi = numpy.meshgrid(self.xgrid, self.ygrid)
self.xyi = numpy.dstack([self.xi.flatten(), self.yi.flatten()])[0]
self.ftime = ftime

# Call gFlex instance
self.flex = gflex.F2D()
Expand Down Expand Up @@ -135,8 +145,11 @@ def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
TeMap = pandas.read_csv(elasticT, sep=r'\s+', engine='c', header=None,
na_filter=False, dtype=numpy.float, low_memory=False)
self.Te = numpy.reshape(TeMap.values, (self.ny, self.nx))
else:
elif elasticT2 is None:
self.Te = elasticT * numpy.ones((self.ny, self.nx))
else:
self.Te = elasticT2 * numpy.ones((self.ny, self.nx))
self.Te1 = elasticT

# Surface load stresses
self.flex.qs = numpy.zeros((self.ny, self.nx), dtype=float)
Expand Down Expand Up @@ -176,7 +189,11 @@ def _compute_flexure(self):
Use gFlex module to compute flexure from surface load.
"""

self.flex.Te = self.Te
if self.Te1 is None:
self.flex.Te = self.Te
else:
coeff = self.Te1*numpy.sqrt(self.dtime)
self.flex.Te = coeff* numpy.ones((self.ny, self.nx)) + self.Te

self.flex.initialize()

Expand Down Expand Up @@ -214,6 +231,8 @@ def get_flexure(self, elev, cumdiff, sea, boundsPt, initFlex=False):
Numpy array containing flexural deflection values for the TIN.
"""

self.dtime += self.ftime

# Average volume of sediment and water on the flexural grid points
sedload = numpy.zeros(len(self.xyi))
waterload = numpy.zeros(len(self.xyi))
Expand Down
14 changes: 14 additions & 0 deletions pyBadlands/forcing/xmlParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ def __init__(self, inputfile = None, makeUniqueOutputDir=True):
self.youndMod = None
self.elasticH = None
self.elasticGrid = None
self.elasticA1 = None
self.elasticA2 = None
self.flexbounds = []

self.erolays = None
Expand Down Expand Up @@ -1215,6 +1217,18 @@ def _get_XmL_Data(self):
else:
self.elasticGrid = None
element = None
element = flex.find('elasticA1')
if element is not None:
self.elasticA1 = float(element.text)
else:
self.elasticA1 = None
element = None
element = flex.find('elasticA2')
if element is not None:
self.elasticA2 = float(element.text)
else:
self.elasticA2 = None
element = None
element = flex.find('boundary_W')
if element is not None:
self.flexbounds.append(element.text)
Expand Down
12 changes: 8 additions & 4 deletions pyBadlands/simulation/buildMesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,18 +375,22 @@ def _init_flexure(FVmesh, input, recGrid, force, elevation, cumdiff,

nx = input.fnx
ny = input.fny
elasticT2 = 0.
if nx == 0:
nx = recGrid.nx
if ny == 0:
ny = recGrid.ny
if input.elasticH is None:
if input.elasticH is not None:
elasticT = input.elasticH
elif input.elasticGrid is not None:
elasticT = str(input.elasticGrid)
else:
elasticT = input.elasticH

elasticT = input.elasticA1
elasticT2 = input.elasticA2

flex = isoFlex.isoFlex()
flex.buildGrid(nx, ny, input.youngMod, input.dmantle, input.dsediment,
elasticT, input.flexbounds, FVmesh.node_coords[:,:2])
elasticT, elasticT2, input.flexbounds, FVmesh.node_coords[:,:2], input.ftime)

tinFlex = np.zeros(totPts, dtype=float)
force.getSea(input.tStart)
Expand Down
9 changes: 6 additions & 3 deletions pyBadlands/simulation/waveSed.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ def __init__(self, input, recGrid, Ce, Cd):
elif self.ds<= 150.:
self.tau_cr = 0.013*np.power(self.ds,0.29)
else:
self.tau_cr = 0.045
self.tau_cr = 0.055

self.tau_cr = self.tau_cr*self.grav*self.dia*(self.rhos-self.rhow)
self.wavebase = input.waveBase
self.resfac = input.resW

Expand Down Expand Up @@ -494,9 +495,10 @@ def cmptwaves(self, src=None, h0=0., sigma=1., shadow=0, shoalC=0.99):

# Friction factor
fric = np.zeros(waveC.shape)
R = waveU*waveT/(2.*np.pi*2.5*self.dia)
kbb = 2.*np.pi*self.dia/12.
R = waveU*waveT/(2.*np.pi*kbb)
tmpr2,tmpc2 = np.where(R>0.)
fric[tmpr2,tmpc2] = 0.237*np.power(R[tmpr2,tmpc2],-0.52)
fric[tmpr2,tmpc2] = 1.39*np.power(R[tmpr2,tmpc2],-0.52)

# Shear stress (N/m2)
self.waveS = 0.5*self.rhow*fric*np.power(waveU,2.)
Expand All @@ -519,6 +521,7 @@ def cmptsed(self, perc, sigma=1.):
self.waveS[self.waveS<1.e-5] = 0.
r,c=np.where(self.waveS>0.)
Hent = np.zeros(self.waveS.shape)
#Hent[r,c] = self.Ce*np.log(self.waveS[r,c]/self.tau_cr)*perc
Hent[r,c] = -self.Ce*np.log(np.sqrt(np.power(self.tau_cr/self.waveS[r,c],2)))*perc
Hent[Hent<0.] = 0.
r,c=np.where(np.logical_and(Hent>0.,Hent>0.25*self.depth))
Expand Down

0 comments on commit c11619c

Please sign in to comment.