All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions
QGpCoreWave::Seismic1DModel Class Reference

Storage class for an horizontaly layered ground model. More...

#include <Seismic1DModel.h>

Inheritance diagram for QGpCoreWave::Seismic1DModel:
QGpCoreWave::GeophysicalModel

List of all members.

Classes

class  SeismicContext
 Brief description of class still missing. More...
class  SeismicStorage
class  VariableH
class  VariableN
class  VariableQp
class  VariableQs
class  VariableRho
class  VariableVp
class  VariableVs

Public Types

enum  SlownessType { P, S }

Public Member Functions

void changeHKeepOtherDepth (int iLayer, double newH)
void changeVpKeepPoisson (int iLayer, double newV)
void changeVsKeepPoisson (int iLayer, double newV)
int checkVelocityInversion () const
virtual GeophysicalModelclone () const
double depth (int iLayer) const
bool elastic () const
double expGrad (int iLayer) const
void exportHerrmann (QTextStream &s) const
virtual GeophysicalContextexpressionContext () const
virtual bool fromStream (QTextStream &s, QString *comments=0)
void fromStream (QDataStream &s)
double h (int iLayer) const
double halfSpaceRayleighSlowness (int iLayer) const
double impedanceAt (double depth) const
Profile impedanceProfile () const
bool initCalculation ()
bool interpole (const Point &at, const Point *refPoints, const Seismic1DModel *refModels)
virtual bool isEmpty () const
virtual bool isValid ()
int layerCount () const
double maxSlowR () const
double maxSlowS () const
double minSlowS () const
double mu (int iLayer) const
void operator= (const Seismic1DModel &o)
double poisson (int iLayer) const
double poissonAt (double depth) const
Profile poissonProfile () const
double qp (int iLayer) const
double qs (int iLayer) const
double rho (int iLayer) const
double rhoAt (double depth) const
Profile rhoProfile () const
double roughFundamentalFrequency () const
 Seismic1DModel ()
 Seismic1DModel (const Seismic1DModel &o)
 Seismic1DModel (int layerCount)
void setH (int iLayer, double v)
void setHFrom (const Seismic1DModel &o)
void setQp (int iLayer, double v)
void setQs (int iLayer, double v)
void setRho (int iLayer, double v)
void setSlowP (int iLayer, double v)
void setSlowS (int iLayer, double v)
double slowP (int iLayer) const
double slowPAt (double depth) const
Profile slowpProfile () const
double slowS (int iLayer) const
double slowSAt (double depth) const
Profile slowsProfile () const
virtual void toStream (QTextStream &s) const
void toStream (QDataStream &s) const
virtual QString toString () const
double vpAt (double depth) const
Profile vpProfile () const
double vsAt (double depth) const
Profile vsProfile () const
 ~Seismic1DModel ()

Static Public Member Functions

static QString formatHelp ()

Protected Member Functions

void allocateData ()
void deleteData ()

Detailed Description

Storage class for an horizontaly layered ground model.

Seismic1DModel stores data vectors for thicknesses, P-wave and S-wave slownesses, and densities of each layer. A series of checks and information functions are implemented.

The same data vectors can be shared automatically using the copy constructor between several instances of Seismic1DModel.


Member Enumeration Documentation

Enumerator:
P 
S 
{P, S};

Constructor & Destructor Documentation

Default constructor

Only called by AnelasticSeismic1DModel.

References TRACE.

{
  TRACE;
  _layerCount=0;
  initMembers();
}

Copy constructor

References operator=(), and TRACE.

   : GeophysicalModel(o)
{
  TRACE;
  _layerCount=0;
  initMembers();
  operator=(o);
}

Constructor: inits the number of layers including half space.

References allocateData(), layerCount(), and TRACE.

{
  TRACE;
  // Sharing initialization
  _layerCount=layerCount;
  initMembers();
  allocateData();
}

Destructor: remove data vectors.

References deleteData(), and TRACE.

{
  TRACE;
  deleteData();
}

Member Function Documentation

Allocates all data vectors (_layerCount must be initialized before)

Internal use only.

References deleteData(), and TRACE.

Referenced by fromStream(), interpole(), operator=(), and Seismic1DModel().

{
  TRACE;
  deleteData();
  // allocate the data vectors
  if(_layerCount>1) {
    _h=new double [_layerCount-1];
    _slowP=new double [_layerCount];
    _slowS=new double [_layerCount];
    _rho=new double [_layerCount];
    _mu=new double [_layerCount];
    _qp=new double [_layerCount];
    _qs=new double [_layerCount];
  }
}
void QGpCoreWave::Seismic1DModel::changeHKeepOtherDepth ( int  iLayer,
double  newH 
)

