CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
read_input.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 <stdlib.h>
25
26#include <fstream>
27using std::ifstream;
28
29#include <iostream>
30using std::cerr;
31using std::cout;
32using std::endl;
33using std::ios;
34
35#include <string>
36using std::to_string;
37
38#include <algorithm>
39using std::find;
40
41#include <random>
42using std::random_device;
43
44#include "cme.h"
45#include "simulation.h"
47
48//===============================================================================================================================
50//===============================================================================================================================
52{
53 // Check if user has supplied home directory
54 if (m_strCMEIni.empty())
55 // if not use the cme executable directory to find cme.ini
57 else
58 {
59 // if user has supplied home directory replace cme run directory with user supplied dir
61 }
62 m_strCMEIni.append(CME_INI);
63
64
65 // The .ini file is assumed to be in the CoastalME executable's directory
66 string strFilePathName(m_strCMEIni);
67
68 // Tell the user what is happening
69 cout << READING_FILE_LOCATIONS << strFilePathName << endl;
70
71 // Create an ifstream object
72 ifstream InStream;
73
74 // Try to open .ini file for input
75 InStream.open(strFilePathName.c_str(), ios::in);
76
77 // Did it open OK?
78 if (! InStream.is_open())
79 {
80 // Error: cannot open .ini file for input
81 cerr << ERR << "cannot open " << strFilePathName << " for input" << endl;
82 return false;
83 }
84
85 int nLine = 0;
86 int i = 0;
87 string strRec, strErr;
88
89 while (getline(InStream, strRec))
90 {
91 nLine++;
92
93 // Trim off leading and trailing whitespace
94 strRec = strTrim(&strRec);
95
96 // If it is a blank line or a comment then ignore it
97 if ((! strRec.empty()) && (strRec[0] != QUOTE1) && (strRec[0] != QUOTE2))
98 {
99 // It isn't so increment counter
100 i++;
101
102 // Find the colon: note that lines MUST have a colon separating data from leading description portion
103 size_t nPos = strRec.find(COLON);
104 if (nPos == string::npos)
105 {
106 // Error: badly formatted (no colon)
107 cerr << ERR << "on line " << nLine << ": badly formatted (no ':') in " << strFilePathName << endl << "'" << strRec << "'" << endl;
108 return false;
109 }
110
111 if (nPos == strRec.size() - 1)
112 {
113 // Error: badly formatted (colon with nothing following)
114 cerr << ERR << "on line " << nLine << ": badly formatted (nothing following ':') in " << strFilePathName << endl << "'" << strRec << "'" << endl;
115 return false;
116 }
117
118 // Strip off leading portion (the bit up to and including the colon)
119 string strRH = strRec.erase(0, nPos+1);
120
121 // Remove leading whitespace
122 strRH = strTrimLeft(&strRH);
123
124 // Look for a trailing comment, if found then terminate string at that point and trim off any trailing whitespace
125 nPos = strRH.rfind(QUOTE1);
126 if (nPos != string::npos)
127 strRH.resize(nPos);
128
129 nPos = strRH.rfind(QUOTE2);
130 if (nPos != string::npos)
131 strRH.resize(nPos);
132
133 // Remove trailing whitespace
134 strRH = strTrimRight(&strRH);
135
136 switch (i)
137 {
138 case 1:
139 // The main input run-data filename
140 if (strRH.empty())
141 strErr = "line " + to_string(nLine) + ": path and name of main datafile";
142 else
143 {
144 // First check that we don't already have an input run-data filename, e.g. one entered on the command-line
145 if (m_strDataPathName.empty())
146 {
147 // We don't: so first check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
148 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
149 // It has an absolute path, so use it 'as is'
150 m_strDataPathName = strRH;
151 else
152 {
153 // It has a relative path, so prepend the CoastalME dir
155 m_strDataPathName.append(strRH);
156 }
157 }
158 }
159 break;
160
161 case 2:
162 // Path for CoastalME output
163 if (strRH.empty())
164 strErr = "line " + to_string(nLine) + ": path for CoastalME output";
165 else
166 {
167 // Check for trailing slash on CoastalME output directory name (is vital)
168 if (strRH[strRH.size() - 1] != PATH_SEPARATOR)
169 strRH.push_back(PATH_SEPARATOR);
170
171 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
172 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
173 // It is an absolute path, so use it 'as is'
174 m_strOutPath = strRH;
175 else
176 {
177 // It is a relative path, so prepend the CoastalME dir
179 m_strOutPath.append(strRH);
180 }
181 }
182 break;
183
184 case 3:
185 // Email address, only useful if running under Linux/Unix
186 if (! strRH.empty())
187 {
188 // Something was entered, do rudimentary check for valid email address
189 if (strRH.find('@') == string::npos)
190 strErr = "line " + to_string(nLine) + ": email address for messages";
191 else
192 m_strMailAddress = strRH;
193 }
194 break;
195 }
196
197 // Did an error occur?
198 if (! strErr.empty())
199 {
200 // Error in input to initialisation file
201 cerr << ERR << "reading " << strErr << " in " << strFilePathName << endl
202 << "'" << strRec << "'" << endl;
203 InStream.close();
204
205 return false;
206 }
207 }
208 }
209
210 InStream.close();
211 return true;
212}
213
214//===============================================================================================================================
216// TODO 000 Should user input be split in two main files: one for frequently-changed things, one for rarely-changed things? If so, what should go into each file ('testing only' OK, but what else?)
217//===============================================================================================================================
219{
220 // Create an ifstream object
221 ifstream InStream;
222
223 // Try to open run details file for input
224 InStream.open(m_strDataPathName.c_str(), ios::in);
225
226 // Did it open OK?
227 if (!InStream.is_open())
228 {
229 // Error: cannot open run details file for input
230 cerr << ERR << "cannot open " << m_strDataPathName << " for input" << endl;
231 return false;
232 }
233
234 int nLine = 0;
235 int i = 0;
236 size_t nPos;
237 string strRec, strErr;
238
239 while (getline(InStream, strRec))
240 {
241 nLine++;
242
243 // Trim off leading and trailing whitespace
244 strRec = strTrim(&strRec);
245
246 // If it is a blank line or a comment then ignore it
247 if ((! strRec.empty()) && (strRec[0] != QUOTE1) && (strRec[0] != QUOTE2))
248 {
249 // It isn't so increment counter
250 i++;
251
252 // Find the colon: note that lines MUST have a colon separating data from leading description portion
253 nPos = strRec.find(COLON);
254 if (nPos == string::npos)
255 {
256 // Error: badly formatted (no colon)
257 cerr << ERR << "on line " << to_string(nLine) << "badly formatted (no ':') in " << m_strDataPathName << endl
258 << strRec << endl;
259 return false;
260 }
261
262 // Strip off leading portion (the bit up to and including the colon)
263 string strRH = strRec.erase(0, nPos+1);
264
265 // Remove leading whitespace after the colon
266 strRH = strTrimLeft(&strRH);
267
268 // Look for trailing comments, if found then terminate string at that point and trim off any trailing whitespace
269 bool bFound = true;
270 while (bFound)
271 {
272 bFound = false;
273
274 nPos = strRH.rfind(QUOTE1);
275 if (nPos != string::npos)
276 {
277 strRH.resize(nPos);
278 bFound = true;
279 }
280
281 nPos = strRH.rfind(QUOTE2);
282 if (nPos != string::npos)
283 {
284 strRH.resize(nPos);
285 bFound = true;
286 }
287
288 // Trim trailing spaces
289 strRH = strTrimRight(&strRH);
290 }
291
292#ifdef _WIN32
293 // For Windows, make sure has backslashes, not Unix-style slashes
294 strRH = pstrChangeToBackslash(&strRH);
295#endif
296 bool bFirst = true;
297 int nRet = 0;
298 int nHour = 0;
299 int nMin = 0;
300 int nSec = 0;
301 int nDay = 0;
302 int nMonth = 0;
303 int nYear = 0;
304 double dMult = 0;
305 string strTmp;
306 vector<string> VstrTmp;
307
308 switch (i)
309 {
310 // ---------------------------------------------- Run Information -----------------------------------------------------
311 case 1:
312 // Text output file names, don't change case
313 if (strRH.empty())
314 strErr = "line " + to_string(nLine) + ": output file names";
315 else
316 {
317 m_strRunName = strRH;
318
320 m_strOutFile.append(strRH);
321 m_strOutFile.append(OUTEXT);
322
324 m_strLogFile.append(strRH);
325 m_strLogFile.append(LOGEXT);
326 }
327 break;
328
329 case 2:
330 // Content of log file, 0 = no log file, 1 = least detail, 3 = most detail
331 if (! bIsStringValidInt(strRH))
332 {
333 strErr = "line " + to_string(nLine) + ": invalid integer for log file detail level '" + strRH + "' in " + m_strDataPathName;
334 break;
335 }
336
337 m_nLogFileDetail = stoi(strRH);
338
340 strErr = "line " + to_string(nLine) + ": log file detail level";
341 break;
342
343 case 3:
344 // Get the start date/time of the simulation, format is [hh-mm-ss dd/mm/yyyy]
345 VstrTmp = VstrSplit(&strRH, SPACE);
346
347 // Both date and time here?
348 if (VstrTmp.size() < 2)
349 {
350 strErr = "line " + to_string(nLine) + ": must have both date and time for simulation start in '" + m_strDataPathName + "'";
351 break;
352 }
353
354 // OK, first sort out the time
355 if (! bParseTime(&VstrTmp[0], nHour, nMin, nSec))
356 {
357 strErr = "line " + to_string(nLine) + ": could not understand simulation start time in '" + m_strDataPathName + "'";
358 break;
359 }
360
361 // Next sort out the date
362 if (! bParseDate(&VstrTmp[1], nDay, nMonth, nYear))
363 {
364 strErr = "line " + to_string(nLine) + ": could not understand simulation start date in '" + m_strDataPathName + "'";
365 break;
366 }
367
368 // Store simulation start time and date
369 m_nSimStartSec = nSec;
370 m_nSimStartMin = nMin;
371 m_nSimStartHour = nHour;
372 m_nSimStartDay = nDay;
373 m_nSimStartMonth = nMonth;
374 m_nSimStartYear = nYear;
375
376 break;
377
378 case 4:
379 // Duration of simulation (in hours, days, months, or years): sort out multiplier and user units, as used in the per-timestep output
380 strRH = strToLower(&strRH);
381
382 nRet = nDoSimulationTimeMultiplier(&strRH);
383 if (nRet != RTN_OK)
384 {
385 strErr = "line " + to_string(nLine) + ": units for duration of simulation";
386 break;
387 }
388
389 // And now calculate the duration of the simulation in hours: first find whitespace between the number and the unit
390 nPos = strRH.rfind(SPACE);
391 if (nPos == string::npos)
392 {
393 strErr = "line " + to_string(nLine) + ": format of duration simulation line";
394 break;
395 }
396
397 // Cut off rh bit of string
398 strRH.resize(nPos);
399
400 // Remove trailing spaces
401 strRH = strTrimRight(&strRH);
402
403 // Calculate the duration of the simulation in hours
404 m_dSimDuration = strtod(strRH.c_str(), NULL) * m_dDurationUnitsMult;
405
406 if (m_dSimDuration <= 0)
407 strErr = "line " + to_string(nLine) + ": duration of simulation must be > 0";
408 break;
409
410 case 5:
411 // Timestep of simulation (in hours or days)
412 strRH = strToLower(&strRH);
413
414 dMult = dGetTimeMultiplier(&strRH);
415 if (static_cast<int>(dMult) == TIME_UNKNOWN)
416 {
417 strErr = "line " + to_string(nLine) + ": units for simulation timestep";
418 break;
419 }
420
421 // we have the multiplier, now calculate the timestep in hours: look for the whitespace between the number and unit
422 nPos = strRH.rfind(SPACE);
423 if (nPos == string::npos)
424 {
425 strErr = "line " + to_string(nLine) + ": format of simulation timestep";
426 break;
427 }
428
429 // cut off rh bit of string
430 strRH.resize(nPos);
431
432 // remove trailing spaces
433 strRH = strTrimRight(&strRH);
434
435 // Check that this is a valid double
436 if (! bIsStringValidDouble(strRH))
437 {
438 strErr = "line " + to_string(nLine) + ": invalid floating point number for timestep '" + strRH + "' in " + m_strDataPathName;
439 break;
440 }
441
442 m_dTimeStep = strtod(strRH.c_str(), NULL) * dMult; // in hours
443
444 if (m_dTimeStep <= 0)
445 strErr = "line " + to_string(nLine) + ": timestep of simulation must be > 0";
446
448 strErr = "line " + to_string(nLine) + ": timestep of simulation must be < the duration of the simulation";
449
450 break;
451
452 case 6:
453 // Save interval(s)
454 strRH = strToLower(&strRH);
455
456 // First get the multiplier
457 dMult = dGetTimeMultiplier(&strRH);
458 if (static_cast<int>(dMult) == TIME_UNKNOWN)
459 {
460 strErr = "line " + to_string(nLine) + ": units for save intervals";
461 break;
462 }
463
464 // Search for a space from the right-hand end of the string
465 nPos = strRH.rfind(SPACE);
466 if (nPos == string::npos)
467 {
468 strErr = "line " + to_string(nLine) + ": format of save times/intervals";
469 break;
470 }
471
472 // Cut off rh bit of string
473 strRH.resize(nPos);
474
475 // Remove trailing spaces
476 strRH = strTrimRight(&strRH);
477
478 // Now find out whether we're dealing with a single regular save interval or a vector of save times: again check for a space
479 nPos = strRH.find(SPACE);
480 if (nPos != string::npos)
481 {
482 // There's another space, so we must have more than one number
483 m_bSaveRegular = false;
484
485 strRH += SPACE;
486
487 do
488 {
489 // Put the number into the array
490 if (m_nUSave > static_cast<int>(SAVEMAX) - 1)
491 {
492 strErr = "line " + to_string(nLine) + ": too many save intervals";
493 break;
494 }
495 m_dUSaveTime[m_nUSave++] = strtod(strRH.substr(0, nPos).c_str(), NULL) * dMult; // convert to hours
496
497 // Trim off the number and remove leading whitespace
498 strRH.erase(0, nPos);
499 strRH = strTrimLeft(&strRH);
500
501 // Now look for another space
502 nPos = strRH.find(SPACE);
503 }
504 while (strRH.size() > 1);
505
506 // Check that we have at least 2 numbers
507 if (m_nUSave < 1)
508 {
509 strErr = "line " + to_string(nLine) + ": must have at least two save times";
510 break;
511 }
512
513 if (m_dUSaveTime[0] < m_dTimeStep)
514 {
515 strErr = "line " + to_string(nLine) + ": first save time cannot be less than timestep";
516 break;
517 }
518
519 // Put a dummy save interval as the last entry in the array: this is needed to stop problems at end of run
521 }
522 else
523 {
524 // There isn't a space, so we have only one number
525 m_bSaveRegular = true;
526 m_dRegularSaveInterval = strtod(strRH.c_str(), NULL) * dMult; // Convert to hours
528 strErr = "line " + to_string(nLine) + ": save interval cannot be less than timestep";
529 else
530 // Set up for first save
532 }
533 break;
534
535 case 7:
536 // Random number seed(s)
537 if (strRH.empty())
538 {
539 // User didn't specify a random number seed, so seed with a real random value, if available
540 random_device rdev;
541 m_ulRandSeed[0] = rdev();
542
543 // Only one seed specified, so make all seeds the same
544 for (int n = 1; n < NUMBER_OF_RNGS; n++)
545 m_ulRandSeed[n] = m_ulRandSeed[n - 1];
546 }
547 else
548 {
549 // User did specify at least one random number seed. Next find out whether we're dealing with a single seed or more than one: check for a space
550 nPos = strRH.find(SPACE);
551 if (nPos == string::npos)
552 {
553 // No space, so we have just one one number
554 m_ulRandSeed[0] = atol(strRH.c_str());
555
556 // Only one seed specified, so make all seeds the same
557 for (int n = 1; n < NUMBER_OF_RNGS; n++)
558 m_ulRandSeed[n] = m_ulRandSeed[n - 1];
559 }
560 else
561 {
562 // The user has supplied more than one random number seed
563 int n = 0;
564 do
565 {
566 // Get LH bit
567 strTmp = strRH.substr(0, nPos);
568 m_ulRandSeed[n++] = atol(strTmp.c_str());
569
570 if (n == NUMBER_OF_RNGS)
571 // All random number seeds read
572 break;
573
574 // We need more seeds, so get the RH bit
575 strRH = strRH.substr(nPos, strRH.size() - nPos);
576 strRH = strTrimLeft(&strRH);
577
578 if (strRH.size() == 0)
579 // No more seeds left to read
580 break;
581 }
582 while (true);
583
584 // If we haven't filled all random number seeds, make all the remainder the same as the last one read
585 if (n < NUMBER_OF_RNGS-1)
586 {
587 for (int m = n; m < NUMBER_OF_RNGS; m++)
589 }
590 }
591 }
592 break;
593
594 case 8:
595 // Max save digits for GIS output file names
596 if (! bIsStringValidInt(strRH))
597 {
598 strErr = "line " + to_string(nLine) + ": invalid integer for max save digits for GIS output file names '" + strRH + "' in " + m_strDataPathName;
599 break;
600 }
601
602 m_nGISMaxSaveDigits = stoi(strRH);
603
604 if (m_nGISMaxSaveDigits < 2)
605 strErr = "line " + to_string(nLine) + ": max save digits for GIS output file names must be > 1";
606 break;
607
608 case 9:
609 // Save digits for GIS output sequential or iteration number? [s = sequential, i = iteration]: s
610 if (strRH.empty())
611 strErr = "line " + to_string(nLine) + ": must specify save digits for GIS output as sequential or as iteration number";
612 else
613 {
614 // Convert to lower case
615 strRH = strToLower(&strRH);
616
617 if (strRH.find('s') != string::npos)
618 {
619 // First look for 's'
621 }
622 else if (strRH.find('i') != string::npos)
623 {
624 // Now look for 'i'
626 }
627 else
628 {
629 strErr = "line " + to_string(nLine) + ": invalid code for save digits for GIS output save number (must be s or i)";
630 break;
631 }
632 }
633 break;
634
635
636 case 10:
637 // Raster GIS files to output
638 if (strRH.empty())
639 strErr = "line " + to_string(nLine) + ": must contain '" + RASTER_ALL_OUTPUT_CODE +"', or '" + RASTER_USUAL_OUTPUT_CODE + "', or at least one raster GIS output code";
640 else
641 {
642 // Convert to lower case
643 strRH = strToLower(&strRH);
644
645 if (strRH.find(RASTER_ALL_OUTPUT_CODE) != string::npos)
646 {
647 // Set switches for all GIS raster output. Some of these (e.g. all relating to fine sediment) are ignored if e.g. no fine sediment layers are read in
695 }
696 else if (strRH.find(RASTER_USUAL_OUTPUT_CODE) != string::npos)
697 {
698 // Set switches for usual GIS raster output. Again, some of these (e.g. all relating to fine sediment) are ignored if they are irrelevant
737
738 // TEST
741 }
742 else
743 {
744 // We are not outputting either the "usual" or the "all" collections of raster GIS files, so set switches (and remove strings) for those optional files for which the user specified the code
745 if (strRH.find(RASTER_SEDIMENT_TOP_CODE) != string::npos)
746 {
749 }
750
751 if (strRH.find(RASTER_TOP_CODE) != string::npos)
752 {
753 m_bTopSurfSave = true;
754 strRH = strRemoveSubstr(&strRH, &RASTER_TOP_CODE);
755 }
756
757 if (strRH.find(RASTER_SEA_DEPTH_CODE) != string::npos)
758 {
759 m_bSeaDepthSave = true;
760 strRH = strRemoveSubstr(&strRH, &RASTER_SEA_DEPTH_CODE);
761 }
762
763 if (strRH.find(RASTER_WAVE_HEIGHT_CODE) != string::npos)
764 {
765 m_bWaveHeightSave = true;
767 }
768
769 if (strRH.find(RASTER_WAVE_ORIENTATION_CODE) != string::npos)
770 {
771 m_bWaveAngleSave = true;
773 }
774
775 if (strRH.find(RASTER_WAVE_PERIOD_CODE) != string::npos)
776 {
779 }
780
781 if (strRH.find(RASTER_POTENTIAL_PLATFORM_EROSION_CODE) != string::npos)
782 {
785 }
786
787 if (strRH.find(RASTER_ACTUAL_PLATFORM_EROSION_CODE) != string::npos)
788 {
791 }
792
793 if (strRH.find(RASTER_TOTAL_POTENTIAL_PLATFORM_EROSION_CODE) != string::npos)
794 {
797 }
798
799 if (strRH.find(RASTER_TOTAL_ACTUAL_PLATFORM_EROSION_CODE) != string::npos)
800 {
803 }
804
805 if (strRH.find(RASTER_POTENTIAL_BEACH_EROSION_CODE) != string::npos)
806 {
809 }
810
811 if (strRH.find(RASTER_ACTUAL_BEACH_EROSION_CODE) != string::npos)
812 {
815 }
816
817 if (strRH.find(RASTER_TOTAL_POTENTIAL_BEACH_EROSION_CODE) != string::npos)
818 {
821 }
822
823 if (strRH.find(RASTER_TOTAL_ACTUAL_BEACH_EROSION_CODE) != string::npos)
824 {
827 }
828
829 if (strRH.find(RASTER_LANDFORM_CODE) != string::npos)
830 {
831 m_bLandformSave = true;
832 strRH = strRemoveSubstr(&strRH, &RASTER_LANDFORM_CODE);
833 }
834
835 if (strRH.find(RASTER_LOCAL_SLOPE_CODE) != string::npos)
836 {
837 m_bLocalSlopeSave = true;
839 }
840
841 if (strRH.find(RASTER_AVG_SEA_DEPTH_CODE) != string::npos)
842 {
843 m_bAvgSeaDepthSave = true;
845 }
846
847 if (strRH.find(RASTER_AVG_WAVE_HEIGHT_CODE) != string::npos)
848 {
851 }
852
853 if (strRH.find(RASTER_AVG_WAVE_ORIENTATION_CODE) != string::npos)
854 {
855 m_bAvgWaveAngleSave = true;
857 }
858
859 if (strRH.find(RASTER_BEACH_PROTECTION_CODE) != string::npos)
860 {
863 }
864
865 if (strRH.find(RASTER_BASEMENT_ELEVATION_CODE) != string::npos)
866 {
867 m_bBasementElevSave = true;
869 }
870
871 if (strRH.find(RASTER_SUSP_SED_CODE) != string::npos)
872 {
873 m_bSuspSedSave = true;
874 strRH = strRemoveSubstr(&strRH, &RASTER_SUSP_SED_CODE);
875 }
876
877 if (strRH.find(RASTER_AVG_SUSP_SED_CODE) != string::npos)
878 {
879 m_bAvgSuspSedSave = true;
881 }
882
883 if (strRH.find(RASTER_FINE_UNCONS_CODE) != string::npos)
884 {
887 }
888
889 if (strRH.find(RASTER_SAND_UNCONS_CODE) != string::npos)
890 {
893 }
894
895 if (strRH.find(RASTER_COARSE_UNCONS_CODE) != string::npos)
896 {
899 }
900
901 if (strRH.find(RASTER_FINE_CONS_CODE) != string::npos)
902 {
903 m_bFineConsSedSave = true;
904 strRH = strRemoveSubstr(&strRH, &RASTER_FINE_CONS_CODE);
905 }
906
907 if (strRH.find(RASTER_SAND_CONS_CODE) != string::npos)
908 {
909 m_bSandConsSedSave = true;
910 strRH = strRemoveSubstr(&strRH, &RASTER_SAND_CONS_CODE);
911 }
912
913 if (strRH.find(RASTER_COARSE_CONS_CODE) != string::npos)
914 {
917 }
918
919 if (strRH.find(RASTER_COAST_CODE) != string::npos)
920 {
922 strRH = strRemoveSubstr(&strRH, &RASTER_COAST_CODE);
923 }
924
925 if (strRH.find(RASTER_COAST_NORMAL_CODE) != string::npos)
926 {
929 }
930
931 if (strRH.find(RASTER_ACTIVE_ZONE_CODE) != string::npos)
932 {
933 m_bActiveZoneSave = true;
935 }
936
937 if (strRH.find(RASTER_CLIFF_COLLAPSE_EROSION_FINE_CODE) != string::npos)
938 {
941 }
942
943 if (strRH.find(RASTER_CLIFF_COLLAPSE_EROSION_SAND_CODE) != string::npos)
944 {
947 }
948
949 if (strRH.find(RASTER_CLIFF_COLLAPSE_EROSION_COARSE_CODE) != string::npos)
950 {
953 }
954
955 if (strRH.find(RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_FINE_CODE) != string::npos)
956 {
959 }
960
961 if (strRH.find(RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_SAND_CODE) != string::npos)
962 {
965 }
966
967 if (strRH.find(RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_COARSE_CODE) != string::npos)
968 {
971 }
972
973 if (strRH.find(RASTER_CLIFF_COLLAPSE_DEPOSITION_SAND_CODE) != string::npos)
974 {
977 }
978
979 if (strRH.find(RASTER_CLIFF_COLLAPSE_DEPOSITION_COARSE_CODE) != string::npos)
980 {
983 }
984
985 if (strRH.find(RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_SAND_CODE) != string::npos)
986 {
989 }
990
991 if (strRH.find(RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_COARSE_CODE) != string::npos)
992 {
995 }
996
997 if (strRH.find(RASTER_POLYGON_CODE) != string::npos)
998 {
1000 strRH = strRemoveSubstr(&strRH, &RASTER_POLYGON_CODE);
1001 }
1002
1003 if (strRH.find(RASTER_POTENTIAL_PLATFORM_EROSION_MASK_CODE) != string::npos)
1004 {
1007 }
1008
1009 if (strRH.find(RASTER_INUNDATION_MASK_CODE) != string::npos)
1010 {
1011 m_bSeaMaskSave = true;
1013 }
1014
1015 if (strRH.find(RASTER_BEACH_MASK_CODE) != string::npos)
1016 {
1017 m_bBeachMaskSave = true;
1018 strRH = strRemoveSubstr(&strRH, &RASTER_BEACH_MASK_CODE);
1019 }
1020
1021 if (strRH.find(RASTER_INTERVENTION_CLASS_CODE) != string::npos)
1022 {
1025 }
1026
1027 if (strRH.find(RASTER_INTERVENTION_HEIGHT_CODE) != string::npos)
1028 {
1031 }
1032
1033 if (strRH.find(RASTER_SHADOW_ZONE_CODE) != string::npos)
1034 {
1036 strRH = strRemoveSubstr(&strRH, &RASTER_SHADOW_ZONE_CODE);
1037 }
1038
1039 if (strRH.find(RASTER_DEEP_WATER_WAVE_ORIENTATION_CODE) != string::npos)
1040 {
1043 }
1044
1045 if (strRH.find(RASTER_DEEP_WATER_WAVE_HEIGHT_CODE) != string::npos)
1046 {
1049 }
1050
1051 if (strRH.find(RASTER_DEEP_WATER_WAVE_PERIOD_CODE) != string::npos)
1052 {
1055 }
1056
1057 if (strRH.find(RASTER_POLYGON_UPDRIFT_OR_DOWNDRIFT_CODE) != string::npos)
1058 {
1061 }
1062
1063 if (strRH.find(RASTER_POLYGON_GAIN_OR_LOSS_CODE) != string::npos)
1064 {
1067 }
1068
1069 if (strRH.find(RASTER_BEACH_DEPOSITION_CODE) != string::npos)
1070 {
1073 }
1074
1075 if (strRH.find(RASTER_TOTAL_BEACH_DEPOSITION_CODE) != string::npos)
1076 {
1079 }
1080
1081 if (strRH.find(RASTER_SEDIMENT_INPUT_EVENT_CODE) != string::npos)
1082 {
1085 }
1086
1087 if (strRH.find(RASTER_SETUP_SURGE_FLOOD_MASK_CODE) != string::npos)
1088 {
1091 }
1092 if (strRH.find(RASTER_SETUP_SURGE_RUNUP_FLOOD_MASK_CODE) != string::npos)
1093 {
1096 }
1097 if (strRH.find(RASTER_WAVE_FLOOD_LINE_CODE) != string::npos)
1098 {
1101 }
1102
1103 // Check to see if all codes have been removed
1104 if (! strRH.empty())
1105 strErr = "line " + to_string(nLine) + ": unknown code '" + strRH + "' in list of codes for raster GIS output";
1106 }
1107 }
1108 break;
1109
1110 case 11:
1111 // Raster GIS output format (note must retain original case). Blank means use same format as input DEM file (if possible)
1113
1114 // TODO 065 Remove this when GDAL gpkg raster output is working correctly
1115 if (strRH.find("gpkg") != string::npos)
1116 strErr = "GDAL gpkg raster create() is not yet working correctly. Please choose another output format.";
1117
1118 break;
1119
1120 case 12:
1121 // If needed, scale GIS raster output values
1122 strRH = strToLower(&strRH);
1123
1124 m_bScaleRasterOutput = false;
1125 if (strRH.find("y") != string::npos)
1126 m_bScaleRasterOutput = true;
1127 break;
1128
1129 case 13:
1130 // If needed, also output GIS raster world file
1131 strRH = strToLower(&strRH);
1132
1133 m_bWorldFile = false;
1134 if (strRH.find("y") != string::npos)
1135 m_bWorldFile = true;
1136 break;
1137
1138 case 14:
1139 // Elevations for raster slice output, if desired
1140 if (! strRH.empty())
1141 {
1142 m_bSliceSave = true;
1143
1144 // OK, so find out whether we're dealing with a single seed or more than one: check for a space
1145 nPos = strRH.find(SPACE);
1146 if (nPos != string::npos)
1147 {
1148 // There's a space, so we must have more than one number
1149 do
1150 {
1151 // Get LH bit
1152 strTmp = strRH.substr(0, nPos);
1153 m_VdSliceElev.push_back(strtod(strTmp.c_str(), NULL));
1154
1155 // Get the RH bit
1156 strRH = strRH.substr(nPos, strRH.size() - nPos);
1157 strRH = strTrimLeft(&strRH);
1158
1159 // Now look for another space
1160 nPos = strRH.find(SPACE);
1161 } while (nPos != string::npos);
1162 }
1163 // Read either the single number, or the left-over number
1164 m_VdSliceElev.push_back(strtod(strTmp.c_str(), NULL));
1165 }
1166 break;
1167
1168 case 15:
1169 // Vector GIS files to output
1170 if (strRH.empty())
1171 strErr = "line " + to_string(nLine) + ": must contain '" + VECTOR_ALL_OUTPUT_CODE +"', or '" + VECTOR_USUAL_OUTPUT_CODE + "', or at least one vector GIS output code";
1172 else
1173 {
1174 strRH = strToLower(&strRH);
1175
1176 if (strRH.find(VECTOR_ALL_OUTPUT_CODE) != string::npos)
1177 {
1178 // Output all vector files
1179 m_bCoastSave =
1196 m_bRunUpSave =
1198 }
1199 else if (strRH.find(VECTOR_USUAL_OUTPUT_CODE) != string::npos)
1200 {
1201 // Output the "usual" collection of vector output files
1202 m_bCoastSave =
1205 m_bInvalidNormalsSave = // DEBUG CODE
1215 }
1216 else
1217 {
1218 // Output only those vector files for which the user specified the code
1219 if (strRH.find(VECTOR_COAST_CODE) != string::npos)
1220 {
1221 m_bCoastSave = true;
1222 strRH = strRemoveSubstr(&strRH, &VECTOR_COAST_CODE);
1223 }
1224
1225 if (strRH.find(VECTOR_AVG_WAVE_ANGLE_AND_HEIGHT_CODE) != string::npos)
1226 {
1229 }
1230
1231 if (strRH.find(VECTOR_NORMALS_CODE) != string::npos)
1232 {
1233 m_bNormalsSave = true;
1234 strRH = strRemoveSubstr(&strRH, &VECTOR_NORMALS_CODE);
1235 }
1236
1237 if (strRH.find(VECTOR_INVALID_NORMALS_CODE) != string::npos)
1238 {
1239 m_bInvalidNormalsSave = true;
1241 }
1242
1243 if (strRH.find(VECTOR_AVG_WAVE_ANGLE_AND_HEIGHT_CODE) != string::npos)
1244 {
1247 }
1248
1249 if (strRH.find(VECTOR_COAST_CURVATURE_CODE) != string::npos)
1250 {
1251 m_bCoastCurvatureSave = true;
1253 }
1254
1255 if (strRH.find(VECTOR_WAVE_ENERGY_SINCE_COLLAPSE_CODE) != string::npos)
1256 {
1259 }
1260
1261 if (strRH.find(VECTOR_MEAN_WAVE_ENERGY_CODE) != string::npos)
1262 {
1263 m_bMeanWaveEnergySave = true;
1265 }
1266
1267 if (strRH.find(VECTOR_BREAKING_WAVE_HEIGHT_CODE) != string::npos)
1268 {
1271 }
1272
1273 if (strRH.find(VECTOR_POLYGON_NODE_CODE) != string::npos)
1274 {
1275 m_bPolygonNodeSave = true;
1276 strRH = strRemoveSubstr(&strRH, &VECTOR_POLYGON_NODE_CODE);
1277 }
1278
1279 if (strRH.find(VECTOR_POLYGON_BOUNDARY_CODE) != string::npos)
1280 {
1283 }
1284
1285 if (strRH.find(VECTOR_CLIFF_NOTCH_SIZE_CODE) != string::npos)
1286 {
1287 m_bCliffNotchSave = true;
1289 }
1290
1291 if (strRH.find(VECTOR_SHADOW_BOUNDARY_CODE) != string::npos)
1292 {
1293 m_bShadowBoundarySave = true;
1295 }
1296
1297 if (strRH.find(VECTOR_DOWNDRIFT_BOUNDARY_CODE) != string::npos)
1298 {
1301 }
1302
1303 if (strRH.find(VECTOR_DEEP_WATER_WAVE_ANGLE_AND_HEIGHT_CODE) != string::npos)
1304 {
1307 }
1308
1309 if (strRH.find(VECTOR_WAVE_SETUP_CODE) != string::npos)
1310 {
1311 m_bWaveSetupSave = true;
1312 strRH = strRemoveSubstr(&strRH, &VECTOR_WAVE_SETUP_CODE);
1313 }
1314
1315 if (strRH.find(VECTOR_STORM_SURGE_CODE) != string::npos)
1316 {
1317 m_bStormSurgeSave = true;
1318 strRH = strRemoveSubstr(&strRH, &VECTOR_STORM_SURGE_CODE);
1319 }
1320
1321 if (strRH.find(VECTOR_RUN_UP_CODE) != string::npos)
1322 {
1323 m_bRunUpSave = true;
1324 strRH = strRemoveSubstr(&strRH, &VECTOR_RUN_UP_CODE);
1325 }
1326
1327 if (strRH.find(VECTOR_FLOOD_LINE_CODE) != string::npos)
1328 {
1330 strRH = strRemoveSubstr(&strRH, &VECTOR_FLOOD_LINE_CODE);
1331 }
1332
1333 // Check to see if all codes have been removed
1334 if (! strRH.empty())
1335 strErr = "line " + to_string(nLine) + ": unknown code '" + strRH + "' in list of vector GIS output codes";
1336 }
1337 }
1338 break;
1339
1340 case 16:
1341 // Vector GIS output format (note must retain original case)
1343
1344 if (strRH.empty())
1345 strErr = "line " + to_string(nLine) + ": vector GIS output format";
1346 break;
1347
1348 case 17:
1349 // Time series files to output
1350 if (! strRH.empty())
1351 {
1352 strRH = strToLower(&strRH);
1353
1354 // First check for "all"
1355 if (strRH.find(RASTER_ALL_OUTPUT_CODE) != string::npos)
1356 {
1369 }
1370 else
1371 {
1372 if (strRH.find(TIME_SERIES_SEA_AREA_CODE) != string::npos)
1373 {
1374 m_bSeaAreaTSSave = true;
1376 }
1377
1378 if (strRH.find(TIME_SERIES_STILL_WATER_LEVEL_CODE) != string::npos)
1379 {
1382 }
1383
1384 if (strRH.find(TIME_SERIES_PLATFORM_EROSION_CODE) != string::npos)
1385 {
1388 }
1389
1390 if (strRH.find(TIME_SERIES_CLIFF_COLLAPSE_EROSION_CODE) != string::npos)
1391 {
1394 }
1395
1396 if (strRH.find(TIME_SERIES_CLIFF_COLLAPSE_DEPOSITION_CODE) != string::npos)
1397 {
1400 }
1401
1402 if (strRH.find(TIME_SERIES_CLIFF_COLLAPSE_NET_CODE) != string::npos)
1403 {
1406 }
1407
1408 if (strRH.find(TIME_SERIES_BEACH_EROSION_CODE) != string::npos)
1409 {
1410 m_bBeachErosionTSSave = true;
1412 }
1413
1414 if (strRH.find(TIME_SERIES_BEACH_DEPOSITION_CODE) != string::npos)
1415 {
1418 }
1419
1420 if (strRH.find(TIME_SERIES_BEACH_CHANGE_NET_CODE) != string::npos)
1421 {
1424 }
1425
1426 if (strRH.find(TIME_SERIES_SUSPENDED_SEDIMENT_CODE) != string::npos)
1427 {
1428 m_bSuspSedTSSave = true;
1430 }
1431
1432 if (strRH.find(TIME_SERIES_FLOOD_SETUP_SURGE_CODE) != string::npos)
1433 {
1436 }
1437
1438 if (strRH.find(TIME_SERIES_FLOOD_SETUP_SURGE_RUNUP_CODE) != string::npos)
1439 {
1442 }
1443
1444 // Check to see if all codes have been removed
1445 if (! strRH.empty())
1446 strErr = "line " + to_string(nLine) + ": unknown code '" + strRH + "' in list of time series output files";
1447 }
1448 }
1449 break;
1450
1451 case 18:
1452 // Vector coastline smoothing algorithm: 0 = none, 1 = running mean, 2 = Savitsky-Golay
1453 if (! bIsStringValidInt(strRH))
1454 {
1455 strErr = "line " + to_string(nLine) + ": invalid integer for coastline smoothing algorithm '" + strRH + "' in " + m_strDataPathName;
1456 break;
1457 }
1458
1459 m_nCoastSmooth = stoi(strRH);
1460
1462 strErr = "line " + to_string(nLine) + ": coastline vector smoothing algorithm";
1463
1464 break;
1465
1466 case 19:
1467 // Size of coastline smoothing window: must be odd
1468 if (! bIsStringValidInt(strRH))
1469 {
1470 strErr = "line " + to_string(nLine) + ": invalid integer for coastline smoothing window '" + strRH + "' in " + m_strDataPathName;
1471 break;
1472 }
1473
1474 m_nCoastSmoothWindow = stoi(strRH);
1475
1476 if ((m_nCoastSmoothWindow <= 0) || !(m_nCoastSmoothWindow % 2))
1477 strErr = "line " + to_string(nLine) + ": size of coastline vector smoothing window (must be > 0 and odd)";
1478
1479 break;
1480
1481 case 20:
1482 // Order of coastline profile smoothing polynomial for Savitsky-Golay: usually 2 or 4, max is 6
1483 if (! bIsStringValidInt(strRH))
1484 {
1485 strErr = "line " + to_string(nLine) + ": invalid integer for Savitsky-Golay polynomial for coastline smoothing '" + strRH + "' in " + m_strDataPathName;
1486 break;
1487 }
1488
1489 m_nSavGolCoastPoly = stoi(strRH);
1490
1491 if ((m_nSavGolCoastPoly <= 0) || (m_nSavGolCoastPoly > 6))
1492 strErr = "line " + to_string(nLine) + ": value of Savitsky-Golay polynomial for coastline smoothing (must be <= 6)";
1493
1494 break;
1495
1496 case 21:
1497 // Grid edge(s) to omit when searching for coastline [NSWE]
1498 strRH = strToLower(&strRH);
1499
1500 bFound = false;
1501 if (strRH.find("n") != string::npos)
1502 {
1504 bFound = true;
1505 }
1506 if (strRH.find("s") != string::npos)
1507 {
1509 bFound = true;
1510 }
1511 if (strRH.find("w") != string::npos)
1512 {
1514 bFound = true;
1515 }
1516 if (strRH.find("e") != string::npos)
1517 {
1519 bFound = true;
1520 }
1521
1522 if (! bFound)
1523 strErr = "line " + to_string(nLine) + ": at least one edge must be omitted from coastline search";
1524
1525 break;
1526
1527 case 22:
1528 // Profile slope running-mean smoothing window size: must be odd
1529 if (! bIsStringValidInt(strRH))
1530 {
1531 strErr = "line " + to_string(nLine) + ": invalid integer for size of coastline smoothing window '" + strRH + "' in " + m_strDataPathName;
1532 break;
1533 }
1534
1535 m_nProfileSmoothWindow = stoi(strRH);
1536
1538 strErr = "line " + to_string(nLine) + ": size of profile vector smoothing window (must be >= 0, if > 0 must be odd)";
1539
1540 break;
1541
1542 case 23:
1543 // Max local slope (m/m), first check that this is a valid double
1544 if (! bIsStringValidDouble(strRH))
1545 {
1546 strErr = "line " + to_string(nLine) + ": invalid floating point number for max local slope '" + strRH + "' in " + m_strDataPathName;
1547 break;
1548 }
1549
1550 m_dProfileMaxSlope = strtod(strRH.c_str(), NULL);
1551
1552 if (m_dProfileMaxSlope <= 0)
1553 strErr = "line " + to_string(nLine) + ": max local slope must be > 0";
1554 break;
1555
1556 case 24:
1557 // Maximum elevation of beach above SWL, first check that this is a valid double
1558 if (! bIsStringValidDouble(strRH))
1559 {
1560 strErr = "line " + to_string(nLine) + ": invalid floating point number for maximum elevation of beach above SWL '" + strRH + "' in " + m_strDataPathName;
1561 break;
1562 }
1563
1564 m_dMaxBeachElevAboveSWL = strtod(strRH.c_str(), NULL);
1565
1567 strErr = "line " + to_string(nLine) + ": maximum elevation of beach above SWL must be >= 0";
1568 break;
1569
1570 // ------------------------------------------------- Raster GIS layers ------------------------------------------------
1571 case 25:
1572 // Number of sediment layers
1573 if (! bIsStringValidInt(strRH))
1574 {
1575 strErr = "line " + to_string(nLine) + ": invalid integer for number of sediment layers '" + strRH + "' in " + m_strDataPathName;
1576 break;
1577 }
1578
1579 m_nLayers = stoi(strRH);
1580
1581 if (m_nLayers < 1)
1582 {
1583 strErr = "line " + to_string(nLine) + ": must be at least one sediment layer";
1584 break;
1585 }
1586
1587 // OK we know the number of layers, so add elements to these vectors
1588 for (int j = 0; j < m_nLayers; j++)
1589 {
1596 m_VstrGDALIUFDriverCode.push_back("");
1597 m_VstrGDALIUFDriverDesc.push_back("");
1598 m_VstrGDALIUFProjection.push_back("");
1599 m_VstrGDALIUFDataType.push_back("");
1600 m_VstrGDALIUSDriverCode.push_back("");
1601 m_VstrGDALIUSDriverDesc.push_back("");
1602 m_VstrGDALIUSProjection.push_back("");
1603 m_VstrGDALIUSDataType.push_back("");
1604 m_VstrGDALIUCDriverCode.push_back("");
1605 m_VstrGDALIUCDriverDesc.push_back("");
1606 m_VstrGDALIUCProjection.push_back("");
1607 m_VstrGDALIUCDataType.push_back("");
1608 m_VstrGDALICFDriverCode.push_back("");
1609 m_VstrGDALICFDriverDesc.push_back("");
1610 m_VstrGDALICFProjection.push_back("");
1611 m_VstrGDALICFDataType.push_back("");
1612 m_VstrGDALICSDriverCode.push_back("");
1613 m_VstrGDALICSDriverDesc.push_back("");
1614 m_VstrGDALICSProjection.push_back("");
1615 m_VstrGDALICSDataType.push_back("");
1616 m_VstrGDALICCDriverCode.push_back("");
1617 m_VstrGDALICCDriverDesc.push_back("");
1618 m_VstrGDALICCProjection.push_back("");
1619 m_VstrGDALICCDataType.push_back("");
1620 }
1621 break;
1622
1623 case 26:
1624 // Basement DEM file (can be blank)
1625 if (! strRH.empty())
1626 {
1627#ifdef _WIN32
1628 // For Windows, make sure has backslashes, not Unix-style slashes
1629 strRH = pstrChangeToBackslash(&strRH);
1630#endif
1631 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1632 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1633 // It has an absolute path, so use it 'as is'
1635 else
1636 {
1637 // It has a relative path, so prepend the CoastalME dir
1639 m_strInitialBasementDEMFile.append(strRH);
1640 }
1641 }
1642 break;
1643
1644 case 27:
1645 // Read 6 x sediment files for each layer
1646 for (int nLayer = 0; nLayer < m_nLayers; nLayer++)
1647 {
1648 for (int j = 1; j <= 6; j++)
1649 {
1650 if (! bFirst)
1651 {
1652 do
1653 {
1654 if (! getline(InStream, strRec))
1655 {
1656 cerr << ERR << "premature end of file in " << m_strDataPathName << endl;
1657 return false;
1658 }
1659
1660 nLine++;
1661
1662 // Trim off leading and trailing whitespace
1663 strRec = strTrim(&strRec);
1664 }
1665 // If it is a blank line or a comment then ignore it
1666 while (strRec.empty() || (strRec[0] == QUOTE1) || (strRec[0] == QUOTE2));
1667
1668 // Not blank or a comment, so find the colon: lines MUST have a colon separating data from leading description portion
1669 nPos = strRec.find(COLON);
1670 if (nPos == string::npos)
1671 {
1672 // Error: badly formatted (no colon)
1673 cerr << ERR << "on line " << to_string(nLine) << ": badly formatted (no ':') in " << m_strDataPathName << endl << strRec << endl;
1674 return false;
1675 }
1676
1677 // Strip off leading portion (the bit up to and including the colon)
1678 strRH = strRec.substr(nPos + 1);
1679// ERROR strRH.resize(nPos);
1680
1681 // Remove leading whitespace after the colon
1682 strRH = strTrimLeft(&strRH);
1683
1684 // Look for a trailing comment, if found then terminate string at that point and trim off any trailing whitespace
1685 nPos = strRH.rfind(QUOTE1);
1686 if (nPos != string::npos)
1687 strRH.resize(nPos);
1688
1689 nPos = strRH.rfind(QUOTE2);
1690 if (nPos != string::npos)
1691 strRH.resize(nPos);
1692
1693 // Trim trailing spaces
1694 strRH = strTrimRight(&strRH);
1695
1696#ifdef _WIN32
1697 // For Windows, make sure has backslashes, not Unix-style slashes
1698 strRH = pstrChangeToBackslash(&strRH);
1699#endif
1700 }
1701
1702 bFirst = false;
1703
1704 switch (j)
1705 {
1706 case 1:
1707 // Initial fine unconsolidated sediment depth GIS file (can be blank)
1708 if (! strRH.empty())
1709 {
1710 // Set switch
1711 m_bHaveFineSediment = true;
1712#ifdef _WIN32
1713 // For Windows, make sure has backslashes, not Unix-style slashes
1714 strRH = pstrChangeToBackslash(&strRH);
1715#endif
1716
1717 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1718 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1719 {
1720 // It has an absolute path, so use it 'as is'
1722 }
1723 else
1724 {
1725 // It has a relative path, so prepend the CoastalME dir
1727 m_VstrInitialFineUnconsSedimentFile[nLayer].append(strRH);
1728 }
1729 }
1730 break;
1731
1732 case 2:
1733 // Initial sand unconsolidated sediment depth GIS file (can be blank)
1734 if (! strRH.empty())
1735 {
1736 // Set switch
1737 m_bHaveSandSediment = true;
1738#ifdef _WIN32
1739 // For Windows, make sure has backslashes, not Unix-style slashes
1740 strRH = pstrChangeToBackslash(&strRH);
1741#endif
1742 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1743 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1744 {
1745 // It has an absolute path, so use it 'as is'
1747 }
1748 else
1749 {
1750 // It has a relative path, so prepend the CoastalME dir
1752 m_VstrInitialSandUnconsSedimentFile[nLayer].append(strRH);
1753 }
1754 }
1755 break;
1756
1757 case 3:
1758 // Initial coarse unconsolidated sediment depth GIS file (can be blank)
1759 if (! strRH.empty())
1760 {
1761 // Set switch
1762 m_bHaveCoarseSediment = true;
1763#ifdef _WIN32
1764 // For Windows, make sure has backslashes, not Unix-style slashes
1765 strRH = pstrChangeToBackslash(&strRH);
1766#endif
1767 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1768 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1769 {
1770 // It has an absolute path, so use it 'as is'
1772 }
1773 else
1774 {
1775 // It has a relative path, so prepend the CoastalME dir
1777 m_VstrInitialCoarseUnconsSedimentFile[nLayer].append(strRH);
1778 }
1779 }
1780 break;
1781
1782 case 4:
1783 // Initial fine consolidated sediment depth GIS file (can be blank)
1784 if (! strRH.empty())
1785 {
1786 // Set switch
1787 m_bHaveFineSediment = true;
1788#ifdef _WIN32
1789 // For Windows, make sure has backslashes, not Unix-style slashes
1790 strRH = pstrChangeToBackslash(&strRH);
1791#endif
1792 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1793 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1794 {
1795 // It has an absolute path, so use it 'as is'
1796 m_VstrInitialFineConsSedimentFile[nLayer] = strRH;
1797 }
1798 else
1799 {
1800 // It has a relative path, so prepend the CoastalME dir
1802 m_VstrInitialFineConsSedimentFile[nLayer].append(strRH);
1803 }
1804 }
1805 break;
1806
1807 case 5:
1808 // Initial sand consolidated sediment depth GIS file (can be blank)
1809 if (! strRH.empty())
1810 {
1811 // Set switch
1812 m_bHaveSandSediment = true;
1813#ifdef _WIN32
1814 // For Windows, make sure has backslashes, not Unix-style slashes
1815 strRH = pstrChangeToBackslash(&strRH);
1816#endif
1817 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1818 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1819 {
1820 // It has an absolute path, so use it 'as is'
1821 m_VstrInitialSandConsSedimentFile[nLayer] = strRH;
1822 }
1823 else
1824 {
1825 // It has a relative path, so prepend the CoastalME dir
1827 m_VstrInitialSandConsSedimentFile[nLayer].append(strRH);
1828 }
1829 }
1830 break;
1831
1832 case 6:
1833 // Initial coarse consolidated sediment depth GIS file (can be blank)
1834 if (! strRH.empty())
1835 {
1836 // Set switch
1837 m_bHaveCoarseSediment = true;
1838#ifdef _WIN32
1839 // For Windows, make sure has backslashes, not Unix-style slashes
1840 strRH = pstrChangeToBackslash(&strRH);
1841#endif
1842 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1843 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1844 {
1845 // It has an absolute path, so use it 'as is'
1847 }
1848 else
1849 {
1850 // It has a relative path, so prepend the CoastalME dir
1852 m_VstrInitialCoarseConsSedimentFile[nLayer].append(strRH);
1853 }
1854 }
1855 break;
1856 }
1857
1858 // Did an error occur?
1859 if (! strErr.empty())
1860 {
1861 // Error in input to run details file
1862 cerr << ERR << "reading " << strErr << " in " << m_strDataPathName << endl
1863 << "'" << strRec << "'" << endl;
1864 InStream.close();
1865 return false;
1866 }
1867 }
1868 }
1869 break;
1870
1871 case 28:
1872 // Initial suspended sediment depth GIS file (can be blank)
1873 if (! strRH.empty())
1874 {
1875 // Set switch
1876 m_bHaveFineSediment = true;
1877#ifdef _WIN32
1878 // For Windows, make sure has backslashes, not Unix-style slashes
1879 strRH = pstrChangeToBackslash(&strRH);
1880#endif
1881 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1882 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1883 {
1884 // It has an absolute path, so use it 'as is'
1886 }
1887 else
1888 {
1889 // It has a relative path, so prepend the CoastalME dir
1891 m_strInitialSuspSedimentFile.append(strRH);
1892 }
1893 }
1894 break;
1895
1896 case 29:
1897 // Initial Landform class GIS file (can be blank)
1898 if (! strRH.empty())
1899 {
1900#ifdef _WIN32
1901 // For Windows, make sure has backslashes, not Unix-style slashes
1902 strRH = pstrChangeToBackslash(&strRH);
1903#endif
1904 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1905 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1906 {
1907 // It has an absolute path, so use it 'as is'
1909 }
1910 else
1911 {
1912 // It has a relative path, so prepend the CoastalME dir
1914 m_strInitialLandformFile.append(strRH);
1915 }
1916 }
1917 break;
1918
1919 case 30:
1920 // Initial Intervention class GIS file (can be blank: if so then intervention height file must also be blank)
1921 if (! strRH.empty())
1922 {
1923#ifdef _WIN32
1924 // For Windows, make sure has backslashes, not Unix-style slashes
1925 strRH = pstrChangeToBackslash(&strRH);
1926#endif
1927 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1928 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1929 {
1930 // It has an absolute path, so use it 'as is'
1932 }
1933 else
1934 {
1935 // It has a relative path, so prepend the CoastalME dir
1937 m_strInterventionClassFile.append(strRH);
1938 }
1939
1940 // Set the save switches
1943 }
1944 break;
1945
1946 case 31:
1947 // Initial Intervention height GIS file (can be blank: if so then intervention class file must also be blank)
1948 if (strRH.empty())
1949 {
1950 if (! m_strInterventionClassFile.empty())
1951 strErr = "line " + to_string(nLine) + ": must specify both intervention class and intervention height files";
1952 break;
1953 }
1954 else
1955 {
1956 if (m_strInterventionClassFile.empty())
1957 {
1958 strErr = "line " + to_string(nLine) + ": must specify both intervention class and intervention height files";
1959 break;
1960 }
1961
1962#ifdef _WIN32
1963 // For Windows, make sure has backslashes, not Unix-style slashes
1964 strRH = pstrChangeToBackslash(&strRH);
1965#endif
1966
1967 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
1968 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
1969 {
1970 // It has an absolute path, so use it 'as is'
1972 }
1973 else
1974 {
1975 // It has a relative path, so prepend the CoastalME dir
1977 m_strInterventionHeightFile.append(strRH);
1978 }
1979 }
1980 break;
1981
1982 // ---------------------------------------------------- Hydrology data ------------------------------------------------
1983 case 32:
1984 // Wave propagation model [0 = COVE, 1 = CShore]
1985 if (! bIsStringValidInt(strRH))
1986 {
1987 strErr = "line " + to_string(nLine) + ": invalid integer for wave propagation model '" + strRH + "' in " + m_strDataPathName;
1988 break;
1989 }
1990
1991 m_nWavePropagationModel = stoi(strRH);
1992
1994 strErr = "line " + to_string(nLine) + ": wave propagation model must be 0 or 1";
1995
1996 break;
1997
1998 case 33:
1999 // Density of sea water (kg/m3), first check that this is a valid double
2000 if (! bIsStringValidDouble(strRH))
2001 {
2002 strErr = "line " + to_string(nLine) + ": invalid floating point number for sea water density '" + strRH + "' in " + m_strDataPathName;
2003 break;
2004 }
2005
2006 m_dSeaWaterDensity = strtod(strRH.c_str(), NULL);
2007
2008 if (m_dSeaWaterDensity <= 0)
2009 strErr = "line " + to_string(nLine) + ": sea water density must be > 0";
2010 break;
2011
2012 case 34:
2013 // Initial still water level (m), first check that this is a valid double TODO 041 Make this a per-timestep SWL file
2014 if (! bIsStringValidDouble(strRH))
2015 {
2016 strErr = "line " + to_string(nLine) + ": invalid floating point number for initial SWL '" + strRH + "' in " + m_strDataPathName;
2017 break;
2018 }
2019
2020 m_dOrigSWL = strtod(strRH.c_str(), NULL);
2021 break;
2022
2023 case 35:
2024 // Final still water level (m) [blank = same as initial SWL]
2025 if (strRH.empty())
2027 else
2028 {
2029 // Check that this is a valid double
2030 if (! bIsStringValidDouble(strRH))
2031 {
2032 strErr = "line " + to_string(nLine) + ": invalid floating point number for final SWL '" + strRH + "' in " + m_strDataPathName;
2033 break;
2034 }
2035
2036 m_dFinalSWL = strtod(strRH.c_str(), NULL);
2037 }
2038 break;
2039
2040 case 36:
2041 // Deep water wave height (m) or a file of point vectors giving deep water wave height (m) and orientation (for units, see below)
2042 if (strRH.empty())
2043 strErr = "line " + to_string(nLine) + ": deep water wave height in " + m_strDataPathName + " must be either a number or a filename (filename must not start with a number)";
2044 else
2045 {
2046 if (isdigit(strRH.at(0))) // If this starts with a number then is a single value, otherwise is a filename. Note that filename must not start with number
2047 {
2048 // Just one value of wave height for all deep water cells, first check that this is a valid double
2049 if (! bIsStringValidDouble(strRH))
2050 {
2051 strErr = "line " + to_string(nLine) + ": invalid floating point number for deep water wave height '" + strRH + "' in " + m_strDataPathName;
2052 break;
2053 }
2054
2056 m_bHaveWaveStationData = false;
2057
2058 m_dAllCellsDeepWaterWaveHeight = strtod(strRH.c_str(), NULL);
2059
2061 strErr = "line " + to_string(nLine) + ": deep water wave height must be > 0";
2062 }
2063 else
2064 {
2065 // We are reading deep water wave height and deep water wave orientation from two files. This first file is a point shape file with the location of the buoys and integer ID for each one
2067#ifdef _WIN32
2068 // For Windows, make sure has backslashes, not Unix-style slashes
2069 strRH = pstrChangeToBackslash(&strRH);
2070#endif
2071 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
2072 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
2073 {
2074 // It has an absolute path, so use it 'as is'
2076 }
2077 else
2078 {
2079 // It has a relative path, so prepend the CoastalME dir
2082 }
2083 }
2084 }
2085 break;
2086
2087 case 37:
2088 // Deep water wave height input file. Each point in m_strDeepWaterWavesInputFile is a triad of wave height, orientation and period for each time step
2090 {
2091 if (strRH.empty())
2092 {
2093 strErr = "line " + to_string(nLine) + ": filename missing for deep water wave height input";
2094 break;
2095 }
2096
2097#ifdef _WIN32
2098 // For Windows, make sure has backslashes, not Unix-style slashes
2099 strRH = pstrChangeToBackslash(&strRH);
2100#endif
2101
2102 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
2103 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
2104 {
2105 // It has an absolute path, so use it 'as is'
2107 }
2108 else
2109 {
2110 // It has a relative path, so prepend the CoastalME dir
2112 m_strDeepWaterWavesInputFile.append(strRH);
2113 }
2114 }
2115 break;
2116
2117 case 38:
2118 // Deep water wave orientation in input CRS: this is the oceanographic convention i.e. direction TOWARDS which the waves move (in degrees clockwise from north)
2120 {
2121 // Only read this if we have just a single value of wave height for all deep water cells. Check that this is a valid double
2122 if (! bIsStringValidDouble(strRH))
2123 {
2124 strErr = "line " + to_string(nLine) + ": invalid floating point number for deep water wave orientation '" + strRH + "' in " + m_strDataPathName;
2125 break;
2126 }
2127
2128 m_dAllCellsDeepWaterWaveAngle = strtod(strRH.c_str(), NULL);
2129
2131 strErr = "line " + to_string(nLine) + ": deep water wave orientation must be zero degrees or more";
2132 else if (m_dAllCellsDeepWaterWaveAngle >= 360)
2133 strErr = "line " + to_string(nLine) + ": deep water wave orientation must be less than 360 degrees";
2134 }
2135 break;
2136
2137 case 39:
2138 // Wave period (sec)
2140 {
2141 // Only read this if we also have just a single value of wave height for all deep water cells. Check that this is a valid double
2142 if (! bIsStringValidDouble(strRH))
2143 {
2144 strErr = "line " + to_string(nLine) + ": invalid floating point number for wave period '" + strRH + "' in " + m_strDataPathName;
2145 break;
2146 }
2147
2148 m_dAllCellsDeepWaterWavePeriod = strtod(strRH.c_str(), NULL);
2149
2151 strErr = "line " + to_string(nLine) + ": wave period must be > 0";
2152 }
2153 break;
2154
2155 case 40:
2156 // Tide data file (can be blank). This is the change (m) from still water level for each timestep
2157 if (! strRH.empty())
2158 {
2159#ifdef _WIN32
2160 // For Windows, make sure has backslashes, not Unix-style slashes
2161 strRH = pstrChangeToBackslash(&strRH);
2162#endif
2163 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
2164 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
2165 // It has an absolute path, so use it 'as is'
2166 m_strTideDataFile = strRH;
2167 else
2168 {
2169 // It has a relative path, so prepend the CoastalME dir
2171 m_strTideDataFile.append(strRH);
2172 }
2173 }
2174 break;
2175
2176 case 41:
2177 // Breaking wave height-to-depth ratio, check that this is a valid double
2178 if (! bIsStringValidDouble(strRH))
2179 {
2180 strErr = "line " + to_string(nLine) + ": invalid floating point number for breaking wave height to depth ratio '" + strRH + "' in " + m_strDataPathName;
2181 break;
2182 }
2183
2184 m_dBreakingWaveHeightDepthRatio = strtod(strRH.c_str(), NULL);
2185
2187 strErr = "line " + to_string(nLine) + ": breaking wave height to depth ratio must be > 0";
2188 break;
2189
2190 // ----------------------------------------------------- Sediment data ------------------------------------------------
2191 case 42:
2192 // Simulate coast platform erosion?
2193 strRH = strToLower(&strRH);
2194
2195 if (strRH.find("y") != string::npos)
2197 break;
2198
2199 case 43:
2200 // If simulating coast platform erosion, R (coast platform resistance to erosion) values along profile, see Walkden & Hall, 2011
2202 {
2203 // First check that this is a valid double
2204 if (! bIsStringValidDouble(strRH))
2205 {
2206 strErr = "line " + to_string(nLine) + ": invalid floating point number for R (coast platform resistance to erosion) '" + strRH + "' in " + m_strDataPathName;
2207 break;
2208 }
2209
2210 m_dR = strtod(strRH.c_str(), NULL);
2211
2212 if (m_dR <= 0)
2213 strErr = "line " + to_string(nLine) + ": R (coast platform resistance to erosion) value must be > 0";
2214 }
2215 break;
2216
2217 case 44:
2218 // Simulate beach sediment transport?
2219 strRH = strToLower(&strRH);
2220
2222 if (strRH.find("y") != string::npos)
2224 break;
2225
2226 case 45:
2227 // If simulating beach sediment transport, beach sediment transport at grid edges [0 = closed, 1 = open, 2 = re-circulate]
2229 {
2230 if (! bIsStringValidInt(strRH))
2231 {
2232 strErr = "line " + to_string(nLine) + ": invalid integer for beach sediment transport at grid edges '" + strRH + "' in " + m_strDataPathName;
2233 break;
2234 }
2235
2237
2239 strErr = "line " + to_string(nLine) + ": switch for handling of beach sediment at grid edges must be 0, 1, or 2";
2240 }
2241 break;
2242
2243 case 46:
2244 // If simulating beach sediment transport, beach erosion/deposition equation [0 = CERC, 1 = Kamphuis]
2246 {
2247 if (! bIsStringValidInt(strRH))
2248 {
2249 strErr = "line " + to_string(nLine) + ": invalid integer for beach erosion/deposition equation '" + strRH + "' in " + m_strDataPathName;
2250 break;
2251 }
2252
2254
2256 strErr = "line " + to_string(nLine) + ": switch for beach erosion/deposition equation must be 0 or 1";
2257 }
2258 break;
2259
2260 case 47:
2261 // Median size of fine sediment (mm), always needed [0 = default, only for Kamphuis eqn]. First check that this is a valid double
2262 if (! bIsStringValidDouble(strRH))
2263 {
2264 strErr = "line " + to_string(nLine) + ": invalid floating point number for median particle size of fine sediment '" + strRH + "' in " + m_strDataPathName;
2265 break;
2266 }
2267
2268 m_dD50Fine = strtod(strRH.c_str(), NULL);
2269
2270 if (m_dD50Fine < 0)
2271 strErr = "line " + to_string(nLine) + ": median particle size of fine sediment must be > 0";
2272 else if (bFPIsEqual(m_dD50Fine, 0.0, TOLERANCE))
2273 // Use default value
2275
2276 break;
2277
2278 case 48:
2279 // Median size of sand sediment (mm), always needed [0 = default, only for Kamphuis eqn]. First check that this is a valid double
2280 if (! bIsStringValidDouble(strRH))
2281 {
2282 strErr = "line " + to_string(nLine) + ": invalid floating point number for median particle size of sand sediment '" + strRH + "' in " + m_strDataPathName;
2283 break;
2284 }
2285
2286 m_dD50Sand = strtod(strRH.c_str(), NULL);
2287
2288 if (m_dD50Sand < 0)
2289 strErr = "line " + to_string(nLine) + ": median particle size of sand sediment must be > 0";
2290 else if (bFPIsEqual(m_dD50Sand, 0.0, TOLERANCE))
2291 // Use default value
2293
2294 break;
2295
2296 case 49:
2297 // Median size of coarse sediment (mm), always needed [0 = default, only for Kamphuis eqn]. First check that this is a valid double
2298 if (! bIsStringValidDouble(strRH))
2299 {
2300 strErr = "line " + to_string(nLine) + ": invalid floating point number for median particle size of coarse sediment '" + strRH + "' in " + m_strDataPathName;
2301 break;
2302 }
2303
2304 m_dD50Coarse = strtod(strRH.c_str(), NULL);
2305
2306 if (m_dD50Coarse < 0)
2307 strErr = "line " + to_string(nLine) + ": median particle size of coarse sediment must be > 0";
2308 else if (bFPIsEqual(m_dD50Coarse, 0.0, TOLERANCE))
2309 // Use default value
2311
2312 break;
2313
2314 case 50:
2315 // Density of unconsolidated beach sediment (kg/m3)
2317 {
2318 // First check that this is a valid double
2319 if (! bIsStringValidDouble(strRH))
2320 {
2321 strErr = "line " + to_string(nLine) + ": invalid floating point number for density of beach sediment '" + strRH + "' in " + m_strDataPathName;
2322 break;
2323 }
2324
2325 m_dBeachSedimentDensity = strtod(strRH.c_str(), NULL);
2326
2327 if (m_dBeachSedimentDensity <= 0)
2328 strErr = "line " + to_string(nLine) + ": density of beach sediment must be > 0";
2329 }
2330 break;
2331
2332 case 51:
2333 // Beach sediment porosity
2335 {
2336 // First check that this is a valid double
2337 if (! bIsStringValidDouble(strRH))
2338 {
2339 strErr = "line " + to_string(nLine) + ": invalid floating point number for porosity of beach sediment '" + strRH + "' in " + m_strDataPathName;
2340 break;
2341 }
2342
2343 m_dBeachSedimentPorosity = strtod(strRH.c_str(), NULL);
2344
2345 if (m_dBeachSedimentPorosity <= 0)
2346 strErr = "line " + to_string(nLine) + ": porosity of beach sediment must be > 0";
2347 }
2348 break;
2349
2350 case 52:
2351 // Relative erodibility (0 - 1) of fine-sized sediment, always needed. First check that this is a valid double
2352 if (! bIsStringValidDouble(strRH))
2353 {
2354 strErr = "line " + to_string(nLine) + ": invalid floating point number for erodibility of fine-sized sediment '" + strRH + "' in " + m_strDataPathName;
2355 break;
2356 }
2357
2358 m_dFineErodibility = strtod(strRH.c_str(), NULL);
2359
2360 if ((m_dFineErodibility < 0) || (m_dFineErodibility > 1))
2361 strErr = "line " + to_string(nLine) + ": relative erodibility of fine-sized sediment must be between 0 and 1";
2362
2363 break;
2364
2365 case 53:
2366 // Relative erodibility (0 - 1) of sand-sized sediment, always needed. First check that this is a valid double
2367 if (! bIsStringValidDouble(strRH))
2368 {
2369 strErr = "line " + to_string(nLine) + ": invalid floating point number for erodibility of sand-sized sediment '" + strRH + "' in " + m_strDataPathName;
2370 break;
2371 }
2372
2373 m_dSandErodibility = strtod(strRH.c_str(), NULL);
2374
2375 if ((m_dSandErodibility < 0) || (m_dSandErodibility > 1))
2376 strErr = "line " + to_string(nLine) + ": relative erodibility of sand-sized sediment must be between 0 and 1";
2377
2378 break;
2379
2380 case 54:
2381 // Relative erodibility (0 - 1) of coarse-sized sediment, always needed. First check that this is a valid double
2382 if (! bIsStringValidDouble(strRH))
2383 {
2384 strErr = "line " + to_string(nLine) + ": invalid floating point number for erodibility of coarse-sized sediment '" + strRH + "' in " + m_strDataPathName;
2385 break;
2386 }
2387
2388 m_dCoarseErodibility = strtod(strRH.c_str(), NULL);
2389
2390 if ((m_dCoarseErodibility < 0) || (m_dCoarseErodibility > 1))
2391 {
2392 strErr = "line " + to_string(nLine) + ": relative erodibility of coarse-sized sediment must be between 0 and 1";
2393 break;
2394 }
2395
2397 strErr = "line " + to_string(nLine) + ": must have at least one non-zero erodibility value";
2398
2399 break;
2400
2401 case 55:
2402 // Transport parameter KLS in CERC equation
2404 {
2405 // First check that this is a valid double
2406 if (! bIsStringValidDouble(strRH))
2407 {
2408 strErr = "line " + to_string(nLine) + ": invalid floating point number for transport parameter KLS of CERC equation '" + strRH + "' in " + m_strDataPathName;
2409 break;
2410 }
2411
2412 m_dKLS = strtod(strRH.c_str(), NULL);
2413 // However, many sites do not have transport data available to calibrate K, and for design applications without calibration data the CERC formula provides only order-of-magnitude accuracy (Fowler et al., 1995; Wang et al., 1998). The recommended value of K = 0.39 has been commonly used to represent the potential longshore transport rate. However, Miller (1998) found that the CERC formula sometimes over and sometimes under predicted longshore transport rate for measurements during storms, indicating the value of K also can be higher than 0.39
2414 // TODO 042 Should this be a user input, or not? The comment above seems inconclusive
2415 // m_dKLS = tMin(m_dKLS, 0.39);
2416
2417 if (m_dKLS <= 0)
2418 strErr = "line " + to_string(nLine) + ": transport parameter KLS of CERC equation must be > 0";
2419 }
2420 break;
2421
2422 case 56:
2423 // Transport parameter for Kamphuis equation
2425 {
2426 // First check that this is a valid double
2427 if (! bIsStringValidDouble(strRH))
2428 {
2429 strErr = "line " + to_string(nLine) + ": invalid floating point number for transport parameter of Kamphuis equation '" + strRH + "' in " + m_strDataPathName;
2430 break;
2431 }
2432
2433 m_dKamphuis = strtod(strRH.c_str(), NULL);
2434
2435 if (m_dKamphuis <= 0)
2436 strErr = "line " + to_string(nLine) + ": transport parameter of Kamphuis equation must be > 0";
2437 }
2438 break;
2439
2440 case 57:
2441 // Berm height i.e. height above SWL of start of depositional Dean profile
2443 {
2444 // First check that this is a valid double
2445 if (! bIsStringValidDouble(strRH))
2446 {
2447 strErr = "line " + to_string(nLine) + ": invalid floating point number for Dean profile start height above SWL '" + strRH + "' in " + m_strDataPathName;
2448 break;
2449 }
2450
2451 m_dDeanProfileStartAboveSWL = strtod(strRH.c_str(), NULL);
2452
2454 strErr = "line " + to_string(nLine) + ": Berm height (Dean profile start height above SWL) must be >= 0";
2455 }
2456 break;
2457
2458 // ------------------------------------------------ Cliff collapse data -----------------------------------------------
2459 case 58:
2460 // Simulate cliff collapse?
2461 strRH = strToLower(&strRH);
2462
2463 if (strRH.find("y") != string::npos)
2464 m_bDoCliffCollapse = true;
2465 break;
2466
2467 case 59:
2468 // Cliff resistance to erosion
2470 {
2471 // First check that this is a valid double
2472 if (! bIsStringValidDouble(strRH))
2473 {
2474 strErr = "line " + to_string(nLine) + ": invalid floating point number for cliff resistance to erosion '" + strRH + "' in " + m_strDataPathName;
2475 break;
2476 }
2477
2478 m_dCliffErosionResistance = strtod(strRH.c_str(), NULL);
2479
2481 strErr = "line " + to_string(nLine) + ": cliff resistance to erosion must be > 0";
2482 }
2483 break;
2484
2485 case 60:
2486 // Notch overhang at collapse (m)
2488 {
2489 // First check that this is a valid double
2490 if (! bIsStringValidDouble(strRH))
2491 {
2492 strErr = "line " + to_string(nLine) + ": invalid floating point number for cliff notch overhang at collapse '" + strRH + "' in " + m_strDataPathName;
2493 break;
2494 }
2495
2496 m_dNotchDepthAtCollapse = strtod(strRH.c_str(), NULL);
2497
2498 if (m_dNotchDepthAtCollapse <= 0)
2499 strErr = "line " + to_string(nLine) + ": cliff notch overhang at collapse must be > 0";
2500 }
2501 break;
2502
2503 case 61:
2504 // Notch base below still water level (m)
2506 {
2507 m_dNotchBaseBelowSWL = strtod(strRH.c_str(), NULL);
2508 if (m_dNotchBaseBelowSWL < 0)
2509 strErr = "line " + to_string(nLine) + ": cliff notch base below still water level must be > 0";
2510 }
2511 break;
2512
2513 case 62:
2514 // Scale parameter A for cliff deposition (m^(1/3)) [0 = auto]
2516 {
2517 // First check that this is a valid double
2518 if (! bIsStringValidDouble(strRH))
2519 {
2520 strErr = "line " + to_string(nLine) + ": invalid floating point number for scale parameter A for cliff deposition '" + strRH + "' in " + m_strDataPathName;
2521 break;
2522 }
2523
2524 m_dCliffDepositionA = strtod(strRH.c_str(), NULL);
2525
2526 if (m_dCliffDepositionA < 0)
2527 strErr = "line " + to_string(nLine) + ": scale parameter A for cliff deposition must be 0 [= auto] or greater";
2528 }
2529 break;
2530
2531 case 63:
2532 // Approximate planview width of cliff collapse talus (in m)
2534 {
2535 // First check that this is a valid double
2536 if (! bIsStringValidDouble(strRH))
2537 {
2538 strErr = "line " + to_string(nLine) + ": invalid floating point number for width of cliff collapse talus '" + strRH + "' in " + m_strDataPathName;
2539 break;
2540 }
2541
2542 m_dCliffDepositionPlanviewWidth = strtod(strRH.c_str(), NULL);
2543
2545 strErr = "line " + to_string(nLine) + ": planview width of cliff deposition must be > 0";
2546
2547 }
2548 break;
2549
2550 case 64:
2551 // Planview length of cliff deposition talus (m)
2553 {
2554 // First check that this is a valid double
2555 if (! bIsStringValidDouble(strRH))
2556 {
2557 strErr = "line " + to_string(nLine) + ": invalid floating point number for planview length of cliff deposition '" + strRH + "' in " + m_strDataPathName;
2558 break;
2559 }
2560
2561 m_dCliffTalusMinDepositionLength = strtod(strRH.c_str(), NULL);
2562
2564 strErr = "line " + to_string(nLine) + ": planview length of cliff deposition must be > 0";
2565 }
2566 break;
2567
2568 case 65:
2569 // Height of landward end of talus, as a fraction of cliff elevation
2571 {
2572 // First check that this is a valid double
2573 if (! bIsStringValidDouble(strRH))
2574 {
2575 strErr = "line " + to_string(nLine) + ": invalid floating point number for height of cliff collapse (as a fraction of cliff elevation) '" + strRH + "' in " + m_strDataPathName;
2576 break;
2577 }
2578
2579 m_dMinCliffTalusHeightFrac = strtod(strRH.c_str(), NULL);
2580
2582 strErr = "line " + to_string(nLine) + ": height of cliff collapse (as a fraction of cliff elevation) must be >= 0";
2583 }
2584 break;
2585
2586 // -------------------------------------------------- Input events data -----------------------------------------------
2587 case 66:
2588 // Simulate riverine flooding?
2589 strRH = strToLower(&strRH);
2590
2591 if (strRH.find("y") != string::npos)
2592 {
2593 m_bRiverineFlooding = true;
2597 }
2598 break;
2599
2600 case 67:
2601 // Output riverine flooding vector files
2603 {
2604 if (! strRH.empty())
2605 {
2606 // Convert to lower case
2607 strRH = strToLower(&strRH);
2608
2609 // First look for "all"
2610 if (strRH.find(VECTOR_ALL_RIVER_FLOOD_OUTPUT_CODE) != string::npos)
2611 {
2615 }
2616 else
2617 {
2618 // We are not outputting all vector flood GIS files, so set switches (and remove strings) for those optional files for which the user specified the code
2619 if (strRH.find(VECTOR_FLOOD_SWL_SETUP_LINE_CODE) != string::npos)
2620 {
2621 m_bFloodSWLSetupLine = true;
2623 }
2624
2625 if (strRH.find(VECTOR_FLOOD_SWL_SETUP_SURGE_LINE_CODE) != string::npos)
2626 {
2629 }
2630
2631 if (strRH.find(VECTOR_FLOOD_SWL_SETUP_SURGE_RUNUP_LINE_CODE) != string::npos)
2632 {
2635 }
2636
2637 // Check to see if all codes have been removed
2638 if (! strRH.empty())
2639 strErr = "line " + to_string(nLine) + ": unknown code '" + strRH + "' in list of riverine flooding output codes";
2640 }
2641 }
2642 else
2643 strErr = "line " + to_string(nLine) + ": if simulating riverine flooding, must contain '" + VECTOR_ALL_RIVER_FLOOD_OUTPUT_CODE + "' or at least one vector GIS output code for riverine flooding";
2644 }
2645 break;
2646
2647 case 68:
2649 {
2650 // Run-up equation?
2651 if (bIsStringValidInt(strRH))
2652 {
2653 m_nRunUpEquation = stoi(strRH);
2654 }
2655 else
2656 strErr = "line " + to_string(nLine) + ": invalid code for run-up equation used in simulating floods";
2657 }
2658 break;
2659
2660 case 69:
2662 {
2663 // Characteristic locations for flood?
2664 strRH = strToLower(&strRH);
2665
2666 m_bFloodLocation = false;
2667 if (strRH.find("y") != string::npos)
2668 {
2669 m_bFloodLocation = true;
2670 }
2671 }
2672 break;
2673
2674 case 70:
2676 {
2677 // Path of location points file
2678 if (! strRH.empty())
2679 {
2680#ifdef _WIN32
2681 // For Windows, make sure has backslashes, not Unix-style slashes
2682 strRH = pstrChangeToBackslash(&strRH);
2683#endif
2684 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
2685 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
2686 // It has an absolute path, so use it 'as is'
2688 else
2689 {
2690 // It has a relative path, so prepend the CoastalME dir
2692 m_strFloodLocationShapefile.append(strRH);
2693 }
2694
2695 // Set the switch
2696 m_bFloodLocation = true;
2697 }
2698 else
2699 strErr = "line " + to_string(nLine) + ": path of location points file must not be empty if simulating floods";
2700 }
2701 break;
2702
2703 case 71:
2704 // Simulate sediment input?
2705 strRH = strToLower(&strRH);
2706
2707 if (strRH.find("y") != string::npos)
2708 {
2709 m_bSedimentInput = true;
2711 }
2712 break;
2713
2714 case 72:
2715 // Sediment input location (point or line shapefile)
2716 if (m_bSedimentInput)
2717 {
2718 if (! strRH.empty())
2719 {
2720#ifdef _WIN32
2721 // For Windows, make sure has backslashes, not Unix-style slashes
2722 strRH = pstrChangeToBackslash(&strRH);
2723#endif
2724 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
2725 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
2726 // It has an absolute path, so use it 'as is'
2728 else
2729 {
2730 // It has a relative path, so prepend the CoastalME dir
2733 }
2734 }
2735 }
2736 break;
2737
2738 case 73:
2739 // Sediment input type: required if have shapefile [P = Point, C = coast block, L = line]
2740 if (m_bSedimentInput)
2741 {
2742 strRH = strToLower(&strRH);
2743
2744 if (strRH.find("p") != string::npos)
2746 else if (strRH.find("c") != string::npos)
2748 else if (strRH.find("l") != string::npos)
2750 else
2751 strErr = "line " + to_string(nLine) + ": Sediment input type must be P, C, or L";
2752 }
2753 break;
2754
2755 case 74:
2756 // Sediment input details file (required if have shapefile)
2757 if (m_bSedimentInput)
2758 {
2759 if (strRH.empty())
2760 {
2761 strErr = "line " + to_string(nLine) + ": filename missing for sediment input";
2762 break;
2763 }
2764
2765#ifdef _WIN32
2766 // For Windows, make sure has backslashes, not Unix-style slashes
2767 strRH = pstrChangeToBackslash(&strRH);
2768#endif
2769
2770 // Now check for leading slash, or leading Unix home dir symbol, or occurrence of a drive letter
2771 if ((strRH[0] == PATH_SEPARATOR) || (strRH[0] == TILDE) || (strRH[1] == COLON))
2772 {
2773 // It has an absolute path, so use it 'as is'
2775 }
2776 else
2777 {
2778 // It has a relative path, so prepend the CoastalME dir
2780 m_strSedimentInputEventFile.append(strRH);
2781 }
2782 }
2783 break;
2784
2785 // ------------------------------------------------------ Other data --------------------------------------------------
2786 case 75:
2787 // Gravitational acceleration (m2/s). First check that this is a valid double
2788 if (! bIsStringValidDouble(strRH))
2789 {
2790 strErr = "line " + to_string(nLine) + ": invalid floating point number for gravitational acceleration '" + strRH + "' in " + m_strDataPathName;
2791 break;
2792 }
2793
2794 m_dG = strtod(strRH.c_str(), NULL);
2795
2796 if (m_dG <= 0)
2797 strErr = "line " + to_string(nLine) + ": gravitational acceleration must be > 0";
2798 break;
2799
2800 case 76:
2801 // Spacing of coastline normals (m)
2802 m_dCoastNormalSpacing = strtod(strRH.c_str(), NULL);
2803
2805 m_nCoastNormalSpacing = DEFAULT_PROFILE_SPACING; // In cells, we will set m_dCoastNormalSpacing later when we know m_dCellSide
2806 else if (m_dCoastNormalSpacing < 0)
2807 strErr = "line " + to_string(nLine) + ": spacing of coastline normals must be > 0";
2808 break;
2809
2810 case 77:
2811 // Random factor for spacing of normals [0 to 1, 0 = deterministic], check that this is a valid double
2812 if (! bIsStringValidDouble(strRH))
2813 {
2814 strErr = "line " + to_string(nLine) + ": invalid floating point number for random factor for spacing of coastline normals '" + strRH + "' in " + m_strDataPathName;
2815 break;
2816 }
2817
2818 m_dCoastNormalRandSpacingFactor = strtod(strRH.c_str(), NULL);
2819
2821 strErr = "line " + to_string(nLine) + ": random factor for spacing of coastline normals must be >= 0";
2823 strErr = "line " + to_string(nLine) + ": random factor for spacing of coastline normals must be < 1";
2824 break;
2825
2826 case 78:
2827 // Length of coastline normals (m), check that this is a valid double
2828 if (! bIsStringValidDouble(strRH))
2829 {
2830 strErr = "line " + to_string(nLine) + ": invalid floating point number for length of coastline normals '" + strRH + "' in " + m_strDataPathName;
2831 break;
2832 }
2833
2834 m_dCoastNormalLength = strtod(strRH.c_str(), NULL);
2835
2836 if (m_dCoastNormalLength <= 0)
2837 strErr = "line " + to_string(nLine) + ": length of coastline normals must be > 0";
2838 break;
2839
2840 case 79:
2841 // Start depth for wave calcs (ratio to deep water wave height), check that this is a valid double
2842 if (! bIsStringValidDouble(strRH))
2843 {
2844 strErr = "line " + to_string(nLine) + ": invalid floating point number for start depth for wave calcs '" + strRH + "' in " + m_strDataPathName;
2845 break;
2846 }
2847
2848 m_dWaveDepthRatioForWaveCalcs = strtod(strRH.c_str(), NULL);
2849
2851 strErr = "line " + to_string(nLine) + ": start depth for wave calcs must be > 0";
2852 break;
2853
2854
2855 // ----------------------------------------------------- Testing only -------------------------------------------------
2856 case 80:
2857 // Output profile data?
2858 strRH = strToLower(&strRH);
2859
2860 m_bOutputProfileData = false;
2861 if (strRH.find("y") != string::npos)
2862 {
2863 m_bOutputProfileData = true;
2864
2866 {
2867 strErr = "line " + to_string(nLine) + ": cannot save profiile data if not simulating shore platform erosion";
2868 break;
2869 }
2870
2871 // TODO 043 What about randomness of profile spacing, since profile location is determined by curvature?
2872 }
2873
2874 break;
2875
2876 case 81:
2877 // Numbers of profiles to be saved
2879 {
2880 VstrTmp = VstrSplit(&strRH, SPACE);
2881 for (unsigned int j = 0; j < VstrTmp.size(); j++)
2882 {
2883 VstrTmp[j] = strTrim(&VstrTmp[j]);
2884
2885 if (! bIsStringValidInt(VstrTmp[j]))
2886 {
2887 strErr = "line " + to_string(nLine) + ": invalid integer for profile to be saved '" + VstrTmp[j] + "' in " + m_strDataPathName;
2888 break;
2889 }
2890
2891 int nTmp = stoi(VstrTmp[j]);
2892
2893 if (nTmp < 0)
2894 {
2895 strErr = "line " + to_string(nLine) + ": Profile number for saving must be >= 0";
2896 break;
2897 }
2898
2899 m_VnProfileToSave.push_back(nTmp);
2900 }
2901 }
2902 break;
2903
2904 case 82:
2905 // Timesteps to save profiles
2907 {
2908 VstrTmp = VstrSplit(&strRH, SPACE);
2909 for (unsigned int j = 0; j < VstrTmp.size(); j++)
2910 {
2911 VstrTmp[j] = strTrim(&VstrTmp[j]);
2912 unsigned long ulTmp = atol(VstrTmp[j].c_str());
2913 if (ulTmp < 1)
2914 {
2915 strErr = "line " + to_string(nLine) + ": Timestep for profile saves must >= 1";
2916 break;
2917 }
2918
2919 m_VulProfileTimestep.push_back(ulTmp);
2920 }
2921 }
2922 break;
2923
2924 case 83:
2925 // Output parallel profile data?
2926 strRH = strToLower(&strRH);
2927
2929 if (strRH.find("y") != string::npos)
2931 break;
2932
2933 case 84:
2934 // Output erosion potential look-up data?
2935 strRH = strToLower(&strRH);
2936
2938 if (strRH.find("y") != string::npos)
2940 break;
2941
2942 case 85:
2943 // Size of moving window for coastline curvature calculation (must be odd)
2944 if (! bIsStringValidInt(strRH))
2945 {
2946 strErr = "line " + to_string(nLine) + ": invalid integer for size of moving window for coastline curvature calculation '" + strRH + "' in " + m_strDataPathName;
2947 break;
2948 }
2950
2952 strErr = "line " + to_string(nLine) + ": size of moving window for coastline curvature calculation (must be > 0 and odd)";
2953
2954 break;
2955 }
2956
2957 // Did an error occur?
2958 if (! strErr.empty())
2959 {
2960 // Error in input to run details file
2961 cerr << endl << ERR << strErr << ".\nPlease edit " << m_strDataPathName << " and change this line:" << endl;
2962 cerr << "'" << strRec << "'" << endl << endl;
2963 InStream.close();
2964 return false;
2965 }
2966 }
2967 }
2968
2969 // Close file
2970 InStream.close();
2971
2972 // Finally, need to check that we have at least one raster file, so that we know the grid size and units (and preferably also the projection)
2973 bool bNoRasterFiles = true;
2974 if ((! m_strInitialBasementDEMFile.empty()) || (! m_strInitialSuspSedimentFile.empty()) || (! m_strInitialLandformFile.empty()) || (! m_strInterventionHeightFile.empty()))
2975 bNoRasterFiles = false;
2976
2977 for (int j = 0; j < m_nLayers; j++)
2978 {
2980 bNoRasterFiles = false;
2981 }
2982
2983 if (bNoRasterFiles)
2984 {
2985 // No raster files
2986 cerr << ERR << "at least one raster GIS file is needed" << endl;
2987 return false;
2988 }
2989
2990 return true;
2991}
2992
2993//===============================================================================================================================
2995//===============================================================================================================================
2997{
2998 // Create an ifstream object
2999 ifstream InStream;
3000
3001 // Try to open the file for input
3002 InStream.open(m_strTideDataFile.c_str(), ios::in);
3003
3004 // Did it open OK?
3005 if (!InStream.is_open())
3006 {
3007 // Error: cannot open tide data file for input
3008 cerr << ERR << "cannot open " << m_strTideDataFile << " for input" << endl;
3009 return RTN_ERR_TIDEDATAFILE;
3010 }
3011
3012 // Opened OK
3013 int nLine = 0;
3014 string strRec;
3015
3016 // Now read the data from the file
3017 while (getline(InStream, strRec))
3018 {
3019 nLine++;
3020
3021 // Trim off leading and trailing whitespace
3022 strRec = strTrim(&strRec);
3023
3024 // If it is a blank line or a comment then ignore it
3025 if ((strRec.empty()) || (strRec[0] == QUOTE1) || (strRec[0] == QUOTE2))
3026 continue;
3027
3028 // Check that this is a valid double
3029 if (! bIsStringValidDouble(strRec))
3030 {
3031 cerr << ERR << "invalid floating point number for tide data '" << strRec << "' on line " << nLine << " of " << m_strTideDataFile << endl;
3032 return RTN_ERR_TIDEDATAFILE;
3033 }
3034
3035 // Convert to double then append the value to the vector
3036 m_VdTideData.push_back(strtod(strRec.c_str(), NULL));
3037 }
3038
3039 // Close file
3040 InStream.close();
3041
3042 return RTN_OK;
3043}
3044
3045//===============================================================================================================================
3047//===============================================================================================================================
3049{
3050 // Sort out the path and filename
3054
3055 // Create an ifstream object
3056 ifstream InStream;
3057
3058 // Try to open the file for input
3059 InStream.open(m_strSCAPEShapeFunctionFile.c_str(), ios::in);
3060
3061 // Did it open OK?
3062 if (!InStream.is_open())
3063 {
3064 // Error: cannot open shape function file for input
3065 cerr << ERR << "cannot open " << m_strSCAPEShapeFunctionFile << " for input" << endl;
3067 }
3068
3069 // Opened OK
3070 int nLine = 0;
3071 int nExpected = 0, nRead = 0;
3072 string strRec;
3073
3074 // Read in the number of data lines expected
3075 InStream >> nExpected;
3076
3077 // Set up the vectors to hold the input data
3078 vector<double> VdDepthOverDB;
3079 vector<double> VdErosionPotential;
3080 vector<double> VdErosionPotentialFirstDeriv;
3081
3082 // Now read the rest of the data from the file to get the Erosion Potential Shape function
3083 while (getline(InStream, strRec))
3084 {
3085 nLine++;
3086
3087 // Trim off leading and trailing whitespace
3088 strRec = strTrim(&strRec);
3089
3090 // If it is a blank line or a comment then ignore it
3091 if ((strRec.empty()) || (strRec[0] == QUOTE1) || (strRec[0] == QUOTE2))
3092 continue;
3093
3094 // It isn't so increment counter
3095 nRead++;
3096
3097 // Split the string, and remove whitespace
3098 vector<string> strTmp = VstrSplit(&strRec, SPACE);
3099 for (unsigned int i = 0; i < strTmp.size(); i++)
3100 {
3101 // Remove leading and trailing whitespace
3102 strTmp[i] = strTrim(&strTmp[i]);
3103
3104 // Check that this is a valid double
3105 if (! bIsStringValidDouble(strTmp[i]))
3106 {
3107 cerr << ERR << "on line " + to_string(nLine) + " invalid floating point number for Erosion Potential Shape data '" << strTmp[i] << "' in " << m_strSCAPEShapeFunctionFile << endl;
3109 }
3110 }
3111
3112 // Convert to doubles then append the values to the vectors
3113 VdDepthOverDB.push_back(strtod(strTmp[0].c_str(), NULL));
3114 VdErosionPotential.push_back(strtod(strTmp[1].c_str(), NULL));
3115 VdErosionPotentialFirstDeriv.push_back(strtod(strTmp[2].c_str(), NULL));
3116 }
3117 // Now create the look up table values
3118 m_VdErosionPotential = VdErosionPotential;
3119 m_VdDepthOverDB = VdDepthOverDB;
3120 m_dDepthOverDBMax = VdDepthOverDB[14];
3121
3122 // Close file
3123 InStream.close();
3124
3125 // Did we read in what we expected?
3126 if (nExpected != nRead)
3127 {
3128 cout << ERR << "read in " << nRead << " lines from " << m_strSCAPEShapeFunctionFile << " but " << nExpected << " lines expected" << endl;
3130 }
3131
3132 // Is the shape funcion well defined? i.e. it must be -ve or 0.0 for all values
3133 for (unsigned int j = 0; j < m_VdErosionPotential.size(); j++)
3134 {
3135 if (m_VdErosionPotential[j] > 0)
3136 {
3137 cout << ERR << " in " << m_strSCAPEShapeFunctionFile << ", erosion potential function cannot be positive" << endl;
3139 }
3140 }
3141
3142 // OK, now use this data to create a look-up table to be used for the rest of the simulation
3143 if (! bCreateErosionPotentialLookUp(&VdDepthOverDB, &VdErosionPotential, &VdErosionPotentialFirstDeriv))
3144 {
3145 cout << ERR << "line " + to_string(nLine) + " in " << m_strSCAPEShapeFunctionFile << ": erosion potential function is unbounded for high values of depth over DB" << endl;
3147 }
3148
3149 return RTN_OK;
3150}
3151
3152//===============================================================================================================================
3154//===============================================================================================================================
3155int CSimulation::nReadWaveStationInputFile(int const nWaveStations)
3156{
3157 // Create an ifstream object
3158 ifstream InStream;
3159
3160 // Try to open the file for input
3161 InStream.open(m_strDeepWaterWavesInputFile.c_str(), ios::in);
3162
3163 // Did it open OK?
3164 if (!InStream.is_open())
3165 {
3166 // Error: cannot open time series file for input
3167 cerr << ERR << "cannot open " << m_strDeepWaterWavesInputFile << " for input" << endl;
3169 }
3170
3171 // Opened OK
3172 int nLine = 0;
3173 int nExpectedStations = 0;
3174 int nRead = 0;
3175 int nTimeStepsRead = 0;
3176 string strRec, strErr;
3177
3178 // Read each line, ignoring blank lines and comment lines
3179 while (getline(InStream, strRec))
3180 {
3181 nLine++;
3182
3183 // Trim off leading and trailing whitespace
3184 strRec = strTrim(&strRec);
3185
3186 // If it is a blank line or a comment then ignore it
3187 if ((! strRec.empty()) && (strRec[0] != QUOTE1) && (strRec[0] != QUOTE2))
3188 {
3189 // It isn't so increment counter
3190 nRead++;
3191
3192 // The header lines (the first four lines of the file) contains leading description separated by a colon from the data
3193 if (nRead < 5)
3194 {
3195 // Find the colon: note that lines MUST have a colon separating data from leading description portion
3196 size_t nPos = strRec.find(COLON);
3197 if (nPos == string::npos)
3198 {
3199 // Error: badly formatted (no colon)
3200 cerr << ERR << "on line " << to_string(nLine) << "badly formatted (no ':') in " << m_strDeepWaterWavesInputFile << endl
3201 << "'" << strRec << "'" << endl;
3203 }
3204
3205 if (nPos == strRec.size() - 1)
3206 {
3207 // Error: badly formatted (colon with nothing following)
3208 cerr << ERR << "on line " << to_string(nLine) << "badly formatted (nothing following ':') in " << m_strDeepWaterWavesInputFile << endl
3209 << "'" << strRec << "'" << endl;
3211 }
3212
3213 // Strip off leading portion (the bit up to and including the colon)
3214 string strRH = strRec.substr(nPos + 1);
3215
3216 // Remove leading whitespace
3217 strRH = strTrimLeft(&strRH);
3218
3219 // Look for a trailing comment, if found then terminate string at that point and trim off any trailing whitespace
3220 nPos = strRH.rfind(QUOTE1);
3221 if (nPos != string::npos)
3222 strRH.resize(nPos);
3223
3224 nPos = strRH.rfind(QUOTE2);
3225 if (nPos != string::npos)
3226 strRH.resize(nPos);
3227
3228 // Remove trailing whitespace
3229 strRH = strTrimRight(&strRH);
3230
3231 int nSec = 0;
3232 int nMin = 0;
3233 int nHour = 0;
3234 int nDay = 0;
3235 int nMonth = 0;
3236 int nYear = 0;
3237 double dMult;
3238 double dThisIter;
3239 vector<string> VstrTmp;
3240
3241 switch (nRead)
3242 {
3243 case 1:
3244 // Get the start date/time for this data, format is [hh-mm-ss dd/mm/yyyy]
3245 VstrTmp = VstrSplit(&strRH, SPACE);
3246
3247 // Both date and time here?
3248 if (VstrTmp.size() < 2)
3249 {
3250 strErr = "line " + to_string(nLine) + ": must have both date and time for start of data in";
3251 break;
3252 }
3253
3254 // OK, first sort out the time
3255 if (! bParseTime(&VstrTmp[0], nHour, nMin, nSec))
3256 {
3257 strErr = "line " + to_string(nLine) + ": could not understand start time for data";
3258 break;
3259 }
3260
3261 // Next sort out the date
3262 if (! bParseDate(&VstrTmp[1], nDay, nMonth, nYear))
3263 {
3264 strErr = "line " + to_string(nLine) + ": could not understand start date for data";
3265 break;
3266 }
3267
3268 // Compare time and date with simulation time and date
3269 if ((nSec != m_nSimStartSec) ||
3270 (nMin != m_nSimStartMin) ||
3271 (nHour != m_nSimStartHour) ||
3272 (nDay != m_nSimStartDay) ||
3273 (nMonth != m_nSimStartMonth) ||
3274 (nYear != m_nSimStartYear))
3275 {
3276 strErr = "line " + to_string(nLine) + ": start time and date for wave time series data differs from simulation start time and date,";
3277 break;
3278 }
3279
3280 break;
3281
3282 case 2:
3283 // Get the timestep of this data (in hours or days)
3284 strRH = strToLower(&strRH);
3285
3286 dMult = dGetTimeMultiplier(&strRH);
3287 if (static_cast<int>(dMult) == TIME_UNKNOWN)
3288 {
3289 strErr = "line " + to_string(nLine) + ": unknown units for timestep";
3290 break;
3291 }
3292
3293 // We have the multiplier, now calculate the timestep in hours: look for the whitespace between the number and unit
3294 nPos = strRH.rfind(SPACE);
3295 if (nPos == string::npos)
3296 {
3297 strErr = "line " + to_string(nLine) + ": format of timestep line";
3298 break;
3299 }
3300
3301 // Cut off rh bit of string
3302 strRH.resize(nPos);
3303
3304 // Remove trailing spaces
3305 strRH = strTrimRight(&strRH);
3306
3307 // Check that this is a valid double
3308 if (! bIsStringValidDouble(strRH))
3309 {
3310 strErr = "line " + to_string(nLine) + ": invalid floating point number for timestep";
3311 break;
3312 }
3313
3314 dThisIter = strtod(strRH.c_str(), NULL) * dMult; // in hours
3315
3316 if (dThisIter <= 0)
3317 strErr = "line " + to_string(nLine) + ": timestep must be > 0";
3318
3319 if (! bFPIsEqual(dThisIter, m_dTimeStep, TOLERANCE))
3320 strErr = "line " + to_string(nLine) + ": timestep must be the same as the simulation timestep";
3321
3322 break;
3323
3324 case 3:
3325 // Read the number of stations
3326 if (! bIsStringValidInt(strRH))
3327 {
3328 strErr = "line " + to_string(nLine) + ": invalid integer for number of wave stations '" + strRH + "' in " + m_strDeepWaterWavesInputFile;
3329 break;
3330 }
3331
3332 nExpectedStations = stoi(strRH);
3333
3334 // Check that the number of expected stations is equal to the number of stations on the point shape file
3335 if (nExpectedStations != nWaveStations)
3336 {
3337 // Error: number of points on shape file does not match the number of stations on the wave time series file
3338 strErr = "line " + to_string(nLine) + ": number of wave stations in " + m_strDeepWaterWaveStationsShapefile + " is " + to_string(nWaveStations) + " but we have " + to_string(nExpectedStations) + " stations";
3339
3340 break;
3341 }
3342
3343 break;
3344
3345 case 4:
3346 // Read the expected number of time steps in the file
3347 if (! bIsStringValidInt(strRH))
3348 {
3349 strErr = "line " + to_string(nLine) + ": invalid integer for expected number of time steps '" + strRH + "' in " + m_strDeepWaterWaveStationsShapefile;
3350 break;
3351 }
3352
3354
3356 {
3357 // Error: must have value(s) for at least one timestep
3358 strErr = "line " + to_string(nLine) + ": must have values for at least one timestep";
3359 break;
3360 }
3361
3362 break;
3363 }
3364 }
3365 else
3366 {
3367 // This is not a header line
3368 nTimeStepsRead++;
3369
3370 // Read in each wave attribute for each time step and station: split the string, and remove whitespace
3371 vector<string> VstrTmp = VstrSplit(&strRec, COMMA);
3372 for (unsigned int i = 0; i < VstrTmp.size(); i++) // VstrTmp.size() should be 3 x nExpectedStations
3373 {
3374 // Remove leading and trailing whitespace
3375 VstrTmp[i] = strTrim(&VstrTmp[i]);
3376
3377 // Check that this is a valid double
3378 if (! bIsStringValidDouble(VstrTmp[i]))
3379 {
3380 strErr = "line " + to_string(nLine) + ": invalid floating point number for deep water wave value '" + VstrTmp[i] + "' in " + m_strDeepWaterWavesInputFile;
3381 break;
3382 }
3383 }
3384
3385 // Convert to doubles then append the values to the vectors
3386 int n = 0;
3387 for (int i = 0; i < nExpectedStations; i++)
3388 {
3389 m_VdTSDeepWaterWaveStationHeight.push_back(strtod(VstrTmp[n + 0].c_str(), NULL));
3390 m_VdTSDeepWaterWaveStationAngle.push_back(strtod(VstrTmp[n + 1].c_str(), NULL));
3391 m_VdTSDeepWaterWaveStationPeriod.push_back(strtod(VstrTmp[n + 2].c_str(), NULL));
3392
3393 // Check some simple wave input stats
3396
3399
3400 n += 3;
3401 }
3402 }
3403 }
3404
3405 // Did an error occur?
3406 if (! strErr.empty())
3407 {
3408 // Error in input to initialisation file
3409 cerr << ERR << strErr << " in deep water wave time series file " << m_strDeepWaterWavesInputFile << endl
3410 << "'" << strRec << "'" << endl;
3411 InStream.close();
3412
3414 }
3415 }
3416
3417 if (nTimeStepsRead != m_nDeepWaterWaveDataNumTimeSteps)
3418 {
3419 // Error: number of timesteps read does not match the number given in the file's header
3420 cerr << ERR << "in " << m_strDeepWaterWavesInputFile << ", data for " << nTimeStepsRead << " timesteps was read, but " << m_nDeepWaterWaveDataNumTimeSteps << " timesteps were specified in the file's header" << endl;
3421
3423 }
3424
3425 // Close file
3426 InStream.close();
3427
3428 // Did we read in what we expected?
3429 unsigned int nTotExpected = nExpectedStations * m_nDeepWaterWaveDataNumTimeSteps;
3430 if (m_VdTSDeepWaterWaveStationHeight.size() != nTotExpected)
3431 {
3432 cout << ERR << "read in " << m_VdTSDeepWaterWaveStationHeight.size() << " lines from " << m_strDeepWaterWavesInputFile << " but " << nTotExpected << " values expected" << endl;
3433
3435 }
3436
3437 if (m_VdTSDeepWaterWaveStationAngle.size() != nTotExpected)
3438 {
3439 cout << ERR << "read in " << m_VdTSDeepWaterWaveStationAngle.size() << " lines from " << m_strDeepWaterWavesInputFile << " but " << nTotExpected << " values expected" << endl;
3440
3442 }
3443
3444 if (m_VdTSDeepWaterWaveStationPeriod.size() != nTotExpected)
3445 {
3446 cout << ERR << "read in " << m_VdTSDeepWaterWaveStationPeriod.size() << " lines from " << m_strDeepWaterWavesInputFile << " but " << nTotExpected << " values expected" << endl;
3447
3449 }
3450
3451 // All is OK, so we can now initialize the vectors that will store this timestep's deep water wave values
3452 for (int j = 0; j < nExpectedStations; j++)
3453 {
3457 }
3458
3459 // Finally, check whether the wave data will 'wrap' i.e. whether the number of timesteps is less than the total number of timesteps in the simulation
3460 int nSimulationTimeSteps = static_cast<int>(floor(m_dSimDuration / m_dTimeStep));
3461 if (m_nDeepWaterWaveDataNumTimeSteps < nSimulationTimeSteps)
3462 {
3464 string strTmp = "Deep water wave data will wrap every " + (m_nDeepWaterWaveDataNumTimeSteps > 1 ? to_string(m_nDeepWaterWaveDataNumTimeSteps) + " " : "") + "time step" + (m_nDeepWaterWaveDataNumTimeSteps > 1 ? "s" : "") + " (every " + to_string(m_dWaveDataWrapHours) + " hours)\n";
3465
3466 cout << NOTE << strTmp;
3467 }
3468
3469 return RTN_OK;
3470}
3471
3472//===============================================================================================================================
3474//===============================================================================================================================
3476{
3477 // Create an ifstream object
3478 ifstream InStream;
3479
3480 // Try to open the file for input
3481 InStream.open(m_strSedimentInputEventFile.c_str(), ios::in);
3482
3483 // Did it open OK?
3484 if (!InStream.is_open())
3485 {
3486 // Error: cannot open time series file for input
3487 cerr << ERR << "cannot open " << m_strSedimentInputEventFile << " for input" << endl;
3489 }
3490
3491 // Opened OK
3492 int nLine = 0;
3493 int nRead = 0;
3494 string strRec, strErr;
3495
3496 // Read each line, ignoring comment lines
3497 while (getline(InStream, strRec))
3498 {
3499 nLine++;
3500
3501 // Trim off leading and trailing whitespace
3502 strRec = strTrim(&strRec);
3503
3504 // If it is a blank line or a comment then ignore it
3505 if ((! strRec.empty()) && (strRec[0] != QUOTE1) && (strRec[0] != QUOTE2))
3506 {
3507 // It isn't so increment counter
3508 nRead++;
3509
3510 // Split at commas
3511 vector<string> VstrTmp = VstrSplit(&strRec, COMMA);
3512
3513 // Check that have all we need
3514 unsigned int nTarget = 7;
3516 nTarget = 5;
3517 if (VstrTmp.size() < nTarget)
3518 {
3519 strErr = "line " + to_string(nLine) + ": too few data items on data line '" + to_string(nRead) + "' in " + m_strSedimentInputEventFile;
3520 break;
3521 }
3522
3523 // First item is the Location ID of the sediment input event (same as the ID in the shapefile)
3524 if (! bIsStringValidInt(VstrTmp[0]))
3525 {
3526 strErr = "line " + to_string(nLine) + ": invalid integer for Location ID of sediment input event '" + VstrTmp[0] + "' in " + m_strSedimentInputEventFile;
3527 break;
3528 }
3529
3530 int nID = stoi(strTrim(&VstrTmp[0]));
3531
3532 // OK, check the ID against IDs read in from the shapefile
3533 auto result = find(m_VnSedimentInputLocationID.begin(), m_VnSedimentInputLocationID.end(), nID);
3534 if (result == m_VnSedimentInputLocationID.end())
3535 {
3536 strErr = "line " + to_string(nLine) + ": invalid Location ID '" + to_string(nID) + "' for sediment input event location event in " + m_strSedimentInputEventFile;
3537 break;
3538 }
3539
3540 // Next get the timestep at which the sediment input event occurs. This may be specified either as a relative time (i.e. a number of hours or days after the simulation start) or as an absolute time (i.e. a time/date in the format hh-mm-ss dd/mm/yyyy)
3541 unsigned long ulEventTimeStep = ulConvertToTimestep(&VstrTmp[1]);
3542 if (ulEventTimeStep == SEDIMENT_INPUT_EVENT_ERROR)
3543 {
3544 strErr = "line " + to_string(nLine) + ": invalid time and/or date '" + VstrTmp[1] + "' for sediment input event in " + m_strSedimentInputEventFile;
3545 break;
3546 }
3547
3548 // Then the volume (m3) of fine sediment, first check that this is a valid double
3549 if (! bIsStringValidDouble(VstrTmp[2]))
3550 {
3551 strErr = "line " + to_string(nLine) + ": invalid floating point number '" + VstrTmp[2] + "' for fine sediment volume for sediment input event in " + m_strSedimentInputEventFile;
3552 break;
3553 }
3554
3555 double dFineSedVol = stod(strTrim(&VstrTmp[2]));
3556 if (dFineSedVol < 0)
3557 {
3558 strErr = "line " + to_string(nLine) + ": negative number '" + to_string(dFineSedVol) + "' for fine sediment volume for sediment input event in " + m_strSedimentInputEventFile;
3559 break;
3560 }
3561
3562 if (dFineSedVol > 0)
3563 m_bHaveFineSediment = true;
3564
3565 // Then the volume (m3) of sand sediment, first check that this is a valid double
3566 if (! bIsStringValidDouble(VstrTmp[3]))
3567 {
3568 strErr = "line " + to_string(nLine) + ": invalid floating point number '" + VstrTmp[3] + "' for sand-sized sediment volume for sediment input event in " + m_strSedimentInputEventFile;
3569 break;
3570 }
3571
3572 double dSandSedVol = stod(strTrim(&VstrTmp[3]));
3573 if (dSandSedVol < 0)
3574 {
3575 strErr = "line " + to_string(nLine) + ": negative number '" + to_string(dSandSedVol) + "' for sand-sized sediment volume for sediment input event in " + m_strSedimentInputEventFile;
3576 break;
3577 }
3578
3579 if (dSandSedVol > 0)
3580 m_bHaveSandSediment = true;
3581
3582 // Then the volume (m3) of coarse sediment, first check that this is a valid double
3583 if (! bIsStringValidDouble(VstrTmp[4]))
3584 {
3585 strErr = "line " + to_string(nLine) + ": invalid floating point number '" + VstrTmp[4] + "' for coarse sediment volume for sediment input event in " + m_strSedimentInputEventFile;
3586 break;
3587 }
3588
3589 double dCoarseSedVol = stod(strTrim(&VstrTmp[4]));
3590 if (dCoarseSedVol < 0)
3591 {
3592 strErr = "line " + to_string(nLine) + ": negative number '" + to_string(dCoarseSedVol) + "' for coarse sediment volume of sediment input event in " + m_strSedimentInputEventFile;
3593 break;
3594 }
3595
3596 if (dCoarseSedVol > 0)
3597 m_bHaveCoarseSediment = true;
3598
3599 // Only read the last two items if we have on-coast sediment block sediment input
3600 double dLen = 0;
3601 double dWidth = 0;
3602 // double dThick = 0;
3604 {
3605 // The coast-normal length (m) of the sediment block, first check that this is a valid double
3606 if (! bIsStringValidDouble(VstrTmp[5]))
3607 {
3608 strErr = "line " + to_string(nLine) + ": invalid floating point number '" + VstrTmp[5] + "' for coast-normal length of sediment input event in " + m_strSedimentInputEventFile;
3609 break;
3610 }
3611
3612 dLen = stod(strTrim(&VstrTmp[5]));
3613 if (dLen <= 0)
3614 {
3615 strErr = "line " + to_string(nLine) + ": coast-normal length of the sediment block '" + to_string(dLen) + "' must be > 0 in " + m_strSedimentInputEventFile;
3616 break;
3617 }
3618
3619 // The along-coast width (m) of the sediment block, first check that this is a valid double
3620 if (! bIsStringValidDouble(VstrTmp[6]))
3621 {
3622 strErr = "line " + to_string(nLine) + ": invalid floating point number '" + VstrTmp[6] + "' for along-coast width of sediment input event in " + m_strSedimentInputEventFile;
3623 break;
3624 }
3625
3626 dWidth = stod(strTrim(&VstrTmp[6]));
3627 if ((! m_bSedimentInputAtCoast) && (dWidth <= 0))
3628 {
3629 strErr = "line " + to_string(nLine) + ": along-coast width (m) of the sediment block '" + to_string(dWidth) + "' must be > 0 in " + m_strSedimentInputEventFile;
3630 break;
3631 }
3632
3633 // // The along-coast thickness (m) of the sediment block, first check that this is a valid double
3634 // if (! bIsStringValidDouble(VstrTmp[7]))
3635 // {
3636 // strErr = "line " + to_string(nLine) + ": invalid floating point number '" + VstrTmp[7] + "' for along-coast thickness of sediment input event in " + m_strSedimentInputEventFile;
3637 // break;
3638 // }
3639 //
3640 // dThick = stod(strTrim(&VstrTmp[7]));
3641 // if ((! m_bSedimentInputAtCoast) && (dWidth <= 0))
3642 // {
3643 // strErr = "line " + to_string(nLine) + ": along-coast thickness (m) of the sediment block '" + to_string(dThick) + "' must be > 0 in " + m_strSedimentInputEventFile;
3644 // break;
3645 // }
3646 }
3647
3648 // Create the CSedInputEvent object
3649 CSedInputEvent* pEvent = new CSedInputEvent(nID, ulEventTimeStep, dFineSedVol, dSandSedVol, dCoarseSedVol, dLen, dWidth); //, dThick);
3650
3651 // And store it in the m_pVSedInputEvent vector
3652 m_pVSedInputEvent.push_back(pEvent);
3653 }
3654 }
3655
3656 // Did an error occur?
3657 if (! strErr.empty())
3658 {
3659 // Error in input to initialisation file
3660 cerr << ERR << strErr << " in sediment input event file " << m_strSedimentInputEventFile << endl << "'" << strRec << "'" << endl;
3661 InStream.close();
3662
3664 }
3665
3666 // Close file
3667 InStream.close();
3668
3669 return RTN_OK;
3670}
Class used to represent a sediment input event.
double m_dCliffDepositionPlanviewWidth
Planview width of cliff collapse talus (m)
Definition simulation.h:875
bool m_bCliffCollapseSave
Save cliff collapse raster GIS files?
Definition simulation.h:204
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:531
bool m_bAvgSeaDepthSave
Save average sea depth raster GIS files?
Definition simulation.h:93
vector< string > m_VstrInitialSandConsSedimentFile
The name of the initial sand-sized consolidated sediment GIS file.
double m_dAllCellsDeepWaterWaveHeight
Deep water wave height (m) for all sea cells.
Definition simulation.h:710
bool m_bDeepWaterWaveAngleSave
Save deep water wave angle raster GIS files?
Definition simulation.h:231
int m_nGISMaxSaveDigits
The maximum number of digits in GIS filenames. These can be sequential, or the iteration number.
Definition simulation.h:459
bool m_bTopSurfSave
Save fop surface (sediment and sea) raster DEMs?
Definition simulation.h:84
string m_strInitialSuspSedimentFile
Name of initial suspended sediment file.
vector< double > m_VdTSDeepWaterWaveStationPeriod
Time series of wave period at deep water wave station.
bool m_bSedimentTopSurfSave
Save sediment top surface raster DEMs?
Definition simulation.h:81
bool m_bFineUnconsSedSave
Save fine unconsolidated sediment raster GIS files?
Definition simulation.h:177
string m_strSedimentInputEventFile
The name of the sediment input events time series file.
double m_dNotchDepthAtCollapse
Notch overhang (i.e. length of horizontal incision) to initiate collapse (m)
Definition simulation.h:866
bool m_bFloodSWLSetupSurgeLine
Are we saving the flood still water level setup surge line? TODO 007.
Definition simulation.h:414
string m_strCMEIni
Folder for the CME .ini file.
bool m_bSedimentInputAtPoint
Do we have sediment inputat a point?
Definition simulation.h:369
double m_dG
Gravitational acceleration (m**2/sec)
Definition simulation.h:767
vector< string > m_VstrInitialCoarseUnconsSedimentFile
The name of the initial coarse-sized unconsolidated sediment GIS file.
int m_nBeachErosionDepositionEquation
Which beach erosion-deposition equation is used. Possible values are UNCONS_SEDIMENT_EQUATION_CERC an...
Definition simulation.h:489
bool m_bCoastSave
Save.
Definition simulation.h:249
bool m_bBeachDepositionTSSave
Save the beach (unconsolidated sediment) deposition time series file?
Definition simulation.h:297
static string strRemoveSubstr(string *, string const *)
Returns a string with a substring removed, and with whitespace trimmed.
Definition utils.cpp:2239
vector< string > m_VstrGDALICCDataType
GDAL data type for the initial consolidated coarse sediment GIS data.
static bool bParseTime(string const *, int &, int &, int &)
Parses a time string into hours, minutes, and seconds, and checks each of them.
Definition utils.cpp:2541
double m_dWaveDataWrapHours
Number of hours after which deep water wave data wraps.
Definition simulation.h:917
vector< string > m_VstrGDALICFDataType
GDAL data type for the initial consolidated fine sediment GIS data.
double m_dMaxUserInputWavePeriod
Used to constrain depth of closure.
Definition simulation.h:722
bool m_bFloodSetupSurgeRunupTSSave
Save the flood setup surge runup time series file? TODO 007 Does this work correctly?
Definition simulation.h:309
vector< string > m_VstrGDALICCDriverCode
GDAL driver code for the initial consolidated coarse sediment GIS data.
double m_dCoastNormalLength
Length of the coastline-normal profiles, in m.
Definition simulation.h:782
vector< string > m_VstrGDALIUFDataType
GDAL data type for the initial unconsolidated fine sediment GIS data.
bool m_bSingleDeepWaterWaveValues
Do we have just a point source for (i.e. only a single measurement of) deep water wave values.
Definition simulation.h:360
string m_strRunName
The name of this simulation.
bool m_bAvgWaveAngleAndHeightSave
Save average wave angle and average wave height raster GIS files?
Definition simulation.h:111
string m_strSCAPEShapeFunctionFile
Name of SCAPE shape function file.
bool m_bAvgWaveAngleSave
Save average wave angle raster GIS files?
Definition simulation.h:105
int nReadWaveStationInputFile(int const)
Reads the deep water wave station input data. Each point in m_strDeepWaterWavesInputFile is a triad o...
bool m_bInvalidNormalsSave
Save invalid coastline-normal vector GIS files?
Definition simulation.h:255
bool m_bShadowBoundarySave
Save wave shadow boundary vector GIS files?
Definition simulation.h:270
int nDoSimulationTimeMultiplier(string const *)
Given a string containing time units, this sets up the appropriate multiplier and display units for t...
Definition utils.cpp:298
int nReadSedimentInputEventFile(void)
Reads the sediment input event file.
vector< int > m_VnSedimentInputLocationID
ID for sediment input location, this corresponds with the ID in the sediment input time series file.
bool m_bActualBeachErosionSave
Save actual (supply-limited) beach (unconsolidated sediment) erosion raster GIS files?
Definition simulation.h:144
vector< double > m_VdErosionPotential
For erosion potential lookup.
vector< double > m_VdTideData
Tide data: one record per timestep, is the change (m) from still water level for that timestep.
vector< string > m_VstrGDALIUFProjection
GDAL projection for the initial unconsolidated fine sediment GIS data.
bool m_bStillWaterLevelTSSave
Save the still water level time series file?
Definition simulation.h:279
bool m_bRunUpSave
Are we saving runup? TODO 007.
Definition simulation.h:393
bool m_bCliffCollapseDepositionSave
Save cliff collapse deposition raster GIS files?
Definition simulation.h:210
string m_strSedimentInputEventShapefile
The name of the sediment input events shape file.
bool m_bTotalActualPlatformErosionSave
Save total actual (supply-limited) shore platform erosion raster GIS files?
Definition simulation.h:138
static string strTrimLeft(string const *)
Trims whitespace from the left side of a string, does not change the original string.
Definition utils.cpp:2163
bool m_bPolygonUnconsSedUpOrDownDriftSave
Save polygon unconsolidated sediment up- or down-drift raster GIS files?
Definition simulation.h:240
double m_dCoarseErodibility
The relative erodibility (0- 1) of coarse unconsolidated beach sediment.
Definition simulation.h:749
double m_dCliffTalusMinDepositionLength
Planview length of cliff deposition talus (m)
Definition simulation.h:878
string m_strVectorGISOutFormat
Base name for CME vector GIS output files.
vector< string > m_VstrGDALICFDriverCode
GDAL driver code for the initial consolidated fine sediment GIS data.
vector< string > m_VstrInitialFineConsSedimentFile
The name of the initial fine-sized consolidated sediment GIS file.
int m_nUnconsSedimentHandlingAtGridEdges
How sediment which moves off an edge of the grid is handled. Possible values are GRID_EDGE_CLOSED,...
Definition simulation.h:486
double m_dSandErodibility
The relative erodibility (0- 1) of sand unconsolidated beach sediment.
Definition simulation.h:746
bool m_bBasementElevSave
Save basement raster DEMs?
Definition simulation.h:78
int m_nSimStartHour
Start time of the simulation (hours)
Definition simulation.h:516
bool m_bCoarseUnconsSedSave
Save coarse unconsolidated sediment raster GIS files?
Definition simulation.h:183
bool m_bSuspSedTSSave
Save the suspended sediment time series file?
Definition simulation.h:303
string m_strDeepWaterWaveStationsShapefile
The name of the deep water wave stations shape file.
vector< double > m_VdDepthOverDB
For erosion potential lookup.
bool m_bCliffCollapseNetTSSave
Save the cliff collapse net change time series file?
Definition simulation.h:291
bool m_bPotentialPlatformErosionMaskSave
Save potential platform erosion mask raster GIS files?
Definition simulation.h:219
vector< string > m_VstrGDALICSDriverCode
GDAL driver code for the initial consolidated sand sediment GIS data.
double m_dWaveDepthRatioForWaveCalcs
Start depth for wave calculations.
Definition simulation.h:704
bool m_bWaveHeightSave
Save wave height raster GIS files?
Definition simulation.h:96
bool m_bFloodLocation
Are we saving the flood location? TODO 007.
Definition simulation.h:408
vector< string > m_VstrGDALIUCProjection
GDAL projection for the initial unconsolidated coarse sediment GIS data.
bool m_bLandformSave
Save coast landform raster GIS files?
Definition simulation.h:159
static string strTrim(string const *)
Trims whitespace from both sides of a string, does not change the original string.
Definition utils.cpp:2194
string m_strRasterGISOutFormat
Base name for CME raster GIS output files.
bool m_bTotalBeachDepositionSave
Save total beach (unconsolidated sediment) deposition raster GIS files?
Definition simulation.h:156
double m_dBeachSedimentPorosity
The porosity of unconsolidated beach sediment (0 - 1)
Definition simulation.h:740
int m_nSimStartSec
Start time of the simulation (seconds)
Definition simulation.h:510
int m_nSimStartDay
Start date of the simulation (day)
Definition simulation.h:519
bool m_bSandUnconsSedSave
Save sand unconsolidated sediment raster GIS files?
Definition simulation.h:180
bool m_bActualPlatformErosionTSSave
Save the actual (supply-limited) shore platform erosion time series file?
Definition simulation.h:282
unsigned long ulConvertToTimestep(string const *) const
For sediment input events, parses a string that may be relative (a number of hours or days after the ...
Definition utils.cpp:2602
int m_nCoastNormalSpacing
Average spacing between coastline normals, measured in cells.
Definition simulation.h:450
bool m_bTotCliffCollapseSave
Save total cliff collapse raster GIS files?
Definition simulation.h:207
int nReadShapeFunctionFile(void)
Reads the shape of the erosion potential distribution (see shape function in Walkden & Hall,...
bool m_bDoShorePlatformErosion
Simulate shore platform erosion?
Definition simulation.h:336
bool m_bSliceSave
Save slices?
Definition simulation.h:87
bool m_bRasterPolygonSave
Save raster polygon raster GIS files?
Definition simulation.h:216
bool m_bBeachDepositionSave
Save beach (unconsolidated sediment) deposition raster GIS files?
Definition simulation.h:153
vector< string > m_VstrGDALICSDriverDesc
GDAL driver description for the initial consolidated sand sediment GIS data.
bool m_bSaveRegular
Save GIS files at regular intervals?
Definition simulation.h:246
int m_nLayers
The number of sediment layers.
Definition simulation.h:435
bool m_bSedimentInputAlongLine
Do we have sediment input along a line?
Definition simulation.h:375
bool m_bSedimentInput
Do we have sediment input events?
Definition simulation.h:366
bool m_bNormalsSave
Save coastline-normal vector GIS files?
Definition simulation.h:252
bool m_bAvgWaveHeightSave
Save wave height raster GIS files?
Definition simulation.h:99
static string strToLower(string const *)
Returns the lower case version of an string, leaving the original unchanged.
Definition utils.cpp:2219
vector< double > m_VdThisIterDeepWaterWaveStationHeight
This-iteration wave height at deep water wave station.
vector< string > m_VstrGDALIUFDriverCode
GDAL driver code for the initial unconsolidated fine sediment GIS data.
bool m_bHaveSandSediment
Does this simulation consider sand-sized sediment?
Definition simulation.h:72
bool bReadRunDataFile(void)
Reads the run details input file and does some initialization.
int m_nUSave
If user-defined GIS save intervals, the number of these.
Definition simulation.h:465
double m_dDeanProfileStartAboveSWL
Berm height i.e. height above SWL of start of depositional Dean profile.
Definition simulation.h:911
int m_nSavGolCoastPoly
The order of the coastline profile smoothing polynomial if Savitsky-Golay smoothing is used (usually ...
Definition simulation.h:444
bool m_bSeaDepthSave
Save sea depth raster GIS files?
Definition simulation.h:90
bool m_bWaveAngleAndHeightSave
Save wave angle and wave height raster GIS files?
Definition simulation.h:108
double m_dNotchBaseBelowSWL
Notch base below SWL (m)
Definition simulation.h:869
string m_strInitialBasementDEMFile
Name of initial basement DEM file.
int m_nRunUpEquation
The run-up equation used TODO 007.
Definition simulation.h:534
bool m_bWorldFile
Write a GIS World file?
Definition simulation.h:357
static string strTrimRight(string const *)
Trims whitespace from the right side of a string, does not change the original string.
Definition utils.cpp:2176
string m_strLogFile
Name of output log file.
double m_dDepthOverDBMax
Maximum value of deoth over DB, is used in erosion potential look-up function.
Definition simulation.h:848
double m_dFineErodibility
The relative erodibility (0- 1) of fine unconsolidated beach sediment.
Definition simulation.h:743
double m_dBreakingWaveHeightDepthRatio
Breaking wave height-to-depth ratio.
Definition simulation.h:707
double m_dCoastNormalSpacing
Average spacing of the coastline-normal profiles, in m.
Definition simulation.h:776
bool m_bHaveWaveStationData
Do we have wave station data?
Definition simulation.h:363
double m_dSeaWaterDensity
Density of sea water in kg/m**3.
Definition simulation.h:656
double m_dR
Coast platform resistance to erosion R, see Walkden & Hall, 2011.
Definition simulation.h:725
bool m_bRasterNormalProfileSave
Save rasterized coastline-normal profiles GIS files?
Definition simulation.h:198
bool m_bActiveZoneSave
Save active zone raster GIS files?
Definition simulation.h:201
vector< string > m_VstrInitialSandUnconsSedimentFile
The name of the initial sand-sized unconsolidated sediment GIS file.
bool m_bOmitSearchWestEdge
Omit the west edge of the grid from coast-end searches?
Definition simulation.h:330
bool m_bSedimentInputAtCoast
Do we have sediment input at the coast?
Definition simulation.h:372
double m_dCliffErosionResistance
Resistance of cliff to notch erosion.
Definition simulation.h:863
vector< string > m_VstrGDALIUSProjection
GDAL projection for the initial unconsolidated sand sediment GIS data.
vector< double > m_VdThisIterDeepWaterWaveStationPeriod
This-iteration wave period at deep water wave station.
double m_dD50Sand
The D50 for sand sediment.
Definition simulation.h:731
string m_strCMEDir
The CME folder.
vector< int > m_VnProfileToSave
The numbers of the profiles which are to be saved.
bool m_bDeepWaterWaveHeightSave
Save deep water wave height raster GIS files?
Definition simulation.h:234
bool m_bMeanWaveEnergySave
Save mean wave energy raster GIS files?
Definition simulation.h:120
double m_dKLS
Transport parameter KLS in the CERC equation.
Definition simulation.h:761
int m_nWavePropagationModel
The wave propagation model used. Possible values are WAVE_MODEL_CSHORE and WAVE_MODEL_COVE.
Definition simulation.h:507
double m_dAllCellsDeepWaterWaveAngle
Deep water wave angle for all sea cells.
Definition simulation.h:713
vector< string > m_VstrGDALICFProjection
GDAL projection for the initial consolidated fine sediment GIS data.
vector< string > m_VstrGDALICCProjection
GDAL projection for the initial consolidated coarse sediment GIS data.
static double dGetTimeMultiplier(string const *)
Given a string containing time units, this returns the appropriate multiplier.
Definition utils.cpp:263
bool m_bCoastCurvatureSave
Save coastline-curvature vector GIS files?
Definition simulation.h:258
int m_nDeepWaterWaveDataNumTimeSteps
The duration of data for deep water waves, expressed as a number of time steps.
Definition simulation.h:528
bool m_bRasterWaveFloodLineSave
Are we saving the raster wave flood line? TODO 007.
Definition simulation.h:402
bool m_bBreakingWaveHeightSave
Save breaking wave height raster GIS files?
Definition simulation.h:123
string m_strMailAddress
An email addresx to which to send end-of-simulation messages.
double m_dRegularSaveTime
The time of the next save, in hours from the start of the simulation, if we are saving regularly.
Definition simulation.h:638
bool m_bPolygonNodeSave
Save polygon node vector GIS files?
Definition simulation.h:261
bool m_bOmitSearchNorthEdge
Omit the north edge of the grid from coast-end searches?
Definition simulation.h:324
bool m_bFloodSetupSurgeTSSave
Save the flood setup surge time series file? TODO 007 Does this work correctly?
Definition simulation.h:306
bool m_bTotalPotentialPlatformErosionSave
Save total potential shore platform erosion raster GIS files?
Definition simulation.h:135
bool m_bSetupSurgeFloodMaskSave
Are we saving the setup surge flood mask? TODO 007.
Definition simulation.h:396
bool m_bWaveEnergySinceCollapseSave
Save wave energy since cliff collapse raster GIS files?
Definition simulation.h:117
double m_dD50Coarse
The D50 for coarse sediment.
Definition simulation.h:734
vector< unsigned long > m_VulProfileTimestep
Timesteps at which to save profiles.
bool m_bPotentialBeachErosionSave
Save potential beach (unconsolidated sediment) erosion raster GIS files?
Definition simulation.h:141
static bool bParseDate(string const *, int &, int &, int &)
Parses a date string into days, months, and years, and checks each of them.
Definition utils.cpp:2480
string m_strFloodLocationShapefile
The name of the flood loction events shape file.
bool m_bGISSaveDigitsSequential
Are the GIS save digits (which are part of each GIS file name) sequential, or are they the iteration ...
Definition simulation.h:420
int m_nSimStartMonth
Start date of the simulation (month)
Definition simulation.h:522
bool m_bSuspSedSave
Save suspended sediment raster GIS files?
Definition simulation.h:171
double m_dMinCliffTalusHeightFrac
Minimum height of the landward end of cliff collapse talus, as a fraction of cliff elevation.
Definition simulation.h:881
vector< string > m_VstrGDALIUSDriverDesc
GDAL driver description for the initial unconsolidated sand sediment GIS data.
bool m_bPolygonBoundarySave
Save polygon boundary vector GIS files?
Definition simulation.h:264
bool m_bStormSurgeSave
Are we saving the storm surge? TODO 007.
Definition simulation.h:390
vector< string > m_VstrInitialFineUnconsSedimentFile
The name of the initial fine-sized unconsolidated sediment GIS file.
bool m_bActualPlatformErosionSave
Save actual (supply-limited) shore platform erosion raster GIS files?
Definition simulation.h:132
vector< CSedInputEvent * > m_pVSedInputEvent
Sediment input events.
int m_nSimStartMin
Start time of the simulation (minutes)
Definition simulation.h:513
bool bReadIniFile(void)
The bReadIniFile member function reads the initialization file.
bool m_bHaveFineSediment
Does this simulation consider fine-sized sediment?
Definition simulation.h:69
double m_dCliffDepositionA
Scale parameter A for cliff deposition (m^(1/3)), may be zero for auto-calculation.
Definition simulation.h:872
string m_strDataPathName
Folder in which the CME data file is found.
string m_strOutPath
Path for all output files.
bool m_bBeachErosionTSSave
Save the beach (unconsolidated sediment) erosion time series file?
Definition simulation.h:294
vector< string > m_VstrGDALICFDriverDesc
GDAL driver description for the initial consolidated fine sediment GIS data.
string m_strTideDataFile
Name of tide data file.
vector< string > m_VstrGDALIUFDriverDesc
GDAL driver description for the initial unconsolidated fine sediment GIS data.
bool m_bTotalPotentialBeachErosionSave
Save total potential beach (unconsolidated sediment) erosion raster GIS files?
Definition simulation.h:147
vector< string > m_VstrGDALIUSDataType
GDAL data type for the initial unconsolidated sand sediment GIS data.
string m_strInterventionClassFile
Name of intervention class file.
bool m_bFloodSWLSetupLine
Are we saving the flood still water level setup line? TODO 007.
Definition simulation.h:411
bool m_bSeaMaskSave
Save sea mask raster GIS files?
Definition simulation.h:222
bool m_bInterventionClassSave
Save intervention class raster GIS files?
Definition simulation.h:165
int m_nSimStartYear
Start date of the simulation (year)
Definition simulation.h:525
bool m_bTotalActualBeachErosionSave
Save total actual (supply-limited) beach (unconsolidated sediment) erosion raster GIS files?
Definition simulation.h:150
bool m_bRasterCoastlineSave
Save rasterized coastline GIS files?
Definition simulation.h:195
string m_strDeepWaterWavesInputFile
The name of the deep water wave stations time series file.
static string pstrChangeToBackslash(string const *)
Changes all forward slashes in the input string to backslashes, leaving the original unchanged.
Definition utils.cpp:2143
bool m_bInterventionHeightSave
Save intervention height raster GIS files?
Definition simulation.h:168
int m_nCoastCurvatureMovingWindowSize
Definition simulation.h:539
bool m_bRiverineFlooding
Are we doing flooding? TODO 007.
Definition simulation.h:384
bool m_bSandConsSedSave
Save sand consolidated sediment raster GIS files?
Definition simulation.h:189
bool m_bSedimentInputEventSave
Save sediment inut data?
Definition simulation.h:378
bool m_bHaveCoarseSediment
Does this simulation consider coarse-sized sediment?
Definition simulation.h:75
double m_dRegularSaveInterval
The interval between regular saves, in hours.
Definition simulation.h:641
bool m_bPolygonUnconsSedGainOrLossSave
Save polygon unconsolidated sediment gain or loss raster GIS files?
Definition simulation.h:243
double m_dTimeStep
The length of an iteration (a time step) in hours.
Definition simulation.h:632
bool m_bCliffCollapseDepositionTSSave
Save the cliff collapse deposition time series file?
Definition simulation.h:288
vector< string > m_VstrGDALIUCDriverCode
GDAL driver code for the initial unconsolidated coarse sediment GIS data.
bool m_bDeepWaterWaveAngleAndHeightSave
Save deep water wave angle and wave height raster GIS files?
Definition simulation.h:114
double m_dCoastNormalRandSpacingFactor
Random factor for spacing of along-coast normals.
Definition simulation.h:908
double m_dMaxUserInputWaveHeight
Maximum deep water wave height.
Definition simulation.h:719
vector< double > m_VdSliceElev
Elevations for raster slice output.
bool m_bBeachProtectionSave
Save beach protection raster GIS files>
Definition simulation.h:126
double m_dFinalSWL
The end-of-simulation still water (m), is same as m_dOrigSWL unless SWL changes.
Definition simulation.h:662
bool m_bDoBeachSedimentTransport
Simulate unconsolidated sediment (beach) transport?
Definition simulation.h:342
bool m_bFineConsSedSave
Save fine consolidated sediment raster GIS files?
Definition simulation.h:186
bool m_bShadowDowndriftBoundarySave
Save wave shadow downdrift boundary vector GIS files?
Definition simulation.h:273
int m_nCoastSmooth
Which method to use for coast smoothing.
Definition simulation.h:438
bool m_bDeepWaterWavePeriodSave
Save deep water wave period raster GIS files?
Definition simulation.h:237
string m_strInitialLandformFile
Name of initial landform file.
string m_strInterventionHeightFile
Name of intervention height file.
bool m_bBeachSedimentChangeNetTSSave
Save the beach (unconsolidated sediment) net change time series file?
Definition simulation.h:300
vector< string > m_VstrGDALICSDataType
GDAL data type for the initial consolidated sand sediment GIS data.
int nReadTideDataFile(void)
Reads the tide time series data.
bool m_bCoarseConsSedSave
Save coarse consolidated sediment raster GIS files?
Definition simulation.h:192
bool m_bSeaAreaTSSave
Save the sea area time series file?
Definition simulation.h:276
bool m_bScaleRasterOutput
Scale raster output?
Definition simulation.h:354
vector< string > m_VstrGDALICSProjection
GDAL dprojection for the initial consolidated sand sediment GIS data.
double m_dD50Fine
The D50 for fine sediment.
Definition simulation.h:728
unsigned long m_ulRandSeed[NUMBER_OF_RNGS]
A seed for each of the random number generators.
Definition simulation.h:560
bool m_bOmitSearchSouthEdge
Omit the south edge of the grid from coast-end searches?
Definition simulation.h:327
bool m_bBeachMaskSave
Save beach mask raster GIS files?
Definition simulation.h:225
bool m_bAvgSuspSedSave
Save average suspended sediment raster GIS files?
Definition simulation.h:174
double m_dBeachSedimentDensity
The density of unconsolidated beach sediment (kg/m**3)
Definition simulation.h:737
vector< string > m_VstrInitialCoarseConsSedimentFile
The name of the initial coarse-sized consolidated sediment GIS file.
double m_dSimDuration
Duration of simulation, in hours.
Definition simulation.h:629
vector< double > m_VdThisIterDeepWaterWaveStationAngle
This-iteration wave orientation at deep water wave station.
bool m_bOutputProfileData
Output profile data?
Definition simulation.h:315
vector< string > m_VstrGDALIUCDriverDesc
GDAL driver description for the initial unconsolidated coarse sediment GIS data.
double m_dMaxBeachElevAboveSWL
Maximum elevation of beach above SWL (m)
Definition simulation.h:860
bool m_bTotCliffCollapseDepositionSave
Save total cliff collapse deposition raster GIS files?
Definition simulation.h:213
double m_dAllCellsDeepWaterWavePeriod
Deep water wave period for all sea cells.
Definition simulation.h:716
bool bCreateErosionPotentialLookUp(vector< double > *, vector< double > *, vector< double > *)
Creates a look-up table for erosion potential, given depth over DB.
double m_dUSaveTime[SAVEMAX]
Save time, in hours from the start of the simukation, if we are not saving regularly.
Definition simulation.h:644
double m_dProfileMaxSlope
Maximum slope on coastline-normal profiles.
Definition simulation.h:857
int m_nProfileSmoothWindow
The size of the window used for running-mean coast-normal profile smoothing (must be odd)
Definition simulation.h:447
bool m_bDoCliffCollapse
Simulate cliff collapse?
Definition simulation.h:339
vector< string > m_VstrGDALICCDriverDesc
GDAL driver decription for the initial consolidated coarse sediment GIS data.
double m_dOrigSWL
The start-of-simulation still water level (m)
Definition simulation.h:659
string m_strOutFile
Name of main output file.
bool m_bSetupSurgeRunupFloodMaskSave
Are we saving the setup surge runup flood mask? TODO 007.
Definition simulation.h:399
bool m_bWaveSetupSave
Are we saving the wave setup? TODO 007.
Definition simulation.h:387
vector< double > m_VdTSDeepWaterWaveStationHeight
Time series of wave heights at deep water wave station.
bool m_bShadowZoneCodesSave
Save wave shadow zones raster GIS files?
Definition simulation.h:228
vector< string > m_VstrGDALIUCDataType
GDAL data type for the initial unconsolidated coarse sediment GIS data.
bool m_bCliffCollapseErosionTSSave
Save the cliff collapse erosion time series file?
Definition simulation.h:285
bool m_bPotentialPlatformErosionSave
Save potential shore platform erosion raster GIS files?
Definition simulation.h:129
double m_dDurationUnitsMult
Multiplier for duration units, to convert to hours.
Definition simulation.h:596
bool m_bFloodSWLSetupSurgeRunupLine
Are we saving the flood still water level setup surge runup line? TODO 007.
Definition simulation.h:417
bool m_bOutputParallelProfileData
Output parallel profile data?
Definition simulation.h:318
double m_dKamphuis
Transport parameter for the Kamphuis equation.
Definition simulation.h:764
vector< double > m_VdTSDeepWaterWaveStationAngle
Time series of wave orientation at deep water wave station.
static vector< string > * VstrSplit(string const *, char const, vector< string > *)
From http://stackoverflow.com/questions/236129/split-a-string-in-c They implement (approximately) Pyt...
Definition utils.cpp:2259
bool m_bOutputErosionPotentialData
Output erosion potential data?
Definition simulation.h:321
bool m_bCliffNotchSave
Save cliff notch incision depth vector GIS files?
Definition simulation.h:267
bool m_bVectorWaveFloodLineSave
Are we saving the vector wave flood line? TODO 007.
Definition simulation.h:405
vector< string > m_VstrGDALIUSDriverCode
GDAL driver code for the initial unconsolidated sand sediment GIS data.
bool m_bWaveAngleSave
Save wave angle raster GIS files?
Definition simulation.h:102
bool m_bOmitSearchEastEdge
Omit the east edge of the grid from coast-end searches?
Definition simulation.h:333
int m_nCoastSmoothWindow
The size of the window used for coast smoothing. Must be an odd number.
Definition simulation.h:441
bool m_bLocalSlopeSave
Save local slope raster GIS files?
Definition simulation.h:162
This file contains global definitions for CoastalME.
string const VECTOR_FLOOD_SWL_SETUP_SURGE_LINE_CODE
Definition cme.h:1051
string const TIME_SERIES_CLIFF_COLLAPSE_DEPOSITION_CODE
Definition cme.h:1094
string const TIME_SERIES_SUSPENDED_SEDIMENT_CODE
Definition cme.h:1109
string const RASTER_POTENTIAL_PLATFORM_EROSION_MASK_CODE
Definition cme.h:847
int const SMOOTH_NONE
Definition cme.h:658
int const WAVE_MODEL_COVE
Definition cme.h:668
int const RTN_ERR_READING_SEDIMENT_INPUT_EVENT
Definition cme.h:644
double const TOLERANCE
Definition cme.h:699
string const RASTER_CLIFF_COLLAPSE_EROSION_FINE_CODE
Definition cme.h:897
string const TIME_SERIES_PLATFORM_EROSION_CODE
Definition cme.h:1088
string const RASTER_COARSE_CONS_CODE
Definition cme.h:889
string const VECTOR_POLYGON_NODE_CODE
Definition cme.h:1029
string const RASTER_USUAL_OUTPUT_CODE
Definition cme.h:817
string const RASTER_DEEP_WATER_WAVE_ORIENTATION_CODE
Definition cme.h:925
string const RASTER_DEEP_WATER_WAVE_HEIGHT_CODE
Definition cme.h:927
string const TIME_SERIES_FLOOD_SETUP_SURGE_RUNUP_CODE
Definition cme.h:1115
string const VECTOR_ALL_OUTPUT_CODE
Definition cme.h:1008
string const VECTOR_FLOOD_SWL_SETUP_SURGE_RUNUP_LINE_CODE
Definition cme.h:1053
string const RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_SAND_CODE
Definition cme.h:913
string const RASTER_ACTIVE_ZONE_CODE
Definition cme.h:895
int const NO_LOG_FILE
Definition cme.h:378
string const RASTER_CLIFF_COLLAPSE_EROSION_COARSE_CODE
Definition cme.h:901
string const RASTER_SAND_CONS_CODE
Definition cme.h:887
string const TIME_SERIES_FLOOD_SETUP_SURGE_CODE
Definition cme.h:1112
int const RTN_ERR_SCAPE_SHAPE_FUNCTION_FILE
Definition cme.h:588
int const UNCONS_SEDIMENT_EQUATION_KAMPHUIS
Definition cme.h:673
string const ERR
Definition cme.h:777
string const RASTER_COAST_NORMAL_CODE
Definition cme.h:893
int const DEFAULT_PROFILE_SPACING
Definition cme.h:374
string const SCAPE_DIR
Definition cme.h:770
string const LOGEXT
Definition cme.h:806
string const RASTER_AVG_SUSP_SED_CODE
Definition cme.h:877
string const RASTER_COAST_CODE
Definition cme.h:891
string const RASTER_SEDIMENT_INPUT_EVENT_CODE
Definition cme.h:935
string const VECTOR_WAVE_ENERGY_SINCE_COLLAPSE_CODE
Definition cme.h:1023
string const RASTER_WAVE_ORIENTATION_CODE
Definition cme.h:837
string const VECTOR_RUN_UP_CODE
Definition cme.h:1045
string const RASTER_ALL_OUTPUT_CODE
Definition cme.h:818
string const RASTER_CLIFF_COLLAPSE_EROSION_SAND_CODE
Definition cme.h:899
string const RASTER_POLYGON_UPDRIFT_OR_DOWNDRIFT_CODE
Definition cme.h:931
string const RASTER_WAVE_FLOOD_LINE_CODE
Definition cme.h:941
int const WAVE_MODEL_CSHORE
Definition cme.h:669
string const RASTER_COARSE_UNCONS_CODE
Definition cme.h:883
string const OUTEXT
Definition cme.h:805
char const PATH_SEPARATOR
Definition cme.h:338
string const VECTOR_INVALID_NORMALS_CODE
Definition cme.h:1015
string const RASTER_BASEMENT_ELEVATION_CODE
Definition cme.h:823
string const RASTER_WAVE_HEIGHT_CODE
Definition cme.h:833
string const RASTER_CLIFF_COLLAPSE_DEPOSITION_COARSE_CODE
Definition cme.h:911
char const COMMA
Definition cme.h:336
string const RASTER_INTERVENTION_CLASS_CODE
Definition cme.h:871
string const RASTER_POTENTIAL_PLATFORM_EROSION_CODE
Definition cme.h:849
string const RASTER_POTENTIAL_BEACH_EROSION_CODE
Definition cme.h:857
string const VECTOR_MEAN_WAVE_ENERGY_CODE
Definition cme.h:1025
string const VECTOR_STORM_SURGE_CODE
Definition cme.h:1043
int const TIME_UNKNOWN
Definition cme.h:409
double const D50_SAND_DEFAULT
Definition cme.h:684
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_COARSE_CODE
Definition cme.h:907
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1178
string const VECTOR_USUAL_OUTPUT_CODE
Definition cme.h:1009
char const QUOTE1
Definition cme.h:339
string const RASTER_WAVE_PERIOD_CODE
Definition cme.h:839
int const GRID_EDGE_CLOSED
Definition cme.h:663
string const TIME_SERIES_CLIFF_COLLAPSE_NET_CODE
Definition cme.h:1097
int const GRID_EDGE_RECIRCULATE
Definition cme.h:665
int const RTN_ERR_OPEN_DEEP_WATER_WAVE_DATA
Definition cme.h:641
string const RASTER_TOTAL_ACTUAL_BEACH_EROSION_CODE
Definition cme.h:863
string const VECTOR_NORMALS_CODE
Definition cme.h:1013
string const RASTER_BEACH_DEPOSITION_CODE
Definition cme.h:865
string const RASTER_SHADOW_ZONE_CODE
Definition cme.h:921
string const RASTER_TOTAL_BEACH_DEPOSITION_CODE
Definition cme.h:867
int const SAVEMAX
Definition cme.h:353
string const VECTOR_DEEP_WATER_WAVE_ANGLE_AND_HEIGHT_CODE
Definition cme.h:1039
int const NUMBER_OF_RNGS
Definition cme.h:352
double const D50_COARSE_DEFAULT
Definition cme.h:685
string const RASTER_BEACH_PROTECTION_CODE
Definition cme.h:845
string const RASTER_TOTAL_POTENTIAL_PLATFORM_EROSION_CODE
Definition cme.h:853
string const TIME_SERIES_CLIFF_COLLAPSE_EROSION_CODE
Definition cme.h:1091
string const RASTER_BEACH_MASK_CODE
Definition cme.h:843
string const RASTER_AVG_WAVE_HEIGHT_CODE
Definition cme.h:835
string const RASTER_SETUP_SURGE_FLOOD_MASK_CODE
Definition cme.h:937
string const TIME_SERIES_BEACH_EROSION_CODE
Definition cme.h:1100
string const RASTER_TOTAL_POTENTIAL_BEACH_EROSION_CODE
Definition cme.h:861
int const SMOOTH_SAVITZKY_GOLAY
Definition cme.h:660
string const RASTER_AVG_SEA_DEPTH_CODE
Definition cme.h:829
string const RASTER_SAND_UNCONS_CODE
Definition cme.h:881
string const READING_FILE_LOCATIONS
Definition cme.h:737
int const LOG_FILE_ALL
Definition cme.h:382
int const RTN_OK
Definition cme.h:580
string const VECTOR_CLIFF_NOTCH_SIZE_CODE
Definition cme.h:1033
string const RASTER_SETUP_SURGE_RUNUP_FLOOD_MASK_CODE
Definition cme.h:939
string const RASTER_LANDFORM_CODE
Definition cme.h:869
string const RASTER_TOTAL_ACTUAL_PLATFORM_EROSION_CODE
Definition cme.h:855
int const RTN_ERR_READING_DEEP_WATER_WAVE_DATA
Definition cme.h:642
string const RASTER_ACTUAL_PLATFORM_EROSION_CODE
Definition cme.h:851
string const VECTOR_BREAKING_WAVE_HEIGHT_CODE
Definition cme.h:1027
unsigned long const SEDIMENT_INPUT_EVENT_ERROR
Definition cme.h:679
int const RTN_ERR_TIDEDATAFILE
Definition cme.h:589
string const RASTER_SUSP_SED_CODE
Definition cme.h:875
string const VECTOR_SHADOW_BOUNDARY_CODE
Definition cme.h:1035
string const VECTOR_COAST_CURVATURE_CODE
Definition cme.h:1017
double const DBL_NODATA
Definition cme.h:709
double const D50_FINE_DEFAULT
Definition cme.h:683
string const VECTOR_ALL_RIVER_FLOOD_OUTPUT_CODE
Definition cme.h:1010
string const CME_INI
Definition cme.h:713
string const NOTE
Definition cme.h:779
string const RASTER_CLIFF_COLLAPSE_DEPOSITION_SAND_CODE
Definition cme.h:909
string const RASTER_SEA_DEPTH_CODE
Definition cme.h:827
string const RASTER_LOCAL_SLOPE_CODE
Definition cme.h:825
string const RASTER_FINE_CONS_CODE
Definition cme.h:885
char const QUOTE2
Definition cme.h:340
string const VECTOR_POLYGON_BOUNDARY_CODE
Definition cme.h:1031
string const RASTER_FINE_UNCONS_CODE
Definition cme.h:879
string const TIME_SERIES_STILL_WATER_LEVEL_CODE
Definition cme.h:1085
string const RASTER_SEDIMENT_TOP_CODE
Definition cme.h:819
int const UNCONS_SEDIMENT_EQUATION_CERC
Definition cme.h:672
string const RASTER_POLYGON_GAIN_OR_LOSS_CODE
Definition cme.h:933
char const TILDE
Definition cme.h:343
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_SAND_CODE
Definition cme.h:905
string const VECTOR_AVG_WAVE_ANGLE_AND_HEIGHT_CODE
Definition cme.h:1022
string const TIME_SERIES_BEACH_CHANGE_NET_CODE
Definition cme.h:1106
string const RASTER_INTERVENTION_HEIGHT_CODE
Definition cme.h:873
string const VECTOR_FLOOD_LINE_CODE
Definition cme.h:1047
string const TIME_SERIES_BEACH_DEPOSITION_CODE
Definition cme.h:1103
string const VECTOR_FLOOD_SWL_SETUP_LINE_CODE
Definition cme.h:1049
string const VECTOR_WAVE_SETUP_CODE
Definition cme.h:1041
string const RASTER_POLYGON_CODE
Definition cme.h:917
string const RASTER_ACTUAL_BEACH_EROSION_CODE
Definition cme.h:859
string const RASTER_INUNDATION_MASK_CODE
Definition cme.h:831
string const VECTOR_COAST_CODE
Definition cme.h:1011
char const COLON
Definition cme.h:335
string const RASTER_TOTAL_CLIFF_COLLAPSE_EROSION_FINE_CODE
Definition cme.h:903
string const RASTER_AVG_WAVE_ORIENTATION_CODE
Definition cme.h:841
string const SCAPE_SHAPE_FUNCTION_FILE
Definition cme.h:771
string const TIME_SERIES_SEA_AREA_CODE
Definition cme.h:1082
string const RASTER_DEEP_WATER_WAVE_PERIOD_CODE
Definition cme.h:929
string const RASTER_TOTAL_CLIFF_COLLAPSE_DEPOSITION_COARSE_CODE
Definition cme.h:915
string const RASTER_TOP_CODE
Definition cme.h:821
char const SPACE
Definition cme.h:342
string const VECTOR_DOWNDRIFT_BOUNDARY_CODE
Definition cme.h:1037
Contains CSedInputEvent definitions.
Contains CSimulation definitions.
bool bIsStringValidInt(string &str)
Checks to see if a string can be read as a valid integer, from https://stackoverflow....
bool bIsStringValidDouble(string &str)
Checks to see if a string can be read as a valid double number. Does not find trailing (i....