// // Constructor that copies all simbox data from simbox // Simbox::Simbox(const Simbox & simbox): Volume(simbox), top_eroded_surface_(NULL), base_eroded_surface_(NULL) { interval_name_ = ""; status_ = simbox.status_; cosrot_ = cos(GetAngle()); sinrot_ = sin(GetAngle()); dx_ = simbox.dx_; dy_ = simbox.dy_; dz_ = simbox.dz_; inLine0_ = simbox.inLine0_; crossLine0_ = simbox.crossLine0_; ilStepX_ = simbox.ilStepX_; ilStepY_ = simbox.ilStepY_; xlStepX_ = simbox.xlStepX_; xlStepY_ = simbox.xlStepY_; lz_eroded_ = 0; constThick_ = simbox.constThick_; minRelThick_ = simbox.minRelThick_; topName_ = simbox.topName_; botName_ = simbox.botName_; grad_x_ = 0; grad_y_ = 0; std::string s = ""; this->setArea(&simbox, static_cast<int>(simbox.getnx()), static_cast<int>(simbox.getny()), s); this->CopyAllPadding(simbox, 0.0, s); //Second parameter is smallest legal ratio between thickest and thinnest; since this is a copy, allow anything. this->SetErodedSurfaces(simbox.GetTopErodedSurface(), simbox.GetBaseErodedSurface()); }
void Simbox::CopyAllPadding(const Simbox & original, double lz_limit, std::string & err_txt) { setDepth(original.GetTopSurface(), original.GetBotSurface(), original.getnz(), true); calculateDz(lz_limit, err_txt); SetNXpad(original.GetNXpad()); SetNYpad(original.GetNYpad()); SetNZpad(original.GetNZpad()); SetXPadFactor(original.GetXPadFactor()); SetYPadFactor(original.GetYPadFactor()); SetZPadFactor(original.GetZPadFactor()); }
void GridMapping::makeTimeDepthMapping(FFTGrid * 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); // velocity->setAccessMode(FFTGrid::RANDOMACCESS); 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*velocity->getRealValue(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*velocity->getRealValue(i,j,kk-1); } double v = velocity->getRealValue(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; }
ModelGravityStatic::ModelGravityStatic(ModelSettings *& modelSettings, ModelGeneral *& modelGeneral, const InputFiles * inputFiles) { modelGeneral_ = modelGeneral; failed_ = false; before_injection_start_ = false; bool failedLoadingModel = false; bool failedReadingFile = false; std::string errText(""); bool doGravityInversion = true; int numberGravityFiles = 0; for(int i = 0; i<modelSettings->getNumberOfVintages(); i++){ if(modelSettings->getGravityTimeLapse(i)) numberGravityFiles++; } if(numberGravityFiles == 0){ // Everything is ok - we do not need gravity inversion failedLoadingModel = false; doGravityInversion = false; } if(numberGravityFiles == 1){ failedLoadingModel = true; doGravityInversion = false; errText+="Need at least two gravity surveys for inversion."; } // Set up gravimetric baseline if(doGravityInversion){ LogKit::WriteHeader("Setting up gravimetric baseline"); // Find first gravity data file std::string fileName = inputFiles->getGravimetricData(0); int nObs = 30; //user input int nColumns = 5; // We require data files to have five columns observation_location_utmx_.resize(nObs); observation_location_utmy_.resize(nObs); observation_location_depth_.resize(nObs); gravity_response_.resize(nObs); gravity_std_dev_.resize(nObs); ReadGravityDataFile(fileName, "gravimetric base survey", nObs, nColumns, observation_location_utmx_, observation_location_utmy_, observation_location_depth_, gravity_response_, gravity_std_dev_, failedReadingFile, errText); failedLoadingModel = failedReadingFile; Simbox * fullTimeSimbox = modelGeneral->getTimeSimbox(); x_upscaling_factor_ = modelSettings->getNXpad()/5 + 1; // should be user input... y_upscaling_factor_ = modelSettings->getNYpad()/5 + 1; z_upscaling_factor_ = modelSettings->getNZpad()/5 + 1; SetUpscaledPaddingSize(modelSettings); // NB: Changes upscaling factors! dx_upscaled_ = fullTimeSimbox->GetLX()/nx_upscaled_; dy_upscaled_ = fullTimeSimbox->GetLY()/ny_upscaled_; dz_upscaled_ = fullTimeSimbox->GetLZ()/nz_upscaled_; LogKit::LogFormatted(LogKit::Low, "Generating smoothing kernel ..."); MakeUpscalingKernel(modelSettings, fullTimeSimbox); LogKit::LogFormatted(LogKit::Low, "ok.\n"); LogKit::LogFormatted(LogKit::Low, "Generating lag index table (size " + NRLib::ToString(nxp_upscaled_) + " x " + NRLib::ToString(nyp_upscaled_) + " x " + NRLib::ToString(nzp_upscaled_) + ") ..."); MakeLagIndex(nxp_upscaled_, nyp_upscaled_, nzp_upscaled_); // Including padded region! LogKit::LogFormatted(LogKit::Low, "ok.\n"); } if (failedLoadingModel) { LogKit::WriteHeader("Error(s) with gravimetric surveys"); LogKit::LogFormatted(LogKit::Error,"\n"+errText); LogKit::LogFormatted(LogKit::Error,"\nAborting\n"); } failed_ = failedLoadingModel || failedReadingFile; failed_details_.push_back(failedReadingFile); }