Modify one thickness keeping all other depth constant (if possible) if not, modify only the thickness of this layer and other depth will also change

References TRACE.

{
  TRACE;
  if(iLayer>=_layerCount-1) return;
  if(iLayer==_layerCount-2 || newH>=_h[iLayer]+_h[iLayer+1]) {
    _h[iLayer]=newH;
    return;
  }
  double dH=newH-_h[iLayer];
  _h[iLayer]=newH;
  _h[iLayer+1]-=dH;
}
void QGpCoreWave::Seismic1DModel::changeVpKeepPoisson ( int  iLayer,
double  newV 
)

Changes Vp without changing the Poisson ratio of layer ilayer

References TRACE.

{
  TRACE;
  if(iLayer>_layerCount-1) return;
  // Get actual Poisson's ratio (equivalent to Vs over Vp)
  // ratio=Vp/Vs=(1/Vs)/(1/Vp)=slowS/slowP
  double ratio=_slowS[iLayer]/_slowP[iLayer];
  _slowP[iLayer]=1.0/newV;
  _slowS[iLayer]=ratio*_slowP[iLayer];
}
void QGpCoreWave::Seismic1DModel::changeVsKeepPoisson ( int  iLayer,
double  newV 
)

Changes Vs without changing the Poisson ratio of layer ilayer

References TRACE.

{
  TRACE;
  if(iLayer>_layerCount-1) return;
  // Get actual Poisson's ratio (equivalent to Vs over Vp)
  // ratio=Vs/Vp=(1/Vp)/(1/Vs)=slowP/slowS
  double ratio=_slowP[iLayer]/_slowS[iLayer];
  _slowS[iLayer]=1.0/newV;
  _slowP[iLayer]=ratio*_slowS[iLayer];
}

Checks velocity inversions on Vp and Vs. The return value is -1 if no LVZ is found, else the first layer index where the condition is not satisfied.

References TRACE.

Referenced by QGpCoreWave::Dispersion::refine().

{
  TRACE;
  for(int i=1;i<_layerCount;i++) {
    if(_slowS[i]>_slowS[i-1] || _slowP[i]>_slowP[i-1]) {
      return i;
    }
  }
  return -1;
}
virtual GeophysicalModel* QGpCoreWave::Seismic1DModel::clone ( ) const [inline, virtual]

Implements QGpCoreWave::GeophysicalModel.

{return new Seismic1DModel(*this);}

Delete all data vectors

Internal use only.

References TRACE.

Referenced by allocateData(), interpole(), operator=(), and ~Seismic1DModel().

{
  TRACE;
  delete [ ] _h;
  delete [ ] _slowP;
  delete [ ] _slowS;
  delete [ ] _rho;
  delete [ ] _mu;
  delete [ ] _qp;
  delete [ ] _qs;
  _h=0;
  _slowP=0;
  _slowS=0;
  _rho=0;
  _mu=0;
  _qp=0;
  _qs=0;
}
double QGpCoreWave::Seismic1DModel::depth ( int  iLayer) const

Returns the depth of the top of layer with index ilayer.

References TRACE.

Referenced by expGrad(), QGpCompatibility::CompatInversionReport::getParamValue(), and roughFundamentalFrequency().

{
  TRACE;
  if(iLayer>=_layerCount) iLayer=_layerCount-1;
  double d=0;
  for(int i=0;i<iLayer;i++) d+=_h[i];
  return d;
}

Returns true if model is elastic (quality factors all set to 0)

Referenced by toStream().

{
  for(int i=_layerCount-1;i>=0;i--) {
    if(_qp[i]>0.0 || _qs[i]>0.0) return false;
  }
  return true;
}
double QGpCoreWave::Seismic1DModel::expGrad ( int  iLayer) const

When a sub-stack of layers has been generated with a power law exponent, this function tries to recalculate the exponent from the values of S-wave slowness and thicknesses.

References depth(), and TRACE.

Referenced by QGpCompatibility::CompatInversionReport::getParamValue().

