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; }
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; }