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
10
11/* ==============================================================================================================================
12 This file is part of CoastalME, the Coastal Modelling Environment.
13
14 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.
15
16 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.
17
18 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.
19==============================================================================================================================*/
20#include <assert.h>
21
22#include <cmath>
23
24#include <algorithm>
25using std::sort;
26
27#include <utility>
28using std::make_pair;
29using std::pair;
30
31#include "cme.h"
32#include "simulation.h"
33#include "coast.h"
34
35namespace
36{
37//===============================================================================================================================
39//===============================================================================================================================
40bool bPolygonLengthPairCompare(const pair<int, double>& prLeft, const pair<int, double>& prRight)
41{
42 // Sort in ascending order (i.e. most concave first)
43 return prLeft.second < prRight.second;
44}
45} // namespace
46
47//===============================================================================================================================
49//===============================================================================================================================
51{
52 // Do this for each coast
53 for (int nCoast = 0; nCoast < static_cast<int>(m_VCoast.size()); nCoast++)
54 {
55 int const nNumPolygons = m_VCoast[nCoast].nGetNumPolygons();
56
57 // Create a vector of pairs: the first value of the pair is the profile index, the second is the seaward length of that profile
58 vector<pair<int, double>> prVPolygonLength;
59
60 for (int nPoly = 0; nPoly < nNumPolygons; nPoly++)
61 {
62 CGeomCoastPolygon const* pPolygon = m_VCoast[nCoast].pGetPolygon(nPoly);
63 double const dSeawardLength = pPolygon->dGetLength();
64 prVPolygonLength.push_back(make_pair(nPoly, dSeawardLength));
65 }
66
67 // Sort this pair vector in ascending order, so that the polygons with the shortest length (i.e. the most concave polygons) are first
68 sort(prVPolygonLength.begin(), prVPolygonLength.end(), bPolygonLengthPairCompare);
69
70 // Do this for every coastal polygon in sequence of coastline concavity
71 for (int n = 0; n < nNumPolygons; n++)
72 {
73 int const nThisPoly = prVPolygonLength[n].first;
74
75 CGeomCoastPolygon* pPolygon = m_VCoast[nCoast].pGetPolygon(nThisPoly);
76
77 // Calculate the average breaking wave height and angle along this polygon's segment of coastline
78 int const nStartNormal = pPolygon->nGetUpCoastProfile();
79 int const nEndNormal = pPolygon->nGetDownCoastProfile();
80 int const nCoastStartPoint = m_VCoast[nCoast].pGetProfile(nStartNormal)->nGetCoastPoint();
81 int const nCoastEndPoint = m_VCoast[nCoast].pGetProfile(nEndNormal)->nGetCoastPoint();
82 int nCoastPoints = 0;
83 int nActiveZonePoints = 0;
84
85 double dAvgBreakingWaveHeight = 0;
86 double dAvgBreakingWaveAngle = 0;
87 double dAvgDeepWaterWavePeriod = 0;
88 double dAvgFluxOrientation = 0;
89 double dAvgBreakingDepth = 0;
90 double dAvgBreakingDist = 0;
91
92 // 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
93 for (int nCoastPoint = nCoastStartPoint; nCoastPoint < nCoastEndPoint - 1; nCoastPoint++)
94 {
95 nCoastPoints++;
96 dAvgFluxOrientation += m_VCoast[nCoast].dGetFluxOrientation(nCoastPoint);
97
98 double const dThisBreakingWaveHeight = m_VCoast[nCoast].dGetBreakingWaveHeight(nCoastPoint);
99
100 if (! bFPIsEqual(dThisBreakingWaveHeight, DBL_NODATA, TOLERANCE))
101 {
102 // We are in the active zone
103 nActiveZonePoints++;
104 dAvgBreakingWaveHeight += dThisBreakingWaveHeight;
105
106 double const dThisBreakingWaveAngle = m_VCoast[nCoast].dGetBreakingWaveAngle(nCoastPoint);
107 double const dThisDeepWaterWavePeriod = m_VCoast[nCoast].dGetCoastDeepWaterWavePeriod(nCoastPoint);
108
109 dAvgBreakingWaveAngle += dThisBreakingWaveAngle;
110 dAvgDeepWaterWavePeriod += dThisDeepWaterWavePeriod;
111
112 dAvgBreakingDepth += m_VCoast[nCoast].dGetDepthOfBreaking(nCoastPoint);
113
114 dAvgBreakingDist += (m_VCoast[nCoast].nGetBreakingDistance(nCoastPoint) * m_dCellSide);
115 }
116 }
117
118 // Safety check
119 if (nCoastPoints == 0)
120 nCoastPoints = 1;
121
122 // Calc the averages
123 dAvgFluxOrientation /= nCoastPoints;
124
125 if (nActiveZonePoints > 0)
126 {
127 // Only calculate sediment movement if the polygon has at least one coast point in its coastline segment which is in the active zone
128 dAvgBreakingWaveHeight /= nActiveZonePoints;
129 dAvgBreakingWaveAngle /= nActiveZonePoints;
130 dAvgDeepWaterWavePeriod /= nActiveZonePoints;
131 dAvgBreakingDepth /= nActiveZonePoints;
132 dAvgBreakingDist /= nActiveZonePoints;
133
134 // Get the coast handedness, and (based on the average tangent) calculate the direction towards which a coastline-normal profile points
135 int const nSeaHand = m_VCoast[nCoast].nGetSeaHandedness();
136 double dNormalOrientation;
137
138 if (nSeaHand == RIGHT_HANDED)
139 dNormalOrientation = dKeepWithin360(dAvgFluxOrientation - 90);
140 else
141 dNormalOrientation = dKeepWithin360(dAvgFluxOrientation + 90);
142
143 // 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)
144 double dThetaBr = dNormalOrientation - dAvgBreakingWaveAngle;
145
146 if (dThetaBr > 270)
147 dThetaBr = dAvgBreakingWaveAngle + 360.0 - dNormalOrientation;
148 else if (dThetaBr < -270)
149 dThetaBr = dNormalOrientation + 360.0 - dAvgBreakingWaveAngle;
150
151 bool bDownCoast = true;
152
153 if (dThetaBr < 0)
154 bDownCoast = false;
155
156 // And save the direction of sediment movement in the polygon object
157 pPolygon->SetDownCoastThisIter(bDownCoast);
158
159 // Now that we have the direction of sediment movement, normalize dThetaBr to be always +ve so that subsequent calculations are clearer
160 dThetaBr = tAbs(dThetaBr);
161
162 // Safety check: not sure why we need this, but get occasional big values
163 dThetaBr = tMin(dThetaBr, 90.0);
164
165 // Calculate the immersed weight of sediment transport
166 double dImmersedWeightTransport = 0;
167
169 {
170 // 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:
171 //
172 // Qls = Kls * Hb^(5/2) * sin(2 * αb)
173 //
174 // where Kls is a transport coefficient which varies between 0.4 to 0.79
175
176 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);
177 }
179 {
180 // Use the Kamphuis (1990) equation to estimate the immersive weight transport of sand in kg/s:
181 //
182 // Qls = 2.33 * (Tp^(1.5)) * (tanBeta^(0.75)) * (d50^(-0.25)) * (Hb^2) * (sin(2 * αb)^(0.6))
183 //
184 // where:
185 // Tp = peak wave period
186 // 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
187 // d50 = median particle size in surf zone (m)
188
189 if (dAvgBreakingDist > 0)
190 {
191 double const dD50 = pPolygon->dGetAvgUnconsD50();
192
193 if (dD50 > 0)
194 {
195 double const dBeachSlope = dAvgBreakingDepth / dAvgBreakingDist;
196
197 // Note that we use a calibration constant here (m_dKamphuis)
198 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);
199 }
200 }
201 }
202
203 // Convert from immersed weight rate to bulk volumetric (sand and voids) transport rate (m3/s)
204 double dSedimentVol = m_dInmersedToBulkVolumetric * dImmersedWeightTransport;
205
206 // Convert to a volume during this timestep
207 dSedimentVol *= (m_dTimeStep * 3600);
208
209 // Convert to a depth in m
210 double dSedimentDepth = dSedimentVol / m_dCellArea;
211
212 // If this is just a tiny depth, do nothing
213 if (dSedimentDepth < SED_ELEV_TOLERANCE)
214 dSedimentDepth = 0;
215
216 // 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;
217
218 // Store the potential erosion value for this polygon
219 pPolygon->AddPotentialErosion(-dSedimentDepth);
220 // LogStream << "\tPotential erosion on polygon " << nThisPoly << " -dSedimentDepth = " << -dSedimentDepth << endl;
221 }
222
223 // else
224 // LogStream << m_ulIter << ": polygon = " << nThisPoly << " NOT IN ACTIVE ZONE dAvgFluxOrientation = " << dAvgFluxOrientation << endl;
225 }
226 }
227}
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:825
int m_nBeachErosionDepositionEquation
Which beach erosion-deposition equation is used. Possible values are UNCONS_SEDIMENT_EQUATION_CERC an...
Definition simulation.h:543
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:828
double m_dBreakingWaveHeightDepthRatio
Breaking wave height-to-depth ratio.
Definition simulation.h:765
double m_dSeaWaterDensity
Density of sea water in kg/m**3.
Definition simulation.h:714
double m_dKLS
Transport parameter KLS in the CERC equation.
Definition simulation.h:819
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 timestep) in hours.
Definition simulation.h:690
double m_dCellArea
Area of a cell (in external CRS units)
Definition simulation.h:675
double m_dCellSide
Length of a cell side (in external CRS units)
Definition simulation.h:672
double m_dKamphuis
Transport parameter for the Kamphuis equation.
Definition simulation.h:822
This file contains global definitions for CoastalME.
T tMin(T a, T b)
Definition cme.h:1175
double const TOLERANCE
Definition cme.h:725
int const UNCONS_SEDIMENT_EQUATION_KAMPHUIS
Definition cme.h:690
double const PI
Definition cme.h:707
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1213
double const DBL_NODATA
Definition cme.h:736
double const SED_ELEV_TOLERANCE
Definition cme.h:726
int const RIGHT_HANDED
Definition cme.h:413
int const UNCONS_SEDIMENT_EQUATION_CERC
Definition cme.h:689
T tAbs(T a)
Definition cme.h:1187
Contains CRWCoast definitions.
Contains CSimulation definitions.