{
  TRACE;
  if(iLayer>=_layerCount-1) iLayer=_layerCount-2;
  double v1=1.0/_slowS[iLayer];
  double v2=1.0/_slowS[iLayer+1];
  double z0=depth(iLayer)+1;
  double z1=z0+0.5*_h[iLayer];
  double z2=z0+_h[iLayer]+0.5*_h[iLayer+1];
  double v21=v2/v1;
  double v211=v21-1;
  /* The problem is to solve f(alpha)=z2^alpha-v2/v1*z1^alpha+(v2/v1-1)*z0^alpha=v2/v1-1
     By Newton-Raphson the process is not stable enough, if transformed into log => too slow
     As f(0)<c and f(1)>c, and that the df/dalpha!=0 there's only one root, the solution
     By bisection it'is the best.
  */
  double a1=0;
  double a2=1;
  double a3=0.5;
  double f3=pow(z2,a3)-v21*pow(z1,a3)+v211*pow(z0,a3);
  do {
    if(f3<v211) a1=a3; else a2=a3;
    a3=0.5*(a1+a2);
    f3=pow(z2,a3)-v21*pow(z1,a3)+v211*pow(z0,a3);
  } while(f3!=v211 && a2-a1>1e-5);
  return a3;
}
void QGpCoreWave::Seismic1DModel::exportHerrmann ( QTextStream &  s) const

Saves model to Herrmann's format

References QGpCoreTools::flush(), str, and TRACE.

{
  TRACE;
  static const QString str("%1 %2 %3 %4 1\n");
  s << "2 1 0 2.25 250 1\n";
  for(int i=0;i<_layerCount-1;i++)
    s << str.arg(_h[i], 0, 'f', 15)
            .arg(1/_slowP[i], 0, 'f', 15)
            .arg(1/_slowS[i], 0, 'f', 15)
            .arg(_rho[i], 0, 'f', 15);
  s << str.arg(0.0, 0, 'f', 20)
          .arg(1/_slowP[_layerCount-1], 0, 'f', 20)
          .arg(1/_slowS[_layerCount-1], 0, 'f', 20)
          .arg(_rho[_layerCount-1], 0, 'f', 20) << flush;
}

Implements QGpCoreWave::GeophysicalModel.

{return new SeismicContext;}

References TRACE.

Referenced by QGpCoreWave::GeophysicalModel::allFormatHelp().

{
  TRACE;
  return "  Line 1    <number of layers including half-space for first model>\n"
         "  Line 2    <thickness (m)> <Vp (m/s)> <Vs (m/s)> <Density (kg/m3)>[ <Qp> <Qs>]\n"
         "  ....\n"
         "  Line n    0 <Vp (m/s)> <Vs (m/s)> <Density (kg/m3)>[ <Qp> <Qs>]\n"
         "  Line n+1  <number of layers including half-space for second model>\n"
         "  ....";
}
bool QGpCoreWave::Seismic1DModel::fromStream ( QTextStream &  s,
QString *  comments = 0 
) [virtual]

Loads model from a text stream

Format:

      layerCount
      h Vp Vs rho Qp Qs (layer 1)
      ...
      0 Vp Vs rho Qp Qs (layer n)
      

Qp and Qs are currently ignored.

Returns false if an error occured during reading or if the read model is not consistent. It returns true even if the number of layers is null or cannot be read. This is the responsability of the caller to test if the number of layers is greater than 1 before doing anything else.

Implements QGpCoreWave::GeophysicalModel.

References allocateData(), QGpCoreTools::endl(), initCalculation(), QGpCoreTools::StringSection::isEmpty(), QGpCoreTools::StringSection::isValid(), QGpCoreTools::StringSection::nextField(), QGpCoreTools::StringSection::set(), QGpCoreTools::StringSection::toInt(), QGpCoreTools::StringSection::toString(), QGpCoreTools::tr(), TRACE, and QGpCoreTools::StringSection::trimmed().

Referenced by QGpCompatibility::CompatAutocorrReport::loadAutocorr(), QGpCompatibility::CompatInversionReport::loadDispersion(), QGpCompatibility::CompatInversionReport::loadModel(), QGpCompatibility::CompatInversionReport::loadNextModel(), QGpCompatibility::CompatRefraReport::loadRefra(), EllipticityReader::parse(), EC8Reader::parse(), ShReader::parse(), Model2ParamReader::parse(), DispersionReader::parse(), SpacReader::parse(), LiveModelReader::parse(), and surfaceModelMode().

