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