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
15 This file is part of CoastalME, the Coastal Modelling Environment.
16
17 CoastalME 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
19 This 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
21 You 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, check the notch elevation
70 int nX = m_VCoast[i].pPtiGetCellMarkedAsCoastline(j)->nGetX();
71 int nY = m_VCoast[i].pPtiGetCellMarkedAsCoastline(j)->nGetY();
72 int nCat = pCoastLandform->nGetLandFormCategory();
73 double dTopElev = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
74 double dNotchElev = 0;
75
76 if ((nCat == LF_CAT_CLIFF) || (nCat == LF_SUBCAT_CLIFF_ON_COASTLINE) || (nCat == LF_SUBCAT_CLIFF_INLAND))
77 {
78 CRWCliff * pCliff = reinterpret_cast<CRWCliff*>(pCoastLandform);
79 dNotchElev = pCliff->dGetNotchBaseElev();
80
81 // Is the notch elevation above the top surface of the sediment?
82 if (dNotchElev > dTopElev)
83 {
84 // It is, so reduce the notch elevation, to be the same as the sediment top surface
85 LogStream << m_ulIter << ": *** DDD [" << nX << "][" << nY << "} dTopElev = " << dTopElev << ", dNotchElev was " << dNotchElev << ", dNotchElev changed, is now " << dTopElev - m_dNotchBaseBelowSWL << endl;
86
87 pCliff->SetNotchBaseElev(dTopElev - m_dNotchBaseBelowSWL);
88 }
89 }
90
91 // // DEBUG CODE ==============
92 // if ((j > 20) && (j <= 30))
93 // {
94 // string strCat;
95 // if (nCat == LF_CAT_HINTERLAND)
96 // strCat = "hinterland";
97 // else if (nCat == LF_CAT_SEA)
98 // strCat = "sea";
99 // else if (nCat == LF_CAT_CLIFF)
100 // strCat = "cliff";
101 // else if (nCat == LF_CAT_DRIFT)
102 // strCat = "drift";
103 // else if (nCat == LF_CAT_INTERVENTION)
104 // strCat = "intervention";
105 // else if (nCat == LF_SUBCAT_CLIFF_ON_COASTLINE)
106 // strCat = "cliff on coastline";
107 // else if (nCat == LF_SUBCAT_CLIFF_INLAND)
108 // strCat = "cliff inland";
109 // else if (nCat == LF_SUBCAT_DRIFT_MIXED)
110 // strCat = "drift mixed";
111 // else if (nCat == LF_SUBCAT_DRIFT_TALUS)
112 // strCat = "drift talus";
113 // else if (nCat == LF_SUBCAT_DRIFT_BEACH)
114 // strCat = "drift beach";
115 // else
116 // strCat = "unknown";
117 //
118 // // LogStream << m_ulIter << ": [" << nX << "][" << nY << "] '" << strCat << "' dWaveEnergy = " << dWaveEnergy << " dGetTotAccumWaveEnergy() = " << pCoastLandform->dGetTotAccumWaveEnergy() << endl;
119 //
120 // LogStream << m_ulIter << ": [" << nX << "][" << nY << "] '" << strCat << "' dNotchElev = " << dNotchElev << " dTopElev = " << dTopElev << " m_dInitialMeanSWL = " << m_dInitialMeanSWL << " m_dThisIterMeanSWL = " << m_dThisIterMeanSWL << " m_dThisIterSWL = " << m_dThisIterSWL << endl;
121 // }
122 // // DEBUG CODE =============
123
124 // Now simulate how the coastal landform responds to this wave energy
125 int nCategory = pCoastLandform->nGetLandFormCategory();
126
127 if (nCategory == LF_CAT_CLIFF)
128 {
129 // This is a cliff
130 CRWCliff * pCliff = reinterpret_cast<CRWCliff*>(pCoastLandform);
131
132 // Calculate this-timestep cliff notch erosion (is a length in external CRS units). Only consolidated sediment can have a cliff notch
133 double dNotchExtension = dWaveEnergy / m_dCliffErosionResistance;
134
135 // 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
136 pCliff->DeepenErosionalNotch(dNotchExtension);
137
138 // 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)?
140 {
141 // // DEBUG CODE ============================================================================================================================================
142 // // Get total depths of sand consolidated and unconsolidated for every cell
143 // if (m_ulIter == 5)
144 // {
145 // double dTmpSandCons = 0;
146 // double dTmpSandUncons = 0;
147 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
148 // {
149 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
150 // {
151 // dTmpSandCons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotConsSandThickConsiderNotch();
152 //
153 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
154 // }
155 // }
156 //
157 // // Get the cliff cell's grid coords
158 // int nXCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
159 // int nYCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
160 //
161 // // Get this cell's polygon
162 // int nPoly = m_pRasterGrid->m_Cell[nXCliff][nYCliff].nGetPolygonID();
163 //
164 // LogStream << endl;
165 // LogStream << "*****************************" << endl;
166 // LogStream << m_ulIter << ": before cliff collapse on nPoly = " << nPoly << " total consolidated sand = " << dTmpSandCons * m_dCellArea << " total unconsolidated sand = " << dTmpSandUncons * m_dCellArea << endl;
167 // }
168 // // DEBUG CODE ============================================================================================================================================
169
170 // It is ready to collapse
171 double dCliffElevPreCollapse = 0;
172 double dCliffElevPostCollapse = 0;
173 double dFineCollapse = 0;
174 double dSandCollapse = 0;
175 double dCoarseCollapse = 0;
176
177 // So do the cliff collapse
178 nRet = nDoCliffCollapse(i, pCliff, dFineCollapse, dSandCollapse, dCoarseCollapse, dCliffElevPreCollapse, dCliffElevPostCollapse);
179
180 if (nRet != RTN_OK)
181 {
183 LogStream << m_ulIter << ": " << WARN << "problem with cliff collapse, continuing however" << endl;
184 }
185
186 // Deposit all sand and/or coarse sediment derived from this cliff collapse as unconsolidated sediment (talus)
187 nRet = nDoCliffCollapseDeposition(i, pCliff, dSandCollapse, dCoarseCollapse, dCliffElevPreCollapse, dCliffElevPostCollapse);
188
189 if (nRet != RTN_OK)
190 return nRet;
191
192 // // DEBUG CODE ============================================================================================================================================
193 // // Get total depths of sand consolidated and unconsolidated for every cell
194 // if (m_ulIter == 5)
195 // {
196 // double dTmpSandCons = 0;
197 // double dTmpSandUncons = 0;
198 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
199 // {
200 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
201 // {
202 // dTmpSandCons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotConsSandThickConsiderNotch();
203 //
204 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
205 // }
206 // }
207 //
208 // // Get the cliff cell's grid coords
209 // int nXCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
210 // int nYCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
211 //
212 // // Get this cell's polygon
213 // int nPoly = m_pRasterGrid->m_Cell[nXCliff][nYCliff].nGetPolygonID();
214 //
215 // LogStream << endl;
216 // LogStream << "*****************************" << endl;
217 // LogStream << m_ulIter << ": after cliff collapse on nPoly = " << nPoly << " total consolidated sand = " << dTmpSandCons * m_dCellArea << " total unconsolidated sand = " << dTmpSandUncons * m_dCellArea << endl;
218 // LogStream << m_ulIter << ": total consolidated sand lost this iteration = " << (m_dStartIterConsSandAllCells - dTmpSandCons) * m_dCellArea << endl;
219 // LogStream << m_ulIter << ": total unconsolidated sand added this iteration = " << (dTmpSandUncons - m_dStartIterUnconsSandAllCells) * m_dCellArea << endl;
220 //
221 // double dTmpAllPolySandErosion = 0;
222 // double dTmpAllPolySandDeposition = 0;
223 // for (unsigned int n = 0; n < m_pVCoastPolygon.size(); n++)
224 // {
225 // double dTmpSandErosion = m_pVCoastPolygon[n]->dGetCliffCollapseErosionSand() * m_dCellArea ;
226 // double dTmpSandDeposition = m_pVCoastPolygon[n]->dGetCliffCollapseUnconsSandDeposition() * m_dCellArea ;
227 //
228 // LogStream << m_ulIter << ": polygon = " << m_pVCoastPolygon[n]->nGetCoastID() << " sand erosion = " << dTmpSandErosion << " sand deposition = " << dTmpSandDeposition << endl;
229 //
230 // dTmpAllPolySandErosion += dTmpSandErosion;
231 // dTmpAllPolySandDeposition += dTmpSandDeposition;
232 // }
233 //
234 // LogStream << "-------------------------------------------" << endl;
235 // LogStream << m_ulIter << ": all polygons, sand erosion = " << dTmpAllPolySandErosion << " sand deposition = " << dTmpAllPolySandDeposition << endl;
236 // LogStream << "*****************************" << endl;
237 // }
238 // // DEBUG CODE ============================================================================================================================================
239 }
240 }
241 }
242 }
243
246
247 return RTN_OK;
248}
249
250//===============================================================================================================================
252//===============================================================================================================================
253int CSimulation::nDoCliffCollapse(int const nCoast, CRWCliff * pCliff, double &dFineCollapse, double &dSandCollapse, double &dCoarseCollapse, double &dPreCollapseCliffElev, double &dPostCollapseCliffElev)
254{
255 // Get the cliff cell's grid coords
256 int nX = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
257 int nY = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
258
259 // Get this cell's polygon
260 int nPoly = m_pRasterGrid->m_Cell[nX][nY].nGetPolygonID();
261
262 if (nPoly == INT_NODATA)
263 {
264 // This cell isn't in a polygon
265 LogStream << m_ulIter << ": " << WARN << "in nDoCliffCollapse(), [" << nX << "][" << nY << "] = {" << dGridCentroidXToExtCRSX(nX) << ", " << dGridCentroidYToExtCRSY(nY) << "} is not in a polygon" << endl;
266
268 }
269
270 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
271
272 double dOrigCliffTopElev = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
273
274 // Get the elevation of the base of the notch from the cliff object
275 double dNotchElev = pCliff->dGetNotchBaseElev();
276
277 // Get the index of the layer containing the notch (layer 0 being just above basement)
278 int nNotchLayer = m_pRasterGrid->m_Cell[nX][nY].nGetLayerAtElev(dNotchElev);
279
280 // Safety check
281 if (nNotchLayer < 0)
282 {
283 // Notch layer is < 0
284 LogStream << m_ulIter << ": " << WARN << "in nDoCliffCollapse(), [" << nX << "][" << nY << "] = {" << dGridCentroidXToExtCRSX(nX) << ", " << dGridCentroidYToExtCRSY(nY) << "} notch layer = " << nNotchLayer << ", dNotchElev = " << dNotchElev << " m_dNotchBaseBelowSWL = " << m_dNotchBaseBelowSWL << " dOrigCliffTopElev = " << dOrigCliffTopElev << endl;
285
286 return RTN_ERR_CLIFFNOTCH;
287 }
288
289 if (nNotchLayer == ELEV_ABOVE_SEDIMENT_TOP)
290 {
291 LogStream << m_ulIter << ": " << WARN << "in nDoCliffCollapse(), [" << nX << "][" << nY << "] has nNotchLayer = " << nNotchLayer << ", this has elevation = " << dNotchElev << " which is above sediment top elevation (" << m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev() << ")" << endl;
292
293 return RTN_ERR_CLIFFNOTCH;
294 }
295
296 // Flag the coastline cliff object as having collapsed
297 pCliff->SetCliffCollapsed();
298
299 int nTopLayer = m_pRasterGrid->m_Cell[nX][nY].nGetTopLayerAboveBasement();
300
301 // Safety check
302 if (nTopLayer == INT_NODATA)
303 {
304 LogStream << m_ulIter << ": " << WARN << "in nDoCliffCollapse(), [" << nX << "][" << nY << "] nTopLayer = " << nTopLayer << endl;
305
307 }
308
309 // Set the base of the collapse (see above)
310 pCliff->SetNotchBaseElev(dNotchElev);
311
312 // Set flags to say that the top layer has changed
313 m_bConsChangedThisIter[nTopLayer] = true;
314 m_bUnconsChangedThisIter[nTopLayer] = true;
315
316 // Get the pre-collapse cliff elevation
317 dPreCollapseCliffElev = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
318
319 // 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
320 double dAvailable = 0;
321 double dFineConsLost = 0;
322 double dFineUnconsLost = 0;
323 double dSandConsLost = 0;
324 double dSandUnconsLost = 0;
325 double dCoarseConsLost = 0;
326 double dCoarseUnconsLost = 0;
327
328 // 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
329 for (int n = nTopLayer; n > nNotchLayer; n--)
330 {
331 // Start with the unconsolidated sediment
332 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetFineDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetNotchFineLost();
333
334 if (dAvailable > 0)
335 {
336 dFineCollapse += dAvailable;
337 dFineUnconsLost += dAvailable;
338 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetFineDepth(0);
339 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetNotchFineLost(0);
340 }
341
342 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetSandDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetNotchSandLost();
343
344 if (dAvailable > 0)
345 {
346 dSandCollapse += dAvailable;
347 dSandUnconsLost += dAvailable;
348 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetSandDepth(0);
349 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetNotchSandLost(0);
350 }
351
352 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetCoarseDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->dGetNotchCoarseLost();
353
354 if (dAvailable > 0)
355 {
356 dCoarseCollapse += dAvailable;
357 dCoarseUnconsLost += dAvailable;
358 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetCoarseDepth(0);
359 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetUnconsolidatedSediment()->SetNotchCoarseLost(0);
360 }
361
362 // Now get the consolidated sediment
363 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetFineDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetNotchFineLost();
364
365 if (dAvailable > 0)
366 {
367 dFineCollapse += dAvailable;
368 dFineConsLost += dAvailable;
369 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetFineDepth(0);
370 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetNotchFineLost(0);
371 }
372
373 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetSandDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetNotchSandLost();
374
375 if (dAvailable > 0)
376 {
377 dSandCollapse += dAvailable;
378 dSandConsLost += dAvailable;
379 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetSandDepth(0);
380 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetNotchSandLost(0);
381 }
382
383 dAvailable = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetCoarseDepth() - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->dGetNotchCoarseLost();
384
385 if (dAvailable > 0)
386 {
387 dCoarseCollapse += dAvailable;
388 dCoarseConsLost += dAvailable;
389 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetCoarseDepth(0);
390 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(n)->pGetConsolidatedSediment()->SetNotchCoarseLost(0);
391 }
392 }
393
394 // Now sort out the sediment lost from the consolidated layer into which the erosional notch was incised
395 double dNotchLayerTop = m_pRasterGrid->m_Cell[nX][nY].dCalcLayerElev(nNotchLayer);
396 double dNotchLayerThickness = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->dGetTotalThickness();
397 double dNotchLayerFracRemoved = (dNotchLayerTop - dNotchElev) / dNotchLayerThickness;
398
399 // Sort out the notched layer's sediment, both consolidated and unconsolidated, for this cell. First the unconsolidated sediment
400 double dFineDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetFineDepth();
401 dAvailable = dFineDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetNotchFineLost();
402
403 if (dAvailable > 0)
404 {
405 // Some unconsolidated fine sediment is available for collapse
406 double dLost = dAvailable * dNotchLayerFracRemoved;
407 dFineCollapse += dLost;
408 dFineUnconsLost += dLost;
409 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetFineDepth(dFineDepth - dLost);
410 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetNotchFineLost(0);
411 }
412
413 double dSandDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetSandDepth();
414 dAvailable = dSandDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetNotchSandLost();
415
416 if (dAvailable > 0)
417 {
418 // Some unconsolidated sand sediment is available for collapse
419 double dLost = dAvailable * dNotchLayerFracRemoved;
420 dSandCollapse += dLost;
421 dSandUnconsLost += dLost;
422 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetSandDepth(dSandDepth - dLost);
423 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetNotchSandLost(0);
424 }
425
426 double dCoarseDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetCoarseDepth();
427 dAvailable = dCoarseDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->dGetNotchCoarseLost();
428
429 if (dAvailable > 0)
430 {
431 // Some unconsolidated coarse sediment is available for collapse
432 double dLost = dAvailable * dNotchLayerFracRemoved;
433 dCoarseCollapse += dLost;
434 dCoarseUnconsLost += dLost;
435 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetCoarseDepth(dCoarseDepth - dLost);
436 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetUnconsolidatedSediment()->SetNotchCoarseLost(0);
437 }
438
439 // Now do the consolidated sediment
440 dFineDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetFineDepth();
441 dAvailable = dFineDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetNotchFineLost();
442
443 if (dAvailable > 0)
444 {
445 // Some consolidated fine sediment is available for collapse
446 double dLost = dAvailable * dNotchLayerFracRemoved;
447 dFineCollapse += dLost;
448 dFineConsLost += dLost;
449 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetFineDepth(dFineDepth - dLost);
450 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetNotchFineLost(0);
451 }
452
453 dSandDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetSandDepth();
454 dAvailable = dSandDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetNotchSandLost();
455
456 if (dAvailable > 0)
457 {
458 // Some consolidated sand sediment is available for collapse
459 double dLost = dAvailable * dNotchLayerFracRemoved;
460 dSandCollapse += dLost;
461 dSandConsLost += dLost;
462 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetSandDepth(dSandDepth - dLost);
463 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetNotchSandLost(0);
464 }
465
466 dCoarseDepth = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetCoarseDepth();
467 dAvailable = dCoarseDepth - m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->dGetNotchCoarseLost();
468
469 if (dAvailable > 0)
470 {
471 // Some consolidated coarse sediment is available for collapse
472 double dLost = dAvailable * dNotchLayerFracRemoved;
473 dCoarseCollapse += dLost;
474 dCoarseConsLost += dLost;
475 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetCoarseDepth(dCoarseDepth - dLost);
476 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nNotchLayer)->pGetConsolidatedSediment()->SetNotchCoarseLost(0);
477 }
478
479 // Update the cell's totals for cliff collapse erosion
480 m_pRasterGrid->m_Cell[nX][nY].IncrCliffCollapseErosion(dFineCollapse, dSandCollapse, dCoarseCollapse);
481
482 // Update the cell's layer elevations and d50
483 m_pRasterGrid->m_Cell[nX][nY].CalcAllLayerElevsAndD50();
484
485 // Get the post-collapse cliff elevation
486 dPostCollapseCliffElev = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
487
489 LogStream << m_ulIter << ": cliff collapse at [" << nX << "][" << nY << "], original cliff elevation = " << dOrigCliffTopElev << ", new cliff elevation = " << dPostCollapseCliffElev << ", change in elevation = " << dOrigCliffTopElev - dPostCollapseCliffElev << endl;
490
491 // And update the cell's sea depth
492 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
493
494 // 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;
495
496 // Update this-polygon totals: add to the depths of cliff collapse erosion for this polygon
497 pPolygon->AddCliffCollapseErosionFine(dFineCollapse);
498 pPolygon->AddCliffCollapseToSuspensionFine(dFineCollapse);
499 pPolygon->AddCliffCollapseErosionSand(dSandCollapse);
500 pPolygon->AddCliffCollapseErosionCoarse(dCoarseCollapse);
501
502 // And update the this-timestep totals and the grand totals for collapse
503 // m_nNThisIterCliffCollapse++;
504 // m_nNTotCliffCollapse++;
505
506 // Add to this-iteration totals
509
510 // 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()
511 m_dThisIterFineSedimentToSuspension += (dFineConsLost + dFineUnconsLost);
512
517
518 return RTN_OK;
519}
520
521//===============================================================================================================================
523//===============================================================================================================================
524int CSimulation::nDoCliffCollapseDeposition(int const nCoast, CRWCliff const* pCliff, double const dSandFromCollapse, double const dCoarseFromCollapse, double const dPreCollapseCliffElev, double const dPostCollapseCliffElev)
525{
526 // Check: is there some sand- or coarse-sized sediment to deposit?
527 if ((dSandFromCollapse + dCoarseFromCollapse) < SEDIMENT_ELEV_TOLERANCE)
528 return RTN_OK;
529
530 // LogStream << "\tdSandFromCollapse = " << dSandFromCollapse << " dCoarseFromCollapse = " << dCoarseFromCollapse << endl;
531
532 // OK, we have some sand- and/or coarse-sized sediment to deposit
533 int nStartPoint = pCliff->nGetPointOnCoast();
534 int nCoastSize = m_VCoast[nCoast].nGetCoastlineSize();
535
536 // Get the cliff cell's grid coords
537 int nXCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetX();
538 int nYCliff = pCliff->pPtiGetCellMarkedAsLF()->nGetY();
539
540 // Get this cell's polygon
541 int nPoly = m_pRasterGrid->m_Cell[nXCliff][nYCliff].nGetPolygonID();
542
543 if (nPoly == INT_NODATA)
544 {
545 // This cell isn't in a polygon
546 LogStream << m_ulIter << " : in nDoCliffCollapse(), [" << nXCliff << "][" << nYCliff << "] = {" << dGridCentroidXToExtCRSX(nXCliff) << ", " << dGridCentroidYToExtCRSY(nYCliff) << "} is not in a polygon" << endl;
547
549 }
550
551 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
552
553 // 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
555
556 // The default talus collapse width 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)
557 if ((nTalusWidthInCells % 2) == 0)
558 nTalusWidthInCells++;
559
560 // This holds the valid coast start points for each cliff collapse Dean profile
561 vector<int> VnTalusProfileCoastStartPoint(nCoastSize);
562
563 // This is the coast start point for the first Dean profile
564 VnTalusProfileCoastStartPoint[0] = nStartPoint;
565 int nn = 1;
566 int nSigned = 1;
567 int nCount = 1;
568
569 do
570 {
571 int nTmpPoint;
572
573 if ((nCount % 2) != 0)
574 nTmpPoint = nStartPoint + nSigned;
575
576 else
577 {
578 nTmpPoint = nStartPoint - nSigned;
579 nSigned++;
580 }
581
582 // Is this start point valid?
583 if ((nTmpPoint < 0) || (nTmpPoint > (nCoastSize - 1)))
584 {
585 // No, it is outside the grid, so find another
586 nCount++;
587 continue;
588 }
589
590 else
591 {
592 // It is valid
593 VnTalusProfileCoastStartPoint[nn] = nTmpPoint;
594 nn++;
595 nCount++;
596 }
597 } while (nn < nCoastSize);
598
599 bool bHitFirstCoastPoint = false;
600 bool bHitLastCoastPoint = false;
601
602 double dTotSandToDepositAllProfiles = dSandFromCollapse; // Note that this can increase, if we get erosion because Dean profile is lower than profile at that point
603 double dTotCoarseToDepositAllProfiles = dCoarseFromCollapse; // Note that this can increase, if we get erosion because Dean profile is lower than profile at that point
604 double dTotSandDepositedAllProfiles = 0;
605 double dTotCoarseDepositedAllProfiles = 0;
606
607 // Process each deposition profile
608 for (int nAcross = 0; nAcross < nCoastSize; nAcross++)
609 {
610 bool bDoSandDepositionOnThisProfile = false;
611 bool bSandDepositionCompletedOnThisProfile = false;
612 bool bDoCoarseDepositionOnThisProfile = false;
613 bool bCoarseDepositionCompletedOnThisProfile = false;
614
615 // int nRemaining = tMax(1, nTalusWidthInCells - nAcross);
616
617 // This is the minimum planview length (in cells) of the Dean profile. The initial length will be increased later if we can't deposit sufficient talus
618 int nTalusProfileLenInCells = nConvertMetresToNumCells(m_dCliffTalusMinDepositionLength);
619
620 // Calculate the target amount to be deposited on each talus profile, assuming the "preferred" talus width
621 double dTargetSandToDepositOnThisProfile = dTotSandToDepositAllProfiles / nTalusWidthInCells;
622 double dTargetCoarseToDepositOnThisProfile = dTotCoarseToDepositAllProfiles / nTalusWidthInCells;
623 // double dTargetSandToDepositOnThisProfile = (dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles) / nRemaining;
624 // double dTargetCoarseToDepositOnThisProfile = (dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles) / nRemaining;
625
626 // 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
627 double dSandProp = 0.5;
628 double dCoarseProp = 1 - dSandProp;
629
630 if (dTargetSandToDepositOnThisProfile + dTargetCoarseToDepositOnThisProfile > 0)
631 {
632 dSandProp = dTargetSandToDepositOnThisProfile / (dTargetSandToDepositOnThisProfile + dTargetCoarseToDepositOnThisProfile);
633 dCoarseProp = 1 - dSandProp;
634 }
635
636 double dSandDepositedOnThisProfile = 0;
637 double dCoarseDepositedOnThisProfile = 0;
638
639 if (dTotSandToDepositAllProfiles > 0)
640 {
641 bDoSandDepositionOnThisProfile = true;
642
643 if (bFPIsEqual(dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
644 bSandDepositionCompletedOnThisProfile = true;
645 }
646
647 else
648 bSandDepositionCompletedOnThisProfile = true;
649
650 if (dTotCoarseToDepositAllProfiles > 0)
651 {
652 bDoCoarseDepositionOnThisProfile = true;
653
654 if (bFPIsEqual(dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
655 bCoarseDepositionCompletedOnThisProfile = true;
656 }
657
658 else
659 bCoarseDepositionCompletedOnThisProfile = true;
660
661 if (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile)
662 {
663 // 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;
664
665 break;
666 }
667
668 // Get the start point of this cliff collapse deposition profile
669 int nThisPoint = VnTalusProfileCoastStartPoint[nAcross];
670
671 // Are we at the start or end of the coast?
672 if (nThisPoint == 0)
673 bHitFirstCoastPoint = true;
674
675 if (nThisPoint == nCoastSize - 1)
676 bHitLastCoastPoint = true;
677
678 CGeom2DPoint PtStart;
679 CGeom2DPoint PtEnd;
680
681 // 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)
682 PtStart.SetX(dGridCentroidXToExtCRSX(m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nThisPoint)->nGetX()));
683 PtStart.SetY(dGridCentroidYToExtCRSY(m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nThisPoint)->nGetY()));
684
685 // Set the initial fraction of cliff height, this will be increased (max is one) if we can't deposit sufficient talus
686 double dCliffHeightFrac = m_dMinCliffTalusHeightFrac;
687
688 bool bJustDepositWhatWeCan = false;
689
690 // The initial seaward offset, in cells. This will be increased if we can't deposit sufficient talus
691 int nSeawardOffset = 1;
692
693 // Process this profile
694 do
695 {
696 if (bJustDepositWhatWeCan || (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile))
697 {
698 // 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;
699
700 break;
701 }
702
703 // Need to deposit more on this profile: increase the seaward offset each time round the loop
704 nSeawardOffset++;
705
706 // Has the seaward offset reached the arbitrary limit?
707 if (nSeawardOffset >= MAX_SEAWARD_OFFSET_FOR_CLIFF_TALUS)
708 {
709 // It has, so if cliff height is not at the maximum, then try again with a larger fraction of cliff height
710 if (dCliffHeightFrac < 1)
711 {
712 dCliffHeightFrac += CLIFF_COLLAPSE_HEIGHT_INCREMENT;
713
714 // Reset seaward offset
715 nSeawardOffset = 1;
716 }
717
718 else
719 {
720 // Cliff height has reached the limit, is the talus length also at its arbitrary limit?
721 if (nTalusProfileLenInCells >= MAX_CLIFF_TALUS_LENGTH)
722 {
723 // 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
724 bJustDepositWhatWeCan = true;
725 }
726
727 else
728 {
729 // The talus length is not at its limit, so try again with an increased talus length
730 nTalusProfileLenInCells += CLIFF_COLLAPSE_LENGTH_INCREMENT;
731
732 // Reset seaward offset
733 nSeawardOffset = 1;
734
735 // Set cliff height to exactly one
736 dCliffHeightFrac = 1;
737 }
738 }
739 }
740
741 if (bHitFirstCoastPoint && bHitLastCoastPoint)
742 {
743 // Uh-oh, we've reached both ends of the coast (!) and we can't increase anything any more
744 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;
745
747 }
748
749 // 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
750 double dThisProfileLength = (nTalusProfileLenInCells + nSeawardOffset + 1) * m_dCellSide;
751
752 // Get the end point of this coastline-normal line
753 CGeom2DIPoint PtiEnd; // In grid CRS
754 int nRtn = nGetCoastNormalEndPoint(nCoast, nThisPoint, nCoastSize, &PtStart, dThisProfileLength, &PtEnd, &PtiEnd, false);
755
756 // Safety check
758 {
759 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;
760
761 return nRtn;
762 }
763
764 // Safety check
765 if (PtStart == PtEnd)
766 {
767 // This would give a zero-length profile, and a zero-divide error during rasterization. So just move on to the next profile
768 break;
769 }
770
771 // OK, both the start and end points of this deposition profile are within the grid
772 // 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;
773
774 vector<CGeom2DPoint> VTmpProfile;
775 VTmpProfile.push_back(PtStart);
776 VTmpProfile.push_back(PtEnd);
777 vector<CGeom2DIPoint> VCellsUnderProfile;
778
779 // Now get the raster cells under this profile
780 RasterizeCliffCollapseProfile(&VTmpProfile, &VCellsUnderProfile);
781
782 int nRasterProfileLength = static_cast<int>(VCellsUnderProfile.size());
783
784 // Check now, for the case where the profile is very short
785 if (nRasterProfileLength - nSeawardOffset < 3)
786 {
787 // 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
788 break;
789 }
790
791 else if (nRasterProfileLength - nSeawardOffset == 3)
792 {
793 // 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
794 bJustDepositWhatWeCan = true;
795 }
796
797 vector<double> dVProfileNow(nRasterProfileLength, 0);
798 vector<bool> bVProfileValid(nRasterProfileLength, true);
799
800 // 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;
801
802 // Calculate the existing elevation for all points along the deposition profile
803 for (int n = 0; n < nRasterProfileLength; n++)
804 {
805 int nX = VCellsUnderProfile[n].nGetX();
806 int nY = VCellsUnderProfile[n].nGetY();
807
808 dVProfileNow[n] = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
809
810 // Don't allow cliff collapse talus onto intervention cells TODO 078 Is this realistic? Should it change with different types on intervention?
811 if (bIsInterventionCell(nX, nY))
812 bVProfileValid[n] = false;
813 }
814
815 // Now calculate the elevation of the talus top at the shoreline
816 double dCliffHeight = dPreCollapseCliffElev - dPostCollapseCliffElev;
817 double dTalusTopElev = dPostCollapseCliffElev + (dCliffHeight * dCliffHeightFrac);
818
819 // LogStream << "Elevations: cliff top = " << dPreCollapseCliffElev << " cliff base = " << dPostCollapseCliffElev << " talus top = " << dTalusTopElev << endl;
820
821 // if (dPreCollapseCliffElev < dPostCollapseCliffElev)
822 // LogStream << "*** ERROR, cliff top is lower than cliff base" << endl;
823
824 // Next calculate the talus slope length in external CRS units, this is approximate but probably OK
825 double dTalusSlopeLength = dThisProfileLength - ((nSeawardOffset - 1) * m_dCellSide);
826
827 // 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
828 double dA = 0;
829
832
833 else
834 dA = (dTalusTopElev - dVProfileNow[nRasterProfileLength - 1]) / pow(dTalusSlopeLength, DEAN_POWER);
835
836 // assert((nRasterProfileLength - nSeawardOffset - 2) > 0);
837 double dInc = dTalusSlopeLength / (nRasterProfileLength - nSeawardOffset - 2);
838 vector<double> dVDeanProfile(nRasterProfileLength);
839
840 // 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)
841 CalcDeanProfile(&dVDeanProfile, dInc, dTalusTopElev, dA, true, nSeawardOffset, dTalusTopElev);
842
843 // 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
844 double dTotElevDiff = dSubtractProfiles(&dVDeanProfile, &dVProfileNow, &bVProfileValid);
845
846 // // DEBUG CODE -----------------------------------------------------
847 // LogStream << endl;
848 // LogStream << "dTalusSlopeLength = " << dTalusSlopeLength << " dA = " << dA << endl;
849 // LogStream << "dDistFromTalusStart - dInc = " << dDistFromTalusStart - dInc << " dThisProfileLength - nSeawardOffset - 2 = " << dThisProfileLength - nSeawardOffset - 2 << endl;
850 // LogStream << "Profile now (inc. cliff cell) = ";
851 // for (int n = 0; n < nRasterProfileLength; n++)
852 // {
853 // int
854 // nX = VCellsUnderProfile[n].nGetX(),
855 // nY = VCellsUnderProfile[n].nGetY();
856 // dVProfileNow[n] = m_pRasterGrid->m_Cell[nX][nY].dGetSedimentTopElev();
857 // LogStream << dVProfileNow[n] << " ";
858 // }
859 // LogStream << endl;
860 // LogStream << "Dean equilibrium profile (inc. cliff cell) = ";
861 // for (int n = 0; n < nRasterProfileLength; n++)
862 // {
863 // LogStream << dVDeanProfile[n] << " ";
864 // }
865 // LogStream << endl;
866 // LogStream << "Difference (inc. cliff cell) = ";
867 // for (int n = 0; n < nRasterProfileLength; n++)
868 // {
869 // LogStream << dVDeanProfile[n] - dVProfileNow[n] << " ";
870 // }
871 // LogStream << endl;
872 // // DEBUG CODE -----------------------------------------------------
873
874 // 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?
875 if (! bJustDepositWhatWeCan && (dTotElevDiff < (dTargetSandToDepositOnThisProfile + dTargetCoarseToDepositOnThisProfile)))
876 {
877 // No it doesn't, so try again with a larger seaward offset and/or a longer Dean profile length
878 // LogStream << m_ulIter << ": bJustDepositWhatWeCan = " << bJustDepositWhatWeCan << " nSeawardOffset = " << nSeawardOffset << " dTotElevDiff = " << dTotElevDiff << endl;
879
880 continue;
881 }
882
883 // OK, now process all cells in this profile, including the first one (which is where the cliff collapse occurred)
884 for (int n = 0; n < nRasterProfileLength; n++)
885 {
886 // Are we depositing sand talus sediment on this profile?
887 if (bDoSandDepositionOnThisProfile)
888 {
889 if (bFPIsEqual(dTargetSandToDepositOnThisProfile - dSandDepositedOnThisProfile, 0.0, MASS_BALANCE_TOLERANCE))
890 bSandDepositionCompletedOnThisProfile = true;
891
892 else
893 bSandDepositionCompletedOnThisProfile = false;
894 }
895
896 // Are we depositing coarse talus sediment on this profile?
897 if (bDoCoarseDepositionOnThisProfile)
898 {
899 if (bFPIsEqual(dTargetCoarseToDepositOnThisProfile - dCoarseDepositedOnThisProfile, 0.0, MASS_BALANCE_TOLERANCE))
900 bCoarseDepositionCompletedOnThisProfile = true;
901
902 else
903 bCoarseDepositionCompletedOnThisProfile = false;
904 }
905
906 // If we have deposited enough, then break out of the loop
907 if (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile)
908 {
909 // 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;
910
911 break;
912 }
913
914 // Nope, we still have some talus left to deposit
915 int nX = VCellsUnderProfile[n].nGetX();
916 int nY = VCellsUnderProfile[n].nGetY();
917
918 // Don't allow cliff collapse talus onto intervention cells TODO 078 Is this realistic? Should it change with different types on intervention?
919 if (bIsInterventionCell(nX, nY))
920 continue;
921
922 int nTopLayer = m_pRasterGrid->m_Cell[nX][nY].nGetTopNonZeroLayerAboveBasement();
923
924 // Safety check
925 if (nTopLayer == INT_NODATA)
927
928 if (nTopLayer == NO_NONZERO_THICKNESS_LAYERS)
929 {
930 // TODO 021 Improve this
931 cerr << "All layers have zero thickness" << endl;
933 }
934
935 // Only do deposition on this cell if its elevation is below the Dean elevation
936 if (dVDeanProfile[n] > dVProfileNow[n])
937 {
938 // At this point along the profile, the Dean profile is higher than the present profile. So we can deposit some sediment on this cell
939 double dSandToDeposit = 0;
940
941 if (bDoSandDepositionOnThisProfile)
942 {
943 dSandToDeposit = (dVDeanProfile[n] - dVProfileNow[n]) * dSandProp;
944 dSandToDeposit = tMin(dSandToDeposit, (dTargetSandToDepositOnThisProfile - dSandDepositedOnThisProfile), (dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles));
945
946 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->AddSandDepth(dSandToDeposit);
947
948 // Set the changed-this-timestep switch
949 m_bUnconsChangedThisIter[nTopLayer] = true;
950
951 dSandDepositedOnThisProfile += dSandToDeposit;
952 dTotSandDepositedAllProfiles += dSandToDeposit;
953 }
954
955 double dCoarseToDeposit = 0;
956
957 if (bDoCoarseDepositionOnThisProfile)
958 {
959 dCoarseToDeposit = (dVDeanProfile[n] - dVProfileNow[n]) * dCoarseProp;
960 dCoarseToDeposit = tMin(dCoarseToDeposit, (dTargetCoarseToDepositOnThisProfile - dCoarseDepositedOnThisProfile), (dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles));
961
962 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->AddCoarseDepth(dCoarseToDeposit);
963
964 // Set the changed-this-timestep switch
965 m_bUnconsChangedThisIter[nTopLayer] = true;
966
967 dCoarseDepositedOnThisProfile += dCoarseToDeposit;
968 dTotCoarseDepositedAllProfiles += dCoarseToDeposit;
969 }
970
971 // Now update the cell's layer elevations
972 m_pRasterGrid->m_Cell[nX][nY].CalcAllLayerElevsAndD50();
973
974 // Update the cell's sea depth
975 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
976
977 // Update the cell's talus deposition, and total talus deposition, values
978 m_pRasterGrid->m_Cell[nX][nY].AddSandTalusDeposition(dSandToDeposit);
979 m_pRasterGrid->m_Cell[nX][nY].AddCoarseTalusDeposition(dCoarseToDeposit);
980
981 // And set the landform category
982 CRWCellLandform* pLandform = m_pRasterGrid->m_Cell[nX][nY].pGetLandform();
983 int nCat = pLandform->nGetLFCategory();
984
987 }
988
989 else if (dVDeanProfile[n] < dVProfileNow[n])
990 {
991 // 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?
992 double dThisLowering = dVProfileNow[n] - dVDeanProfile[n];
993
994 // Find out how much sediment we have available on this cell
995 double dExistingAvailableFine = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetFineDepth();
996 double dExistingAvailableSand = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetSandDepth();
997 double dExistingAvailableCoarse = m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->dGetCoarseDepth();
998
999 // Now partition the total lowering for this cell between the three size fractions: do this by relative erodibility
1000 int nFineWeight = (dExistingAvailableFine > 0 ? 1 : 0);
1001 int nSandWeight = (dExistingAvailableSand > 0 ? 1 : 0);
1002 int nCoarseWeight = (dExistingAvailableCoarse > 0 ? 1 : 0);
1003
1004 double dTotErodibility = (nFineWeight * m_dFineErodibilityNormalized) + (nSandWeight * m_dSandErodibilityNormalized) + (nCoarseWeight * m_dCoarseErodibilityNormalized);
1005
1006 if (nFineWeight)
1007 {
1008 // Erode some fine-sized sediment
1009 double dFineLowering = (m_dFineErodibilityNormalized * dThisLowering) / dTotErodibility;
1010
1011 // Make sure we don't get -ve amounts left on the cell
1012 double dFine = tMin(dExistingAvailableFine, dFineLowering);
1013 double dRemaining = dExistingAvailableFine - dFine;
1014
1015 // Set the value for this layer
1016 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->SetFineDepth(dRemaining);
1017
1018 // And set the changed-this-timestep switch
1019 m_bUnconsChangedThisIter[nTopLayer] = true;
1020
1021 // 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)
1023
1024 // LogStream << m_ulIter << ": FINE erosion during cliff collapse talus deposition = " << dFine * m_dCellArea << endl;
1025
1026 // Also add to the suspended load
1028 }
1029
1030 if (nSandWeight)
1031 {
1032 // Erode some sand-sized sediment
1033 double dSandLowering = (m_dSandErodibilityNormalized * dThisLowering) / dTotErodibility;
1034
1035 // Make sure we don't get -ve amounts left on the source cell
1036 double dSandToErode = tMin(dExistingAvailableSand, dSandLowering);
1037 double dRemaining = dExistingAvailableSand - dSandToErode;
1038
1039 // Set the value for this layer
1040 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->SetSandDepth(dRemaining);
1041
1042 // Set the changed-this-timestep switch
1043 m_bUnconsChangedThisIter[nTopLayer] = true;
1044
1045 // And increment the per-timestep total for sand sediment eroded during cliff collapse deposition
1047
1048 // Increase the all-profiles and this-profile sand deposition targets
1049 dTargetSandToDepositOnThisProfile += dSandToErode;
1050 dTotSandToDepositAllProfiles += dSandToErode;
1051
1052 // LogStream << m_ulIter << ": SAND erosion during cliff collapse talus deposition = " << dSandToErode * m_dCellArea << endl;
1053
1054 // Store the depth of sand sediment eroded during Dean profile deposition of sand cliff collapse talus
1055 pPolygon->AddCliffCollapseSandErodedDeanProfile(dSandToErode);
1056 }
1057
1058 if (nCoarseWeight)
1059 {
1060 // Erode some coarse-sized sediment
1061 double dCoarseLowering = (m_dCoarseErodibilityNormalized * dThisLowering) / dTotErodibility;
1062
1063 // Make sure we don't get -ve amounts left on the source cell
1064 double dCoarseToErode = tMin(dExistingAvailableCoarse, dCoarseLowering);
1065 double dRemaining = dExistingAvailableCoarse - dCoarseToErode;
1066
1067 // Set the value for this layer
1068 m_pRasterGrid->m_Cell[nX][nY].pGetLayerAboveBasement(nTopLayer)->pGetUnconsolidatedSediment()->SetCoarseDepth(dRemaining);
1069
1070 // Set the changed-this-timestep switch
1071 m_bUnconsChangedThisIter[nTopLayer] = true;
1072
1073 // And increment the per-timestep total for coarse sediment eroded during cliff collapse deposition
1075
1076 // Increase the all-profiles and this-profile coarse deposition targets
1077 dTargetCoarseToDepositOnThisProfile += dCoarseToErode;
1078 dTotCoarseToDepositAllProfiles += dCoarseToErode;
1079
1080 // LogStream << m_ulIter << ": COARSE erosion during cliff collapse talus deposition = " << dCoarseToErode * m_dCellArea << endl;
1081
1082 // Store the depth of coarse sediment eroded during Dean profile deposition of coarse cliff collapse talus
1083 pPolygon->AddCliffCollapseCoarseErodedDeanProfile(dCoarseToErode);
1084 }
1085
1086 // for this cell, recalculate the elevation of every layer
1087 m_pRasterGrid->m_Cell[nX][nY].CalcAllLayerElevsAndD50();
1088
1089 // And update the cell's sea depth
1090 m_pRasterGrid->m_Cell[nX][nY].SetSeaDepth();
1091 }
1092 } // All cells in this profile
1093
1094 // OK we have either processed all cells in this profile, or we have deposited enough talus sediment on this profile
1095 break;
1096 } while (true); // The seaward offset etc. loop
1097
1098 // 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;
1099
1100 // Have we deposited enough for this cliff collapse?
1101 if (bDoSandDepositionOnThisProfile)
1102 {
1103 if (bFPIsEqual(dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
1104 bSandDepositionCompletedOnThisProfile = true;
1105 }
1106
1107 if (bDoCoarseDepositionOnThisProfile)
1108 {
1109 if (bFPIsEqual(dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles, 0.0, MASS_BALANCE_TOLERANCE))
1110 bCoarseDepositionCompletedOnThisProfile = true;
1111 }
1112
1113 if (bSandDepositionCompletedOnThisProfile && bCoarseDepositionCompletedOnThisProfile)
1114 {
1115 // 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;
1116 }
1117 } // Process each deposition profile
1118
1119 // Safety check for sand sediment
1120 if (! bFPIsEqual((dTotSandToDepositAllProfiles - dTotSandDepositedAllProfiles), 0.0, MASS_BALANCE_TOLERANCE))
1121 LogStream << ERR << m_ulIter << ": non-zero dTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << endl;
1122
1123 // Ditto for coarse sediment
1124 if (! bFPIsEqual((dTotCoarseToDepositAllProfiles - dTotCoarseDepositedAllProfiles), 0.0, MASS_BALANCE_TOLERANCE))
1125 LogStream << ERR << m_ulIter << ": non-zero dTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << endl;
1126
1127 // Store the total depths of cliff collapse deposition for this polygon
1128 pPolygon->AddCliffCollapseUnconsSandDeposition(dTotSandDepositedAllProfiles);
1129 pPolygon->AddCliffCollapseUnconsCoarseDeposition(dTotCoarseDepositedAllProfiles);
1130
1131 // Increment this-timestep totals for cliff collapse deposition
1132 m_dThisIterUnconsSandCliffDeposition += dTotSandDepositedAllProfiles;
1133 m_dThisIterUnconsCoarseCliffDeposition += dTotCoarseDepositedAllProfiles;
1134
1135 // LogStream << endl;
1136 // LogStream << "\tdTotSandToDepositAllProfiles = " << dTotSandToDepositAllProfiles << " dTotSandDepositedAllProfiles = " << dTotSandDepositedAllProfiles << endl;
1137 // LogStream << "\tdTotCoarseToDepositAllProfiles = " << dTotCoarseToDepositAllProfiles << " dTotCoarseDepositedAllProfiles = " << dTotCoarseDepositedAllProfiles << endl;
1138 // LogStream << endl << "****************************************" << endl << endl;
1139
1140 return RTN_OK;
1141}
1142
1143//===============================================================================================================================
1145//===============================================================================================================================
1146void CSimulation::RasterizeCliffCollapseProfile(vector<CGeom2DPoint> const* pVPointsIn, vector<CGeom2DIPoint> *pVIPointsOut) const
1147{
1148 pVIPointsOut->clear();
1149
1150 // The start point of the normal is the centroid of a coastline cell. Convert from the external CRS to grid CRS
1151 double dXStart = dExtCRSXToGridX(pVPointsIn->at(0).dGetX());
1152 double dYStart = dExtCRSYToGridY(pVPointsIn->at(0).dGetY());
1153
1154 // The end point of the normal, again convert from the external CRS to grid CRS. Note too that it could be off the grid
1155 double dXEnd = dExtCRSXToGridX(pVPointsIn->at(1).dGetX());
1156 double dYEnd = dExtCRSYToGridY(pVPointsIn->at(1).dGetY());
1157
1158 // 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
1159 double dXInc = dXEnd - dXStart;
1160 double dYInc = dYEnd - dYStart;
1161 double dLength = tMax(tAbs(dXInc), tAbs(dYInc));
1162
1163 dXInc /= dLength;
1164 dYInc /= dLength;
1165
1166 double dX = dXStart;
1167 double dY = dYStart;
1168
1169 // Process each interpolated point
1170 int nLength = nRound(dLength);
1171
1172 for (int m = 0; m <= nLength; m++)
1173 {
1174 int nX = nRound(dX);
1175 int nY = nRound(dY);
1176
1177 // Make sure the interpolated point is within the raster grid (can get this kind of problem due to rounding)
1178 if (! bIsWithinValidGrid(nX, nY))
1179 KeepWithinValidGrid(nRound(dXStart), nRound(dYStart), nX, nY);
1180
1181 // This point is fine, so append it to the output vector
1182 pVIPointsOut->push_back(CGeom2DIPoint(nX, nY)); // In raster grid coordinates
1183
1184 // And increment for next time
1185 dX += dXInc;
1186 dY += dYInc;
1187 }
1188}
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:110
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:983
int m_nLogFileDetail
Definition simulation.h:591
double m_dNotchDepthAtCollapse
Definition simulation.h:973
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:834
double m_dThisIterCliffCollapseFineErodedDuringDeposition
Definition simulation.h:934
double m_dCliffTalusMinDepositionLength
Planview length of cliff deposition talus (m)
Definition simulation.h:986
double m_dCoarseErodibilityNormalized
Relative erodibility of coarse unconsolidated beach sediment, normalized.
Definition simulation.h:840
void KeepWithinValidGrid(int &, int &) const
Constrains the supplied point (in the grid CRS) to be a valid cell within the raster grid.
double m_dThisIterCliffCollapseErosionCoarseUncons
double m_dThisIterCliffCollapseErosionFineUncons
Definition simulation.h:994
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:2569
double m_dNotchBaseBelowSWL
Notch base below SWL (m)
Definition simulation.h:976
double m_dSandErodibilityNormalized
Relative erodibility of sand unconsolidated beach sediment, normalized.
Definition simulation.h:837
double m_dCliffErosionResistance
Resistance of cliff to notch erosion.
Definition simulation.h:969
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:70
int nConvertMetresToNumCells(double const) const
Given a length in m, this returns the rounded equivalent number of cells.
double m_dThisIterUnconsCoarseCliffDeposition
double m_dThisIterUnconsSandCliffDeposition
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
Definition simulation.h:990
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
Definition simulation.h:914
int nDoAllWaveEnergyToCoastLandforms(void)
Update accumulated wave energy in coastal landform objects.
double m_dThisIterCliffCollapseSandErodedDuringDeposition
Definition simulation.h:938
double m_dCliffDepositionA
Definition simulation.h:980
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
double m_dThisIterCliffCollapseErosionFineCons
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:692
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
double m_dThisIterCliffCollapseErosionSandUncons
Definition simulation.h:998
unsigned long m_ulIter
The number of the current iteration (time step)
Definition simulation.h:618
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:689
bool bIsInterventionCell(int const, int const) const
Returns true if the cell is an intervention.
Definition utils.cpp:2918
double m_dThisIterCliffCollapseCoarseErodedDuringDeposition
Definition simulation.h:942
double m_dThisIterCliffCollapseErosionCoarseCons
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:2528
vector< bool > m_bConsChangedThisIter
Contains CRWCliff definitions.
This file contains global definitions for CoastalME.
int const NO_NONZERO_THICKNESS_LAYERS
Definition cme.h:767
int const INT_NODATA
Definition cme.h:474
T tMin(T a, T b)
Definition cme.h:1251
int const RTN_ERR_CLIFFNOTCH
Definition cme.h:729
double const TOLERANCE
Definition cme.h:811
int const RTN_ERR_NO_TOP_LAYER
Definition cme.h:738
int const LF_SUBCAT_CLIFF_ON_COASTLINE
Definition cme.h:546
int const ELEV_ABOVE_SEDIMENT_TOP
Definition cme.h:766
int const LF_CAT_SEDIMENT_INPUT
Definition cme.h:536
string const ERR
Definition cme.h:890
int const LF_CAT_SEDIMENT_INPUT_SUBMERGED
Definition cme.h:537
int const MAX_SEAWARD_OFFSET_FOR_CLIFF_TALUS
Definition cme.h:479
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:489
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1284
double const MASS_BALANCE_TOLERANCE
Definition cme.h:814
T tMax(T a, T b)
Definition cme.h:1240
double const CLIFF_COLLAPSE_HEIGHT_INCREMENT
Definition cme.h:819
int const MAX_CLIFF_TALUS_LENGTH
Definition cme.h:475
int const LF_SUBCAT_DRIFT_TALUS
Definition cme.h:551
int const LF_SUBCAT_CLIFF_INLAND
Definition cme.h:547
int const RTN_ERR_CLIFF_NOT_IN_POLYGON
Definition cme.h:761
string const WARN
Definition cme.h:891
double const SEDIMENT_ELEV_TOLERANCE
Definition cme.h:813
int const CLIFF_COLLAPSE_LENGTH_INCREMENT
Definition cme.h:787
int const LOG_FILE_ALL
Definition cme.h:491
int const RTN_OK
Definition cme.h:692
double const DBL_NODATA
Definition cme.h:822
int const RTN_ERR_CLIFFDEPOSIT
Definition cme.h:730
double const DEAN_POWER
Definition cme.h:805
int const LF_CAT_SEDIMENT_INPUT_NOT_SUBMERGED
Definition cme.h:538
int const RTN_ERR_NO_SOLUTION_FOR_ENDPOINT
Definition cme.h:719
int const LF_CAT_CLIFF
Definition cme.h:541
T tAbs(T a)
Definition cme.h:1261
Contains CSimulation definitions.
int nRound(double const d)
Version of the above that returns an int.