{
  TRACE;
  // read the number of layers
  StringSection field, fields;
  const QChar * ptr;
  QString buf;
  buf=File::readLineNoComments(s, comments);
  fields.set(buf);
  fields.trimmed();
  ptr=0;
  field=fields.nextField(ptr);
  if(field.isValid()) {
    bool ok=true;
    _layerCount=field.toInt(&ok);
    if(!ok && !field.isEmpty()) { // Not a blank line but failed
      App::stream() << tr("Layered model: bad number of layers: \"%1\" interpreted as %2").arg(field.toString()).arg(_layerCount) << endl;
       _layerCount=0;
       return false;
    }
  } else {
    _layerCount=0;
    return true;  // This is just a blank line, before doing anything, you must test if the number of layer is >0
  }
  if(_layerCount>1 && !s.atEnd()) {
    allocateData();
    // read the data
    for(int i=0;i<_layerCount;i++) {
      if(s.atEnd()) {
        App::stream() << tr("Layered model: reaching the end of file, %1 layers found, expecting %2")
                  .arg(i).arg(_layerCount) << endl;
        _layerCount=0;
        return false;
      }
      buf=File::readLineNoComments(s, comments);
      fields.set(buf);
      fields.trimmed();
      ptr=0;
      if(i<_layerCount-1) {
        field=fields.nextField(ptr);
        if(!setValue(_h[i], field, i, tr("thickness"), false) ) return false;
      } else {
        fields.nextField(ptr);
      }
      field=fields.nextField(ptr);
      if(!setValue(_slowP[i], field, i, tr("Vp"), false) ) return false;
      field=fields.nextField(ptr);
      if(!setValue(_slowS[i], field, i, tr("Vs"), false) ) return false;
      field=fields.nextField(ptr);
      if(!setValue(_rho[i], field, i, tr("density"), false) ) return false;
      // Not mandatory quality factors
      field=fields.nextField(ptr);
      if(!setValue(_qp[i], field, i, tr("Qp"), true) ) _qp[i]=0.0;;
      field=fields.nextField(ptr);
      if(!setValue(_qs[i], field, i, tr("Qs"), true) ) _qs[i]=0.0;;
      // Switch to slowness
      _slowP[i]=1/_slowP[i];
      _slowS[i]=1/_slowS[i];
    }
    return initCalculation();
  } else {
    _layerCount=0;
    return false;
  }
}
void QGpCoreWave::Seismic1DModel::fromStream ( QDataStream &  s)

Loads model from a binary stream

References TRACE.

{
  TRACE;
  int n;
  s >> n;
  if(n>_layerCount) n=_layerCount;
  ASSERT(n>0);
  for(int i=0;i<n-1;i++)
  {
    s >> _h[i];
    s >> _slowP[i];
    s >> _slowS[i];
    s >> _rho[i];
  }
  s >> _slowP[n-1];
  s >> _slowS[n-1];
  s >> _rho[n-1];
}
double * QGpCoreWave::Seismic1DModel::h ( int  iLayer) const [inline]

Calculates the Rayleigh-wave velovity as if the model was homogeneous and had the velocity of the layer iLayer.

sq_cob means (c/b)^2 and sq_boa means (b/a)^2.

Equation : (2-sq_cob)-4*sqrt(1-sq_boa*sq_cob)*sqrt(1-sq_cob)=0

The sqrt can be elevated to square, interiors are positive: [(2-x)]=16* (1-sq_boa*x) * (1-x), where x=sq_cob

Calculating all terms: x * [x-8*x+(24-16*sq_boa) *x+(16*sq_boa-16)]=0

x=0 is not a valid solution Thus we are looking for the roots of: x-8*x+a3*x+a4 where, a4=16*sq_boa-16 a3=8-a4

3rd degree poly which solutions are calculated by newton raphson using the derivative : 3*x-16*x+a3

This poly has a simple root in the neighborhood of the starting value (for all boa), thus there is no problem of convergence

References QGpCoreTools::sqrt(), and TRACE.

Referenced by initCalculation().

{
  TRACE;
  double y,x=0.9025;
  /* (c/beta)=0.95 solution for a=infinity, this is a maximum bound
     value for the Rayleigh velocity
  */
  double boa=_slowP[iLayer]/_slowS[iLayer];
  double a4=16*boa*boa-16;
  double a3=8-a4;
  do {
    double sqx=x*x;
    y=x*sqx-8*sqx+a3*x+a4;
    double dy=3*sqx-16*x+a3;
    x=x-y/dy;
  } while(fabs(y)>1e-10);
  // This condition over y achieves a precision over x of about 1e-15
  return _slowS[iLayer]/sqrt(x);
}
double QGpCoreWave::Seismic1DModel::impedanceAt ( double  depth) const

