SurfaceWaveObjective.cpp

Go to the documentation of this file.
00001 #include "SurfaceWaveObjective.h"
00002 #include <boost/bind.hpp>
00003 #include "SeisTools.h"
00004 #include <numeric>
00005 #include <boost/shared_ptr.hpp>
00006 #include "Sdisp96Model.h"
00007 
00008 using namespace std;
00009 
00010 namespace gplib
00011   {
00012     SurfaceWaveObjective::SurfaceWaveObjective(const SurfaceWaveData &Data) :
00013       MeasuredData(Data)
00014       {
00015         poisson = sqrt(3.);
00016         errorlevel = 0.02;
00017       }
00018 
00019     SurfaceWaveObjective& SurfaceWaveObjective::operator=(
00020         const SurfaceWaveObjective& source)
00021       {
00022         if (this == &source)
00023           return *this;
00024         PlottableObjective::operator=(source);
00025         MeasuredData = source.MeasuredData;
00026         SynthData = source.SynthData;
00027         Synthetic = source.Synthetic;
00028         errorlevel = source.errorlevel;
00029         poisson = source.poisson;
00030         return *this;
00031       }
00032 
00033     SurfaceWaveObjective::SurfaceWaveObjective(const SurfaceWaveObjective &Old) :
00034       PlottableObjective(Old), MeasuredData(Old.MeasuredData), SynthData(
00035           Old.SynthData), Synthetic(Old.Synthetic)
00036       {
00037         errorlevel = Old.errorlevel;
00038         poisson = Old.poisson;
00039       }
00040 
00041     SurfaceWaveObjective::~SurfaceWaveObjective()
00042       {
00043       }
00044 
00045     void SurfaceWaveObjective::PreParallel(const ttranscribed &member)
00046       {
00047         const unsigned int nfulllayers = member.size() / 2;
00048         Sdisp96Model Model;
00049         ttranscribed thickness(nfulllayers), velocity(nfulllayers);
00050         copy(member.begin(), member.begin() + nfulllayers, thickness.begin()); //copy values
00051         copy(member.begin() + nfulllayers, member.begin() + 2 * nfulllayers,
00052             velocity.begin());
00053         //The model object has been newly created above, so it is safe to use back_inserter to fill the vectors
00054         copy(thickness.begin(), thickness.end(), back_inserter(
00055             Model.SetThicknesses()));
00056         //Sh velocities and Sv velocities are the same
00057         copy(velocity.begin(), velocity.end(), back_inserter(
00058             Model.SetShVelocities()));
00059         copy(velocity.begin(), velocity.end(), back_inserter(
00060             Model.SetSvVelocities()));
00061         //We calculate density from S-Velocity
00062         transform(velocity.begin(), velocity.end(), back_inserter(
00063             Model.SetDensities()), CalcDensity());
00064         //PVelocity is calculated by multiplication of SVel by poisson's ratio
00065         transform(velocity.begin(), velocity.end(), back_inserter(
00066             Model.SetPhVelocities()), boost::bind(multiplies<double> (), _1,
00067             poisson));
00068         copy(Model.GetPhVelocities().begin(), Model.GetPhVelocities().end(),
00069             back_inserter(Model.SetPvVelocities()));
00070         //We give some fixed values to the attenuation parameters
00071         fill_n(back_inserter(Model.SetEta()), nfulllayers, 1.0);
00072         fill_n(back_inserter(Model.SetQmu()), nfulllayers, 100.0);
00073         fill_n(back_inserter(Model.SetQkappa()), nfulllayers, 99999.00);
00074 
00075         Synthetic.SetModel(Model);
00076         if (Synthetic.GetCalculationPeriods().empty())
00077           {
00078             Synthetic.SetCalculationPeriods(MeasuredData.GetPeriods());
00079           }
00080         Synthetic.PreParallel(GetParallelID());
00081       }
00082 
00083     double SurfaceWaveObjective::PostParallel(const ttranscribed &member)
00084       {
00085         return GetRMS();
00086 
00087       }
00088 
00089     void SurfaceWaveObjective::SafeParallel(const ttranscribed &member)
00090       {
00091         //We can safely calculate the synthetic data in parallel
00092         SynthData = Synthetic.SafeParallel(GetParallelID());
00093         assert(errorlevel > 1e-4);
00094         // an errorlevel < 0.01% is absolutely unrealistic
00095         const unsigned int ndata = min(SynthData.GetPhaseVelocities().size(),
00096             MeasuredData.GetPhaseVelocities().size());
00097         SetMisfit().resize(ndata); // we need vectors of the right size for misfit
00098         SetSynthData().resize(ndata); // and  data
00099         double returnvalue = 0; // init returnvalue
00100         // this loop calculates the misfit for each datum
00101         for (unsigned int i = 0; i < ndata; ++i)
00102           {
00103             returnvalue += CalcMisfit(MeasuredData.GetPhaseVelocities().at(i),
00104                 SynthData.GetPhaseVelocities().at(i), 0.0, errorlevel, i);
00105 
00106           }
00107 
00108         SetRMS(std::pow(returnvalue / ndata, 1.0 / GetFitExponent())); //return misfit
00109       }
00110   }

Generated on Tue May 4 16:52:15 2010 for GPLIB++ by  doxygen 1.5.8