CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
interpolate.cpp
Go to the documentation of this file.
1
11
12/*===============================================================================================================================
13
14This file is part of CoastalME, the Coastal Modelling Environment.
15
16CoastalME 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.
17
18This 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.
19
20You 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.
21
22===============================================================================================================================*/
23#include <assert.h>
24#include <cfloat>
25#include <iostream>
26#include <iomanip>
27#include <vector>
28using namespace std;
29
30#include "cme.h"
31
32//===============================================================================================================================
35//===============================================================================================================================
36double dGetInterpolatedValue(vector<double> const* pVdXdata, vector<double> const* pVdYdata, double dX, bool bExtrapolate)
37{
38 int size = static_cast<int>(pVdXdata->size());
39
40 int i = 0; // Find left end of interval for interpolation
41 if (dX >= pVdXdata->at(size - 2)) // Special case: beyond right end
42 {
43 i = size - 2;
44 }
45 else
46 {
47 while (dX > pVdXdata->at(i+1)) i++;
48 }
49
50 double dXL = pVdXdata->at(i);
51 double dYL = pVdYdata->at(i);
52 double dXR = pVdXdata->at(i+1);
53 double dYR = pVdYdata->at(i+1); // Points on either side (unless beyond ends)
54
55 if (! bExtrapolate) // If beyond ends of array and not extrapolating
56 {
57 if (dX < dXL)
58 dYR = dYL;
59
60 if (dX > dXR)
61 dYL = dYR;
62 }
63
64 double ddYdX = (dYR - dYL) / (dXR - dXL); // Gradient
65
66 return (dYL + ddYdX * (dX - dXL)); // Linear interpolation
67}
68
69//===============================================================================================================================
72//===============================================================================================================================
73double dGetInterpolatedValue(vector<int> const* pVnXdata, vector<double> const* pVdYdata, int nX, bool bExtrapolate )
74{
75 unsigned int nSize = static_cast<unsigned int>(pVnXdata->size());
76
77 int i = 0; // Find left end of interval for interpolation
78 if (nX >= pVnXdata->at(nSize - 2)) // Special case: beyond right end
79 {
80 i = nSize - 2;
81 }
82 else
83 {
84 while (nX > pVnXdata->at(i+1)) i++;
85 }
86
87 int nXL = pVnXdata->at(i);
88 int nXR = pVnXdata->at(i+1);
89
90 double dYL = pVdYdata->at(i);
91 double dYR = pVdYdata->at(i+1); // Points on either side (unless beyond ends)
92
93 if (! bExtrapolate) // If beyond ends of array and not extrapolating
94 {
95 if (nX < nXL) dYR = dYL;
96 if (nX > nXR) dYL = dYR;
97 }
98
99 double ddYdX = (dYR - dYL) / static_cast<double>(nXR - nXL); // Gradient
100
101 return dYL + ddYdX * static_cast<double>(nX - nXL); // Linear interpolation
102}
103
104//===============================================================================================================================
106//===============================================================================================================================
107int nFindIndex(vector<double> const* pVdX, double const dValueIn)
108{
109 double dLastValue = DBL_MAX;
110 int nIndexFound = 0;
111
112 for (unsigned int i = 0; i < pVdX->size(); ++i)
113 {
114 double dThisValue = tAbs(dValueIn - pVdX->at(i));
115
116 if (dThisValue <= dLastValue)
117 {
118 dLastValue = dThisValue;
119 nIndexFound = i;
120 }
121 }
122
123 return nIndexFound;
124}
125
126//===============================================================================================================================
128//===============================================================================================================================
129vector<double> VdInterpolateCShoreProfileOutput(vector<double> const* pVdX, vector<double> const* pVdY, vector<double> const* pVdXNew)
130{
131 int nXSize = static_cast<int>(pVdX->size());
132 int nXNewSize = static_cast<int>(pVdXNew->size());
133
134 // assert(nXSize > 0);
135 // assert(nXNewSize > 0);
136
137 double dX;
138 double dY;
139 vector<double> VdYNew(nXNewSize, 0.0);
140
141 for (int i = 0; i < nXNewSize; ++i)
142 {
143 int idx = nFindIndex(pVdX, pVdXNew->at(i));
144
145 if (pVdX->at(idx) > pVdXNew->at(i))
146 {
147 if (idx > 0)
148 {
149 dX = pVdX->at(idx) - pVdX->at(idx-1);
150 dY = pVdY->at(idx) - pVdY->at(idx-1);
151 }
152 else
153 {
154 dX = pVdX->at(idx+1) - pVdX->at(idx);
155 dY = pVdY->at(idx+1) - pVdY->at(idx);
156 }
157 }
158 else
159 {
160 if (idx < nXSize-1)
161 {
162 dX = pVdX->at(idx+1) - pVdX->at(idx);
163 dY = pVdY->at(idx+1) - pVdY->at(idx);
164 }
165 else
166 {
167 dX = pVdX->at(idx) - pVdX->at(idx-1);
168 dY = pVdY->at(idx) - pVdY->at(idx-1);
169 }
170 }
171
172 // Safety check: this crashes (divide by zero) if there are identical consecutive values in pVdX, and thus if dX becomes 0. To prevent this, if dX is near zero, set to a small non-zero number
173 if (bFPIsEqual(dX, 0.0, TOLERANCE))
174 dX = 1e-10;
175
176 double dM = dY / dX;
177 double dB = pVdY->at(idx) - pVdX->at(idx) * dM;
178
179 // VdYNew[i] = (pVdXNew->at(i) * dM) + dB;
180 VdYNew[nXNewSize-1 - i] = (pVdXNew->at(i) * dM) + dB;
181 }
182
183 return VdYNew;
184}
185
This file contains global definitions for CoastalME.
double const TOLERANCE
Definition cme.h:698
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1176
T tAbs(T a)
Definition cme.h:1148
int nFindIndex(vector< double > const *pVdX, double const dValueIn)
This is used by VdInterpolateCShoreProfileOutput, it returns the index of the value in pVdX which is ...
vector< double > VdInterpolateCShoreProfileOutput(vector< double > const *pVdX, vector< double > const *pVdY, vector< double > const *pVdXNew)
Returns a linearly interpolated vector of doubles, to make CShore profile output compatible with CME....
double dGetInterpolatedValue(vector< double > const *pVdXdata, vector< double > const *pVdYdata, double dX, bool bExtrapolate)