References TRACE.

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return _rho[i]/_slowS[i];
  }
  return _rho[_layerCount-1]/_slowS[_layerCount-1];
}

Returns the impedance (density*S-wave velocity) profile as a Profile

References QGpCoreWave::Profile::resize(), QGpCoreWave::Profile::setDepth(), QGpCoreWave::Profile::setValue(), and TRACE.

{
  TRACE;
  Profile p;
  p.resize(_layerCount);
  double d=0;
  int i;
  for(i=0;i<_layerCount-1;i++) {
    d+= _h[i];
    p.setDepth(i, d);
    p.setValue(i, _rho[i]/_slowS[i] );
  }
  p.setDepth(i, 1e99);
  p.setValue(i, _rho[i]/_slowS[i] );
  return p;
}

Calculates the basic parameters for future calculations and test model validity.

References halfSpaceRayleighSlowness(), and TRACE.

Referenced by dispersion_curve_love_(), dispersion_curve_rayleigh_(), fromStream(), interpole(), ModelGenerator::misfit(), and DinverDCCore::TargetList::surfaceMisfit().

{
  TRACE;
  bool ret=true;
  // Initialize calculation variables:
  for(int i=0;i<_layerCount;i++) {
    if(_slowS[i]!=0) _mu[i]=_rho[i]/ (_slowS[i]*_slowS[i]);
  }
  // Gets index of the layer with beta min or _slowS max
  int iSlowSMax;
  slowMinMax(iSlowSMax);
  if(!checkPoissonRatio()) ret=false;
  _maxRayleighSlowness=1.05 * halfSpaceRayleighSlowness(iSlowSMax);
  return ret;
}
bool QGpCoreWave::Seismic1DModel::interpole ( const Point at,
const Point refPoints,
const Seismic1DModel refModels 
)

refPoints and refModels must contains exactly tree elements, the three reference models. All models must have the same number of layers. This model is initialized with the interpolation of the three models. Linear interpolation in velocity domain.

References allocateData(), deleteData(), QGpCoreTools::endl(), initCalculation(), layerCount(), QGpCoreTools::Plane::setNormalVector(), QGpCoreTools::Plane::setNormalVectorXY(), QGpCoreTools::Plane::setReference(), QGpCoreTools::Plane::setZ(), str, toStream(), QGpCoreTools::tr(), TRACE, and QGpCoreTools::Plane::z().

Referenced by ProfileReader::terminate().

{
  TRACE;
  _layerCount=refModels[0].layerCount();
  if(_layerCount!=refModels[1].layerCount()) {
    App::stream() << tr("Model 1 has not the same number of layers as model 0") << endl;
    return false;
  }
  if(_layerCount!=refModels[2].layerCount()) {
    App::stream() << tr("Model 2 has not the same number of layers as model 0") << endl;
    return false;
  }
  deleteData();
  allocateData();
  Plane p;
  p.setReference(0, refPoints[0]);
  p.setReference(1, refPoints[1]);
  p.setReference(2, refPoints[2]);
  if(!p.setNormalVector()) {
    return false;
  }
  for(int i=0; i<_layerCount; i++) {
    if(i<_layerCount-1) {
      p.setZ(0, refModels[0]._h[i]);
      p.setZ(1, refModels[1]._h[i]);
      p.setZ(2, refModels[2]._h[i]);
      p.setNormalVectorXY();
      _h[i]=p.z(at);
    }
    p.setZ(0, 1.0/refModels[0]._slowP[i]);
    p.setZ(1, 1.0/refModels[1]._slowP[i]);
    p.setZ(2, 1.0/refModels[2]._slowP[i]);
    p.setNormalVectorXY();
    _slowP[i]=1.0/p.z(at);
    p.setZ(0, 1.0/refModels[0]._slowS[i]);
    p.setZ(1, 1.0/refModels[1]._slowS[i]);
    p.setZ(2, 1.0/refModels[2]._slowS[i]);
    p.setNormalVectorXY();
    _slowS[i]=1.0/p.z(at);
    p.setZ(0, refModels[0]._rho[i]);
    p.setZ(1, refModels[1]._rho[i]);
    p.setZ(2, refModels[2]._rho[i]);
    p.setNormalVectorXY();
    _rho[i]=p.z(at);
    p.setZ(0, refModels[0]._qp[i]);
    p.setZ(1, refModels[1]._qp[i]);
    p.setZ(2, refModels[2]._qp[i]);
    p.setNormalVectorXY();
    _qp[i]=p.z(at);
    p.setZ(0, refModels[0]._qs[i]);
    p.setZ(1, refModels[1]._qs[i]);
    p.setZ(2, refModels[2]._qs[i]);
    p.setNormalVectorXY();
    _qs[i]=p.z(at);
  }
  if(initCalculation()) {
    return true;
  } else {
    App::stream() << tr("Poisson's ratio is not physical for interpolated model") << endl;
    QString str;
    QTextStream s(&str);
    toStream(s);
    App::stream() << str;
    return false;
  }
}
virtual bool QGpCoreWave::Seismic1DModel::isEmpty ( ) const [inline, virtual]

