GPLIB++
AnisoSurfaceWaveObjective.cpp
Go to the documentation of this file.
3 #include <boost/bind.hpp>
4 #include <cmath>
5 #include "SeisTools.h"
6 
7 using namespace std;
8 
9 namespace gplib
10  {
11  AnisoSurfaceWaveObjective::AnisoSurfaceWaveObjective(
12  const ParkSurfaceWaveData &Data, const double ba, const double avel,
13  const double pois, const double err) :
14  MeasuredData(Data)
15  {
16  avelratio = avel;
17  backazimuth = ba;
18  poisson = pois;
19  errorlevel = err;
20  }
21 
23  {
24  }
25 
27  const AnisoSurfaceWaveObjective& source)
28  {
29  if (this == &source)
30  return *this;
32  MeasuredData = source.MeasuredData;
33  SynthData = source.SynthData;
34  Synthetic = source.Synthetic;
35  errorlevel = source.errorlevel;
36  poisson = source.poisson;
37  avelratio = source.avelratio;
38  return *this;
39  }
40 
42  const AnisoSurfaceWaveObjective &Old) :
43  PlottableObjective(Old), MeasuredData(Old.MeasuredData), SynthData(
44  Old.SynthData), Synthetic(Old.Synthetic)
45  {
46  errorlevel = Old.errorlevel;
47  poisson = Old.poisson;
48  avelratio = Old.avelratio;
49  }
50 
52  {
53  const unsigned int nfulllayers = member.size() / 6;
54  boost::shared_ptr<AnisoSurfaceWaveModel> Model(
56  ttranscribed thickness(nfulllayers), velocity(nfulllayers), angle(
57  nfulllayers), deltaangle(nfulllayers), anisotropy1(nfulllayers),
58  anisotropy2(nfulllayers);
59  copy(member.begin(), member.begin() + nfulllayers, thickness.begin()); //copy values
60  copy(member.begin() + nfulllayers, member.begin() + 2 * nfulllayers,
61  velocity.begin());
62  transform(member.begin() + 2 * nfulllayers, member.begin() + 3
63  * nfulllayers, angle.begin(), boost::bind(std::minus<double>(), _1,
64  backazimuth));
65  copy(member.begin() + 3 * nfulllayers,
66  member.begin() + 4 * nfulllayers, deltaangle.begin());
67  copy(member.begin() + 4 * nfulllayers,
68  member.begin() + 5 * nfulllayers, anisotropy1.begin());
69  copy(member.begin() + 5 * nfulllayers,
70  member.begin() + 6 * nfulllayers, anisotropy2.begin());
71 
72  //Set parameters for Modes
73  copy(thickness.begin(), thickness.end(), back_inserter(
74  Model->SetThicknesses()));
75  copy(velocity.begin(), velocity.end(), back_inserter(Model->SetVs()));
76  //No link assumed between the two anisotropic coefficients; Set B to anisotropy 2
77  copy(anisotropy2.begin(), anisotropy2.end(), back_inserter(
78  Model->SetB()));
79 
80  // Set B to anisotropy2 for the first layers (always >0) - No relation between seismic and electrical anisotropies
81  // copy(anisotropy2.begin(), anisotropy2.begin() + (nfulllayers - 2) ,back_inserter(Model->SetB()));
82  // For the last two layers of the model (asthenosphere + HS), we introduce a relation between seismic and electrical anisotropies
83  // Set Temp to Pow(10, an1)
84  // transform(anisotropy1.begin()+ (nfulllayers - 2), anisotropy1.end(), back_inserter(
85  // Model->SetTemp()), Pow10());
86  // Set B to product of Temp and anisotropy2
87  // transform(anisotropy2.begin()+ (nfulllayers-2), anisotropy2.end(),
88  // Model->GetTemp().begin(), back_inserter(Model->SetB()),std::multiplies<double>());
89 
90  //Set anisotropy angle to sum of angle and deltaangle - phi
91  transform(angle.begin(), angle.end(), deltaangle.begin(),
92  back_inserter(Model->SetPhi()), std::plus<double>());
93  //Set angle1 to product of cos(2phi) - cos (2*phi)
94  transform(Model->GetPhi().begin(), Model->GetPhi().end(),
95  back_inserter(Model->SetAngle1()), CalcAngle1());
96  //Set AnisoS to product of B and angle1 - B*cos(2*phi)
97  transform(Model->GetB().begin(), Model->GetB().end(),
98  Model->GetAngle1().begin(), back_inserter(Model->SetAnisoS()),
99  std::multiplies<double>());
100  //Set Vsapp to sum of Vs and AnisoS - Vs + B*cos(2*phi)
101  transform(Model->GetVs().begin(), Model->GetVs().end(),
102  Model->GetAnisoS().begin(), back_inserter(Model->SetVsapp()),
103  std::plus<double>());
104  //We compute Vp and Density from Vsapp
105  transform(Model->GetVsapp().begin(), Model->GetVsapp().end(),
106  back_inserter(Model->SetDensities()), CalcDensity());
107  transform(Model->GetVsapp().begin(), Model->GetVsapp().end(), //P Velocity is calculated by multiplication of SVel by poisson's ratio
108  back_inserter(Model->SetVp()), boost::bind(multiplies<double> (),
109  _1, poisson));
110 
111  Synthetic.SetModel(Model);
112  Synthetic.PreParallel(GetParallelID());
113  }
114 
116  {
117  return GetRMS();
118  }
119 
121  {
122  SynthData = Synthetic.SafeParallel(GetParallelID());
123  assert(errorlevel> 1e-4);
124  // an errorlevel < 0.01% is absolutely unrealistic
125  const unsigned int ndata = min(SynthData.GetPhaseVelocities().size(),
126  MeasuredData.GetPhaseVelocities().size());
127  SetMisfit().resize(ndata); // we need vectors of the right size for misfit
128  SetSynthData().resize(ndata); // and data
129  double returnvalue = 0.0; // init returnvalue
130  for (unsigned int i = 0; i < ndata; ++i)
131  {
132  returnvalue += CalcMisfit(MeasuredData.GetPhaseVelocities().at(i),
133  SynthData.GetPhaseVelocities().at(i), 0.0, errorlevel, i);
134  }
135 
136  SetRMS(pow(returnvalue / ndata, 1.0 / GetFitExponent())); //return misfit
137  }
138  }
A class to store information about anisotropic surface wave models.
ublas::vector< double > ttranscribed
Definition: gentypes.h:21
AnisoSurfaceWaveObjective & operator=(const AnisoSurfaceWaveObjective &source)
Calculate density from a given S-velocity, the formula is taken from Owen et al. JGR 89...
Definition: SeisTools.h:15
This only adds a few plotting functions to GeneralObjective to define a common interface.
const trealdata & GetPhaseVelocities() const
Read-only access to the vector of phase velocities.
void SetModel(const boost::shared_ptr< AnisoSurfaceWaveModel > m)
int GetFitExponent()
Get the Fit exponent.
double CalcMisfit(const double measured, const double predicted, const double measerror, const double errorlevel, const int index)
This class calculates the misfit for anisotropic surface wave dispersion data.
ParkSurfaceWaveData SafeParallel(const std::string &filename)
const std::string & GetParallelID()
Derived classes need to read the ParallelId for their forward calculations.
double GetRMS()
Get the current RMS.
void PreParallel(const std::string &filename)
tdata & SetSynthData()
Only derived classes can write access the Synthetic data.
tmisfit & SetMisfit()
Only derived classes can write access the Misfit.
virtual void PreParallel(const ttranscribed &member)
Some operations cannot be done in parallel, these are done before.
AnisoSurfaceWaveObjective(const AnisoSurfaceWaveObjective &Old)
PlottableObjective & operator=(const PlottableObjective &source)
virtual double PostParallel(const ttranscribed &member)
Some operations cannot be done in parallel, these are done after, returns the misfit value...
virtual void SafeParallel(const ttranscribed &member)
The core performance calculation, has to be safe to be done in parallel.
void SetRMS(const double x)