CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
do_beach_potential_erosion.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 <algorithm>
35using std::stable_sort;
36
37#include <utility>
38using std::make_pair;
39using std::pair;
40
41#include "cme.h"
42#include "simulation.h"
43#include "coast.h"
44
45//===============================================================================================================================
47//===============================================================================================================================
48bool bPolygonLengthPairCompare(const pair<int, double>& prLeft, const pair<int, double>& prRight)
49{
50 // Sort in ascending order (i.e. most concave first)
51 return prLeft.second < prRight.second;
52}
53
54//===============================================================================================================================
56//===============================================================================================================================
58{
59 // Do this for each coast
60 for (int nCoast = 0; nCoast < static_cast<int>(m_VCoast.size()); nCoast++)
61 {
62 int nNumPolygons = m_VCoast[nCoast].nGetNumPolygons();
63
64 // Create a vector of pairs: the first value of the pair is the profile index, the second is the seaward length of that profile
65 vector<pair<int, double>> prVPolygonLength;
66 for (int nPoly = 0; nPoly < nNumPolygons; nPoly++)
67 {
68 CGeomCoastPolygon const* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
69 double dSeawardLength = pPolygon->dGetLength();
70 prVPolygonLength.push_back(make_pair(nPoly, dSeawardLength));
71 }
72
73 // Sort this pair vector in ascending order, so that the polygons with the shortest length (i.e. the most concave polygons) are first
74 sort(prVPolygonLength.begin(), prVPolygonLength.end(), bPolygonLengthPairCompare);
75
76 // Do this for every coastal polygon in sequence of coastline concavity
77 for (int n = 0; n < nNumPolygons; n++)
78 {
79 int nThisPoly = prVPolygonLength[n].first;
80
81 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nThisPoly);
82
83 // Calculate the average breaking wave height and angle along this polygon's segment of coastline
84 int nStartNormal = pPolygon->nGetUpCoastProfile();
85 int nEndNormal = pPolygon->nGetDownCoastProfile();
86 int nCoastStartPoint = m_VCoast[nCoast].pGetProfile(nStartNormal)->nGetCoastPoint();
87 int nCoastEndPoint = m_VCoast[nCoast].pGetProfile(nEndNormal)->nGetCoastPoint();
88 int nCoastPoints = 0;
89 int nActiveZonePoints = 0;
90
91 double dAvgBreakingWaveHeight = 0;
92 double dAvgBreakingWaveAngle = 0;
93 double dAvgDeepWaterWavePeriod = 0;
94 double dAvgFluxOrientation = 0;
95 double dAvgBreakingDepth = 0;
96 double dAvgBreakingDist = 0;
97
98 // Calculate the average tangent to the polygon's coast segment, the average wave breaking height, the average depth of breaking, and the average distance of breaking, for this coast segment
99 for (int nCoastPoint = nCoastStartPoint; nCoastPoint < nCoastEndPoint - 1; nCoastPoint++)
100 {
101 nCoastPoints++;
102 dAvgFluxOrientation += m_VCoast[nCoast].dGetFluxOrientation(nCoastPoint);
103
104 double dThisBreakingWaveHeight = m_VCoast[nCoast].dGetBreakingWaveHeight(nCoastPoint);
105 if (! bFPIsEqual(dThisBreakingWaveHeight, DBL_NODATA, TOLERANCE))
106 {
107 // We are in the active zone
108 nActiveZonePoints++;
109 dAvgBreakingWaveHeight += dThisBreakingWaveHeight;
110
111 double dThisBreakingWaveAngle = m_VCoast[nCoast].dGetBreakingWaveAngle(nCoastPoint);
112 double dThisDeepWaterWavePeriod = m_VCoast[nCoast].dGetCoastDeepWaterWavePeriod(nCoastPoint);
113
114 dAvgBreakingWaveAngle += dThisBreakingWaveAngle;
115 dAvgDeepWaterWavePeriod += dThisDeepWaterWavePeriod;
116
117 dAvgBreakingDepth += m_VCoast[nCoast].dGetDepthOfBreaking(nCoastPoint);
118
119 dAvgBreakingDist += (m_VCoast[nCoast].nGetBreakingDistance(nCoastPoint) * m_dCellSide);
120 }
121 }
122
123 // Safety check
124 if (nCoastPoints == 0)
125 nCoastPoints = 1;
126
127 // Calc the averages
128 dAvgFluxOrientation /= nCoastPoints;
129
130 if (nActiveZonePoints > 0)
131 {
132 // Only calculate sediment movement if the polygon has at least one coast point in its coastline segment which is in the active zone
133 dAvgBreakingWaveHeight /= nActiveZonePoints;
134 dAvgBreakingWaveAngle /= nActiveZonePoints;
135 dAvgDeepWaterWavePeriod /= nActiveZonePoints;
136 dAvgBreakingDepth /= nActiveZonePoints;
137 dAvgBreakingDist /= nActiveZonePoints;
138
139 // Get the coast handedness, and (based on the average tangent) calculate the direction towards which a coastline-normal profile points
140 int nSeaHand = m_VCoast[nCoast].nGetSeaHandedness();
141 double dNormalOrientation;
142 if (nSeaHand == RIGHT_HANDED)
143 dNormalOrientation = dKeepWithin360(dAvgFluxOrientation - 90);
144 else
145 dNormalOrientation = dKeepWithin360(dAvgFluxOrientation + 90);
146
147 // Determine dThetaBr, the angle between the coastline-normal orientation and the breaking wave orientation (the direction FROM which the waves move). This tells us whether the sediment movement is up-coast (-ve) or down-coast (+ve)
148 double dThetaBr = dNormalOrientation - dAvgBreakingWaveAngle;
149 if (dThetaBr > 270)
150 dThetaBr = dAvgBreakingWaveAngle + 360.0 - dNormalOrientation;
151 else if (dThetaBr < -270)
152 dThetaBr = dNormalOrientation + 360.0 - dAvgBreakingWaveAngle;
153
154 bool bDownCoast = true;
155 if (dThetaBr < 0)
156 bDownCoast = false;
157
158 // And save the direction of sediment movement in the polygon object
159 pPolygon->SetDownCoastThisIter(bDownCoast);
160
161 // Now that we have the direction of sediment movement, normalize dThetaBr to be always +ve so that subsequent calculations are clearer
162 dThetaBr = tAbs(dThetaBr);
163
164 // Safety check: not sure why we need this, but get occasional big values
165 dThetaBr = tMin(dThetaBr, 90.0);
166
167 // Calculate the immersed weight of sediment transport
168 double dImmersedWeightTransport = 0;
170 {
171 /*
172 Use the CERC equation (Komar and Inman, 1970; USACE, 1984), this describes the immersive weight transport of sand (i.e. sand transport in suspension). Depth-integrated alongshore volumetric sediment transport is a function of breaking wave height Hb and angle αb:
173
174 Qls = Kls * Hb^(5/2) * sin(2 * αb)
175
176 where Kls is a transport coefficient which varies between 0.4 to 0.79
177 */
178 dImmersedWeightTransport = m_dKLS / (16 * pow(m_dBreakingWaveHeightDepthRatio, 0.5)) * m_dSeaWaterDensity * pow(m_dG, 1.5) * pow(dAvgBreakingWaveHeight, 2.5) * sin((PI / 180) * 2 * dThetaBr);
179 }
181 {
182 /*
183 Use the Kamphuis (1990) equation to estimate the immersive weight transport of sand in kg/s:
184
185 Qls = 2.33 * (Tp^(1.5)) * (tanBeta^(0.75)) * (d50^(-0.25)) * (Hb^2) * (sin(2 * αb)^(0.6))
186
187 where:
188
189 Tp = peak wave period
190 tanBeta = beach slope, defined as the ratio of the water depth at the breaker line and the distance from the still water beach line to the breaker line
191 d50 = median particle size in surf zone (m)
192 */
193
194 if (dAvgBreakingDist > 0)
195 {
196 double dD50 = pPolygon->dGetAvgUnconsD50();
197 if (dD50 > 0)
198 {
199 double dBeachSlope = dAvgBreakingDepth / dAvgBreakingDist;
200
201 // Note that we use a calibration constant here (m_dKamphuis)
202 dImmersedWeightTransport = m_dKamphuis * 2.33 * pow(dAvgDeepWaterWavePeriod, 1.5) * pow(dBeachSlope, 0.75) * pow(dD50, -0.25) * pow(dAvgBreakingWaveHeight, 2) * pow(sin((PI / 180) * 2 * dThetaBr), 0.6);
203 }
204 }
205 }
206
207 // Convert from immersed weight rate to bulk volumetric (sand and voids) transport rate (m3/s)
208 double dSedimentVol = m_dInmersedToBulkVolumetric * dImmersedWeightTransport;
209
210 // Convert to a volume during this timestep
211 dSedimentVol *= (m_dTimeStep * 3600);
212
213 // Convert to a depth in m
214 double dSedimentDepth = dSedimentVol / m_dCellArea;
215
216 // If this is just a tiny depth, do nothing
217 if (dSedimentDepth < SEDIMENT_ELEV_TOLERANCE)
218 dSedimentDepth = 0;
219
220 // LogStream << m_ulIter << ": polygon = " << nThisPoly << " nActiveZonePoints = " << nActiveZonePoints << " dAvgBreakingWaveHeight = " << dAvgBreakingWaveHeight << " dAvgFluxOrientation = " << dAvgFluxOrientation << " dNormalOrientation = " << dNormalOrientation << " dAvgBreakingWaveAngle = " << dAvgBreakingWaveAngle << " potential sediment transport this timestep = " << dSedimentDepth << " m " << (bDownCoast ? "DOWN" : "UP") << " coast" << endl;
221
222 // Store the potential erosion value for this polygon
223 pPolygon->AddPotentialErosion(-dSedimentDepth);
224 // LogStream << "\tPotential erosion on polygon " << nThisPoly << " -dSedimentDepth = " << -dSedimentDepth << endl;
225 }
226 // else
227 // LogStream << m_ulIter << ": polygon = " << nThisPoly << " NOT IN ACTIVE ZONE dAvgFluxOrientation = " << dAvgFluxOrientation << endl;
228 }
229 }
230}
Geometry class used for coast polygon objects.
double dGetLength(void) const
Gets the polygon's length.
void AddPotentialErosion(double const)
Adds in potential beach erosion of unconsolidated sediment (all size classes) on this polygon (m_dPot...
void SetDownCoastThisIter(bool const)
Set a flag to say whether sediment movement on this polygon is downcoast this iteration.
int nGetUpCoastProfile(void) const
Return the number of the up-coast profile.
double dGetAvgUnconsD50(void) const
Get the average d50 for unconsolidated sediment on this polygon.
int nGetDownCoastProfile(void) const
Return the number of the down-coast profile.
double m_dG
Gravitational acceleration (m**2/sec)
Definition simulation.h:766
int m_nBeachErosionDepositionEquation
Which beach erosion-deposition equation is used. Possible values are UNCONS_SEDIMENT_EQUATION_CERC an...
Definition simulation.h:488
vector< CRWCoast > m_VCoast
The coastline objects.
static double dKeepWithin360(double const)
Constrains the supplied angle to be within 0 and 360 degrees.
double m_dInmersedToBulkVolumetric
For beach erosion/deposition, conversion from immersed weight to bulk volumetric (sand and voids) tra...
Definition simulation.h:769
double m_dBreakingWaveHeightDepthRatio
Breaking wave height-to-depth ratio.
Definition simulation.h:706
double m_dSeaWaterDensity
Density of sea water in kg/m**3.
Definition simulation.h:655
double m_dKLS
Transport parameter KLS in the CERC equation.
Definition simulation.h:760
void DoAllPotentialBeachErosion(void)
Uses either the CERC equation or the Kamphuis (1990) equation to calculate potential (unconstrained) ...
double m_dTimeStep
The length of an iteration (a time step) in hours.
Definition simulation.h:631
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:616
double m_dCellSide
Length of a cell side (in external CRS units)
Definition simulation.h:613
double m_dKamphuis
Transport parameter for the Kamphuis equation.
Definition simulation.h:763
This file contains global definitions for CoastalME.
T tMin(T a, T b)
Definition cme.h:1136
double const TOLERANCE
Definition cme.h:698
int const UNCONS_SEDIMENT_EQUATION_KAMPHUIS
Definition cme.h:670
double const PI
Definition cme.h:680
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1176
double const SEDIMENT_ELEV_TOLERANCE
Definition cme.h:699
double const DBL_NODATA
Definition cme.h:707
int const RIGHT_HANDED
Definition cme.h:397
int const UNCONS_SEDIMENT_EQUATION_CERC
Definition cme.h:669
T tAbs(T a)
Definition cme.h:1148
Contains CRWCoast definitions.
bool bPolygonLengthPairCompare(const pair< int, double > &prLeft, const pair< int, double > &prRight)
Function used to sort polygon length values. If the first argument must be ordered before the second,...
Contains CSimulation definitions.