Implements QGpCoreWave::GeophysicalModel.

{return layerCount()==0;}
virtual bool QGpCoreWave::Seismic1DModel::isValid ( ) [inline, virtual]

Reimplemented from QGpCoreWave::GeophysicalModel.

{return initCalculation();}
double QGpCoreWave::Seismic1DModel::maxSlowR ( ) const [inline]

Referenced by QGpCoreWave::Dispersion::refine().

{return _maxRayleighSlowness;}
double QGpCoreWave::Seismic1DModel::maxSlowS ( ) const [inline]
{return _slowSMax;}
double QGpCoreWave::Seismic1DModel::minSlowS ( ) const [inline]

Referenced by QGpCoreWave::Dispersion::refine().

{return _slowSMin;}
double * QGpCoreWave::Seismic1DModel::mu ( int  iLayer) const [inline]

Returns the of layer iLayer.

Referenced by QGpCoreWave::Love::y().

{return _mu[iLayer];}
void QGpCoreWave::Seismic1DModel::operator= ( const Seismic1DModel o)

Copy oprator

References allocateData(), and deleteData().

Referenced by Seismic1DModel().

{
  deleteData();
  _layerCount=o._layerCount;
  allocateData();
  int i=_layerCount-1;
  _slowP[i]=o._slowP[i];
  _slowS[i]=o._slowS[i];
  _rho[i]=o._rho[i];
  _mu[i]=o._mu[i];
  _qp[i]=o._qp[i];
  _qs[i]=o._qs[i];
  for(i--;i>=0;i--) {
    _h[i]=o._h[i];
    _slowP[i] =o. _slowP[i];
    _slowS[i]=o._slowS[i];
    _rho[i]=o._rho[i];
    _mu[i]=o._mu[i];
    _qp[i]=o._qp[i];
    _qs[i]=o._qs[i];
  }
  // Calculated variables:
  _slowSMin=o._slowSMin;
  _slowSMax=o._slowSMax;
  _maxRayleighSlowness=o._maxRayleighSlowness;
}
double QGpCoreWave::Seismic1DModel::poisson ( int  iLayer) const

Returns Poisson's ratio for layer iLayer

References TRACE.

Referenced by poissonAt(), and poissonProfile().

{
  TRACE;
  double slowP2=_slowP[iLayer];
  slowP2 *= slowP2;
  double slowS2=_slowS[iLayer];
  slowS2 *= slowS2;
  return (slowP2-0.5*slowS2)/(slowP2-slowS2);
}
double QGpCoreWave::Seismic1DModel::poissonAt ( double  depth) const

References poisson(), and TRACE.

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return poisson(i);
  }
  return poisson(_layerCount-1);
}

Returns the Poisson's ratio profile as a Profile

References poisson(), QGpCoreWave::Profile::resize(), QGpCoreWave::Profile::setDepth(), QGpCoreWave::Profile::setValue(), and TRACE.

{
  TRACE;
  Profile p;
  p.resize(_layerCount);
  double d=0;
  int i;
  for(i=0;i<_layerCount-1;i++) {
    d+= _h[i];
    p.setDepth(i, d);
    p.setValue(i, poisson(i));
  }
  p.setDepth(i, 1e99);
  p.setValue(i, poisson(i));
  return p;
}
double QGpCoreWave::Seismic1DModel::qp ( int  iLayer) const [inline]
double QGpCoreWave::Seismic1DModel::qs ( int  iLayer) const [inline]
double * QGpCoreWave::Seismic1DModel::rho ( int  iLayer) const [inline]
double QGpCoreWave::Seismic1DModel::rhoAt ( double  depth) const

References TRACE.

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return _rho[i];
  }
  return _rho[_layerCount-1];
}

Returns the density profile as a Profile

References QGpCoreWave::Profile::resize(), QGpCoreWave::Profile::setDepth(), QGpCoreWave::Profile::setValue(), and TRACE.

