00001 #include "AnisoSurfaceWaveObjective.h"
00002 #include "AnisoSurfaceWaveModel.h"
00003 #include <boost/bind.hpp>
00004 #include <cmath>
00005 #include "SeisTools.h"
00006
00007 using namespace std;
00008
00009 namespace gplib
00010 {
00011 AnisoSurfaceWaveObjective::AnisoSurfaceWaveObjective(
00012 const ParkSurfaceWaveData &Data, const double ba, const double avel) :
00013 MeasuredData(Data)
00014 {
00015 avelratio = avel;
00016 backazimuth = ba;
00017 poisson = sqrt(3.);
00018 errorlevel = 0.01;
00019 }
00020
00021 AnisoSurfaceWaveObjective::~AnisoSurfaceWaveObjective()
00022 {
00023 }
00024
00025 AnisoSurfaceWaveObjective& AnisoSurfaceWaveObjective::operator=(const AnisoSurfaceWaveObjective& source)
00026 {
00027 if (this == &source) return *this;
00028 PlottableObjective::operator=(source);
00029 MeasuredData = source.MeasuredData;
00030 SynthData = source.SynthData;
00031 Synthetic = source.Synthetic;
00032 errorlevel = source.errorlevel;
00033 poisson = source.poisson;
00034 avelratio = source.avelratio;
00035 return *this;
00036 }
00037
00038 AnisoSurfaceWaveObjective::AnisoSurfaceWaveObjective(
00039 const AnisoSurfaceWaveObjective &Old) :
00040 PlottableObjective(Old), MeasuredData(Old.MeasuredData), SynthData(
00041 Old.SynthData), Synthetic(Old.Synthetic)
00042 {
00043 errorlevel = Old.errorlevel;
00044 poisson = Old.poisson;
00045 avelratio = Old.avelratio;
00046 }
00047
00048 void AnisoSurfaceWaveObjective::PreParallel(const ttranscribed &member)
00049 {
00050 const unsigned int nfulllayers = member.size() / 6;
00051 boost::shared_ptr<AnisoSurfaceWaveModel> Model(new AnisoSurfaceWaveModel);
00052 ttranscribed thickness(nfulllayers), velocity(nfulllayers), angle(
00053 nfulllayers), deltaangle(nfulllayers), anisotropy1(nfulllayers),
00054 anisotropy2(nfulllayers);
00055 copy(member.begin(), member.begin() + nfulllayers, thickness.begin());
00056 copy(member.begin() + nfulllayers, member.begin() + 2 * nfulllayers,
00057 velocity.begin());
00058 transform(member.begin() + 2 * nfulllayers, member.begin() + 3
00059 * nfulllayers, angle.begin(), boost::bind(std::minus<double>(), _1,
00060 backazimuth));
00061 copy(member.begin() + 3 * nfulllayers, member.begin() + 4 * nfulllayers,
00062 deltaangle.begin());
00063 copy(member.begin() + 4 * nfulllayers, member.begin() + 5 * nfulllayers,
00064 anisotropy1.begin());
00065 copy(member.begin() + 5 * nfulllayers, member.begin() + 6 * nfulllayers,
00066 anisotropy2.begin());
00067
00068 copy(thickness.begin(), thickness.end(), back_inserter(
00069 Model->SetThicknesses()));
00070 copy(velocity.begin(), velocity.end(), back_inserter(Model->SetVs()));
00071 transform(velocity.begin(), velocity.end(),
00072 back_inserter(Model->SetVp()), boost::bind(multiplies<double> (), _1,
00073 poisson));
00074 transform(velocity.begin(), velocity.end(), back_inserter(
00075 Model->SetDensities()), CalcDensity());
00076 fill_n(back_inserter(Model->SetTheta()), nfulllayers, 90.0);
00077 fill_n(back_inserter(Model->SetC()), nfulllayers, 0.0);
00078
00079 transform(anisotropy1.begin(), anisotropy1.end(), anisotropy2.begin(),
00080 back_inserter(Model->SetB()), std::multiplies<double>());
00081
00082
00083
00084 transform(Model->GetB().begin(), Model->GetB().end(), back_inserter(
00085 Model->SetE()), boost::bind(multiplies<double> (), _1, avelratio));
00086
00087 transform(angle.begin(), angle.end(), deltaangle.begin(), back_inserter(
00088 Model->SetPhi()), std::plus<double>());
00089
00090 Synthetic.SetModel(Model);
00091 Synthetic.PreParallel(GetParallelID());
00092 }
00093
00094 double AnisoSurfaceWaveObjective::PostParallel(const ttranscribed &member)
00095 {
00096 return GetRMS();
00097 }
00098
00099 void AnisoSurfaceWaveObjective::SafeParallel(const ttranscribed &member)
00100 {
00101 SynthData = Synthetic.SafeParallel(GetParallelID());
00102 assert(errorlevel> 1e-4);
00103
00104 const unsigned int ndata = min(SynthData.GetPhaseVelocities().size(),
00105 MeasuredData.GetPhaseVelocities().size());
00106 SetMisfit().resize(ndata);
00107 SetSynthData().resize(ndata);
00108 double returnvalue = 0.0;
00109 for (unsigned int i = 0; i < ndata -2 ; ++i)
00110 {
00111 returnvalue += CalcMisfit(MeasuredData.GetPhaseVelocities().at(i),
00112 SynthData.GetPhaseVelocities().at(i), 0.0, errorlevel, i);
00113 }
00114
00115 SetRMS(std::pow(returnvalue / (ndata -2), 1.0 / GetFitExponent()));
00116 }
00117 }