AnisoSurfaceWaveObjective.cpp

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

Generated on Tue Nov 3 13:24:13 2009 for GPLIB++ by  doxygen 1.5.8