Referenced by DinverDCCore::DCReportBlock::writeNaViewer().

{
  TRACE;
  Profile p;
  p.resize(_layerCount);
  double d=0;
  int i;
  for(i=0;i<_layerCount-1;i++) {
    d+= _h[i];
    p.setDepth(i, d);
    p.setValue(i, _rho[i] );
  }
  p.setDepth(i, 1e99);
  p.setValue(i, _rho[i] );
  return p;
}

Returns an estimation of the fundamental resonnance frequency

\[\frac {V_{soft}}{4 H_t}\]

$V_{soft}$ is the average velocity

$H_t$ is the total thickness of layers except the half space.

References QGpCoreWave::Profile::average(), depth(), slowsProfile(), and QGpCoreWave::Profile::values().

Referenced by QGpCoreWave::Ellipticity::peakMisfit().

{
  // TODO: replace by a more accurate estimation of resonance frequency
  Profile p=slowsProfile();
  p.average();
  return p.values()[_layerCount-1]/(4*depth(_layerCount-1));
}
void QGpCoreWave::Seismic1DModel::setH ( int  iLayer,
double  v 
) [inline]

Copies H values from another model (only if same number of layers)

References TRACE.

{
  TRACE;
  if(_layerCount!=o._layerCount) return;
  for(int i=_layerCount-2;i>=0;i--) _h[i]=o._h[i];
}
void QGpCoreWave::Seismic1DModel::setQp ( int  iLayer,
double  v 
) [inline]
void QGpCoreWave::Seismic1DModel::setQs ( int  iLayer,
double  v 
) [inline]
void QGpCoreWave::Seismic1DModel::setRho ( int  iLayer,
double  v 
) [inline]
void QGpCoreWave::Seismic1DModel::setSlowP ( int  iLayer,
double  v 
) [inline]
void QGpCoreWave::Seismic1DModel::setSlowS ( int  iLayer,
double  v 
) [inline]
double * QGpCoreWave::Seismic1DModel::slowP ( int  iLayer) const [inline]
double QGpCoreWave::Seismic1DModel::slowPAt ( double  depth) const

References TRACE.

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return _slowP[i];
  }
  return _slowP[_layerCount-1];
}

Returns the P-wave slowness profile as a Profile

References QGpCoreWave::Profile::resize(), QGpCoreWave::Profile::setDepth(), QGpCoreWave::Profile::setValue(), and TRACE.

Referenced by vpProfile().

{
  TRACE;
  Profile p;
  p.resize(_layerCount);
  double d=0;
  int i;
  for(i=0;i<_layerCount-1;i++) {
    d+= _h[i];
    p.setDepth(i, d);
    p.setValue(i, _slowP[i] );
  }
  p.setDepth(i, 1e99);
  p.setValue(i, _slowP[i] );
  return p;
}
double * QGpCoreWave::Seismic1DModel::slowS ( int  iLayer) const [inline]
double QGpCoreWave::Seismic1DModel::slowSAt ( double  depth) const

References TRACE.

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return _slowS[i];
  }
  return _slowS[_layerCount-1];
}

Returns the S-wave slowness profile as a Profile

References QGpCoreWave::Profile::resize(), QGpCoreWave::Profile::setDepth(), QGpCoreWave::Profile::setValue(), and TRACE.

Referenced by roughFundamentalFrequency(), and vsProfile().

{
  TRACE;
  Profile p;
  p.resize(_layerCount);
  double d=0;
  int i;
  for(i=0;i<_layerCount-1;i++) {
    d+= _h[i];
    p.setDepth(i, d);
    p.setValue(i, _slowS[i] );
  }
  p.setDepth(i, 1e99);
  p.setValue(i, _slowS[i] );
  return p;
}
void QGpCoreWave::Seismic1DModel::toStream ( QTextStream &  s) const [virtual]

Saves model to text stream s

Format:

      nLayers
      h Vp Vs rho Qp Qs (layer 1)
      ...
      0 Vp Vs rho Qp Qs (layer n)
      

Implements QGpCoreWave::GeophysicalModel.

References elastic(), QGpCoreTools::flush(), and TRACE.

Referenced by QGpCompatibility::CompatAutocorrReport::addModel(), QGpCompatibility::CompatInversionReport::addModel(), DinverDCGui::GroundModelViewer::exportModels(), interpole(), main(), ModelGenerator::misfit(), outputDCModel(), surfaceModelMode(), and ProfileReader::terminate().

