void GridMapping::makeTimeDepthMapping(NRLib::Grid<float> * velocity, const Simbox * timeSimbox) { Simbox * depthSimbox = simbox_; // For readability int nx = depthSimbox->getnx(); int ny = depthSimbox->getny(); int nz = depthSimbox->getnz(); mapping_ = new StormContGrid(*depthSimbox, nx, ny, nz); for(int i=0;i<nx;i++) { for(int j=0;j<ny;j++) { double x,y; depthSimbox->getXYCoord(i,j,x,y); double tTop = timeSimbox->getTop(x,y); double tBase = timeSimbox->getBot(x,y); double zTop = depthSimbox->getTop(x,y); double zBase = depthSimbox->getBot(x,y); double deltaT = (tBase-tTop)/(static_cast<double>(2000*timeSimbox->getnz())); double deltaZ = (zBase-zTop)/static_cast<double>(nz); double sum = 0.0; double sumz = 0.0; for(int k=0 ; k<timeSimbox->getnz() ; k++) sumz +=deltaT*static_cast<double>(velocity->GetValue(i,j,k)); double c = (zBase-zTop)/sumz; (*mapping_)(i,j,0) = static_cast<float>(tTop); int kk = 0; for(int k=1;k<nz;k++) { double z = k*deltaZ; while(sum<z && kk<nz) { kk++; sum+=deltaT*c*static_cast<double>(velocity->GetValue(i,j,kk-1)); } double v = velocity->GetValue(i,j,kk-1); double z0 = tTop; double dz1 = 2000.0*static_cast<double>(kk-1)*deltaT; double dz2 = 2000.0*(z - sum + deltaT*c*v)/(c*v); (*mapping_)(i,j,k) = static_cast<float>(z0 + dz1 + dz2); } } } // velocity->endAccess(); }
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; }