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
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#include <cfloat>
28
29#include <algorithm>
30using std::sort;
31
32#include <utility>
33using std::make_pair;
34using std::pair;
35
36#include "cme.h"
37#include "simulation.h"
38#include "coast.h"
39
40namespace
41{
42//===============================================================================================================================
44//===============================================================================================================================
45bool bPolygonLengthPairCompare(const pair<int, double>& prLeft, const pair<int, double>& prRight)
46{
47 // Sort in ascending order (i.e. most concave first)
48 return prLeft.second < prRight.second;
49}
50} // namespace
51
52//===============================================================================================================================
54//===============================================================================================================================
56{
57 // Do this for each coast
58 for (int nCoast = 0; nCoast < static_cast<int>(m_VCoast.size()); nCoast++)
59 {
60 int const nNumPolygons = m_VCoast[nCoast].nGetNumPolygons();
61
62 // Create a vector of pairs: the first value of the pair is the profile index, the second is the seaward length of that profile
63 vector<pair<int, double>> prVPolygonLength;
64
65 for (int nPoly = 0; nPoly < nNumPolygons; nPoly++)
66 {
67 CGeomCoastPolygon const* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
68 double const dSeawardLength = pPolygon->dGetLength();
69 prVPolygonLength.push_back(make_pair(nPoly, dSeawardLength));
70 }
71
72 // Sort this pair vector in ascending order, so that the polygons with the shortest length (i.e. the most concave polygons) are first
73 sort(prVPolygonLength.begin(), prVPolygonLength.end(), bPolygonLengthPairCompare);
74
75 // Do this for every coastal polygon in sequence of coastline concavity
76 for (int n = 0; n < nNumPolygons; n++)
77 {
78 int const nThisPoly = prVPolygonLength[n].first;
79
80 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nThisPoly);
81
82 // Calculate the average breaking wave height and angle along this polygon's segment of coastline
83 int const nStartNormal = pPolygon->nGetUpCoastProfile();
84 int const nEndNormal = pPolygon->nGetDownCoastProfile();
85 int const nCoastStartPoint = m_VCoast[nCoast].pGetProfile(nStartNormal)->nGetCoastPoint();
86 int const nCoastEndPoint = m_VCoast[nCoast].pGetProfile(nEndNormal)->nGetCoastPoint();
87 int nCoastPoints = 0;
88 int nActiveZonePoints = 0;
89
90 double dAvgBreakingWaveHeight = 0;
91 double dAvgBreakingWaveAngle = 0;
92 double dAvgDeepWaterWavePeriod = 0;
93 double dAvgFluxOrientation = 0;
94 double dAvgBreakingDepth = 0;
95 double dAvgBreakingDist = 0;
96
97 // 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
98 for (int nCoastPoint = nCoastStartPoint; nCoastPoint < nCoastEndPoint - 1; nCoastPoint++)
99 {
100 nCoastPoints++;
101 dAvgFluxOrientation += m_VCoast[nCoast].dGetFluxOrientation(nCoastPoint);
102
103 double const dThisBreakingWaveHeight = m_VCoast[nCoast].dGetBreakingWaveHeight(nCoastPoint);
104
105 if (! bFPIsEqual(dThisBreakingWaveHeight, DBL_NODATA, TOLERANCE))
106 {
107 // We are in the active zone
108 nActiveZonePoints++;
109 dAvgBreakingWaveHeight += dThisBreakingWaveHeight;
110
111 double const dThisBreakingWaveAngle = m_VCoast[nCoast].dGetBreakingWaveAngle(nCoastPoint);
112 double const 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 const nSeaHand = m_VCoast[nCoast].nGetSeaHandedness();
141 double dNormalOrientation;
142
143 if (nSeaHand == RIGHT_HANDED)
144 dNormalOrientation = dKeepWithin360(dAvgFluxOrientation - 90);
145
146 else
147 dNormalOrientation = dKeepWithin360(dAvgFluxOrientation + 90);
148
149 // 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)
150 double dThetaBr = dNormalOrientation - dAvgBreakingWaveAngle;
151
152 if (dThetaBr > 270)
153 dThetaBr = dAvgBreakingWaveAngle + 360.0 - dNormalOrientation;
154
155 else if (dThetaBr < -270)
156 dThetaBr = dNormalOrientation + 360.0 - dAvgBreakingWaveAngle;
157
158 bool bDownCoast = true;
159
160 if (dThetaBr < 0)
161 bDownCoast = false;
162
163 // And save the direction of sediment movement in the polygon object
164 pPolygon->SetDownCoastThisIter(bDownCoast);
165
166 // Now that we have the direction of sediment movement, normalize dThetaBr to be always +ve so that subsequent calculations are clearer
167 dThetaBr = tAbs(dThetaBr);
168
169 // Safety check: not sure why we need this, but get occasional big values
170 dThetaBr = tMin(dThetaBr, 90.0);
171
172 // Calculate the immersed weight of sediment transport
173 double dImmersedWeightTransport = 0;
174
176 {
177 /*
178 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:
179
180 Qls = Kls * Hb^(5/2) * sin(2 * αb)
181
182 where Kls is a transport coefficient which varies between 0.4 to 0.79
183 */
184 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);
185 }
186
188 {
189 /*
190 Use the Kamphuis (1990) equation to estimate the immersive weight transport of sand in kg/s:
191
192 Qls = 2.33 * (Tp^(1.5)) * (tanBeta^(0.75)) * (d50^(-0.25)) * (Hb^2) * (sin(2 * αb)^(0.6))
193
194 where:
195
196 Tp = peak wave period
197 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
198 d50 = median particle size in surf zone (m)
199 */
200
201 if (dAvgBreakingDist > 0)
202 {
203 double const dD50 = pPolygon->dGetAvgUnconsD50();
204
205 if (dD50 > 0)
206 {
207 double const dBeachSlope = dAvgBreakingDepth / dAvgBreakingDist;
208
209 // Note that we use a calibration constant here (m_dKamphuis)
210 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);
211 }
212 }
213 }
214
215 // Convert from immersed weight rate to bulk volumetric (sand and voids) transport rate (m3/s)
216 double dSedimentVol = m_dInmersedToBulkVolumetric * dImmersedWeightTransport;
217
218 // Convert to a volume during this timestep
219 dSedimentVol *= (m_dTimeStep * 3600);
220
221 // Convert to a depth in m
222 double dSedimentDepth = dSedimentVol / m_dCellArea;
223
224 // If this is just a tiny depth, do nothing
225 if (dSedimentDepth < SEDIMENT_ELEV_TOLERANCE)
226 dSedimentDepth = 0;
227
228 // 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;
229
230 // Store the potential erosion value for this polygon
231 pPolygon->AddPotentialErosion(-dSedimentDepth);
232 // LogStream << "\tPotential erosion on polygon " << nThisPoly << " -dSedimentDepth = " << -dSedimentDepth << endl;
233 }
234
235 // else
236 // LogStream << m_ulIter << ": polygon = " << nThisPoly << " NOT IN ACTIVE ZONE dAvgFluxOrientation = " << dAvgFluxOrientation << endl;
237 }
238 }
239}
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 down-coast 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:811
int m_nBeachErosionDepositionEquation
Which beach erosion-deposition equation is used. Possible values are UNCONS_SEDIMENT_EQUATION_CERC an...
Definition simulation.h:529
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:814
double m_dBreakingWaveHeightDepthRatio
Breaking wave height-to-depth ratio.
Definition simulation.h:751
double m_dSeaWaterDensity
Density of sea water in kg/m**3.
Definition simulation.h:700
double m_dKLS
Transport parameter KLS in the CERC equation.
Definition simulation.h:805
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:676
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:661
double m_dCellSide
Length of a cell side (in external CRS units)
Definition simulation.h:658
double m_dKamphuis
Transport parameter for the Kamphuis equation.
Definition simulation.h:808
This file contains global definitions for CoastalME.
T tMin(T a, T b)
Definition cme.h:1265
double const TOLERANCE
Definition cme.h:823
int const UNCONS_SEDIMENT_EQUATION_KAMPHUIS
Definition cme.h:796
double const PI
Definition cme.h:805
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1303
double const SEDIMENT_ELEV_TOLERANCE
Definition cme.h:825
double const DBL_NODATA
Definition cme.h:834
int const RIGHT_HANDED
Definition cme.h:511
int const UNCONS_SEDIMENT_EQUATION_CERC
Definition cme.h:795
T tAbs(T a)
Definition cme.h:1277
Contains CRWCoast definitions.
Contains CSimulation definitions.