{
  TRACE;
  static const QString str4("%1 %2 %3 %4\n");
  static const QString str6("%1 %2 %3 %4 %5 %6\n");
  s << _layerCount << "\n";
  if(elastic()) {
    for(int i=0;i<_layerCount-1;i++)
      s << str4.arg(_h[i], 0, 'g', 20)
               .arg(_slowP[i]==0.0 ? 0.0 : 1/_slowP[i], 0, 'g', 20)
               .arg(_slowS[i]==0.0 ? 0.0 : 1/_slowS[i], 0, 'g', 20)
               .arg(_rho[i], 0, 'g', 20);
    s << str4.arg(0.0, 0, 'g', 20)
             .arg(_slowP[_layerCount-1]==0.0 ? 0.0 : 1/_slowP[_layerCount-1], 0, 'g', 20)
             .arg(_slowS[_layerCount-1]==0.0 ? 0.0 : 1/_slowS[_layerCount-1], 0, 'g', 20)
             .arg(_rho[_layerCount-1], 0, 'g', 20) << flush;
   } else {
    for(int i=0;i<_layerCount-1;i++)
      s << str6.arg(_h[i], 0, 'g', 20)
               .arg(_slowP[i]==0.0 ? 0.0 : 1/_slowP[i], 0, 'g', 20)
               .arg(_slowS[i]==0.0 ? 0.0 : 1/_slowS[i], 0, 'g', 20)
               .arg(_rho[i], 0, 'g', 20)
               .arg(_qp[i], 0, 'g', 20)
               .arg(_qs[i], 0, 'g', 20);
    s << str6.arg(0.0, 0, 'g', 20)
             .arg(_slowP[_layerCount-1]==0.0 ? 0.0 : 1/_slowP[_layerCount-1], 0, 'g', 20)
             .arg(_slowS[_layerCount-1]==0.0 ? 0.0 : 1/_slowS[_layerCount-1], 0, 'g', 20)
             .arg(_rho[_layerCount-1], 0, 'g', 20)
             .arg(_qp[_layerCount-1], 0, 'g', 20)
             .arg(_qs[_layerCount-1], 0, 'g', 20) << flush;
   }
}
void QGpCoreWave::Seismic1DModel::toStream ( QDataStream &  s) const

Saves model to a binary stream

References TRACE.

{
  TRACE;
  s << _layerCount;
  for(int i=0;i<_layerCount-1;i++)
  {
    s << _h[i];
    s << _slowP[i];
    s << _slowS[i];
    s << _rho[i];
  }
  s << _slowP[_layerCount-1];
  s << _slowS[_layerCount-1];
  s << _rho[_layerCount-1];
}
QString QGpCoreWave::Seismic1DModel::toString ( ) const [virtual]

Returns model as a string

Implements QGpCoreWave::GeophysicalModel.

References str, and TRACE.

Referenced by ModelGenerator::misfit(), and DinverDCCore::TargetList::surfaceMisfit().

{
  TRACE;
  QString str;
  str=QString("%1 layers\n").arg(_layerCount);
  str+="          H(m)       Vp(m/s)       Vs(m/s)    Rho(kg/m3)\n";
  for(int i=0;i<_layerCount-1;i++) {
    str+=QString::number(_h[i],'f',1).leftJustified(14,' ',true);
    str+=QString::number(1/_slowP[i],'f',1).leftJustified(14,' ',true);
    str+=QString::number(1/_slowS[i],'f',1).leftJustified(14,' ',true);
    str+=QString::number(_rho[i],'f',1).leftJustified(14,' ',true);
    str+="\n";
  }
  str+=QString("-").leftJustified(14,' ',true);
  str+=QString::number(1/_slowP[_layerCount-1],'f',1).leftJustified(14,' ',true);
  str+=QString::number(1/_slowS[_layerCount-1],'f',1).leftJustified(14,' ',true);
  str+=QString::number(_rho[_layerCount-1],'f',1).leftJustified(14,' ',true);
  str+="\n";
  return str;
}
double QGpCoreWave::Seismic1DModel::vpAt ( double  depth) const

References TRACE.

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return 1/_slowP[i];
  }
  return 1/_slowP[_layerCount-1];
}
double QGpCoreWave::Seismic1DModel::vsAt ( double  depth) const

References TRACE.

Referenced by EC8Reader::parse().

{
  TRACE;
  double d=0;
  for(int i=0;i<_layerCount-1;i++) {
    d+=_h[i];
    if(depth<d) return 1/_slowS[i];
  }
  return 1/_slowS[_layerCount-1];
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines