CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
do_beach_sediment_movement.cpp
Go to the documentation of this file.
1
12
13/*==============================================================================================================================
14
15This file is part of CoastalME, the Coastal Modelling Environment.
16
17CoastalME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
18
19This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23==============================================================================================================================*/
24#include <assert.h>
25
26#include <cmath>
27
28#include <cfloat>
29
30#include <iostream>
31using std::cout;
32using std::endl;
33
34#include <string>
35using std::to_string;
36
37#include <algorithm>
38using std::stable_sort;
39
40#include "cme.h"
41#include "simulation.h"
42#include "coast.h"
43
44//===============================================================================================================================
46//===============================================================================================================================
47bool bPolygonAndAdjCompare(const vector<int>& nVLeft, const vector<int>& nVRight)
48{
49 // Each row (vector) of this vector-of-vectors is: // Each row (vector) of this vector-of-vectors is:
50 // 0: This-polygon global ID
51 // 1: This-polygon coast ID (in down-coast seq when sorted)
52 // 2: This-polygon down-coast (true) or up-coast (false) sediment movement
53 // 3 and subsequent: down-coast seqs of down-coast (if sediment movement is down-coast) or up-coast (if sediment movement is up-coast) adjacent polygons
54 //
55 // For safety, check that the LHS polygon has at least one adjacent polygon (it should have, apart from the bad situation where just one big polygon is created)
56 if ((nVLeft.size() >= 4) && (nVRight.size() >= 4))
57 {
58 // Polygons with off-edge sediment movement (i.e. at the grid edge) are processed last, so put LHS grid-edge polygons on the RHS
59 if (nVLeft[3] == INT_NODATA)
60 return false;
61
62 // Polygons with off-edge sediment movement (i.e. at the grid edge) are processed last, so keep RHS grid-edge polygons where they are
63 if (nVRight[3] == INT_NODATA)
64 return true;
65
66 // Now sort out polygon-to-polygon dependencies. We need to put 'target' polygons after 'source' polygons, so that the source is processed before the target. So does the LHS polygon have the RHS polygon as one of its adjacent polygons?
67 for (unsigned int n = 3; n < nVLeft.size(); n++)
68 {
69 if (nVRight[1] == nVLeft[n])
70 // It does, so keep the existing sequence
71 return true;
72 }
73
74 // Does the RHS polygon have the LHS polygon as one of its adjacent polygons?
75 for (unsigned int n = 3; n < nVRight.size(); n++)
76 {
77 if (nVLeft[1] == nVRight[n])
78 // It does, so swap them
79 return false;
80 }
81 }
82
83 bool bDownCoast = nVLeft[2];
84 if (bDownCoast)
85 // Sediment going down-coast
86 return nVLeft < nVRight;
87 else
88 // Sediment going up-coast
89 return nVLeft > nVRight;
90
91 // Default return value, should never get here
92 return true;
93}
94
95//===============================================================================================================================
97//===============================================================================================================================
99{
100 for (int nCoast = 0; nCoast < static_cast<int>(m_VCoast.size()); nCoast++)
101 {
102 int nRet;
103
105 LogStream << m_ulIter << ": Calculating unconsolidated sediment transport" << endl;
106
107 // Update the values of pre-existing unconsolidated sediment, for all three size classes, to include unconsolidated sediment derived from platform erosion, cliff collapse, and sediment input events
109
111 {
114 }
115
116 // Now route actually-eroded sand/coarse sediment to adjacent polygons, or off-grid. Sort polygons first
117 // Each row (vector) of this vector-of-vectors is:
118 // 0: This-polygon global ID
119 // 1: This-polygon coast ID (in down-coast seq when sorted)
120 // 2: This-polygon down-coast (true) or up-coast (false) sediment movement
121 // 3 and subsequent: down-coast seqs of down-coast (if sediment movement is down-coast) or up-coast (if sediment movement is up-coast) adjacent polygons
122 vector<vector<int> > nVVPolyAndAdjacent;
123 for (int nn = 0; nn < m_VCoast[nCoast].nGetNumPolygons(); nn++)
124 {
125 CGeomCoastPolygon const* pPolygon = m_VCoast[nCoast].pGetPolygon(nn);
126 vector<int> nVPolyAndAdj;
127
128 // The first [0] nVPolyAndAdj array item is the polygon's global ID
129 nVPolyAndAdj.push_back(pPolygon->nGetGlobalID());
130
131 // The second [1] nVPolyAndAdj array item is the polygon's down-coast ID
132 nVPolyAndAdj.push_back(pPolygon->nGetCoastID());
133
134 if (pPolygon->bDownCoastThisIter())
135 {
136 // Sediment is leaving this polygon in a down-coast direction: so set this as the third [2] nVPolyAndAdj array item
137 nVPolyAndAdj.push_back(true);
138
139 // Fourth [3] and subsequent nVPolyAndAdj array items are the down-coast seqs of adjacent down-coast polygons
140 for (int nAdj = 0; nAdj < pPolygon->nGetNumDownCoastAdjacentPolygons(); nAdj++)
141 {
142 // Save the coast ID of each down-coast adjacent polygon
143 int nAdjPolyID = pPolygon->nGetDownCoastAdjacentPolygon(nAdj);
144 nVPolyAndAdj.push_back(nAdjPolyID);
145 }
146 }
147 else
148 {
149 // Sediment is leaving this polygon in an up-coast direction: so set this as the third [2] nVPolyAndAdj array item
150 nVPolyAndAdj.push_back(false);
151
152 // Fourth [3] and susequent nVPolyAndAdj array items are the down-coast IDs of adjacent up-coast polygons
153 for (int nAdj = 0; nAdj < pPolygon->nGetNumUpCoastAdjacentPolygons(); nAdj++)
154 {
155 // Save the coast ID of each up-coast adjacent polygon
156 int nAdjPolyID = pPolygon->nGetUpCoastAdjacentPolygon(nAdj);
157 nVPolyAndAdj.push_back(nAdjPolyID);
158 }
159 }
160
161 // Save this 'row'
162 nVVPolyAndAdjacent.push_back(nVPolyAndAdj);
163 }
164
166 WritePolygonUnsortedSequence(nCoast, nVVPolyAndAdjacent);
167
168 // OK, now sort the array using bPolygonAndAdjCompare(), so that 'target' polygons are processed after 'source' polygons
169 stable_sort(nVVPolyAndAdjacent.begin(), nVVPolyAndAdjacent.end(), bPolygonAndAdjCompare);
170
171 // And check for circularities i.e. where poly X -> poly Y -> poly X. Note that we only look for two-way circularities. i.e. we ignore poly A -> poly B -> Poly C -> poly A patterns. These are probably pretty rare, however
172 vector<int> VnSourcePolyDownCoastSeq;
173 for (int n = 0; n < static_cast<int>(nVVPolyAndAdjacent.size()); n++)
174 {
175 for (int m = 0; m < static_cast<int>(nVVPolyAndAdjacent[n].size()); m++)
176 {
177 if (m == 1)
178 VnSourcePolyDownCoastSeq.push_back(nVVPolyAndAdjacent[n][m]); // This-polygon down-coast seq
179
180 else if (m >= 3)
181 {
182 // Check for circularities
183 vector<int>::iterator it = find(VnSourcePolyDownCoastSeq.begin(), VnSourcePolyDownCoastSeq.end(), nVVPolyAndAdjacent[n][m]);
184 if (it != VnSourcePolyDownCoastSeq.end())
185 {
186 // Uh-oh: this polygon is in the list of previously-processed source polygons. So store the coast ID numbers of the polygons with circularity
187 CGeomCoastPolygon* pPoly = m_VCoast[nCoast].pGetPolygon(nVVPolyAndAdjacent[n][1]);
188 pPoly->AddCircularity(*it);
189
190 pPoly = m_VCoast[nCoast].pGetPolygon(*it);
191 pPoly->AddCircularity(nVVPolyAndAdjacent[n][m]);
192 }
193 }
194 }
195 }
196
198 WritePolygonSortedSequence(nCoast, nVVPolyAndAdjacent);
199
200 int nNumPolygons = m_VCoast[nCoast].nGetNumPolygons();
201
202 // Now process all polygons and do the actual (supply-limited) unconsolidated sediment movement
203 for (int n = 0; n < nNumPolygons; n++)
204 {
205 int nPolygon = nVVPolyAndAdjacent[n][1];
206 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nPolygon);
207
208 // // DEBUG CODE =====================
209 // int nUpCoastProfile = pPolygon->nGetUpCoastProfile();
210 // CGeomProfile* pUpCoastProfile = m_VCoast[nCoast].pGetProfile(nUpCoastProfile);
211 // int nDownCoastProfile = pPolygon->nGetDownCoastProfile();
212 // CGeomProfile* pDownCoastProfile = m_VCoast[nCoast].pGetProfile(nDownCoastProfile);
213 // int nNumUpCoastCell = pUpCoastProfile->nGetNumCellsInProfile();
214 // int nNumDownCoastCell = pDownCoastProfile->nGetNumCellsInProfile();
215 // LogStream << "pUpCoastProfile->nGetNumCellsInProfile() = " << nNumUpCoastCell << " pDownCoastProfile->nGetNumCellsInProfile() = " << nNumDownCoastCell << endl;
216 // // DEBUG CODE =====================
217
218
219 // // DEBUG CODE ============================================================================================================================================
220 // // Get total depths of sand consolidated and unconsolidated for every cell
221 // if (m_ulIter == 5)
222 // {
223 // double dTmpSandUncons = 0;
224 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
225 // {
226 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
227 // {
228 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
229 // }
230 // }
231 //
232 // LogStream << endl;
233 // LogStream << "*****************************" << endl;
234 // LogStream << m_ulIter << ": before beach movement on nPoly = " << nPoly << " TOTAL UNCONSOLIDATED SAND ON ALL CELLS = " << dTmpSandUncons * m_dCellArea << endl;
235 // }
236 // // DEBUG CODE ============================================================================================================================================
237
238 // Do deposition first: does this polygon have coarse deposition?
239 double dCoarseDepositionTarget = pPolygon->dGetToDoBeachDepositionUnconsCoarse();
240
241 if (dCoarseDepositionTarget > 0)
242 {
243 // It does, first tho', if we have some coarse sediment which we were unable to deposit on the previously-processed polygon (which could be the last-processed polygon of the previous timestep), then add this in
245 {
246 // We had some coarse unconsolidated sediment which we were unable to deoosit on the last polygon (which could have been the last polygon of the previous iteration). So add it to the total to be deposited here
248 LogStream << m_ulIter << ": nPoly = " << nPolygon << " dCoarseDepositionTarget was = " << dCoarseDepositionTarget * m_dCellArea << " adding m_dDepositionCoarseDiff = " << m_dDepositionCoarseDiff * m_dCellArea;
249
250 dCoarseDepositionTarget += m_dDepositionCoarseDiff;
252
254 LogStream << " dCoarseDepositionTarget now = " << dCoarseDepositionTarget << endl;
255 }
256
257 // OK, do deposition of coarse sediment: calculate a net increase in depth of coarse-sized unconsolidated sediment on the cells within the polygon. Note that some cells may decrease in elevation (i.e. have some coarse-sized sediment erosion) however
258 double dCoarseDeposited = 0;
259 nRet = nDoUnconsDepositionOnPolygon(nCoast, pPolygon, TEXTURE_COARSE, dCoarseDepositionTarget, dCoarseDeposited);
260 if (nRet != RTN_OK)
261 return nRet;
262
263 double dCoarseNotDeposited = dCoarseDepositionTarget - dCoarseDeposited;
264 if (dCoarseNotDeposited > 0)
265 {
266 m_dDepositionCoarseDiff += dCoarseNotDeposited;
267 }
268 }
269
270 // Does this polygon have sand deposition?
271 double dSandDepositionTarget = pPolygon->dGetToDoBeachDepositionUnconsSand();
272
273 if (dSandDepositionTarget > 0)
274 {
275 // It does, first tho', if we have some sand sediment which we were unable to deposit on the previously-processed polygon (which could be the last-processed polygon of the previous timestep), then add this in
277 {
278 // We had some sand unconsolidated sediment which we were unable to deoosit on the last polygon (which could have been the last polygon of the previous iteration). So add it to the total to be deposited here
280 LogStream << m_ulIter << ": nPolygon = " << nPolygon << " dSandDepositionTarget was = " << dSandDepositionTarget * m_dCellArea << " adding m_dDepositionSandDiff = " << m_dDepositionSandDiff * m_dCellArea;
281
282 dSandDepositionTarget += m_dDepositionSandDiff;
284
286 LogStream << " dSandDepositionTarget now = " << dSandDepositionTarget << endl;
287 }
288
289 // Now do deposition of sand sediment: calculate a net increase in depth of sand-sized unconsolidated sediment on the cells within the polygon. Note that some cells may decrease in elevation (i.e. have some sand-sized sediment erosion) however
290 double dSandDeposited = 0;
291 nRet = nDoUnconsDepositionOnPolygon(nCoast, pPolygon, TEXTURE_SAND, dSandDepositionTarget, dSandDeposited);
292 if (nRet != RTN_OK)
293 return nRet;
294
295 double dSandNotDeposited = dSandDepositionTarget - dSandDeposited;
296 if (dSandNotDeposited > 0)
297 {
298 m_dDepositionSandDiff += dSandNotDeposited;
299 }
300
301 // // DEBUG CODE #####################
302 // if (m_ulIter == 5)
303 // {
304 // LogStream << m_ulIter << ": after sand deposition on nPoly = " << nPoly << " dSandDepositionTarget = " << dSandDepositionTarget * m_dCellArea << " dSandDeposited = " << dSandDeposited * m_dCellArea << " dSandNotDeposited = " << dSandNotDeposited * m_dCellArea << " m_dDepositionSandDiff = " << m_dDepositionSandDiff * m_dCellArea << endl;
305 //
306 // double dTmpSandUncons = 0;
307 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
308 // {
309 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
310 // {
311 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
312 // }
313 // }
314 //
315 // LogStream << m_ulIter << ": after sand deposition on nPoly = " << nPoly << " TOTAL UNCONSOLIDATED SAND ON ALL CELLS = " << dTmpSandUncons * m_dCellArea << endl;
316 // }
317 // // DEBUG CODE #####################
318 }
319
320 // Now do erosion
321 double dPotentialErosion = -pPolygon->dGetPotentialErosion();
322 if (dPotentialErosion > 0)
323 {
324 // There is some erosion on this polygon: process this in the sequence fine, sand, coarse. Is there any fine sediment on this polygon?
325 double dExistingUnconsFine = pPolygon->dGetPreExistingUnconsFine();
326
327 if (dExistingUnconsFine > 0)
328 {
329 // Yes there is, so crudely partition this potential value for this size class by erodibility, the result will almost always be much greater than actual (supply limited) erosion
330 double dFinePotentialErosion = dPotentialErosion * m_dFineErodibilityNormalized;
331
332 // Now reduce this further, by considering the total depth of fine sediment on the polygon
333 double dFineErosionTarget = tMin(dFinePotentialErosion, dExistingUnconsFine);
334
335 // OK, do the supply-limited erosion of fine sediment
336 double dFineEroded = 0;
337 nRet = nDoUnconsErosionOnPolygon(nCoast, pPolygon, TEXTURE_FINE, dFineErosionTarget, dFineEroded);
338 if (nRet != RTN_OK)
339 return nRet;
340
341 if (dFineEroded > 0)
342 {
343 // We eroded some fine sediment, so add to the this-iteration total. Note that total this gets added in to the suspended load elsewhere, so no need to do it here
344 m_dThisIterBeachErosionFine += dFineEroded;
345
346 // Also add to the suspended load
348
349 // Store the amount of unconsolidated fine beach sediment eroded for this polygon
350 pPolygon->SetBeachErosionUnconsFine(-dFineEroded);
351 }
352 }
353
354 // Is there any sand-sized sediment on this polygon?
355 double dExistingUnconsSand = pPolygon->dGetPreExistingUnconsSand();
356 double dSandEroded = 0;
357 if (dExistingUnconsSand > 0)
358 {
359 // There is: so crudely partition this potential value for this size class by erodibility, the result will almost always be much greater than actual (supply limited) erosion
360 double dSandPotentialErosion = dPotentialErosion * m_dSandErodibilityNormalized;
361
362 // Now reduce this further, by considering the total depth of sand sediment on the polygon
363 double dSandErosionTarget = tMin(dSandPotentialErosion, dExistingUnconsSand);
364
365 // OK, do the supply-limited erosion of sand sediment
366 nRet = nDoUnconsErosionOnPolygon(nCoast, pPolygon, TEXTURE_SAND, dSandErosionTarget, dSandEroded);
367 if (nRet != RTN_OK)
368 return nRet;
369
370 if (dSandEroded > 0)
371 {
372 // We eroded some sand sediment, so add to the this-iteration total
373 m_dThisIterBeachErosionSand += dSandEroded;
374
375 // Store the amount eroded for this polygon
376 pPolygon->SetBeachErosionUnconsSand(-dSandEroded);
377 }
378
379 // // DEBUG CODE #####################
380 // if (m_ulIter == 5)
381 // {
382 // LogStream << m_ulIter << ": nPoly = " << nPoly << " dSandErosionTarget = " << dSandErosionTarget * m_dCellArea << " m_dDepositionSandDiff = " << m_dDepositionSandDiff * m_dCellArea << " dSandEroded = " << dSandEroded * m_dCellArea << " m_dThisIterBeachErosionSand = " << m_dThisIterBeachErosionSand * m_dCellArea << endl;
383 //
384 // double dTmpSandUncons = 0;
385 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
386 // {
387 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
388 // {
389 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
390 // }
391 // }
392 //
393 // LogStream << m_ulIter << ": after sand erosion on nPoly = " << nPoly << " TOTAL UNCONSOLIDATED SAND ON ALL CELLS = " << dTmpSandUncons * m_dCellArea << endl;
394 // }
395 // // DEBUG CODE #####################
396 }
397
398 // Is there any coarse sediment on this polygon?
399 double dExistingUnconsCoarse = pPolygon->dGetPreExistingUnconsCoarse();
400 double dCoarseEroded = 0;
401 if (dExistingUnconsCoarse > 0)
402 {
403 // There is: so crudely partition this potential value for this size class by erodibility, the result will almost always be much greater than actual (supply limited) erosion
404 double dCoarsePotentialErosion = dPotentialErosion * m_dCoarseErodibilityNormalized;
405
406 // Now reduce this further, by considering the total depth of coarse sediment on the polygon
407 double dCoarseErosionTarget = tMin(dCoarsePotentialErosion, dExistingUnconsCoarse);
408
409 // OK, do the supply-limited erosion of coarse sediment
410 nRet = nDoUnconsErosionOnPolygon(nCoast, pPolygon, TEXTURE_COARSE, dCoarseErosionTarget, dCoarseEroded);
411 if (nRet != RTN_OK)
412 return nRet;
413
414 if (dCoarseEroded > 0)
415 {
416 // We eroded some coarse sediment, so add to the this-iteration toal
417 m_dThisIterBeachErosionCoarse += dCoarseEroded;
418
419 // Store the amount eroded for this polygon
420 pPolygon->SetBeachErosionUnconsCoarse(-dCoarseEroded);
421 }
422 }
423
424 // OK we now have the actual values of sediment eroded from this polygon, so next determine where this eroded sand and coarse sediment goes (have to consider fine sediment too, because this goes off-grid on grid-edge polygons). Only do this if some sand or coarse was eroded on this polygon
425 if ((dSandEroded + dCoarseEroded) > 0)
426 {
427 if (pPolygon->bDownCoastThisIter())
428 {
429 // Moving eroded sediment down-coast
430 int nNumAdjPoly = pPolygon->nGetNumDownCoastAdjacentPolygons();
431 for (int nn = 0; nn < nNumAdjPoly; nn++)
432 {
433 int nAdjPoly = pPolygon->nGetDownCoastAdjacentPolygon(nn);
434
435 // if (m_nLogFileDetail >= LOG_FILE_MIDDLE_DETAIL)
436 // LogStream << m_ulIter << ": polygon " << nPoly << " moves sediment down-coast to polygon " << nAdjPoly << endl;
437
438 if (nAdjPoly == INT_NODATA)
439 {
440 // Sediment is leaving the grid
441 if (pPolygon->bIsCoastStartPolygon())
442 {
443 // Error: uncons sediment movement is down-coast and off-edge, but this polygon is at the up-coast end of the coastline
445 LogStream << m_ulIter << ": " << ERR << "in sediment export. Unconsolidated sediment movement is DOWN-COAST, and sediment is leaving the grid, but polygon " << nPolygon << " is at the up-coast end of the coastline. This will result in mass balance problems." << endl;
446 }
447 else if (pPolygon->bIsCoastEndPolygon())
448 {
449 // This is the polygon at the down-coast end of the coastline, and uncons sediment movement is down-coast. Decide what to do based on the user setting m_nUnconsSedimentHandlingAtGridEdges
451 {
452 // Closed grid edges: no uncons sediment moves off-grid, nothing is removed from this polygon, so cannot adjust sediment export
454 LogStream << m_ulIter << ": when adjusting sediment export, polygon " << nPolygon << " is at the down-coast end of the coastline, and actual sediment movement is DOWN-COAST. Since grid edges are closed, no sand or coarse unconsolidated sediment goes off-grid so cannot adjust sediment export. This will result in mass balance problems." << endl;
455 }
456
458 {
459 // Open grid edges, so this sediment goes off-grid
460 m_dThisIterLeftGridUnconsSand += dSandEroded;
461 m_dThisIterLeftGridUnconsCoarse += dCoarseEroded;
462
463 // // DEBUG CODE ##################
464 // if (m_ulIter == 5)
465 // {
466 // LogStream << m_ulIter << ": nPoly = " << nPoly << " LOST FROM GRID = " << dSandEroded * m_dCellArea << endl;
467 // }
468 // // DEBUG CODE ##################
469 }
470
472 {
473 // Re-circulating grid edges, so adjust the sediment exported to the polygon at the up-coast end of this coastline
474 int nOtherEndPoly = 0;
475 CGeomCoastPolygon* pOtherEndPoly = m_VCoast[nCoast].pGetPolygon(nOtherEndPoly);
476
477 if (dSandEroded > 0)
478 {
479 // Add to the still-to-do total of unconsolidated sand to be deposited on the polygon at the up-coast end of this coastline
480 pOtherEndPoly->AddToDoBeachDepositionUnconsSand(dSandEroded);
481 }
482
483 if (dCoarseEroded > 0)
484 {
485 // Add to the still-to-do total of unconsolidated coarse sediment to be deposited on the polygon at the up-coast end of this coastline
486 pOtherEndPoly->AddToDoBeachDepositionUnconsCoarse(dCoarseEroded);
487 }
488 }
489 }
490 }
491 else
492 {
493 // This polygon is not at the grid edge
494 CGeomCoastPolygon* pAdjPolygon = m_VCoast[nCoast].pGetPolygon(nAdjPoly);
495 double dBoundaryShare = pPolygon->dGetDownCoastAdjacentPolygonBoundaryShare(nn);
496
497 if (dSandEroded > 0)
498 {
499 // if (m_ulIter == 5)
500 // LogStream << m_ulIter << ": B polygon not at grid edge nPoly = " << nPoly << " nAdjPoly = " << nAdjPoly << ", dGetToDoBeachDepositionUnconsSand() on nAdjPoly is = " << pAdjPolygon->dGetToDoBeachDepositionUnconsSand() * m_dCellArea << endl;
501
502 // Add to the still-to-do total of unconsolidated sand to be deposited on the adjacent polygon
503 pAdjPolygon->AddToDoBeachDepositionUnconsSand(dSandEroded * dBoundaryShare);
504
505 // if (m_ulIter == 5)
506 // LogStream << m_ulIter << ": B after nAdjPoly = " << nAdjPoly << " AddToDoBeachDepositionUnconsSand(" << dSandEroded * dBoundaryShare * m_dCellArea << ") dGetToDoBeachDepositionUnconsSand() now = " << pAdjPolygon->dGetToDoBeachDepositionUnconsSand() * m_dCellArea << endl;
507 }
508
509 if (dCoarseEroded > 0)
510 {
511 // if (m_nLogFileDetail >= LOG_FILE_ALL)
512 // LogStream << m_ulIter << ": polygon = " << nPoly << " adjacent polygon = " << nAdjPoly << ", beach deposition 1 of uncons coarse was = " << pAdjPolygon->dGetToDoBeachDepositionUnconsCoarse() * m_dCellArea;
513
514 // Add to the still-to-do total of unconsolidated coarse sediment to be deposited on the adjacent polygon
515 pAdjPolygon->AddToDoBeachDepositionUnconsCoarse(dCoarseEroded * dBoundaryShare);
516
517 // if (m_nLogFileDetail >= LOG_FILE_ALL)
518 // LogStream << " after AddToDoBeachDepositionUnconsCoarse(" << dCoarseEroded * dBoundaryShare << ") beach deposition 1 of uncons coarse now = " << pAdjPolygon->dGetToDoBeachDepositionUnconsCoarse() * m_dCellArea << endl;
519 }
520 }
521 }
522
523 // if (m_nLogFileDetail >= LOG_FILE_ALL)
524 // LogStream << m_ulIter << ": 1 uncons sand eroded = " << dSandEroded * m_dCellArea << " 1 uncons coarse eroded = " << dCoarseEroded * m_dCellArea << endl;
525 }
526 else
527 {
528 // Moving eroded sediment up-coast
529 int nNumAdjPoly = pPolygon->nGetNumUpCoastAdjacentPolygons();
530 for (int nn = 0; nn < nNumAdjPoly; nn++)
531 {
532 int nAdjPoly = pPolygon->nGetUpCoastAdjacentPolygon(nn);
533 // if (m_nLogFileDetail >= LOG_FILE_ALL)
534 // LogStream << m_ulIter << ": polygon " << nPoly << " moves sediment up-coast to polygon " << nAdjPoly << endl;
535
536 if (nAdjPoly == INT_NODATA)
537 {
538 // Sediment is leaving the grid
539 if (pPolygon->bIsCoastEndPolygon())
540 {
541 // Error: uncons sediment movement is down-coast and off-edge, but this polygon is at the up-coast end of the coastline
543 LogStream << m_ulIter << ": " << ERR << "in sediment export. Unconsolidated sediment movement is UP-COAST, and sediment is leaving the grid, but polygon " << nPolygon << " is at the down-coast end of the coastline. This will result in mass balance problems." << endl;
544
545 }
546 else if (pPolygon->bIsCoastStartPolygon())
547 {
548 // This is the polygon at the up-coast end of the coastline, and uncons sediment movement is up-coast. Decide what to do based on the user setting m_nUnconsSedimentHandlingAtGridEdges
550 {
551 // Closed grid edges: no uncons sediment moves off-grid, nothing is removed from this polygon, so cannot adjust sediment export
553 LogStream << m_ulIter << ": when adjusting sediment export, polygon " << nPolygon << " is at the up-coast end of the coastline, and actual sediment movement is UP-COAST. Since grid edges are closed, no sand or coarse unconsolidated sediment goes off-grid so cannot adjust sediment export" << endl;
554 }
555
557 {
558 // Open grid edges, so this sediment goes off-grid
559 m_dThisIterLeftGridUnconsSand += dSandEroded;
560 m_dThisIterLeftGridUnconsCoarse += dCoarseEroded;
561 }
562
564 {
565 // Re-circulating grid edges, so adjust the sediment exported to the polygon at the up-coast end of this coastline TODO 016 Check whether this causes mass balance problems, depending on the sequence of polygon processing
566 int nOtherEndPoly = 0;
567 CGeomCoastPolygon* pOtherEndPoly = m_VCoast[nCoast].pGetPolygon(nOtherEndPoly);
568
569 if (dSandEroded > 0)
570 {
571 // Add to the still-to-do total of unconsolidated sand to be deposited on the polygon at the up-coast end of this coastline
572 pOtherEndPoly->AddToDoBeachDepositionUnconsSand(dSandEroded);
573 }
574
575 if (dCoarseEroded > 0)
576 {
577 // Add to the still-to-do total of unconsolidated coarse sediment to be deposited on the polygon at the up-coast end of this coastline
578 pOtherEndPoly->AddToDoBeachDepositionUnconsCoarse(dCoarseEroded);
579 }
580 }
581 }
582 }
583 else
584 {
585 // This polygon is not at the grid edge
586 CGeomCoastPolygon* pAdjPolygon = m_VCoast[nCoast].pGetPolygon(nAdjPoly);
587 double dBoundaryShare = pPolygon->dGetUpCoastAdjacentPolygonBoundaryShare(nn);
588
589 if (dSandEroded > 0)
590 {
591 // if (m_ulIter == 5)
592 // LogStream << m_ulIter << ": A polygon not at grid edge nPoly = " << nPoly << " nAdjPoly = " << nAdjPoly << ", dGetToDoBeachDepositionUnconsSand() on nAdjPoly is = " << pAdjPolygon->dGetToDoBeachDepositionUnconsSand() * m_dCellArea << endl;
593
594 // Add to the still-to-do total of unconsolidated sand to be deposited on the the adjacent polygon
595 pAdjPolygon->AddToDoBeachDepositionUnconsSand(dSandEroded * dBoundaryShare);
596
597 // if (m_ulIter == 5)
598 // LogStream << m_ulIter << ": A after nAdjPoly = " << nAdjPoly << " AddToDoBeachDepositionUnconsSand(" << dSandEroded * dBoundaryShare * m_dCellArea << ") dGetToDoBeachDepositionUnconsSand() now = " << pAdjPolygon->dGetToDoBeachDepositionUnconsSand() * m_dCellArea << endl;
599 }
600
601 if (dCoarseEroded > 0)
602 {
603 // if (m_ulIter == 5)
604 // LogStream << m_ulIter << ": polygon not at grid edge nPoly = " << nPoly << " nAdjPoly = " << nAdjPoly << ", beach deposition of uncons coarse was = " << pAdjPolygon->dGetToDoBeachDepositionUnconsCoarse() * m_dCellArea << endl;
605
606 // Add to the still-to-do total of unconsolidated coarse sediment to be deposited on the adjacent polygon
607 pAdjPolygon->AddToDoBeachDepositionUnconsCoarse(+dCoarseEroded * dBoundaryShare);
608
609 // if (m_ulIter == 5)
610 // LogStream << " After AddToDoBeachDepositionUnconsCoarse(" << dCoarseEroded * dBoundaryShare << ") uncons coarse now = " << pAdjPolygon->dGetToDoBeachDepositionUnconsCoarse() * m_dCellArea << endl;
611 }
612 }
613 }
614 }
615 }
616
617 // if (m_nLogFileDetail >= LOG_FILE_ALL)
618 // LogStream << m_ulIter << ": sand eroded on poly = " << dSandEroded * m_dCellArea << " coarse eroded on poly = " << dCoarseEroded * m_dCellArea << endl;
619
620 } // if (dPotentialErosion > 0)
621
622 // // DEBUG CODE ============================================================================================================================================
623 // // Get total depths of unconsolidated sand for every cell
624 // if (m_ulIter == 5)
625 // {
626 // double dTmpSandUncons = 0;
627 // for (int nX1 = 0; nX1 < m_nXGridSize; nX1++)
628 // {
629 // for (int nY1 = 0; nY1 < m_nYGridSize; nY1++)
630 // {
631 // dTmpSandUncons += m_pRasterGrid->m_Cell[nX1][nY1].dGetTotUnconsSand();
632 // }
633 // }
634 //
635 // LogStream << endl;
636 // LogStream << m_ulIter << ": TOTAL UNCONSOLIDATED SAND ON ALL CELLS after beach movement on nPoly = " << nPoly << " dTmpSandUncons = " << dTmpSandUncons * m_dCellArea << " (dTmpSandUncons - m_dStartIterUnconsSandAllCells) = " << (dTmpSandUncons - m_dStartIterUnconsSandAllCells) * m_dCellArea << endl;
637 //
638 // // Now get the total in all still-to-do fields of all polygons
639 // double dToDoTot = 0;
640 //
641 // for (int nn = 0; nn < nPolygons; nn++)
642 // {
643 // CGeomCoastPolygon* pThisPolygon = m_VCoast[nCoast].pGetPolygon(nn);
644 // dToDoTot += pThisPolygon->dGetToDoBeachDepositionUnconsSand();
645 // }
646 //
647 // LogStream << endl << m_ulIter << ": dToDoTot = " << dToDoTot * m_dCellArea << endl;
648 // LogStream << m_ulIter << ": dTmpSandUncons + dToDoTot = " << (dTmpSandUncons + dToDoTot) * m_dCellArea << endl << endl;
649 //
650 // LogStream << m_ulIter << ": m_dThisIterLeftGridUnconsSand = " << m_dThisIterLeftGridUnconsSand * m_dCellArea << endl;
651 //
652 // LogStream << "*****************************" << endl;
653 // }
654 // // DEBUG CODE ============================================================================================================================================
655
656 } // for (int n = 0; n < nNumPolygons; n++)
657
658 // OK we have processed all polygons, But if there are adjacent-polygon circularities (i.e. Polygon A -> Polygon B -> Polygon A) then we may have some still-to-do deposition on at least one polygon. So look through all polygons and check their still-to-do lists
659 int nPolygons = m_VCoast[nCoast].nGetNumPolygons();
660// for (int nn = 0; nn < nPolygons; nn++)
661 for (int nn = nPolygons-1; nn >= 0; nn--)
662 {
663 int nThisPoly = nVVPolyAndAdjacent[nn][1];
664 CGeomCoastPolygon* pThisPolygon = m_VCoast[nCoast].pGetPolygon(nThisPoly);
665
666 double dSandToDepositOnPoly = pThisPolygon->dGetToDoBeachDepositionUnconsSand();
667 if (dSandToDepositOnPoly > 0)
668 {
669 // There is some still-to-do deposition of sand sediment on this polygon: calculate a net increase in depth of sand-sized unconsolidated sediment on the cells within the polygon. Note that some cells may decrease in elevation (i.e. have some sand-sized sediment erosion) however
670 double dSandDeposited = 0;
671 nRet = nDoUnconsDepositionOnPolygon(nCoast, pThisPolygon, TEXTURE_SAND, dSandToDepositOnPoly, dSandDeposited);
672 if (nRet != RTN_OK)
673 return nRet;
674
675 double dSandNotDeposited = dSandToDepositOnPoly - dSandDeposited;
676 if (dSandNotDeposited > 0)
677 m_dDepositionSandDiff += dSandNotDeposited;
678
680 LogStream << m_ulIter << ": re-processing nThisPoly = " << nThisPoly << " dSandDeposited = " << dSandDeposited * m_dCellArea << " dSandNotDeposited = " << dSandNotDeposited * m_dCellArea << " m_dDepositionSandDiff = " << m_dDepositionSandDiff * m_dCellArea << endl;
681 }
682
683 double dCoarseToDepositOnPoly = pThisPolygon->dGetToDoBeachDepositionUnconsCoarse();
684 if (dCoarseToDepositOnPoly > 0)
685 {
686 // There is some still-to-do deposition of coarse sediment on this polygon: calculate a net increase in depth of coarse-sized unconsolidated sediment on the cells within the polygon. Note that some cells may decrease in elevation (i.e. have some coarse-sized sediment erosion) however
687 double dCoarseDeposited = 0;
688 nRet = nDoUnconsDepositionOnPolygon(nCoast, pThisPolygon, TEXTURE_COARSE, dCoarseToDepositOnPoly, dCoarseDeposited);
689 if (nRet != RTN_OK)
690 return nRet;
691
692 double dCoarseNotDeposited = dCoarseToDepositOnPoly - dCoarseDeposited;
693 if (dCoarseNotDeposited > 0)
694 m_dDepositionCoarseDiff += dCoarseNotDeposited;
695
697 LogStream << m_ulIter << ": re-processing nThisPoly = " << nThisPoly << " dCoarseDeposited = " << dCoarseDeposited * m_dCellArea << " dCoarseNotDeposited = " << dCoarseNotDeposited * m_dCellArea << " m_dDepositionCoarseDiff = " << m_dDepositionCoarseDiff * m_dCellArea << endl;
698 }
699 }
700
702 WritePolygonActualMovement(nCoast, nVVPolyAndAdjacent);
703 }
704
705 return RTN_OK;
706}
707
708//===============================================================================================================================
710//===============================================================================================================================
712{
713 int nNumPolygons = m_VCoast[nCoast].nGetNumPolygons();
714
715 for (int nPoly = 0; nPoly < nNumPolygons; nPoly++)
716 {
717 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
718
719 // Only include unconsolidated fine sediment from sediment input events, don't include any unconsolidated fine sediment from platform erosion and cliff collapse since these have gone to suspension
720 double dFine = pPolygon->dGetSedimentInputUnconsFine();
721 pPolygon->SetPreExistingUnconsFine(dFine);
722
723 // Include unconsolidated sand sediment derived from platform erosion, cliff collapse, and sediment input events
725 pPolygon->SetPreExistingUnconsSand(dSand);
726
727 // Include unconsolidated coarse sediment derived from platform erosion, cliff collapse, and sediment input events
729 pPolygon->SetPreExistingUnconsCoarse(dCoarse);
730 }
731}
Geometry class used for coast polygon objects.
bool bIsCoastStartPolygon(void) const
Is this polygon the coast-start polygon?
double dGetSedimentInputUnconsSand(void) const
Get the value of sand sediment on the polygon derived from sediment input events(s)
double dGetPotentialErosion(void) const
Returns this timestep's total change in depth of unconsolidated sediment (all size classes) due to be...
double dGetCliffCollapseUnconsSandDeposition(void) const
Get the this-iteration total of unconsolidated sand sediment deposited from cliff collapse on this po...
bool bIsCoastEndPolygon(void) const
Is this polygon the coast-end polygon?
void SetPreExistingUnconsFine(double const)
Set the value of pre-existing unconsolidated fine sediment stored on this polygon.
double dGetPreExistingUnconsSand(void) const
Get the value of pre-existing unconsolidated sand sediment stored on this polygon.
void AddToDoBeachDepositionUnconsSand(double const)
Adds a depth (in m) of sand-sized unconsolidated sediment to this timestep's still-to-do deposition o...
void SetPreExistingUnconsSand(double const)
Set the value of pre-existing unconsolidated sand sediment stored on this polygon.
double dGetUpCoastAdjacentPolygonBoundaryShare(int const) const
Gets the boundary shares for all up-coast adjacent polygons.
int nGetUpCoastAdjacentPolygon(int const) const
Gets a single up-coast adjacent polygon.
double dGetPlatformErosionUnconsCoarse(void) const
Get the this-iteration total of unconsolidated coarse sediment derived from shore platform erosion on...
double dGetSedimentInputUnconsFine(void) const
Get the value of fine sediment on the polygon derived from sediment input events(s)
int nGetNumUpCoastAdjacentPolygons(void) const
Gets all up-coast adjacent polygons.
int nGetGlobalID(void) const
Get the global ID.
double dGetCliffCollapseUnconsCoarseDeposition(void) const
Get the this-iteration total of unconsolidated coarse sediment deposited from cliff collapse on this ...
double dGetDownCoastAdjacentPolygonBoundaryShare(int const) const
Gets the boundary shares for all down-coast adjacent polygons.
void SetBeachErosionUnconsFine(double const)
Sets a value (must be < 0) for this timestep's erosion of fine unconsolidated sediment (beach redistr...
double dGetPreExistingUnconsFine(void) const
Get the value of pre-existing unconsolidated fine sediment stored on this polygon.
void AddToDoBeachDepositionUnconsCoarse(double const)
Adds a depth (in m) of coarse unconsolidated sediment to this timestep's still-to-do deposition of un...
int nGetDownCoastAdjacentPolygon(int const) const
Gets a single down-coast adjacent polygon.
int nGetNumDownCoastAdjacentPolygons(void) const
Gets all down-coast adjacent polygons.
double dGetToDoBeachDepositionUnconsSand(void) const
Returns this timestep's still-to-do deposition of sand-sized unconsolidated sediment (from beach redi...
void SetPreExistingUnconsCoarse(double const)
Set the value of pre-existing unconsolidated coarse sediment stored on this polygon.
double dGetPlatformErosionUnconsSand(void) const
Get the this-iteration total of unconsolidated sand sediment derived from shore platform erosion on t...
double dGetPreExistingUnconsCoarse(void) const
Get the value of pre-existing unconsolidated coarse sediment stored on this polygon.
void SetBeachErosionUnconsSand(double const)
Sets a value (must be < 0) for this timestep's erosion of sand-sized unconsolidated sediment (beach r...
double dGetSedimentInputUnconsCoarse(void) const
Get the value of coarse sediment on the polygon derived from sediment input events(s)
bool bDownCoastThisIter(void) const
Is sediment movement on this polygon downcoast this iteration?
int nGetCoastID(void) const
Get the coast ID, this is the same as the down-coast sequence.
void AddCircularity(int const)
Add a circularity to this polygon.
void SetBeachErosionUnconsCoarse(double const)
Sets a value (must be < 0) for this timestep's erosion of coarse unconsolidated sediment (beach redis...
double dGetToDoBeachDepositionUnconsCoarse(void) const
Returns this timestep's still-to-do deposition of coarse unconsolidated sediment (from beach redistri...
int m_nLogFileDetail
The level of detail in the log file output. Can be LOG_FILE_LOW_DETAIL, LOG_FILE_MIDDLE_DETAIL,...
Definition simulation.h:530
ofstream LogStream
double m_dThisIterBeachErosionCoarse
Total actual beach erosion (coarse unconsolidated sediment) for this iteration (depth in m)
Definition simulation.h:805
vector< CRWCoast > m_VCoast
The coastline objects.
double m_dFineErodibilityNormalized
Relative erodibility of fine unconsolidated beach sediment, normalized.
Definition simulation.h:751
void WritePolygonSedimentBeforeMovement(int const)
Writes to the log file a table showing per-polygon totals of stored unconsolidated beach sediment pri...
void WritePolygonSortedSequence(int const, vector< vector< int > > &)
Writes to the log file a table showing the sorted sequence of polygon processing, and any circulariti...
int m_nUnconsSedimentHandlingAtGridEdges
How sediment which moves off an edge of the grid is handled. Possible values are GRID_EDGE_CLOSED,...
Definition simulation.h:485
double m_dCoarseErodibilityNormalized
Relative erodibility of coarse unconsolidated beach sediment, normalized.
Definition simulation.h:757
double m_dDepositionCoarseDiff
Error term: if we are unable to deposit enough unconslidated coarse on polygon(s),...
Definition simulation.h:841
int nDoAllActualBeachErosionAndDeposition(void)
Does between-polygon and within-polygon actual (supply-limited) redistribution of transported beach s...
double m_dDepositionSandDiff
Error term: if we are unable to deposit enough unconslidated sand on polygon(s), this is held over to...
Definition simulation.h:838
void WritePolygonPotentialErosion(int const)
Writes to the log file a table showing per-polygon potential erosion of all size classes of unconsoli...
void WritePolygonActualMovement(int const, vector< vector< int > > const &)
Writes to the log file a table showing per-polygon actual movement of unconsolidated beach sediment.
int nDoUnconsDepositionOnPolygon(int const, CGeomCoastPolygon *, int const, double, double &)
Deposits unconsolidated beach sediment (sand or coarse) on the cells within a polygon....
double m_dSandErodibilityNormalized
Relative erodibility of sand unconsolidated beach sediment, normalized.
Definition simulation.h:754
double m_dThisIterBeachErosionSand
Total actual beach erosion (sand unconsolidated sediment) for this iteration (depth in m)
Definition simulation.h:802
double m_dThisIterFineSedimentToSuspension
Total fine unconsolidated sediment in suspension for this iteration (depth in m)
Definition simulation.h:814
double m_dThisIterBeachErosionFine
Total actual beach erosion (fine unconsolidated sediment) for this iteration (depth in m)
Definition simulation.h:799
void AllPolygonsUpdateStoredUncons(int const)
Before simulating beach erosion, update the per-polygon values of pre-existing unconsolidated sedimen...
int nDoUnconsErosionOnPolygon(int const, CGeomCoastPolygon *, int const, double const, double &)
Erodes unconsolidated beach sediment of one texture class on the cells within a polygon....
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:616
double m_dThisIterLeftGridUnconsCoarse
Total coarse unconsolidated sediment lost from the grid this iteration (depth in m)
Definition simulation.h:826
unsigned long m_ulIter
The number of the current iteration (time step)
Definition simulation.h:553
void WritePolygonUnsortedSequence(int const, vector< vector< int > > &)
Writes to the log file a table showing the unsorted sequence of polygon processing.
double m_dThisIterLeftGridUnconsSand
Total sand unconsolidated sediment lost from the grid this iteration (depth in m)
Definition simulation.h:823
STL iterator class.
This file contains global definitions for CoastalME.
int const INT_NODATA
Definition cme.h:362
T tMin(T a, T b)
Definition cme.h:1136
string const ERR
Definition cme.h:775
int const TEXTURE_COARSE
Definition cme.h:403
int const LOG_FILE_MIDDLE_DETAIL
Definition cme.h:377
int const GRID_EDGE_CLOSED
Definition cme.h:660
int const GRID_EDGE_RECIRCULATE
Definition cme.h:662
double const MASS_BALANCE_TOLERANCE
Definition cme.h:700
int const LOG_FILE_HIGH_DETAIL
Definition cme.h:378
int const TEXTURE_FINE
Definition cme.h:401
int const RTN_OK
Definition cme.h:577
int const GRID_EDGE_OPEN
Definition cme.h:661
int const TEXTURE_SAND
Definition cme.h:402
Contains CRWCoast definitions.
bool bPolygonAndAdjCompare(const vector< int > &nVLeft, const vector< int > &nVRight)
Function used to sort polygons before doing the polygon-to-polygon source-target pattern....
Contains CSimulation definitions.