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