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