CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
do_cliff_collapse.cpp
Go to the documentation of this file.
1
12
13/*==============================================================================================================================
14
15This file is part of CoastalME, the Coastal Modelling Environment.
16
17CoastalME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
18
19This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23==============================================================================================================================*/
24#include <assert.h>
25
26#include <cmath>
27
28#include <iostream>
29using std::cerr;
30using std::cout;
31using std::endl;
32using std::ios;
33
34#include "cme.h"
35#include "simulation.h"
36#include "cliff.h"
37
38//===============================================================================================================================
40//===============================================================================================================================
42{
44 LogStream << m_ulIter << ": Calculating cliff collapse" << endl;
45
46 int nRet;
47
48 // First go along each coastline and update the total wave energy which it has experienced
49 for (int i = 0; i < static_cast<int>(m_VCoast.size()); i++)
50 {
51 for (int j = 0; j < m_VCoast[i].nGetCoastlineSize(); j++)
52 {
53 CACoastLandform* pCoastLandform = m_VCoast[i].pGetCoastLandform(j);
54
55 // First get wave energy for the coastal landform object
56 double dWaveHeightAtCoast = m_VCoast[i].dGetCoastWaveHeight(j);
57
58 // If the waves at this point are off-shore, then do nothing, just move to next coast point
59 if (bFPIsEqual(dWaveHeightAtCoast, DBL_NODATA, TOLERANCE))
60 continue;
61
62 // OK we have on-shore waves so get the previously-calculated wave energy
63 double dWaveEnergy = m_VCoast[i].dGetWaveEnergyAtBreaking(j);
64// assert(isfinite(dWaveEnergy));
65
66 // And save the accumulated value
67 pCoastLandform->IncTotAccumWaveEnergy(dWaveEnergy);
68
69 // Now simulate how the coastal landform responds to this wave energy
70 int nCategory = pCoastLandform->nGetLandFormCategory();
71 if (nCategory == LF_CAT_CLIFF)
72 {
73 // This is a cliff
74 CRWCliff* pCliff = reinterpret_cast<CRWCliff*>(pCoastLandform);
75
76 // Calculate this-timestep cliff notch erosion (is a length in external CRS units). Only consolidated sediment can have a cliff notch
77 double dNotchExtension = dWaveEnergy / m_dCliffErosionResistance;
78
79 // Deepen the cliff object's erosional notch as a result of wave energy during this timestep. Note that notch deepening may be constrained, since this-timestep notch extension cannot exceed the length (i.e. cellside minus notch depth) of sediment remaining on the cell
80 pCliff->DeepenErosionalNotch(dNotchExtension);
81
82 // OK, is the notch now extended enough to cause collapse (either because the overhang is greater than the threshold overhang, or because there is no sediment remaining)?
84 {
85 // // DEBUG CODE ============================================================================================================================================
86 // // Get total depths of sand consolidated and unconsolidated for every cell
87 // if (m_ulIter == 5)
88 // {
89 // double dTmpSandCons = 0;
90 // double dTmpSandUncons = 0;
91 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
92 // {
93 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
94 // {
95 // dTmpSandCons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotConsSandThickConsiderNotch();
96 //
97 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
98 // }
99 // }
100 //
101 // // Get the cliff cell's grid coords
102 // int nXCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
103 // int nYCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
104 //
105 // // Get this cell's polygon
106 // int nPoly = m_pRasterGrid->m_Cell[nXCliff][nYCliff].nGetPolygonID();
107 //
108 // LogStream << endl;
109 // LogStream << "*****************************" << endl;
110 // LogStream << m_ulIter << ": before cliff collapse on nPoly = " << nPoly << " total consolidated sand = " << dTmpSandCons * m_dCellArea << " total unconsolidated sand = " << dTmpSandUncons * m_dCellArea << endl;
111 // }
112 // // DEBUG CODE ============================================================================================================================================
113
114 // It is ready to collapse
115 double dCliffElevPreCollapse = 0;
116 double dCliffElevPostCollapse = 0;
117 double dFineCollapse = 0;
118 double dSandCollapse = 0;
119 double dCoarseCollapse = 0;
120
121 // So do the cliff collapse
122 nRet = nDoCliffCollapse(i, pCliff, dFineCollapse, dSandCollapse, dCoarseCollapse, dCliffElevPreCollapse, dCliffElevPostCollapse);
123 if (nRet != RTN_OK)
124 {
126 LogStream << m_ulIter << WARN << " problem with cliff collapse, continuing however" << endl;
127 }
128
129 // Deposit all sand and/or coarse sediment derived from this cliff collapse as unconsolidated sediment (talus)
130 nRet = nDoCliffCollapseDeposition(i, pCliff, dSandCollapse, dCoarseCollapse, dCliffElevPreCollapse, dCliffElevPostCollapse);
131 if (nRet != RTN_OK)
132 return nRet;
133
134 // // DEBUG CODE ============================================================================================================================================
135 // // Get total depths of sand consolidated and unconsolidated for every cell
136 // if (m_ulIter == 5)
137 // {
138 // double dTmpSandCons = 0;
139 // double dTmpSandUncons = 0;
140 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
141 // {
142 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
143 // {
144 // dTmpSandCons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotConsSandThickConsiderNotch();
145 //
146 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
147 // }
148 // }
149 //
150 // // Get the cliff cell's grid coords
151 // int nXCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
152 // int nYCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
153 //
154 // // Get this cell's polygon
155 // int nPoly = m_pRasterGrid->m_Cell[nXCliff][nYCliff].nGetPolygonID();
156 //
157 // LogStream << endl;
158 // LogStream << "*****************************" << endl;
159 // LogStream << m_ulIter << ": after cliff collapse on nPoly = " << nPoly << " total consolidated sand = " << dTmpSandCons * m_dCellArea << " total unconsolidated sand = " << dTmpSandUncons * m_dCellArea << endl;
160 // LogStream << m_ulIter << ": total consolidated sand lost this iteration = " << (m_dStartIterConsSandAllCells - dTmpSandCons) * m_dCellArea << endl;
161 // LogStream << m_ulIter << ": total unconsolidated sand added this iteration = " << (dTmpSandUncons - m_dStartIterUnconsSandAllCells) * m_dCellArea << endl;
162 //
163 // double dTmpAllPolySandErosion = 0;
164 // double dTmpAllPolySandDeposition = 0;
165 // for (unsigned int n = 0; n < m_pVCoastPolygon.size(); n++)
166 // {
167 // double dTmpSandErosion = m_pVCoastPolygon[n]->dGetCliffCollapseErosionSand() * m_dCellArea ;
168 // double dTmpSandDeposition = m_pVCoastPolygon[n]->dGetCliffCollapseUnconsSandDeposition() * m_dCellArea ;
169 //
170 // LogStream << m_ulIter << ": polygon = " << m_pVCoastPolygon[n]->nGetCoastID() << " sand erosion = " << dTmpSandErosion << " sand deposition = " << dTmpSandDeposition << endl;
171 //
172 // dTmpAllPolySandErosion += dTmpSandErosion;
173 // dTmpAllPolySandDeposition += dTmpSandDeposition;
174 // }
175 //
176 // LogStream << "-------------------------------------------" << endl;
177 // LogStream << m_ulIter << ": all polygons, sand erosion = " << dTmpAllPolySandErosion << " sand deposition = " << dTmpAllPolySandDeposition << endl;
178 // LogStream << "*****************************" << endl;
179 // }
180 // // DEBUG CODE ============================================================================================================================================
181 }
182 }
183 }
184 }
185
188
189 return RTN_OK;
190}
191
192//===============================================================================================================================
194//===============================================================================================================================
195int CSimulation::nDoCliffCollapse(int const nCoast, CRWCliff* pCliff, double& dFineCollapse, double& dSandCollapse, double& dCoarseCollapse, double& dPreCollapseCliffElev, double& dPostCollapseCliffElev)
196{
197 // Get the cliff cell's grid coords
198 int nX = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
199 int nY = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
200
201 // Get this cell's polygon
202 int nPoly = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
203 if (nPoly == INT_NODATA)
204 {
205 // This cell isn't in a polygon
206 LogStream << m_ulIter << " : in nDoCliffCollapse(), [" << nX << "][" << nY << "] = {" << dGridCentroidXToExtCRSX(nX) << ", " << dGridCentroidYToExtCRSY(nY) << "} is not in a polygon" << endl;
207
209 }
210
211 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
212
213 // Get the elevation of the base of the notch from the cliff object
214 double dNotchElev = pCliff->dGetNotchBaseElev() - m_dNotchBaseBelowSWL;
215
216 // Get the index of the layer containing the notch (layer 0 being just above basement)
217 int nNotchLayer = m_pRasterGrid->m_Cell[nX][nY].nGetLayerAtElev(dNotchElev);
218 if (nNotchLayer == ELEV_ABOVE_SEDIMENT_TOP)
219 {
221 LogStream << m_ulIter << ": " << ERR << " cell [" << nX << "][" << nY << "] has dNotchElev (" << dNotchElev << ") above sediment top elevation (" << m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() << ")" << endl;
222
223 return RTN_ERR_CLIFFNOTCH;
224 }
225
226 // Flag the coastline cliff object as having collapsed
227 pCliff->SetCliffCollapsed();
228
229 int nTopLayer = m_pRasterGrid->m_Cell[nX][nY].nGetTopLayerAboveBasement();
230
231 // Safety check
232 if (nTopLayer == INT_NODATA)
234
235 // Set the base of the collapse (see above)
236 pCliff->SetNotchBaseElev(dNotchElev);
237
238 // Set flags to say that the top layer has changed
239 m_bConsChangedThisIter[nTopLayer] = true;
240 m_bUnconsChangedThisIter[nTopLayer] = true;
241
242 // Get the pre-collapse cliff elevation
243 dPreCollapseCliffElev = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
244
245 // Now calculate the vertical depth of sediment lost in this cliff collapse. In CoastalME, all depth equivalents are assumed to be a depth upon the whole of a cell i.e. upon the area of a whole cell. So to keep the depth of cliff collapse consistent with all other depth equivalents, weight it by the fraction of the cell's area which is being removed
246 double dAvailable = 0;
247 double dFineConsLost = 0;
248 double dFineUnconsLost = 0;
249 double dSandConsLost = 0;
250 double dSandUnconsLost = 0;
251 double dCoarseConsLost = 0;
252 double dCoarseUnconsLost = 0;
253
254 // Now update the cell's sediment. If there are sediment layers above the notched layer, we must remove sediment from the whole depth of each layer
255 for (int n = nTopLayer; n > nNotchLayer; n--)
256 {
257 // Start with the unconsolidated sediment
258 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetFineDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetNotchFineLost();
259 if (dAvailable > 0)
260 {
261 dFineCollapse += dAvailable;
262 dFineUnconsLost += dAvailable;
263 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetFineDepth(0);
264 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetNotchFineLost(0);
265 }
266
267 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetSandDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetNotchSandLost();
268 if (dAvailable > 0)
269 {
270 dSandCollapse += dAvailable;
271 dSandUnconsLost += dAvailable;
272 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetSandDepth(0);
273 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetNotchSandLost(0);
274 }
275
276 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetCoarseDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetNotchCoarseLost();
277 if (dAvailable > 0)
278 {
279 dCoarseCollapse += dAvailable;
280 dCoarseUnconsLost += dAvailable;
281 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetCoarseDepth(0);
282 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetNotchCoarseLost(0);
283 }
284
285 // Now get the consolidated sediment
286 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetFineDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetNotchFineLost();
287 if (dAvailable > 0)
288 {
289 dFineCollapse += dAvailable;
290 dFineConsLost += dAvailable;
291 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetFineDepth(0);
292 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetNotchFineLost(0);
293 }
294
295 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetSandDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetNotchSandLost();
296 if (dAvailable > 0)
297 {
298 dSandCollapse += dAvailable;
299 dSandConsLost += dAvailable;
300 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetSandDepth(0);
301 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetNotchSandLost(0);
302 }
303
304 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetCoarseDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetNotchCoarseLost();
305 if (dAvailable > 0)
306 {
307 dCoarseCollapse += dAvailable;
308 dCoarseConsLost += dAvailable;
309 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetCoarseDepth(0);
310 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetNotchCoarseLost(0);
311 }
312 }
313
314 // Now sort out the sediment lost from the consolidated layer into which the erosional notch was incised
315 double dNotchLayerTop = m_pRasterGrid->m_Cell[nX][nY].dCalcLayerElev(nNotchLayer);
316 double dNotchLayerThickness = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->dGetTotalThickness();
317 double dNotchLayerFracRemoved = (dNotchLayerTop - dNotchElev) / dNotchLayerThickness;
318
319 // Sort out the notched layer's sediment, both consolidated and unconsolidated, for this cell. First the unconsolidated sediment
320 double dFineDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetFineDepth();
321 dAvailable = dFineDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetNotchFineLost();
322 if (dAvailable > 0)
323 {
324 // Some unconsolidated fine sediment is available for collapse
325 double dLost = dAvailable * dNotchLayerFracRemoved;
326 dFineCollapse += dLost;
327 dFineUnconsLost += dLost;
328 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetFineDepth(dFineDepth - dLost);
329 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetNotchFineLost(0);
330 }
331
332 double dSandDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetSandDepth();
333 dAvailable = dSandDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetNotchSandLost();
334 if (dAvailable > 0)
335 {
336 // Some unconsolidated sand sediment is available for collapse
337 double dLost = dAvailable * dNotchLayerFracRemoved;
338 dSandCollapse += dLost;
339 dSandUnconsLost += dLost;
340 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetSandDepth(dSandDepth - dLost);
341 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetNotchSandLost(0);
342 }
343
344 double dCoarseDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetCoarseDepth();
345 dAvailable = dCoarseDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetNotchCoarseLost();
346 if (dAvailable > 0)
347 {
348 // Some unconsolidated coarse sediment is available for collapse
349 double dLost = dAvailable * dNotchLayerFracRemoved;
350 dCoarseCollapse += dLost;
351 dCoarseUnconsLost += dLost;
352 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetCoarseDepth(dCoarseDepth - dLost);
353 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetNotchCoarseLost(0);
354 }
355
356 // Now do the consolidated sediment
357 dFineDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetFineDepth();
358 dAvailable = dFineDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetNotchFineLost();
359 if (dAvailable > 0)
360 {
361 // Some consolidated fine sediment is available for collapse
362 double dLost = dAvailable * dNotchLayerFracRemoved;
363 dFineCollapse += dLost;
364 dFineConsLost += dLost;
365 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetFineDepth(dFineDepth - dLost);
366 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetNotchFineLost(0);
367 }
368
369 dSandDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetSandDepth();
370 dAvailable = dSandDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetNotchSandLost();
371 if (dAvailable > 0)
372 {
373 // Some consolidated sand sediment is available for collapse
374 double dLost = dAvailable * dNotchLayerFracRemoved;
375 dSandCollapse += dLost;
376 dSandConsLost += dLost;
377 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetSandDepth(dSandDepth - dLost);
378 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetNotchSandLost(0);
379 }
380
381 dCoarseDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetCoarseDepth();
382 dAvailable = dCoarseDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetNotchCoarseLost();
383 if (dAvailable > 0)
384 {
385 // Some consolidated coarse sediment is available for collapse
386 double dLost = dAvailable * dNotchLayerFracRemoved;
387 dCoarseCollapse += dLost;
388 dCoarseConsLost += dLost;
389 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetCoarseDepth(dCoarseDepth - dLost);
390 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetNotchCoarseLost(0);
391 }
392
393 // Update the cell's totals for cliff collapse erosion
394 m_pRasterGrid->m_Cell[nX][nY].IncrCliffCollapseErosion(dFineCollapse, dSandCollapse, dCoarseCollapse);
395
396 // Update the cell's layer elevations and d50
397 m_pRasterGrid->m_Cell[nX][nY].CalcAllLayerElevsAndD50();
398
399 // Get the post-collapse cliff elevation
400 dPostCollapseCliffElev = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
401
402 // And update the cell's sea depth
403 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
404
405 // LogStream << m_ulIter << ": cell [" << nX << "][" << nY << "] after removing sediment, dGetVolEquivSedTopElev() = " << m_pRasterGrid->m_Cell[nX][nY].dGetVolEquivSedTopElev() << ", dGetSedimentTopElev() = " << m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() << endl << endl;
406
407 // Update this-polygon totals: add to the depths of cliff collapse erosion for this polygon
408 pPolygon->AddCliffCollapseErosionFine(dFineCollapse);
409 pPolygon->AddCliffCollapseToSuspensionFine(dFineCollapse);
410 pPolygon->AddCliffCollapseErosionSand(dSandCollapse);
411 pPolygon->AddCliffCollapseErosionCoarse(dCoarseCollapse);
412
413 // And update the this-timestep totals and the grand totals for collapse
414 // m_nNThisIterCliffCollapse++;
415 // m_nNTotCliffCollapse++;
416
417 // Add to this-iteration totals
420
421 // Also add to the total suspended load. Note that this addition to the suspended load has not yet been added to all cells, this happens in nUpdateGrid()
422 m_dThisIterFineSedimentToSuspension += (dFineConsLost + dFineUnconsLost);
423
428
429 return RTN_OK;
430}
431
432//===============================================================================================================================
434//===============================================================================================================================
435int CSimulation::nDoCliffCollapseDeposition(int const nCoast, CRWCliff const* pCliff, double const dSandFromCollapse, double const dCoarseFromCollapse, double const dPreCollapseCliffElev, double const dPostCollapseCliffElev)
436{
437 // Check: is there some sand- or coarse-sized sediment to deposit?
438 if ((dSandFromCollapse + dCoarseFromCollapse) < SEDIMENT_ELEV_TOLERANCE)
439 return RTN_OK;
440
441 // LogStream << "\tdSandFromCollapse = " << dSandFromCollapse << " dCoarseFromCollapse = " << dCoarseFromCollapse << endl;
442
443 // OK, we have some sand- and/or coarse-sized sediment to deposit
444 int nStartPoint = pCliff->nGetPointOnCoast();
445 int nCoastSize = m_VCoast[nCoast].nGetCoastlineSize();
446
447 // Get the cliff cell's grid coords
448 int nXCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
449 int nYCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
450
451 // Get this cell's polygon
452 int nPoly = m_pRasterGrid->m_Cell[nXCliff][nYCliff].nGetPolygonID();
453 if (nPoly == INT_NODATA)
454 {
455 // This cell isn't in a polygon
456 LogStream << m_ulIter << " : in nDoCliffCollapse(), [" << nXCliff << "][" << nYCliff << "] = {" << dGridCentroidXToExtCRSX(nXCliff) << ", " << dGridCentroidYToExtCRSY(nYCliff) << "} is not in a polygon" << endl;
457
459 }
460
461 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
462
463 // OK, now set up the planview sequence talus deposition. First we deposit to create a Dean profile starting from the cliff collapse cell. Then we deposit along two profiles which start from the coast cells on either side of the cliff collapse cell, and then on two profiles starting on the next two "outside" coast cells, etc. However, we do have a "preferred" talus width
465
466 // The default talus collapse must be an odd number of cells in width i.e. centred on the cliff collapse cell (but only if we are not at the end of the coast)
467 if ((nTalusWidth % 2) == 0)
468 nTalusWidth++;
469
470 // This holds the valid coast start points for each Dean profile
471 vector<int> VnTalusProfileCoastStartPoint(nCoastSize);
472
473 // This is the coast start point for the first Dean profile
474 VnTalusProfileCoastStartPoint[0] = nStartPoint;
475 int nn = 1;
476 int nSigned = 1;
477 int nCount = 1;
478
479 do
480 {
481 int nTmpPoint;
482
483 if ((nCount % 2) != 0)
484 nTmpPoint = nStartPoint + nSigned;
485 else
486 {
487 nTmpPoint = nStartPoint - nSigned;
488 nSigned++;
489 }
490
491 // Is this start point valid?
492 if ((nTmpPoint < 0) || (nTmpPoint > (nCoastSize - 1)))
493 {
494 // No, it is outside the grid, so find another
495 nCount++;
496 continue;
497 }
498 else
499 {
500 // It is valid
501 VnTalusProfileCoastStartPoint[nn] = nTmpPoint;
502 nn++;
503 nCount++;
504 }
505 }
506 while (nn < static_cast<int>(VnTalusProfileCoastStartPoint.size()));
507
508 bool bHitFirstCoastPoint = false;
509 bool bHitLastCoastPoint = false;
510
511 double dTotSandToDepositAllProfiles = dSandFromCollapse; // Note that this can increase, if we get erosion because Dean profile is lower than profile
512 double dTotCoarseToDepositAllProfiles = dCoarseFromCollapse; // Note that this can increase, if we get erosion because Dean profile is lower than profile
513 double dTotSandDepositedAllProfiles = 0;
514 double dTotCoarseDepositedAllProfiles = 0;
515
516 // Process each deposition profile
517 int nStartPointSize = static_cast<int>(VnTalusProfileCoastStartPoint.size());
518 for (int nAcross = 0; nAcross < nStartPointSize; nAcross++)
519 {
520 bool bDoSandDepositionOnThisProfile = false;
521 bool bSandDepositionCompletedOnThisProfile = false;
522 bool bDoCoarseDepositionOnThisProfile = false;
523 bool bCoarseDepositionCompletedOnThisProfile = false;
524
525 int nRemaining = tMax(1, nTalusWidth - nAcross);
526
527 // This is the minimum planview length of the Dean profile (the initial length will be increased later if we can't deposit sufficient talus)
529
530 // Calculate the target amount to be deposited on each talus profile, assuming the "preferred" talus width
531 double dTargetSandToDepositOnThisProfile = (dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles) / nRemaining;
532 double dTargetCoarseToDepositOnThisProfile = (dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles) / nRemaining;
533
534 // Use this to make sure that, if we have both sand and coarse to deposit, we don't drop all the sand on a cell and then be unable to deposit any coarse
535 double dSandProp = 0.5;
536 double dCoarseProp = 1 - dSandProp;
537 if (dTargetSandToDepositOnThisProfile + dTargetCoarseToDepositOnThisProfile > 0)
538 {
539 dSandProp = dTargetSandToDepositOnThisProfile / (dTargetSandToDepositOnThisProfile + dTargetCoarseToDepositOnThisProfile);
540 dCoarseProp = 1 - dSandProp;
541 }
542
543 double dSandDepositedOnThisProfile = 0;
544 double dCoarseDepositedOnThisProfile = 0;
545
546 if (dTotSandToDepositAllProfiles > 0)
547 {
548 bDoSandDepositionOnThisProfile = true;
549
550 if (bFPIsEqual(dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
551 bSandDepositionCompletedOnThisProfile = true;
552 }
553 else
554 bSandDepositionCompletedOnThisProfile = true;
555
556 if (dTotCoarseToDepositAllProfiles > 0)
557 {
558 bDoCoarseDepositionOnThisProfile = true;
559
560 if (bFPIsEqual(dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
561 bCoarseDepositionCompletedOnThisProfile = true;
562 }
563 else
564 bCoarseDepositionCompletedOnThisProfile = true;
565
566 if (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile)
567 {
568 // LogStream << m_ulIter << ": break 2 for cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nAcross = " << nAcross << endl << "\tdTargetSandToDepositOnThisProfile = " << dTargetSandToDepositOnThisProfile << " dSandDepositedOnThisProfile = " << dSandDepositedOnThisProfile << " dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl << "\tdTargetCoarseToDepositOnThisProfile = " << dTargetCoarseToDepositOnThisProfile << " dCoarseDepositedOnThisProfile = " << dCoarseDepositedOnThisProfile << " dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
569
570 break;
571 }
572
573 // Get the start point of this cliff collapse deposition profile
574 int nThisPoint = VnTalusProfileCoastStartPoint[nAcross];
575
576 // Are we at the start or end of the coast?
577 if (nThisPoint == 0)
578 bHitFirstCoastPoint = true;
579
580 if (nThisPoint == nCoastSize-1)
581 bHitLastCoastPoint = true;
582
583 CGeom2DPoint PtStart;
584 CGeom2DPoint PtEnd;
585
586 // Make the start of the deposition profile the cliff cell that is marked as coast (not the cell under the smoothed vector coast, they may well be different)
587 PtStart.SetX(dGridCentroidXToExtCRSX(m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nThisPoint)->nGetX()));
588 PtStart.SetY(dGridCentroidYToExtCRSY(m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nThisPoint)->nGetY()));
589
590 // Set the initial fraction of cliff height, this will be increased (max is one) if we can't deposit sufficient talus
591 double dCliffHeightFrac = m_dMinCliffTalusHeightFrac;
592
593 bool bJustDepositWhatWeCan = false;
594
595 // The initial seaward offset, in cells. This will be increased if we can't deposit sufficient talus
596 int nSeawardOffset = 0;
597
598 // Process this profile
599 do
600 {
601 if (bJustDepositWhatWeCan || (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile))
602 {
603 // LogStream << m_ulIter << ": break 3 for cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nThisPoint = " << nThisPoint << endl << "\tnSeawardOffset = " << nSeawardOffset << " dCliffHeightFrac = " << dCliffHeightFrac << " nAcross = " << nAcross << endl << "\tbJustDepositWhatWeCan = " << bJustDepositWhatWeCan << "\tdTargetSandToDepositOnThisProfile = " << dTargetSandToDepositOnThisProfile << " dSandDepositedOnThisProfile = " << dSandDepositedOnThisProfile << " dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl << "\tdTargetCoarseToDepositOnThisProfile = " << dTargetCoarseToDepositOnThisProfile << " dCoarseDepositedOnThisProfile = " << dCoarseDepositedOnThisProfile << " dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
604
605 break;
606 }
607
608 // Need to deposit more on this profile: increase the seaward offset each time round the loop
609 nSeawardOffset++;
610
611 // Has the seaward offset reached the arbitrary limit?
612 if (nSeawardOffset >= MAX_SEAWARD_OFFSET_FOR_CLIFF_TALUS)
613 {
614 // It has, so if cliff height is not at the maximum, then try again with a larger fraction of cliff height
615 if (dCliffHeightFrac < 1)
616 {
617 dCliffHeightFrac += CLIFF_COLLAPSE_HEIGHT_INCREMENT;
618
619 // Reset seaward offset
620 nSeawardOffset = 1;
621 }
622 else
623 {
624 // Cliff height has reached the limit, is the talus length also at its arbitrary limit?
625 if (nTalusProfileLen >= MAX_CLIFF_TALUS_LENGTH)
626 {
627 // The talus length is also at this limit, so there is nothing more we can increase on this profile. Just deposit what we can and move on to the next profile
628 bJustDepositWhatWeCan = true;
629 }
630 else
631 {
632 // The talus length is not at its limit, so try again with an increased talus length
633 nTalusProfileLen += CLIFF_COLLAPSE_LENGTH_INCREMENT;
634
635 // Reset seaward offset
636 nSeawardOffset = 1;
637
638 // Set cliff height to exactly one
639 dCliffHeightFrac = 1;
640 }
641 }
642 }
643
644 if (bHitFirstCoastPoint && bHitLastCoastPoint)
645 {
646 // Uh-oh, we've reached both ends of the coast (!) and we can't increase anything any more
647 LogStream << m_ulIter << ": unable to deposit sufficient unconsolidated talus from cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nThisPoint = " << nThisPoint << endl << "\tnSeawardOffset = " << nSeawardOffset << " dCliffHeightFrac = " << dCliffHeightFrac << " nAcross = " << nAcross << endl << "\tdTargetSandToDepositOnThisProfile = " << dTargetSandToDepositOnThisProfile << " dSandDepositedOnThisProfile = " << dSandDepositedOnThisProfile << " dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl << "\tdTargetCoarseToDepositOnThisProfile = " << dTargetCoarseToDepositOnThisProfile << " dCoarseDepositedOnThisProfile = " << dCoarseDepositedOnThisProfile << " dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
648
650 }
651
652 // Now construct a deposition collapse profile from the start point, it is one cell longer than the specified length because it includes the cliff point in the profile. Calculate its length in external CRS units, the way it is done here is approximate but probably OK
653 double dThisProfileLength = (nTalusProfileLen + nSeawardOffset + 1) * m_dCellSide;
654
655 // Get the end point of this coastline-normal line
656 CGeom2DIPoint PtiEnd; // In grid CRS
657 int nRtn = nGetCoastNormalEndPoint(nCoast, nThisPoint, nCoastSize, &PtStart, dThisProfileLength, &PtEnd, &PtiEnd, false);
658
659 // Safety check
661 {
662 LogStream << m_ulIter << ": unable to deposit sufficient unconsolidated talus from cliff collapse, could not find a solution for the end point of the Dean profile" << endl;
663
664 return nRtn;
665 }
666
667 // Safety check
668 if (PtStart == PtEnd)
669 {
670 // This would give a zero-length profile, and a zero-divide error during rasterization. So just move on to the next profile
671 break;
672 }
673
674 // OK, both the start and end points of this deposition profile are within the grid
675 // LogStream << m_ulIter << ": nWidthDistSigned = " << nWidthDistSigned << " cliff collapse profile from " << PtStart.dGetX() << ", " << PtStart.dGetY() << " to " << PtEnd.dGetX() << ", " << PtEnd.dGetY() << " with length (inc. cliff point) = " << dThisProfileLength << endl;
676
677 vector<CGeom2DPoint> VTmpProfile;
678 VTmpProfile.push_back(PtStart);
679 VTmpProfile.push_back(PtEnd);
680 vector<CGeom2DIPoint> VCellsUnderProfile;
681
682 // Now get the raster cells under this profile
683 RasterizeCliffCollapseProfile(&VTmpProfile, &VCellsUnderProfile);
684
685 int nRasterProfileLength = static_cast<int>(VCellsUnderProfile.size());
686
687 // Check now, for the case where the profile is very short
688 if (nRasterProfileLength - nSeawardOffset < 3)
689 {
690 // Can't do anything with this very short profile, since (nRasterProfileLength - nSeawardOffset - 2) later will give zero or -ve dInc. So just move on to the next profile
691 break;
692 }
693 else if (nRasterProfileLength - nSeawardOffset == 3)
694 {
695 // Can't increase offset any more, or get zero divide with (nRasterProfileLength - nSeawardOffset - 2) later. So just deposit what we can and then move on to the next profile
696 bJustDepositWhatWeCan = true;
697 }
698
699 vector<double> dVProfileNow(nRasterProfileLength, 0);
700 vector<bool> bVProfileValid(nRasterProfileLength, true);
701
702 // LogStream << m_ulIter << ": for cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nAcross = " << nAcross << endl << "\tnRasterProfileLength = " << nRasterProfileLength << " nSeawardOffset = " << nSeawardOffset << " nRasterProfileLength - nSeawardOffset - 2 = " << nRasterProfileLength - nSeawardOffset - 2 << endl;
703
704 // Calculate the existing elevation for all points along the deposition profile
705 for (int n = 0; n < nRasterProfileLength; n++)
706 {
707 int nX = VCellsUnderProfile[n].nGetX();
708 int nY = VCellsUnderProfile[n].nGetY();
709
710 dVProfileNow[n] = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
711
712 // Don't allow cliff collapse talus onto intervention cells TODO 078 Is this realistic? Should it change with different types on intervention?
713 if (bIsInterventionCell(nX, nY))
714 bVProfileValid[n] = false;
715 }
716
717 // Now calculate the elevation of the talus top at the shoreline
718 double dCliffHeight = dPreCollapseCliffElev - dPostCollapseCliffElev;
719 double dTalusTopElev = dPostCollapseCliffElev + (dCliffHeight * dCliffHeightFrac);
720
721 // LogStream << "Elevations: cliff top = " << dPreCollapseCliffElev << " cliff base = " << dPostCollapseCliffElev << " talus top = " << dTalusTopElev << endl;
722
723 // if (dPreCollapseCliffElev < dPostCollapseCliffElev)
724 // LogStream << "*** ERROR, cliff top is lower than cliff base" << endl;
725
726 // Next calculate the talus slope length in external CRS units, this is approximate but probably OK
727 double dTalusSlopeLength = dThisProfileLength - ((nSeawardOffset - 1) * m_dCellSide);
728
729 // If user has not supplied a value for m_dCliffDepositionA, then solve for dA so that the elevations at end of the existing profile, and at the end of the Dean equilibrium profile, are the same
730 double dA = 0;
733 else
734 dA = (dTalusTopElev - dVProfileNow[nRasterProfileLength - 1]) / pow(dTalusSlopeLength, DEAN_POWER);
735
736 // assert((nRasterProfileLength - nSeawardOffset - 2) > 0);
737 double dInc = dTalusSlopeLength / (nRasterProfileLength - nSeawardOffset - 2);
738 vector<double> dVDeanProfile(nRasterProfileLength);
739
740 // Calculate the Dean equilibrium profile of the talus h(y) = A * y^(2/3) where h(y) is the distance below the talus-top elevation (the highest point in the Dean profile) at a distance y from the cliff (the landward start of the profile)
741 CalcDeanProfile(&dVDeanProfile, dInc, dTalusTopElev, dA, true, nSeawardOffset, dTalusTopElev);
742
743 // Get the total difference in elevation between the two profiles (Dean profile - present profile). Since we want the Dean profile to be higher than the present profile, a good result is a +ve number
744 double dTotElevDiff = dSubtractProfiles(&dVDeanProfile, &dVProfileNow, &bVProfileValid);
745
746 // // DEBUG CODE -----------------------------------------------------
747 // LogStream << endl;
748 // LogStream << "dTalusSlopeLength = " << dTalusSlopeLength << " dA = " << dA << endl;
749 // LogStream << "dDistFromTalusStart - dInc = " << dDistFromTalusStart - dInc << " dThisProfileLength - nSeawardOffset - 2 = " << dThisProfileLength - nSeawardOffset - 2 << endl;
750 // LogStream << "Profile now (inc. cliff cell) = ";
751 // for (int n = 0; n < nRasterProfileLength; n++)
752 // {
753 // int
754 // nX = VCellsUnderProfile[n].nGetX(),
755 // nY = VCellsUnderProfile[n].nGetY();
756 // dVProfileNow[n] = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
757 // LogStream << dVProfileNow[n] << " ";
758 // }
759 // LogStream << endl;
760 // LogStream << "Dean equilibrium profile (inc. cliff cell) = ";
761 // for (int n = 0; n < nRasterProfileLength; n++)
762 // {
763 // LogStream << dVDeanProfile[n] << " ";
764 // }
765 // LogStream << endl;
766 // LogStream << "Difference (inc. cliff cell) = ";
767 // for (int n = 0; n < nRasterProfileLength; n++)
768 // {
769 // LogStream << dVDeanProfile[n] - dVProfileNow[n] << " ";
770 // }
771 // LogStream << endl;
772 // // DEBUG CODE -----------------------------------------------------
773
774 // If we are not in a "just deposit what we can" situation, then for this planview profile, does the Dean equilibrium profile allow us to deposit all the talus sediment which we need to get rid of?
775 if (! bJustDepositWhatWeCan && (dTotElevDiff < (dTargetSandToDepositOnThisProfile + dTargetCoarseToDepositOnThisProfile)))
776 {
777 // No it doesn't, so try again with a larger seaward offset and/or a longer Dean profile length
778 // LogStream << m_ulIter << ": bJustDepositWhatWeCan = " << bJustDepositWhatWeCan << " nSeawardOffset = " << nSeawardOffset << " dTotElevDiff = " << dTotElevDiff << endl;
779
780 continue;
781 }
782
783 // OK, now process all cells in this profile, including the first one (which is where the cliff collapse occurred)
784 for (int n = 0; n < nRasterProfileLength; n++)
785 {
786 // Are we depositing sand talus sediment on this profile?
787 if (bDoSandDepositionOnThisProfile)
788 {
789 if (bFPIsEqual(dTargetSandToDepositOnThisProfile - dSandDepositedOnThisProfile, 0.0, MASS_BALANCE_TOLERANCE))
790 bSandDepositionCompletedOnThisProfile = true;
791 else
792 bSandDepositionCompletedOnThisProfile = false;
793 }
794
795 // Are we depositing coarse talus sediment on this profile?
796 if (bDoCoarseDepositionOnThisProfile)
797 {
798 if (bFPIsEqual(dTargetCoarseToDepositOnThisProfile - dCoarseDepositedOnThisProfile, 0.0, MASS_BALANCE_TOLERANCE))
799 bCoarseDepositionCompletedOnThisProfile = true;
800 else
801 bCoarseDepositionCompletedOnThisProfile = false;
802 }
803
804 // If we have deposited enough, then break out of the loop
805 if (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile)
806 {
807 // LogStream << m_ulIter << ": break 1 for cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nThisPoint = " << nThisPoint << endl << "\tbJustDepositWhatWeCan = " << bJustDepositWhatWeCan << " nSeawardOffset = " << nSeawardOffset << " dCliffHeightFrac = " << dCliffHeightFrac << " nAcross = " << nAcross << endl << "\tdTargetSandToDepositOnThisProfile = " << dTargetSandToDepositOnThisProfile << " dSandDepositedOnThisProfile = " << dSandDepositedOnThisProfile << " dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl << "\tdTargetCoarseToDepositOnThisProfile = " << dTargetCoarseToDepositOnThisProfile << " dCoarseDepositedOnThisProfile = " << dCoarseDepositedOnThisProfile << " dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
808
809 break;
810 }
811
812 // Nope, we still have some talus left to deposit
813 int nX = VCellsUnderProfile[n].nGetX();
814 int nY = VCellsUnderProfile[n].nGetY();
815
816 // Don't allow cliff collapse talus onto intervention cells TODO 078 Is this realistic? Should it change with different types on intervention?
817 if (bIsInterventionCell(nX, nY))
818 continue;
819
820 int nTopLayer = m_pRasterGrid->m_Cell[nX][nY].nGetTopNonZeroLayerAboveBasement();
821
822 // Safety check
823 if (nTopLayer == INT_NODATA)
825
826 if (nTopLayer == NO_NONZERO_THICKNESS_LAYERS)
827 {
828 // TODO 021 Improve this
829 cerr << "All layers have zero thickness" << endl;
831 }
832
833 // Only do deposition on this cell if its elevation is below the Dean elevation
834 if (dVDeanProfile[n] > dVProfileNow[n])
835 {
836 // At this point along the profile, the Dean profile is higher than the present profile. So we can deposit some sediment on this cell
837 double dSandToDeposit = 0;
838 if (bDoSandDepositionOnThisProfile)
839 {
840 dSandToDeposit = (dVDeanProfile[n] - dVProfileNow[n]) * dSandProp;
841 dSandToDeposit = tMin(dSandToDeposit, (dTargetSandToDepositOnThisProfile - dSandDepositedOnThisProfile), (dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles));
842
843 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->AddSandDepth(dSandToDeposit);
844
845 // Set the changed-this-timestep switch
846 m_bUnconsChangedThisIter[nTopLayer] = true;
847
848 dSandDepositedOnThisProfile += dSandToDeposit;
849 dTotSandDepositedAllProfiles += dSandToDeposit;
850 }
851
852 double dCoarseToDeposit = 0;
853 if (bDoCoarseDepositionOnThisProfile)
854 {
855 dCoarseToDeposit = (dVDeanProfile[n] - dVProfileNow[n]) * dCoarseProp;
856 dCoarseToDeposit = tMin(dCoarseToDeposit, (dTargetCoarseToDepositOnThisProfile - dCoarseDepositedOnThisProfile), (dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles));
857
858 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->AddCoarseDepth(dCoarseToDeposit);
859
860 // Set the changed-this-timestep switch
861 m_bUnconsChangedThisIter[nTopLayer] = true;
862
863 dCoarseDepositedOnThisProfile += dCoarseToDeposit;
864 dTotCoarseDepositedAllProfiles += dCoarseToDeposit;
865 }
866
867 // Now update the cell's layer elevations
868 m_pRasterGrid->m_Cell[nX][nY].CalcAllLayerElevsAndD50();
869
870 // Update the cell's sea depth
871 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
872
873 // Update the cell's talus deposition, and total talus deposition, values
874 m_pRasterGrid->m_Cell[nX][nY].AddSandTalusDeposition(dSandToDeposit);
875 m_pRasterGrid->m_Cell[nX][nY].AddCoarseTalusDeposition(dCoarseToDeposit);
876
877 // And set the landform category
878 CRWCellLandform* pLandform = m_pRasterGrid->m_Cell[nX][nY].pGetLandform();
879 int nCat = pLandform->nGetLFCategory();
880
883 }
884
885 else if (dVDeanProfile[n] < dVProfileNow[n])
886 {
887 // Here, the Dean profile is lower than the existing profile, so we must remove some sediment from this cell TODO 075 What if bedrock sticks above Dean profile?
888 double dThisLowering = dVProfileNow[n] - dVDeanProfile[n];
889
890 // Find out how much sediment we have available on this cell
891 double dExistingAvailableFine = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetFineDepth();
892 double dExistingAvailableSand = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetSandDepth();
893 double dExistingAvailableCoarse = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetCoarseDepth();
894
895 // Now partition the total lowering for this cell between the three size fractions: do this by relative erodibility
896 int nFineWeight = (dExistingAvailableFine > 0 ? 1 : 0);
897 int nSandWeight = (dExistingAvailableSand > 0 ? 1 : 0);
898 int nCoarseWeight = (dExistingAvailableCoarse > 0 ? 1 : 0);
899
900 double dTotErodibility = (nFineWeight * m_dFineErodibilityNormalized) + (nSandWeight * m_dSandErodibilityNormalized) + (nCoarseWeight * m_dCoarseErodibilityNormalized);
901
902 if (nFineWeight)
903 {
904 // Erode some fine-sized sediment
905 double dFineLowering = (m_dFineErodibilityNormalized * dThisLowering) / dTotErodibility;
906
907 // Make sure we don't get -ve amounts left on the cell
908 double dFine = tMin(dExistingAvailableFine, dFineLowering);
909 double dRemaining = dExistingAvailableFine - dFine;
910
911 // Set the value for this layer
912 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->SetFineDepth(dRemaining);
913
914 // And set the changed-this-timestep switch
915 m_bUnconsChangedThisIter[nTopLayer] = true;
916
917 // And increment the per-timestep total for fine sediment eroded during cliff collapse deposition (note that this gets added in to the suspended load elsewhere, so no need to do it here)
919
920 // LogStream << m_ulIter << ": FINE erosion during cliff collapse talus deposition = " << dFine * m_dCellArea << endl;
921
922 // Also add to the suspended load
924 }
925
926 if (nSandWeight)
927 {
928 // Erode some sand-sized sediment
929 double dSandLowering = (m_dSandErodibilityNormalized * dThisLowering) / dTotErodibility;
930
931 // Make sure we don't get -ve amounts left on the source cell
932 double dSandToErode = tMin(dExistingAvailableSand, dSandLowering);
933 double dRemaining = dExistingAvailableSand - dSandToErode;
934
935 // Set the value for this layer
936 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->SetSandDepth(dRemaining);
937
938 // Set the changed-this-timestep switch
939 m_bUnconsChangedThisIter[nTopLayer] = true;
940
941 // And increment the per-timestep total for sand sediment eroded during cliff collapse deposition
943
944 // Increase the all-profiles and this-profile sand deposition targets
945 dTargetSandToDepositOnThisProfile += dSandToErode;
946 dTotSandToDepositAllProfiles += dSandToErode;
947
948 // LogStream << m_ulIter << ": SAND erosion during cliff collapse talus deposition = " << dSandToErode * m_dCellArea << endl;
949
950 // Store the depth of sand sediment eroded during Dean profile deposition of sand cliff collapse talus
951 pPolygon->AddCliffCollapseSandErodedDeanProfile(dSandToErode);
952 }
953
954 if (nCoarseWeight)
955 {
956 // Erode some coarse-sized sediment
957 double dCoarseLowering = (m_dCoarseErodibilityNormalized * dThisLowering) / dTotErodibility;
958
959 // Make sure we don't get -ve amounts left on the source cell
960 double dCoarseToErode = tMin(dExistingAvailableCoarse, dCoarseLowering);
961 double dRemaining = dExistingAvailableCoarse - dCoarseToErode;
962
963 // Set the value for this layer
964 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->SetCoarseDepth(dRemaining);
965
966 // Set the changed-this-timestep switch
967 m_bUnconsChangedThisIter[nTopLayer] = true;
968
969 // And increment the per-timestep total for coarse sediment eroded during cliff collapse deposition
971
972 // Increase the all-profiles and this-profile coarse deposition targets
973 dTargetCoarseToDepositOnThisProfile += dCoarseToErode;
974 dTotCoarseToDepositAllProfiles += dCoarseToErode;
975
976 // LogStream << m_ulIter << ": COARSE erosion during cliff collapse talus deposition = " << dCoarseToErode * m_dCellArea << endl;
977
978 // Store the depth of coarse sediment eroded during Dean profile deposition of coarse cliff collapse talus
979 pPolygon->AddCliffCollapseCoarseErodedDeanProfile(dCoarseToErode);
980 }
981
982 // for this cell, recalculate the elevation of every layer
983 m_pRasterGrid->m_Cell[nX][nY].CalcAllLayerElevsAndD50();
984
985 // And update the cell's sea depth
986 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
987 }
988 } // All cells in this profile
989
990 // OK we have either processed all cells in this profile, or we have deposited enough talus sediment on this profile
991 break;
992 }
993 while (true); // The seaward offset etc. loop
994
995 // LogStream << m_ulIter << ": left seaward offset loop for cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nThisPoint = " << nThisPoint << endl << "\tnSeawardOffset = " << nSeawardOffset << " dCliffHeightFrac = " << dCliffHeightFrac << " nAcross = " << nAcross << " bJustDepositWhatWeCan = " << bJustDepositWhatWeCan << endl << "\tdTargetSandToDepositOnThisProfile = " << dTargetSandToDepositOnThisProfile << " dSandDepositedOnThisProfile = " << dSandDepositedOnThisProfile << " dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl << "\tdTargetCoarseToDepositOnThisProfile = " << dTargetCoarseToDepositOnThisProfile << " dCoarseDepositedOnThisProfile = " << dCoarseDepositedOnThisProfile << " dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
996
997 // Have we deposited enough for this cliff collapse?
998 if (bDoSandDepositionOnThisProfile)
999 {
1000 if (bFPIsEqual(dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
1001 bSandDepositionCompletedOnThisProfile = true;
1002 }
1003
1004 if (bDoCoarseDepositionOnThisProfile)
1005 {
1006 if (bFPIsEqual(dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
1007 bCoarseDepositionCompletedOnThisProfile = true;
1008 }
1009
1010 if (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile)
1011 {
1012 // LogStream << m_ulIter << ": bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile for cliff collapse at [" << nXCliff << "][" << nYCliff << "] nStartPoint = " << nStartPoint << " nThisPoint = " << nThisPoint << endl << "\tnbJustDepositWhatWeCan = " << bJustDepositWhatWeCan << " SeawardOffset = " << nSeawardOffset << " dCliffHeightFrac = " << dCliffHeightFrac << " nAcross = " << nAcross << endl << "\tdTargetSandToDepositOnThisProfile = " << dTargetSandToDepositOnThisProfile << " dSandDepositedOnThisProfile = " << dSandDepositedOnThisProfile << " dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl << "\tdTargetCoarseToDepositOnThisProfile = " << dTargetCoarseToDepositOnThisProfile << " dCoarseDepositedOnThisProfile = " << dCoarseDepositedOnThisProfile << " dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
1013 }
1014 } // Process each deposition profile
1015
1016 // Safety check for sand sediment
1017 if (! bFPIsEqual((dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles), 0.0, MASS_BALANCE_TOLERANCE))
1018 LogStream << ERR << m_ulIter << ": non-zero dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << endl;
1019
1020 // Ditto for coarse sediment
1021 if (! bFPIsEqual((dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles), 0.0, MASS_BALANCE_TOLERANCE))
1022 LogStream << ERR << m_ulIter << ": non-zero dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << endl;
1023
1024 // Store the total depths of cliff collapse deposition for this polygon
1025 pPolygon->AddCliffCollapseUnconsSandDeposition(dTotSandDepositedAllProfiles);
1026 pPolygon->AddCliffCollapseUnconsCoarseDeposition(dTotCoarseDepositedAllProfiles);
1027
1028 // Increment this-timestep totals for cliff collapse deposition
1029 m_dThisIterUnconsSandCliffDeposition += dTotSandDepositedAllProfiles;
1030 m_dThisIterUnconsCoarseCliffDeposition += dTotCoarseDepositedAllProfiles;
1031
1032 // LogStream << endl;
1033 // LogStream << "\tdTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl;
1034 // LogStream << "\tdTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
1035 // LogStream << endl << "****************************************" << endl << endl;
1036
1037 return RTN_OK;
1038}
1039
1040//===============================================================================================================================
1042//===============================================================================================================================
1043void CSimulation::RasterizeCliffCollapseProfile(vector<CGeom2DPoint> const* pVPointsIn, vector<CGeom2DIPoint>* pVIPointsOut) const
1044{
1045 pVIPointsOut->clear();
1046
1047 // The start point of the normal is the centroid of a coastline cell. Convert from the external CRS to grid CRS
1048 double dXStart = dExtCRSXToGridX(pVPointsIn->at(0).dGetX());
1049 double dYStart = dExtCRSYToGridY(pVPointsIn->at(0).dGetY());
1050
1051 // The end point of the normal, again convert from the external CRS to grid CRS. Note too that it could be off the grid
1052 double dXEnd = dExtCRSXToGridX(pVPointsIn->at(1).dGetX());
1053 double dYEnd = dExtCRSYToGridY(pVPointsIn->at(1).dGetY());
1054
1055 // Interpolate between cells by a simple DDA line algorithm, see http://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm) Note that Bresenham's algorithm gave occasional gaps
1056 double dXInc = dXEnd - dXStart;
1057 double dYInc = dYEnd - dYStart;
1058 double dLength = tMax(tAbs(dXInc), tAbs(dYInc));
1059
1060 dXInc /= dLength;
1061 dYInc /= dLength;
1062
1063 double dX = dXStart;
1064 double dY = dYStart;
1065
1066 // Process each interpolated point
1067 int nLength = nRound(dLength);
1068 for (int m = 0; m <= nLength; m++)
1069 {
1070 int nX = nRound(dX);
1071 int nY = nRound(dY);
1072
1073 // Make sure the interpolated point is within the raster grid (can get this kind of problem due to rounding)
1074 if (! bIsWithinValidGrid(nX, nY))
1075 KeepWithinValidGrid(nRound(dXStart), nRound(dYStart), nX, nY);
1076
1077 // This point is fine, so append it to the output vector
1078 pVIPointsOut->push_back(CGeom2DIPoint(nX, nY)); // In raster grid coordinates
1079
1080 // And increment for next time
1081 dX += dXInc;
1082 dY += dYInc;
1083 }
1084}
Abstract class, used as a base class for landform objects on the coastline.
int nGetPointOnCoast(void) const
Get the point on the coast on which this coast landform sits.
int nGetLandFormCategory(void) const
Get the landform category.
void IncTotAccumWaveEnergy(double const)
Increment total accumulated wave energy.
CGeom2DIPoint * pPtiGetCellMarkedAsLF(void) const
Get the grid coordinates of the cell on which this coast landform sits.
Geometry class used to represent 2D point objects with integer coordinates.
Definition 2di_point.h:29
int nGetY(void) const
Returns the CGeom2DIPoint object's integer Y coordinate.
Definition 2di_point.cpp:48
int nGetX(void) const
Returns the CGeom2DIPoint object's integer X coordinate.
Definition 2di_point.cpp:42
Geometry class used to represent 2D point objects with floating-point coordinates.
Definition 2d_point.h:27
void SetY(double const)
The double parameter sets a value for the CGeom2DIPoint object's Y coordinate.
Definition 2d_point.cpp:58
void SetX(double const)
The double parameter sets a value for the CGeom2DIPoint object's X coordinate.
Definition 2d_point.cpp:52
Geometry class used for coast polygon objects.
void AddCliffCollapseUnconsCoarseDeposition(double const)
Add to the this-iteration total of unconsolidated coarse sediment deposited from cliff collapse on th...
void AddCliffCollapseToSuspensionFine(double const)
Add to the this-iteration total of unconsolidated fine sediment from cliff collapse which goes to sus...
void AddCliffCollapseUnconsSandDeposition(double const)
Add to the this-iteration total of unconsolidated sand sediment deposited from cliff collapse on this...
void AddCliffCollapseErosionCoarse(double const)
Add to the this-iteration total of unconsolidated coarse sediment from cliff collapse on this polygon...
void AddCliffCollapseSandErodedDeanProfile(double const)
Add to the this-iteration total of unconsolidated sand sediment eroded during deposition of cliff col...
void AddCliffCollapseErosionFine(double const)
Add to the this-iteration total of unconsolidated fine sediment eroded from cliff collapse on this po...
void AddCliffCollapseCoarseErodedDeanProfile(double const)
Add to the this-iteration total of unconsolidated coarse sediment eroded during deposition of cliff c...
void AddCliffCollapseErosionSand(double const)
Add to the this-iteration total of unconsolidated sand sediment from cliff collapse on this polygon,...
Real-world class used to represent the landform of a cell.
int nGetLFCategory(void) const
Get the landform category.
void SetLFSubCategory(int const)
Set the both the landform sub-category, and the landform category.
Real-world class used to represent the 'cliff' category of coastal landform object.
Definition cliff.h:33
bool bReadyToCollapse(double const) const
Returns true if the horizontal depth of the erosional notch exceeds the critical notch overhang.
Definition cliff.cpp:100
void DeepenErosionalNotch(double const)
Increases the XY-plane length (in external CRS units) of the erosional notch, measured inland from th...
Definition cliff.cpp:109
double dGetNotchBaseElev(void) const
Returns the elevation of the base of the erosional notch.
Definition cliff.cpp:70
void SetNotchBaseElev(double const)
Sets the elevation of the base of the erosional notch.
Definition cliff.cpp:76
void SetCliffCollapsed(void)
Flags the cliff as having collapsed.
Definition cliff.cpp:64
double m_dCliffDepositionPlanviewWidth
Planview width of cliff collapse talus (m)
Definition simulation.h:871
int m_nLogFileDetail
The level of detail in the log file output. Can be LOG_FILE_LOW_DETAIL, LOG_FILE_MIDDLE_DETAIL,...
Definition simulation.h:530
double m_dNotchDepthAtCollapse
Notch overhang (i.e. length of horizontal incision) to initiate collapse (m)
Definition simulation.h:862
CGeomRasterGrid * m_pRasterGrid
Pointer to the raster grid object.
void RasterizeCliffCollapseProfile(vector< CGeom2DPoint > const *, vector< CGeom2DIPoint > *) const
Given the start and end points of a cliff-collapse normal profile, returns an output vector of cells ...
int nDoCliffCollapseDeposition(int const, CRWCliff const *, double const, double const, double const, double const)
Redistributes the sand-sized and coarse-sized sediment from a cliff collapse onto the foreshore,...
ofstream LogStream
vector< CRWCoast > m_VCoast
The coastline objects.
double m_dFineErodibilityNormalized
Relative erodibility of fine unconsolidated beach sediment, normalized.
Definition simulation.h:751
double m_dThisIterCliffCollapseFineErodedDuringDeposition
Total fine sediment eroded during Dean profile deposition of talus following cliff collapse (depth in...
Definition simulation.h:829
double m_dCliffTalusMinDepositionLength
Planview length of cliff deposition talus (m)
Definition simulation.h:874
double m_dCoarseErodibilityNormalized
Relative erodibility of coarse unconsolidated beach sediment, normalized.
Definition simulation.h:757
double m_dThisIterCliffCollapseErosionCoarseUncons
This-iteration total of coarse unconsolidated sediment produced by cliff collapse (m^3)
Definition simulation.h:886
double m_dThisIterCliffCollapseErosionFineUncons
This-iteration total of fine unconsolidated sediment produced by cliff collapse (m^3)
Definition simulation.h:880
static double dSubtractProfiles(vector< double > const *, vector< double > const *, vector< bool > const *)
Calculate the total elevation difference between every point in two elevation profiles (first profile...
Definition utils.cpp:2394
double m_dNotchBaseBelowSWL
Notch base below SWL (m)
Definition simulation.h:865
double m_dSandErodibilityNormalized
Relative erodibility of sand unconsolidated beach sediment, normalized.
Definition simulation.h:754
double m_dCliffErosionResistance
Resistance of cliff to notch erosion.
Definition simulation.h:859
double dGridCentroidYToExtCRSY(int const) const
Given the integer Y-axis ordinate of a cell in the raster grid CRS, returns the external CRS Y-axis o...
Definition gis_utils.cpp:71
int nConvertMetresToNumCells(double const) const
Given a length in m, this returns the rounded equivalent number of cells.
double m_dThisIterUnconsCoarseCliffDeposition
This-iteration total of coarse unconsolidated sediment deposited due to cliff collapse (m^3)
Definition simulation.h:901
double m_dThisIterUnconsSandCliffDeposition
This-iteration total of sand unconsolidated sediment deposited due to cliff collapse (m^3)
Definition simulation.h:898
int nGetCoastNormalEndPoint(int const, int const, int const, CGeom2DPoint const *, double const, CGeom2DPoint *, CGeom2DIPoint *, bool const)
Finds the end point of a coastline-normal line, given the start point on the vector coastline....
double m_dMinCliffTalusHeightFrac
Minimum height of the landward end of cliff collapse talus, as a fraction of cliff elevation.
Definition simulation.h:877
double dExtCRSXToGridX(double const) const
Transforms an X-axis ordinate in the external CRS to the equivalent X-axis ordinate in the raster gri...
double m_dThisIterFineSedimentToSuspension
Total fine unconsolidated sediment in suspension for this iteration (depth in m)
Definition simulation.h:814
int nDoAllWaveEnergyToCoastLandforms(void)
Update accumulated wave energy in coastal landform objects.
void KeepWithinValidGrid(int, int, int &, int &) const
Given two points in the grid CRS (the points assumed not to be coincident), this routine modifies the...
double m_dThisIterCliffCollapseSandErodedDuringDeposition
Total sand sediment eroded during Dean profile deposition of talus following cliff collapse (depth in...
Definition simulation.h:832
double m_dCliffDepositionA
Scale parameter A for cliff deposition (m^(1/3)), may be zero for auto-calculation.
Definition simulation.h:868
int nDoCliffCollapse(int const, CRWCliff *, double &, double &, double &, double &, double &)
Simulates cliff collapse on a single cliff object, which happens when when a notch (incised into a co...
vector< bool > m_bUnconsChangedThisIter
One element per layer: has the consolidated sediment of this layer been changed during this iteration...
double m_dThisIterCliffCollapseErosionFineCons
This-iteration total of fine consolidated sediment produced by cliff collapse (m^3)
Definition simulation.h:889
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:616
double dExtCRSYToGridY(double const) const
Transforms a Y-axis ordinate in the external CRS to the equivalent Y-axis ordinate in the raster grid...
bool bIsWithinValidGrid(int const, int const) const
Checks whether the supplied point (an x-y pair, in the grid CRS) is within the raster grid,...
double m_dThisIterCliffCollapseErosionSandCons
This-iteration total of sand consolidated sediment produced by cliff collapse (m^3)
Definition simulation.h:892
double m_dThisIterCliffCollapseErosionSandUncons
This-iteration total of sand unconsolidated sediment produced by cliff collapse (m^3)
Definition simulation.h:883
unsigned long m_ulIter
The number of the current iteration (time step)
Definition simulation.h:553
double dGridCentroidXToExtCRSX(int const) const
Given the integer X-axis ordinate of a cell in the raster grid CRS, returns the external CRS X-axis o...
Definition gis_utils.cpp:62
double m_dCellSide
Length of a cell side (in external CRS units)
Definition simulation.h:613
bool bIsInterventionCell(int const, int const) const
Returns true if the cell is an intervention.
Definition utils.cpp:2736
double m_dThisIterCliffCollapseCoarseErodedDuringDeposition
Total coarse sediment eroded during Dean profile deposition of talus following cliff collapse (depth ...
Definition simulation.h:835
double m_dThisIterCliffCollapseErosionCoarseCons
This-iteration total of coarse consolidated sediment produced by cliff collapse (m^3)
Definition simulation.h:895
static void CalcDeanProfile(vector< double > *, double const, double const, double const, bool const, int const, double const)
Calculates a Dean equilibrium profile h(y) = A * y^(2/3) where h(y) is the distance below the highest...
Definition utils.cpp:2356
vector< bool > m_bConsChangedThisIter
One element per layer: has the consolidated sediment of this layer been changed during this iteration...
Contains CRWCliff definitions.
This file contains global definitions for CoastalME.
int const NO_NONZERO_THICKNESS_LAYERS
Definition cme.h:652
int const INT_NODATA
Definition cme.h:362
T tMin(T a, T b)
Definition cme.h:1136
int const RTN_ERR_CLIFFNOTCH
Definition cme.h:614
double const TOLERANCE
Definition cme.h:698
int const RTN_ERR_NO_TOP_LAYER
Definition cme.h:623
int const ELEV_ABOVE_SEDIMENT_TOP
Definition cme.h:651
int const LF_CAT_SEDIMENT_INPUT
Definition cme.h:424
string const ERR
Definition cme.h:775
int const LF_CAT_SEDIMENT_INPUT_SUBMERGED
Definition cme.h:425
int const MAX_SEAWARD_OFFSET_FOR_CLIFF_TALUS
Definition cme.h:367
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:377
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1176
double const MASS_BALANCE_TOLERANCE
Definition cme.h:700
T tMax(T a, T b)
Definition cme.h:1123
double const CLIFF_COLLAPSE_HEIGHT_INCREMENT
Definition cme.h:705
int const MAX_CLIFF_TALUS_LENGTH
Definition cme.h:363
int const LOG_FILE_HIGH_DETAIL
Definition cme.h:378
int const LF_SUBCAT_DRIFT_TALUS
Definition cme.h:439
int const RTN_ERR_CLIFF_NOT_IN_POLYGON
Definition cme.h:646
string const WARN
Definition cme.h:776
double const SEDIMENT_ELEV_TOLERANCE
Definition cme.h:699
int const CLIFF_COLLAPSE_LENGTH_INCREMENT
Definition cme.h:672
int const LOG_FILE_ALL
Definition cme.h:379
int const RTN_OK
Definition cme.h:577
double const DBL_NODATA
Definition cme.h:707
int const RTN_ERR_CLIFFDEPOSIT
Definition cme.h:615
double const DEAN_POWER
Definition cme.h:692
int const LF_CAT_SEDIMENT_INPUT_NOT_SUBMERGED
Definition cme.h:426
int const RTN_ERR_NO_SOLUTION_FOR_ENDPOINT
Definition cme.h:604
int const LF_CAT_CLIFF
Definition cme.h:429
T tAbs(T a)
Definition cme.h:1148
Contains CSimulation definitions.
int nRound(double const d)
Version of the above that returns an int.