GPLIB++
SurfaceWaveModel.cpp
Go to the documentation of this file.
1 #include "SurfaceWaveModel.h"
2 #include <fstream>
3 #include <cassert>
4 #include <iterator>
5 #include <iomanip>
6 #include <numeric>
7 #include <algorithm>
8 #include <boost/bind.hpp>
9 #include <boost/numeric/conversion/cast.hpp>
10 #include <iostream>
11 using namespace std;
12 
13 namespace gplib
14  {
15  SurfaceWaveModel::SurfaceWaveModel() :
16  refperiod(50), anisotropic(1), name("surf"), carddeckmodel(1),
17  ninnercore(0), noutercore(0)
18  {
19  }
20 
22  {
23  }
24 
26  pvvelocities(Old.pvvelocities), phvelocities(Old.phvelocities),
27  svvelocities(Old.svvelocities), shvelocities(Old.shvelocities),
28  densities(Old.densities), thicknesses(Old.thicknesses), eta(Old.eta),
29  qmu(Old.qmu), qkappa(Old.qkappa), refperiod(Old.refperiod),
30  anisotropic(Old.anisotropic), name(Old.name), carddeckmodel(
31  Old.carddeckmodel), ninnercore(Old.ninnercore), noutercore(
32  Old.noutercore)
33  {
34 
35  }
36 
38  const SurfaceWaveModel& source)
39  {
40  if (this == &source)
41  return *this;
42  source.CheckConsistency();
43  pvvelocities.clear();
44  phvelocities.clear();
45  svvelocities.clear();
46  shvelocities.clear();
47  densities.clear();
48  thicknesses.clear();
49  eta.clear();
50  qmu.clear();
51  qkappa.clear();
52  copy(source.pvvelocities.begin(), source.pvvelocities.end(),
53  back_inserter(pvvelocities));
54  copy(source.phvelocities.begin(), source.phvelocities.end(),
55  back_inserter(phvelocities));
56  copy(source.svvelocities.begin(), source.svvelocities.end(),
57  back_inserter(svvelocities));
58  copy(source.shvelocities.begin(), source.shvelocities.end(),
59  back_inserter(shvelocities));
60  copy(source.densities.begin(), source.densities.end(), back_inserter(
61  densities));
62  copy(source.thicknesses.begin(), source.thicknesses.end(),
63  back_inserter(thicknesses));
64  copy(source.eta.begin(), source.eta.end(), back_inserter(eta));
65  copy(source.qmu.begin(), source.qmu.end(), back_inserter(qmu));
66  copy(source.qkappa.begin(), source.qkappa.end(), back_inserter(qkappa));
67 
68  refperiod = source.refperiod;
69  anisotropic = source.anisotropic;
70  name = source.name;
71  carddeckmodel = source.carddeckmodel;
72  ninnercore = source.ninnercore;
73  noutercore = source.noutercore;
74  return *this;
75  }
76 
78  {
79  assert(pvvelocities.size() == phvelocities.size());
80  assert(pvvelocities.size() == svvelocities.size());
81  assert(pvvelocities.size() == shvelocities.size());
82  assert(pvvelocities.size() == densities.size());
83  assert(pvvelocities.size() == thicknesses.size());
84  assert(pvvelocities.size() == eta.size());
85  assert(pvvelocities.size() == qmu.size());
86  assert(pvvelocities.size() == qkappa.size());
87  }
88 
89  double SurfaceWaveModel::GetMaxDepth(const double depth)
90  {
91  assert(depth >= 0.0);
92  if (depth < 10.0)
93  return 1.0;
94  if (depth < 20.0)
95  return 2.0;
96  if (depth < 100)
97  return 5;
98  if (depth < 400)
99  return 10;
100  return 100;
101  }
102 
104  {
105  const unsigned int ninsert = 1;
106  assert(index-1 < thicknesses.size());
107  assert(index > 0);
108 
109  thicknesses.insert(thicknesses.begin() + index, ninsert, 0.0);
110  pvvelocities.insert(pvvelocities.begin() + index, ninsert,
111  pvvelocities.at(index));
112  phvelocities.insert(phvelocities.begin() + index, ninsert,
113  phvelocities.at(index));
114  svvelocities.insert(svvelocities.begin() + index, ninsert,
115  svvelocities.at(index));
116  shvelocities.insert(shvelocities.begin() + index, ninsert,
117  shvelocities.at(index));
118  densities.insert(densities.begin() + index, ninsert,
119  densities.at(index));
120  eta.insert(eta.begin() + index, ninsert, eta.at(index));
121  qmu.insert(qmu.begin() + index, ninsert, qmu.at(index));
122  qkappa.insert(qkappa.begin() + index, ninsert, qkappa.at(index));
123  }
124 
125  int SurfaceWaveModel::SplitLayer(const int index, const double maxthick)
126  {
127  assert(maxthick > 0.0);
128  assert(index < thicknesses.size());
129  double currthick = thicknesses.at(index);
130  unsigned int ninsert = boost::numeric_cast<unsigned int>(floor(
131  currthick / maxthick));
132  if (ninsert > 0)
133  {
134  double diffthick = currthick - ninsert * maxthick;
135  if (diffthick > 0.0) // we need diffthick extra layers and one with the difference
136 
137  {
138  thicknesses.at(index) = diffthick;
139  }
140  else //they fit exactly
141 
142  {
143  ninsert -= 1;
144  thicknesses.at(index) = maxthick;
145  }
146  thicknesses.insert(thicknesses.begin() + index, ninsert, maxthick);
147  pvvelocities.insert(pvvelocities.begin() + index, ninsert,
148  pvvelocities.at(index));
149  phvelocities.insert(phvelocities.begin() + index, ninsert,
150  phvelocities.at(index));
151  svvelocities.insert(svvelocities.begin() + index, ninsert,
152  svvelocities.at(index));
153  shvelocities.insert(shvelocities.begin() + index, ninsert,
154  shvelocities.at(index));
155  densities.insert(densities.begin() + index, ninsert, densities.at(
156  index));
157  eta.insert(eta.begin() + index, ninsert, eta.at(index));
158  qmu.insert(qmu.begin() + index, ninsert, qmu.at(index));
159  qkappa.insert(qkappa.begin() + index, ninsert, qkappa.at(index));
160 
161  }
162  if (index + ninsert + 1 < thicknesses.size())
163  {
164  AddDiscontinuity(index + ninsert + 1);
165  return index + ninsert + 1;
166  }
167  return index + ninsert;
168  }
169 
171  {
173  Background.CheckConsistency();
174  trealdata thisdepth(thicknesses.size(), 0.0), backgrounddepth(
175  Background.thicknesses.size());
176  partial_sum(thicknesses.begin(), thicknesses.end(), thisdepth.begin());
177  partial_sum(Background.thicknesses.begin(),
178  Background.thicknesses.end(), backgrounddepth.begin());
179  //find the index of the layer in the backgroundmodel that lies below the last layer of this model
180  const unsigned int layerindex = distance(backgrounddepth.begin(),
181  upper_bound(backgrounddepth.begin(), backgrounddepth.end(),
182  thisdepth.back()));
183  //cout << layerindex << " " << thisdepth.back() << " " << backgrounddepth.at(layerindex) << endl;
184  assert(layerindex < Background.thicknesses.size());
185  trealdata localthick(Background.thicknesses.begin() + layerindex,
186  Background.thicknesses.end()); // we want to keep Background as it is
187  localthick.front() = backgrounddepth.at(layerindex) - thisdepth.back(); //adjust thickness of bottom layer
188  //copy(thicknesses.begin(),thicknesses.end(),ostream_iterator<double>(cout," "));
189  //cout << endl;
190  copy(localthick.begin(), localthick.end(), back_inserter(thicknesses));
191  copy(Background.pvvelocities.begin() + layerindex,
192  Background.pvvelocities.end(), back_inserter(pvvelocities));
193  copy(Background.phvelocities.begin() + layerindex,
194  Background.phvelocities.end(), back_inserter(phvelocities));
195  copy(Background.svvelocities.begin() + layerindex,
196  Background.svvelocities.end(), back_inserter(svvelocities));
197  copy(Background.shvelocities.begin() + layerindex,
198  Background.shvelocities.end(), back_inserter(shvelocities));
199  copy(Background.densities.begin() + layerindex,
200  Background.densities.end(), back_inserter(densities));
201  copy(Background.eta.begin() + layerindex, Background.eta.end(),
202  back_inserter(eta));
203  copy(Background.qmu.begin() + layerindex, Background.qmu.end(),
204  back_inserter(qmu));
205  copy(Background.qkappa.begin() + layerindex, Background.qkappa.end(),
206  back_inserter(qkappa));
207  ninnercore = Background.ninnercore;
208  noutercore = Background.noutercore;
209  }
210 
211  void SurfaceWaveModel::WriteLayer(std::ostream &stream,
212  const unsigned int index, const trealdata &depth) const
213  {
214  stream << setw(10) << setprecision(6) << (6371 - depth.at(index))
215  * 1000;
216  stream << setw(10) << setprecision(6) << densities.at(index) * 1000
217  << " " << pvvelocities.at(index) * 1000 << " ";
218  stream << svvelocities.at(index) * 1000 << " " << qkappa.at(index)
219  << " " << qmu.at(index) << " ";
220  stream << phvelocities.at(index) * 1000 << " "
221  << shvelocities.at(index) * 1000 << " " << eta.at(index) << " ";
222  stream << depth.at(index); // have to write depth here
223  stream << endl;
224  }
225 
226  void SurfaceWaveModel::WritePlot(const std::string &filename) const
227  {
229  ofstream outfile(filename.c_str());
230  double cumthick = 0;
231  const unsigned int size = thicknesses.size();
232  for (unsigned int i = 0; i < size; ++i)
233  {
234  outfile << cumthick << " " << svvelocities.at(i) << endl;
235  cumthick += thicknesses.at(i);
236  outfile << cumthick << " " << svvelocities.at(i) << endl;
237  }
238  outfile << cumthick * 2.0 << " " << svvelocities.at(size - 1) << endl;
239  }
240  }
void AddDiscontinuity(const int index)
Insert a layer with 0 thickness to create a discontinuity for the forward code.
double GetMaxDepth(const double depth)
void WritePlot(const std::string &filename) const
Write out an ascii file for plotting with xmgrace or similar programs.
A class to store 1D model for calculation of synthetic surface wave data.
SurfaceWaveModel & operator=(const SurfaceWaveModel &source)
void MergeModel(const SurfaceWaveModel &Background)
Merge this model with another background model, the depth range below this model will be filled with ...
int SplitLayer(const int index, const double maxthick)
Splits a layer into several layers with a maximum thickness of maxthick, but otherwise identical prop...
const int size
Definition: perftest.cpp:14