Esempio n. 1
0
void ModelGravityDynamic::BuildGMatrix(ModelGravityStatic      * modelGravityStatic,
                                       SeismicParametersHolder & seismicParameters)
{
  // Building gravity matrix for each time vintage, using updated mean Vp in generating the grid.
  double gamma = 6.67384e-11; // units: m^3/(kg*s^2)

  Simbox * fullSizeTimeSimbox = modelGeneral_     ->getTimeSimbox();

  // Use vp_current, found in Seismic parameters holder.
  FFTGrid * expMeanAlpha      = new FFTGrid(seismicParameters.GetMuAlpha());  // for upscaling
  FFTGrid * meanAlphaFullSize = new FFTGrid(expMeanAlpha);                    // for full size matrix

  int nx = fullSizeTimeSimbox->getnx();
  int ny = fullSizeTimeSimbox->getny();
  int nz = fullSizeTimeSimbox->getnz();

  double dx = fullSizeTimeSimbox->getdx();
  double dy = fullSizeTimeSimbox->getdy();

  int nxp = expMeanAlpha->getNxp();
  int nyp = expMeanAlpha->getNyp();
  int nzp = expMeanAlpha->getNzp();

  int nxp_upscaled = modelGravityStatic->GetNxp_upscaled();
  int nyp_upscaled = modelGravityStatic->GetNyp_upscaled();
  int nzp_upscaled = modelGravityStatic->GetNzp_upscaled();

  int upscaling_factor_x = nxp/nxp_upscaled;
  int upscaling_factor_y = nyp/nyp_upscaled;
  int upscaling_factor_z = nzp/nzp_upscaled;

  // dimensions of one grid cell
  double dx_upscaled = dx*upscaling_factor_x;
  double dy_upscaled = dy*upscaling_factor_y;

  int nx_upscaled = modelGravityStatic->GetNx_upscaled();
  int ny_upscaled = modelGravityStatic->GetNy_upscaled();
  int nz_upscaled = modelGravityStatic->GetNz_upscaled();

  int N_upscaled = nx_upscaled*ny_upscaled*nz_upscaled;
  int N_fullsize = nx*ny*nz;

  int nObs = 30;

  G_         .resize(nObs, N_upscaled);
  G_fullsize_.resize(nObs, N_fullsize);

  // Need to be in real domain for transforming from log domain
  if(expMeanAlpha->getIsTransformed())
    expMeanAlpha->invFFTInPlace();

  if(meanAlphaFullSize->getIsTransformed())
    meanAlphaFullSize->invFFTInPlace();

  float sigma_squared = GravimetricInversion::GetSigmaForTransformation(seismicParameters.GetCovAlpha());
  GravimetricInversion::MeanExpTransform(expMeanAlpha,      sigma_squared);
  GravimetricInversion::MeanExpTransform(meanAlphaFullSize, sigma_squared);


  //Smooth (convolve) and subsample
  FFTGrid * upscalingKernel_conj = modelGravityStatic->GetUpscalingKernel();
   if(upscalingKernel_conj->getIsTransformed() == false)
    upscalingKernel_conj->fftInPlace();
  upscalingKernel_conj->conjugate();  // Conjugate only in FFT domain.

  // Need to be in FFT domain for convolution and subsampling
  if(expMeanAlpha->getIsTransformed() == false)
    expMeanAlpha->fftInPlace();

  expMeanAlpha->multiply(upscalingKernel_conj);  // Now is expMeanAlpha smoothed

  FFTGrid * upscaledMeanAlpha;
  GravimetricInversion::Subsample(upscaledMeanAlpha, expMeanAlpha, nx_upscaled, ny_upscaled, nz_upscaled, nxp_upscaled, nyp_upscaled, nzp_upscaled);

  upscaledMeanAlpha->invFFTInPlace();

  float x0, y0, z0; // Coordinates for the observations points
  int J = 0;        // Index in matrix counting cell number
  int I = 0;

  float  vp;
  double dt;
  double localMass;
  double localDistanceSquared;

  for(int i = 0; i < nObs; i++){
    x0 = observation_location_utmx_[i];
    y0 = observation_location_utmy_[i];
    z0 = observation_location_depth_[i];

     J = 0; I = 0;

    // Loop through upscaled simbox to get x, y, z for each grid cell
    for(int ii = 0; ii < nx_upscaled; ii++){
      for(int jj = 0; jj < ny_upscaled; jj++){
        for(int kk = 0; kk < nz_upscaled; kk++){
          double x, y, z;
          vp = upscaledMeanAlpha->getRealValue(ii,jj,kk);

          int istart = ii*upscaling_factor_x;
          int istop  = (ii+1)*upscaling_factor_x;
          int jstart = jj*upscaling_factor_y;
          int jstop  = (jj+1)*upscaling_factor_y;
          int kstart = kk*upscaling_factor_z;
          int kstop = (kk+1)*upscaling_factor_z;

          double x_local  = 0;
          double y_local  = 0;
          double z_local  = 0;
          double dt_local = 0;
          //Find center position of coarse grid cell using indices of fine grid and averaging their cell centers.
          for(int iii=istart; iii<istop; iii++){
            for(int jjj=jstart; jjj<jstop; jjj++){
              for(int kkk=kstart; kkk<kstop; kkk++){
                fullSizeTimeSimbox->getCoord(iii, jjj, kkk, x, y, z);
                x_local += x;
                y_local += y;
                z_local += z;   // NB Need time depth mapping!

                dt_local += fullSizeTimeSimbox->getdz(iii, jjj);
              }
            }
          }
          x_local  /= (upscaling_factor_x*upscaling_factor_y*upscaling_factor_z);
          y_local  /= (upscaling_factor_x*upscaling_factor_y*upscaling_factor_z);
          z_local  /= (upscaling_factor_x*upscaling_factor_y*upscaling_factor_z);
          dt_local /= (upscaling_factor_x*upscaling_factor_y*upscaling_factor_z);

          // Find fraction of dx_upscaled and dy_upscaled according to indicies
          double xfactor = 1;
          if(istop <= nx){  // inside
            xfactor = 1;
          }
          else if(istart > nx){ //outside
            xfactor = 0;
          }
          else{
            xfactor = (nx - istart)/upscaling_factor_x;
          }

          double yfactor = 1;
          if(jstop <= ny){
            yfactor = 1;
          }
          else if(jstart > ny){
            yfactor = 0;
          }
          else{
            yfactor = (ny - jstart)/upscaling_factor_y;
          }

          localMass = (xfactor*dx_upscaled)*(yfactor*dy_upscaled)*dt_local*vp*0.5*1000; // units kg
          localDistanceSquared = pow((x_local-x0),2) + pow((y_local-y0),2) + pow((z_local-z0),2); //units m^2

          G_(i,J) = localMass/localDistanceSquared;
          J++;
        }
      }
    }
    // Loop through full size simbox to get x, y, z for each grid cell
    for(int ii = 0; ii < nx; ii++){
      for(int jj = 0; jj < ny; jj++){
        for(int kk = 0; kk < nz; kk++){
          double x, y, z;
          fullSizeTimeSimbox->getCoord(ii, jj, kk, x, y, z); // assuming these are center positions...
          vp = meanAlphaFullSize->getRealValue(ii, jj, kk);
          dt = fullSizeTimeSimbox->getdz(ii, jj);

          localMass = dx*dy*dt*vp*0.5*1000; // units kg
          localDistanceSquared = pow((x-x0),2) + pow((y-y0),2) + pow((z-z0),2); //units m^2

          G_fullsize_(i,I) = localMass/localDistanceSquared;
          I++;
        }
      }
    }
  }
  G_ = G_*gamma;
  G_fullsize_ = G_fullsize_*gamma;
}
Esempio n. 2
0
PosteriorElasticPDF3D::PosteriorElasticPDF3D(const std::vector<double>               & d1,        // first dimension of data points
        const std::vector<double>               & d2,        // second dimension of data points
        const std::vector<double>               & d3,        // third dimension of data points
        const std::vector<int>                  & t1,        // trend data points
        const std::vector<std::vector<double> > & v,        // Transformation of elastic variables from 3D to 2D
        const double             *const*const   sigma,     // Gaussian smoothing kernel in 2D
        int                                     n1,        // resolution of density grid in elastic dimension 1
        int                                     n2,        // resolution of density grid in elastic dimension 2
        int                                     n3,        // resolution of density grid in the trend dimension
        double                                  d1_min,
        double                                  d1_max,
        double                                  d2_min,
        double                                  d2_max,
        double                                  t1_min,
        double                                  t1_max,
        int                                     ind)
    : n1_(n1),
      n2_(n2),
      n3_(n3),
      x_min_(d1_min),
      x_max_(d1_max),
      y_min_(d2_min),
      y_max_(d2_max),
      z_min_(t1_min),
      z_max_(t1_max)
{
    // We assume that the input vectors are of the same length
    if (d1.size()!=d2.size() || d2.size()!=d3.size() || d3.size()!=t1.size())
        throw NRLib::Exception("Facies probabilities: Size of input vectors do not match.");
    if (v.size()>2 || static_cast<int>(v[0].size()) != 3 ||  static_cast<int>(v[1].size()) != 3)
        throw NRLib::Exception("Facies probabilities: Transformation matrix v does not have the right dimensions");

    v1_.resize(3);
    v2_.resize(3);

    for(int i=0; i<3; i++) {
        v1_[i] = v[0][i];
        v2_[i] = v[1][i];
    }

    int dim = static_cast<int>(d1.size());

    std::vector<std::vector<double> > x(2);
    x[0].resize(dim);
    x[1].resize(dim);

    //computes x and y from d1, d2 and d3
    CalculateTransform2D(d1, d2, d3, x, v);

    histogram_ = new FFTGrid(n1_, n2_, n3_, n1_, n2_, n3_);
    histogram_->createRealGrid(false);
    int rnxp = histogram_->getRNxp();
    histogram_->setType(FFTGrid::PARAMETER);
    histogram_->setAccessMode(FFTGrid::WRITE);

    for(int l=0; l<n3_; l++) {
        for(int k=0; k<n2_; k++) {
            for(int j=0; j<rnxp; j++)
                histogram_->setNextReal(0.0f);
        }
    }
    histogram_->endAccess();

    // Spacing variables in the density grid
    dx_ = (x_max_ - x_min_)/n1_;
    dy_ = (y_max_ - y_min_)/n2_;
    dz_ = (z_max_ - z_min_)/n3_;

    // Go through data points and place in bins in histogram

    for (int i = 0; i < dim; i++) {
        //volume->getIndexes(d1[i], d2[i], d3[i], i_tmp, j_tmp, k_tmp);
        int i_tmp = static_cast<int>(floor((x[0][i]-x_min_)/dx_));
        int j_tmp = static_cast<int>(floor((x[1][i]-y_min_)/dy_));
        int k_tmp = t1[i];
        // Counting data points in index (i,j,k)
        histogram_->setAccessMode(FFTGrid::RANDOMACCESS);
        histogram_->setRealValue(i_tmp, j_tmp, k_tmp, histogram_->getRealValue(i_tmp,j_tmp,k_tmp) + 1.0f);
        histogram_->endAccess();
    }

    //multiply by normalizing constant for the PDF - dim is the total number of entries
    histogram_->setAccessMode(FFTGrid::READANDWRITE);
    histogram_->multiplyByScalar(float(1.0f/dim));
    histogram_->endAccess();

    if(ModelSettings::getDebugLevel() >= 1) {
        std::string baseName = "Hist_" + NRLib::ToString(ind) + IO::SuffixAsciiFiles();
        std::string fileName = IO::makeFullFileName(IO::PathToDebug(), baseName);
        histogram_->writeAsciiFile(fileName);
    }

    histogram_->fftInPlace();

    double **sigma_tmp = new double *[2];
    for (int i=0; i<2; i++) {
        sigma_tmp[i] = new double[2];
    }
    for(int i=0; i<2; i++) {
        for(int j=0; j<2; j++)
            sigma_tmp[i][j] = sigma[i][j];
    }
    // Matrix inversion of the covariance matrix sigma
    // SINGULAR MATRIX ?!
    double **sigma_inv = new double *[2];
    for(int i=0; i<2; i++)
        sigma_inv[i] = new double [2];

    InvertSquareMatrix(sigma_tmp,sigma_inv,2);

    FFTGrid *smoother = new FFTGrid(n1, n2, n3, n1, n2, n3);

    smoother->createRealGrid(false);
    smoother->setType(FFTGrid::PARAMETER);
    smoother->setAccessMode(FFTGrid::WRITE);
    for(int l=0; l<n3_; l++) {
        for(int k=0; k<n2_; k++) {
            for(int j=0; j<static_cast<int>(smoother->getRNxp()); j++)
                smoother->setNextReal(0.0f);
        }
    }
    smoother->endAccess();

    //SetupSmoothingGaussian2D(smoother, sigma_inv, n1, n2, n3, dx_, dy_);

    if(ModelSettings::getDebugLevel() >= 1) {
        std::string baseName = "Smoother" + IO::SuffixAsciiFiles();
        std::string fileName = IO::makeFullFileName(IO::PathToDebug(), baseName);
        smoother->writeAsciiFile(fileName);
    }

    // Carry out multiplication of the smoother with the density grid (histogram) in the Fourier domain
    smoother->fftInPlace();
    histogram_->multiply(smoother);
    histogram_->invFFTInPlace();
    histogram_->multiplyByScalar(sqrt(float(n1_*n2_*n3_)));
    histogram_->endAccess();

    delete smoother;
    for(int i=0; i<2; i++) {
        delete [] sigma_inv[i];
        delete [] sigma_tmp[i];
    }
    delete [] sigma_tmp;
    delete [] sigma_inv;
}