Пример #1
0
int SeisPipe2D(DsuTask *zz)
{

  int nt,nx,nz,nw,ntpad,ntfft;
  int it,ix,iz,izz,iw,iw0,iw1,iw2,iw3,iwmin,iwmax;
  int nfreqs,verbose;

  float dt,dx,dy,dz,dw;
  float freqs[4],fw,w,scale,fftscl;
  float *p, **v, *wdxov,*sx;

  complex *cpx;
  float **qx;

  void *TabInfo;
  eTable *et;


  char 	msg[80];

  int   info, ToTid, MasterTid;
  int   sz, pz, pei;

  int	SeisIntPars[20];
  float	SeisFloPars[20];


/* Receive process control information */
  MsgLog(zz, "Receiving Control info  ... " );

  MasterTid = RecvInt(SeisIntPars, 2, -1, MsgCntl); 
  pei = SeisIntPars[0];
  ToTid = SeisIntPars[1];

  MsgLog(zz, " Ready  \n");
  
/*  Receive: 	efile and other pars ...  */

  MsgLog(zz, "Receiving parameters ..." );

  TabInfo = RecvBytes(-1, MsgTable);
  RecvFI(SeisFloPars, 10, SeisIntPars, 10, -1, -1);

  MsgLog(zz, " Ready  \n" );

/* get integer parameters */

  nt = SeisIntPars[0];
  nx = SeisIntPars[1];
  nz = SeisIntPars[2];
  ntpad = SeisIntPars[3];
  verbose = SeisIntPars[4];
  sz = SeisIntPars[5];
  pz = SeisIntPars[6];

  	
/* get Floating point parameters */
  dt = SeisFloPars[0];
  dx = SeisFloPars[1];
  dz = SeisFloPars[2];

  freqs[0] = SeisFloPars[3];
  freqs[1] = SeisFloPars[4];
  freqs[2] = SeisFloPars[5];
  freqs[3] = SeisFloPars[6];

  sz = nz / pz;
  if (pei == (pz - 1)) sz += nz % pz;

  sprintf(msg, "Receiving Velocity info (pei = %d, sz = %d) ... ", pei, sz);
  MsgLog(zz,msg);
  
  v   = alloc2float(nx, sz);

  for (iz=0; iz<sz; ++iz)
    RecvFloat(v[iz], nx, -1, MsgVel);

  MsgLog(zz, " Ready  \n" );

/* determine frequency w sampling */
  ntfft = npfar(nt+ntpad);
  nw = ntfft/2+1;
  dw = 2.0*PI/(ntfft*dt);
  iwmin = MAX(0,MIN(nw-1,NINT(2.0*PI*freqs[0]/dw)));
  iwmax = MAX(0,MIN(nw-1,NINT(2.0*PI*freqs[3]/dw)));
	
/* read extrapolator table */
  et = ezread(TabInfo);
  /* pret(zz -> fp_log, et); */
	
/* allocate workspace */

  MsgLog(zz, "Allocating space ... ");

  qx = alloc2float(nx,sz);
  sx = alloc1float(nx);
  wdxov = alloc1float(nx);
  cpx = alloc1complex(nx);
 
  MsgLog(zz, " Ready \n");

  sprintf(msg, "Process (%d) starting loop on depth steps(%d,%d)\n", 
			pei, pei*(nz/pz), pei*(nz/pz) + sz);
  MsgLog(zz, msg);

  /*  Cleanup qx */

  for (iz=0; iz<sz; ++iz)
          for (ix=0; ix<nx; ++ix)
                  qx[iz][ix] = 0.0;

  /* loop over frequencies w */
  for (iw=iwmin,w=iwmin*dw; iw<iwmax; ++iw,w+=dw) {

    if (verbose && !(iw%1)) {
      sprintf(msg, "\t%d/%d\n",iw,iwmax);
      MsgLog(zz, msg);
    }

    /* load wavefield */
    RecvCplx(cpx, nx, -1, MsgSlice);

    /* loop over depth steps nz */

    for (iz=0; iz<sz; ++iz) {

        /* compute 2.0*dx/v(x) and zero migrated data */
        for (ix=0; ix<nx; ix++)
                  sx[ix] = 2.0*dx/v[iz][ix];

        /* make w*dx/v(x) */
        for (ix=0; ix<nx; ++ix)
                wdxov[ix] = w*sx[ix];

        /* extrapolate wavefield */
        etextrap(et,nx,wdxov,cpx);

        /* accumulate migrated data */
        for (ix=0; ix<nx; ++ix)
                qx[iz][ix] += cpx[ix].r;
    }
    /* Send down the wavefield */
    if ( pei != (pz -1))
            SendCplx(cpx, nx, ToTid, MsgSlice);

  } /* End of loop for iw */

  for (iz=0; iz<sz; iz++) {

    izz = pei*(nz/pz) + iz;
    if (verbose) {
      sprintf(msg, "Sending values for iz = %d\n",izz);
      MsgLog(zz, msg);
    }

    SendFI(qx[iz], nx, &izz, 1, MasterTid, MsgDepth);
  }

  sprintf(msg, "End of processing  for (%d)\n",pei);
  MsgLog(zz, msg);

  /* free workspace */
  free1float(sx);
  free1float(wdxov);
  free2float(v);
  free2float(qx);
  free1complex(cpx);

  pvm_exit();
  return(0);
}
Пример #2
0
void gradient(float *grad)
{
   /* declaration of variables */
   int i, iF, iR, iProc, iDer, iL, iU, offset; 
                                   /* counters */
   int FReceived;                  /* number of frequencies processed */
   int die;                        /* die processor flag */ 
   int apl_pid;                    /* PVM process id control */
   int pid;                        /* process id */
   int masterId;                   /* master id */
   int processControl;             /* monitoring PVM start */
   int FInfo[2];                   /* frequency delimiters */
   float wallcpu;                   /* wall clock time */     
   float *gradPart;                 /* partition of gradients */
   complex **resCDPart;             /* partition of resCD */
   
   /* Clean up log files */
   CleanLog();
     
   /* Reseting synchronization flags */
   for (i = 0; i < nFreqPart; i++)
   {
      statusFreq[i][2] = 0;
   }
      
   /* allocating some memory */
   gradPart = alloc1float(numberPar * limRange);
    
   for (i = 0; i < numberPar * limRange; i++)
   {
      grad[i] = 0;
   }
   
   fprintf(stderr, "Starting communication with PVM for derivatives\n");
   /* starting communication with PVM */
   if ((apl_pid = pvm_mytid()) < 0)
   {
      pvm_perror("Error enrolling master process");
      exit(-1);
   }
   processControl = CreateSlaves(processes, PROCESS_FRECHET, nProc);
   
   if (processControl != nProc)
   {
      fprintf(stderr,"Problem starting PVM daemons\n");
      exit(-1);
   }
      
   /* converting to velocities */
   if (IMPEDANCE)
   {
      for (i = 0; i < info->nL + 1; i++)
      {
         alpha[i] /= rho[i];
         beta[i] /= rho[i];
      }
   }

   /* Broadcasting all processes common information */
   BroadINFO(info, 1, processes, nProc, GENERAL_INFORMATION);
   
   /* sending all profiles */
   BroadFloat(thick, info->nL + 1, processes, nProc, THICKNESS);
   BroadFloat(rho, info->nL + 1, processes, nProc, DENSITY);
   BroadFloat(alpha, info->nL + 1, processes, nProc, ALPHAS);
   BroadFloat(qP, info->nL + 1, processes, nProc, QALPHA);
   BroadFloat(beta, info->nL + 1, processes, nProc, BETAS);
   BroadFloat(qS, info->nL + 1, processes, nProc, QBETA);

   /* sending frequency partitions for each process */
   for (iProc = 0; iProc < nProc; iProc++)
   {
      FInfo[0] = statusFreq[iProc][0];
      FInfo[1] = statusFreq[iProc][1];
      if (info->verbose)
	 fprintf(stderr, 
	 "Master sending frequencies [%d, %d] out of %d to slave Frechet %d [id:%d]\n", FInfo[0], FInfo[1], info->nF, iProc, processes[iProc]);

      procInfo[iProc][0] = FInfo[0];
      procInfo[iProc][1] = FInfo[1];
      SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS);
      statusFreq[iProc][2] = 1;
      
      /* and sending the appropriate correlation chunk */
      /* allocating some memory */
      resCDPart = alloc2complex(FInfo[1] - FInfo[0] + 1, info->nR);

      for (iR = 0; iR < info->nR; iR++)
      {
	 for (i = 0, iF = FInfo[0]; iF <= FInfo[1]; iF++, i++)
	 {
	    resCDPart[iR][i] = resCD[iR][iF - initF];
/*	    fprintf(stderr, "iR %d iF %d [%f %f]\n",
		    iR, iF, resCDPart[iR][i].r, resCDPart[iR][i].i);*/
	 }
      }
      
      /* sending frequency partition to the slave process */
      SendCplx(resCDPart[0], (FInfo[1] - FInfo[0] + 1) * info->nR, 
	       processes[iProc], COVARIANCE_PARTITION);
      free2complex(resCDPart);
   }
   /* waiting modelled frequencies */
   /* master process will send more frequencies if there's more work to do */
   /* measuring elapsed time */
   wallcpu = walltime();


   /* reseting frequency counter */
   FReceived = 0;
   while (FOREVER)
   {
      pid = RecvFloat(gradPart, info->numberPar * info->limRange, -1,
		     PARTIAL_GRADIENT);

      /* finding the frequency limits of this process */
      /* DD 
 fprintf(stderr, "Master finding the frequency limits of this process\n");
      */

      iProc = 0;
      while (pid != processes[iProc])
	 iProc++;
	                       
      /* stacking gradient */
      for (i = 0; i < info->numberPar * info->limRange; i++)
      {
	 grad[i] += gradPart[i];
	 /* DD
	 fprintf(stderr, "i %d grad %f gradPart %f\n", i, grad[i], gradPart[i]);*/
      }
      
      /* summing frequencies that are done */
      FReceived += procInfo[iProc][1] - procInfo[iProc][0] + 1;
      if (info->verbose)
	 fprintf(stderr, "Master received %d frequencies, remaining %d\n",
		 FReceived, info->nF - FReceived);
             
      /* defining new frequency limits */
      i = 0;
      while (i < nFreqPart && statusFreq[i][2])
	 i++;

      /* DD 
      fprintf(stderr, "i %d nFreqPart %d\n", i, nFreqPart);*/
           
      if (i < nFreqPart)
      {
	 /* there is still more work to be done */
	 /* tell this process to not die */
	 die = 0;
	 SendInt(&die, 1, processes[iProc], DIE);
	 FInfo[0] = statusFreq[i][0];
	 FInfo[1] = statusFreq[i][1];
	 
	 if (info->verbose)
	    fprintf(stderr, 
		    "Master sending frequencies [%d, %d] to slave %d\n",
		    FInfo[0], FInfo[1], processes[iProc]);

	 procInfo[iProc][0] = FInfo[0];
	 procInfo[iProc][1] = FInfo[1];
	 SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS);
	 statusFreq[i][2] = 1;

	 /* sending covariance partition */
	 /* allocating some memory */
	 resCDPart = alloc2complex(FInfo[1] - FInfo[0] + 1, info->nR);

	 for (iR = 0; iR < info->nR; iR++)
	 {
	    for (i = 0, iF = FInfo[0]; iF <= FInfo[1]; iF++, i++)
	    {
	       resCDPart[iR][i] = resCD[iR][iF - initF];
	    }
	 }
	 /* sending frequency partition to the slave process */
	 SendCplx(resCDPart[0], (FInfo[1] - FInfo[0] + 1) * info->nR, 
		  processes[iProc], COVARIANCE_PARTITION);
	 free2complex(resCDPart);
      }
      else
      {
	 /* tell this process to die since there is no more work to do */
	 if (info->verbose)
	    fprintf(stderr, "Master ''killing'' slave %d\n", processes[iProc]);
	 die = 1;
	 SendInt(&die, 1, processes[iProc], DIE);
      }
      /* a check to get out the loop */
      if (FReceived >= info->nF) break;
   }

   /* getting elapsed time */
   wallcpu = walltime() - wallcpu;
   fprintf(stderr, "Frechet derivative wall clock time = %f seconds\n\n", 
	   wallcpu);   
   
   /* back to impedances*/
   if (IMPEDANCE)
   {
      for (i = 0; i < info->nL + 1; i++)
      {
         alpha[i] *= rho[i];
         beta[i] *= rho[i];
      }
   }

   /* finally the gradient, the 2 is due Parseval */
   for (iDer = 0; iDer < numberPar * limRange; iDer++)
   {
      grad[iDer] *= 2 / (float) (nTotalSamples * oFNorm);
   }

   /* getting gradient in impedance domain */
   if (IMPEDANCE)
   {
      offset = 0;
      for (i = lim[0], iL = 0; iL < limRange; iL++, i++)
      {
         if (vpFrechet) 
         {
            grad[iL] /= rho[i];
            offset = limRange;
	 }
	 
         if (vsFrechet) 
         {
            grad[iL + offset] /= rho[i];
            offset += limRange;
	 }
	 
         if (rhoFrechet)
         {
            grad[iL + offset] = - alpha[i] * grad[iL] -
	      beta[i] * grad[iL + limRange] + grad[iL + 2 * limRange];
         }
      }
   }

   if (PRIOR)
   {
      auxm1 = 1. / (float) (numberPar * limRange);     /* normalization */
      /* considering the regularization or model covariance term */
      for (i = 0; i < limRange; i++)
      {
	 for (offset = i, iL = 0; iL < limRange; iL++)
	 {
	    iU = 0;
	    if (vpFrechet)
	    {
	       grad[iL] += (alpha[i + lim[0]] - alphaMean[i + lim[0]]) * 
		            CMvP[offset] * auxm1;
	       iU = limRange; /* used as offset in gradient vector */
	    }
	    
	    if (vsFrechet)
	    {
	       grad[iL + iU] += (beta[i + lim[0]] - betaMean[i + lim[0]]) * 
	 	                 CMvS[offset] * auxm1;
	       iU += limRange;
	    }

	    if (rhoFrechet)
	    {
	       grad[iL + iU] += (rho[i + lim[0]] - rhoMean[i + lim[0]]) * 
		                 CMrho[offset] * auxm1;
	    }

	    offset += MAX(SGN0(i - iL) * (limRange - 1 - iL), 1);
	 }
      }
   }

   /* normalizing gradient 
   normalize(grad, numberPar * limRange);*/
   /* freeing memory */
   free1float(gradPart);
}